Cromponent ๐ now lets your components bind cookies, query-string params, headers and HTTP-auth credentials directly in the method signature ๐ชโ๐๐ and push live HTML over WebSockets with two tiny hooks ๐๐ฐ๏ธ.
Paired with HTMX on the client, that means real-time Raku apps with zero JavaScript ๐. Below youโll find the new API plus a complete โlive pollโ example. Dive in! ๐โโ๏ธ
โธป
- Why Cromponent? ๐คโจ
Cromponent glues together Croโs reactive HTTP / WebSocket server and Cro Templates to give Raku developers a component abstraction ร la modern SPA frameworks โ but rendered on the server and streamed as HTML fragments.
The latest release focuses on state & interaction: declarative request-context binding and built-in WebSocket wiring. โค๏ธโ๐ฅ
โธป
- Prerequisites at a Glance ๐๐
Layer | Role | 1-Liner |
---|---|---|
HTMX โก | Enriches plain HTML with AJAX, SSE & WebSockets via attributes. |
hx-put, hx-target, hx-ext="ws" , โฆ |
Cro ๐งฉ | Reactive HTTP/WebSocket server & router for Raku. | route { โฆ } |
Cro Templates ๐๏ธ | HTML-centric templating DSL compiled on first use. | template 'view.crotmp', %data |
Red ORM ๐๏ธ | DB-agnostic ORM with migrations & relationships. | model Foo { has Int $.id is serial โฆ } |
Dynamic vars ๐ |
$*foo passes per-request context through deep calls. |
$*user in our example |
- New API: Context Traits ๐ชโ๐๐
Any method tagged is accessible becomes an endpoint and auto-binds request data:
method profile(
Str :$uuid is cookie,
Str :$q is query,
Str :$accept is header,
Str :$creds is auth
) is accessible { ... }
- Zero plumbing ๐ ๏ธ
- Type-safe input ๐ก๏ธ
- Self-documenting signatures ๐
Route pattern:
/ComponentName/<idsโฆ>/profile
- New API: Automatic WebSockets ๐๐ฐ๏ธ
- Channel key โ
method IDS { $!id }
groups browsers in the same room. - Re-render hook โ
method REDRAW(:$*user is cookie) { $.Str }
returns fresh HTML when you redraw $component. -
<|WebSocket>
cromponent addshx-ext="ws" ws-connect="/ws"
and the htmx-ws extension swaps fragments for you.
- Channel key โ
No manual frames, pings or reconnect loops โ Cro & HTMX handle all that jazz. ๐ท
โธป
- Building a Live Poll ๐ณ๏ธโก
5.1. Router & DB Setup ๐ฃ๏ธ
my $routes = route {
red-defaults "SQLite";
PollItem.^add-cromponent-routes; # auto REST ๐
WebSocket.^add-cromponent-routes; # auto WS ๐
get -> 'polls', Str :$*user is cookie = UUID.new.Str {
response.set-cookie: :name<user>, :value($*user);
template 'polls.crotmp', { :$*user, :@polls = Poll.^all }
}
}
Cro::HTTP::Server.new(:host<0.0.0.0>, :port(2000), :$routes).start;
First visit โก๏ธ generates UUID โก๏ธ saves in ๐ช โก๏ธ available as $*user.
5.2. Poll Component ๐
model Poll does Cromponent {
has UInt $.id is serial;
has Str $.descr is column;
has @.items is relationship(*.poll-id, :model<PollItem>);
has @.votes is relationship(*.poll-id, :model<PollVote>);
method LOAD($id) { Poll.^load: $id } # rebuild
method IDS { $!id } # WS room
method REDRAW(:$*user) { $.Str } # push update
method did-user-vote($who = $*user) {
?@.votes.first: *.user eq $who
}
method RENDER { โฆ } # the template
}
5.3. PollItem Component โ
method vote(Str :$*user is cookie)
is accessible { :http-method<PUT>, :returns-cromponent } {
red-do :transaction, {
$!votes++;
self.^save;
$!poll.votes.create: :$*user;
redraw $!poll; # broadcast ๐
$!poll
}
}
HTMX button:
<button
hx-put="/poll-item/42/vote"
hx-target="closest .poll"
hx-swap="outerHTML">๐ณ๏ธ Vote</button>
5.4. WebSocket-Enabled Page ๐ฅ๏ธ
<|Boilerplate(:title('Polls ๐ณ๏ธ'), :htmx, :style-sheets('/css'))>
<|WebSocket>
<h6>Logged in as <.user> ๐โโ๏ธ</h6>
<@.polls><&HTML($_)></@>
<a href="/polls">All polls ๐</a>
</|>
</|>
- Generated Endpoints Recap ๐ค๏ธ
Method | Path | Source | |
---|---|---|---|
GET | /polls |
manual route | โ |
GET | /polls/<id> |
manual route | โ |
PUT | /poll-item/<id>/vote |
PollItem.vote | โ |
GET | /cromponent-ws |
WebSocket | โ |
One call to .^add-cromponent-routes
โก๏ธ endpoints galore! ๐
โธป
- Key Take-aways ๐ก
- Context traits (
is cookie
๐ช,is query
โ,is header
๐,is auth
๐) shred boilerplate. -
IDS
+REDRAW
inject WebSocket magic with two methods. โจ - Everything lives in one file: model + template + behaviour โ still plain Raku, still testable. ๐งช
Result: back-end-driven UX with instant updates and zero JavaScript. ๐
โธป
- Further Reading ๐
- ๐ Cromponent โ https://github.com/FCO/Cromponent
- ๐ Cro docs โ https://cro.services
- ๐๏ธ Red ORM โ https://github.com/FCO/Red
- โก HTMX โ https://htmx.org
- ๐ htmx-ws extension โ https://htmx.org/extensions/ws/
- ๐ง Dynamic vars in Raku โ https://docs.raku.org/language/variables#Dynamic_variables
Happy hacking โ and may your components stay Crom-pact! ๐ฆ๐
Top comments (0)