star#
A native Lightspeed LiveView app on Mist (port 8080).
Server-owned state, typed events, verified routes, and the Lightspeed wire protocol — no Datastar.
What you get#
| Piece | Role |
|---|---|
star/live.gleam |
stateful.LifecycleComponent — model, msgs, routes, render |
star/ws.gleam |
Live session host — protocol Event → handle → Diff patch |
star.gleam |
Mist HTTP + /live WebSocket + endpoint |
/assets/lightspeed.js |
Minimal browser runtime (data-ls-click → Event frames) |
UI (all server-driven)#
- Counter (
inc/dec/reset) - Toggle panel
- Greeting form
- Notes (save / delete)
Run#
# enter the flake dev shell, then run
nix develop
gleam run
# or one-shot from the repo root
nix run
Open http://localhost:8080/
Routes#
| Path | What |
|---|---|
GET / |
LiveView shell (data-ls-* + initial HTML) |
WS /live |
Lightspeed protocol (hello / event / diff / ack) |
GET /health |
Controller route (ok) |
GET /assets/app.css |
Styles |
GET /assets/lightspeed.js |
Client runtime |
Idioms used#
// verified route + live controller
endpoint.new(contract.allow_all("owner-1"), "/live")
|> endpoint.get_live(index, "star_view", fn(_conn) { initial_body() })
// stateful component (mount / handle / render / routes)
stateful.LifecycleComponent(
mount: mount,
update: update_assigns,
handle: handle,
render: render,
routes: routes(),
)
// typed event decoding
stateful.route("greet", fn(e) {
event.decode_form(e, "greet", fn(data) { ... })
})
Client hooks are LiveView-style attributes:
<button data-ls-click="inc">+</button>
<button data-ls-click="delete_note" data-ls-value="1">Delete</button>
Development#
gleam test