← In use

Webraku

One Raku program, on the server and in the browser. Raku++ runs each page on the server to answer the request with finished HTML, and rakupp --target=js compiles the same file into the script the browser runs, which picks the page up where the server left it.

Open the live demos Webraku on GitHub

use Webraku;

sub rendered-at(--> Str) is server { DateTime.now.hh-mm-ss }

page '/', :title('Counter'), {
    my $n = 0;
    main {
        h1 'Camelia counts';
        my $out = p 'clicked 0 times';
        my $up  = button 'Click me';
        p "rendered on the server at {rendered-at()}";

        react {
            whenever $up.clicks { $out.text = "clicked {++$n} times" }
        }
    }
}

serve;

The clicks are counted in the browser, with no request after the page loads. rendered-at is marked is server: its body stays on the server, and the browser calls it over HTTP without anyone writing a request, a route or a line of JSON. Its answer was written into the page when the server rendered it, so the browser's first render does not ask again, and the page is complete with JavaScript switched off.

The demos #

Each demo is one Raku program with a module or two beside it, and each draws the line between the two halves in a different place, for a different reason. The front page of the demo site shows, for every demo, which subs and modules stay on the server — read from its source by Webraku's own bundler.

Two small ones show the extremes: a sieve whose code never reaches the browser, only its answer, and a counter that needs nothing from the server once the page has loaded.

How one file becomes two programs #

Pagesa page block builds the HTML with a sub per tag: div :class<card>, { h2 $title; p $text }. On the server it renders; in the browser the same block adopts the nodes the server sent.
Stateplain Raku variables. A changed element is written into the page after the event that changed it; there is no virtual DOM.
EventsSupplies: whenever $button.clicks { … } in a react block, which in the browser is the page for as long as it is open.
Server codesub load() is server { … }. Its body, and any module beside the program that only server code uses, stays out of the browser’s script.
Modulesa module the browser’s code calls is compiled into the script by rakupp --target=js, installed ones included.

--target=js exists in no other Raku, so Webraku needs Raku++; there are no other dependencies — no npm, no bundler, no JavaScript to write. The HTTP server is Webraku’s own, in Raku. Webraku is version 0.0.1 and a work in progress.

Run it yourself #

$ rakupp install Webraku
$ webraku run hello.raku --port=8080

With a checkout of the repository, rakupp demo/run.raku --proxy=8080 serves every demo on one port, the way the demo site runs them, and demo/README.md says how to put them behind a proxy on a server of your own.

Next #