Native Lightspeed LiveView app on Mist (Gleam)
1.8 kB
79 lines
1# star
2
3A **native Lightspeed** LiveView app on [Mist](https://hexdocs.pm/mist) (port **8080**).
4
5Server-owned state, typed events, verified routes, and the Lightspeed wire protocol — no Datastar.
6
7## What you get
8
9| Piece | Role |
10|-------|------|
11| `star/live.gleam` | `stateful.LifecycleComponent` — model, msgs, routes, render |
12| `star/ws.gleam` | Live session host — protocol Event → handle → Diff patch |
13| `star.gleam` | Mist HTTP + `/live` WebSocket + `endpoint` |
14| `/assets/lightspeed.js` | Minimal browser runtime (`data-ls-click` → Event frames) |
15
16### UI (all server-driven)
17
18- Counter (`inc` / `dec` / `reset`)
19- Toggle panel
20- Greeting form
21- Notes (save / delete)
22
23## Run
24
25```sh
26# enter the flake dev shell, then run
27nix develop
28gleam run
29
30# or one-shot from the repo root
31nix run
32```
33
34Open **http://localhost:8080/**
35
36## Routes
37
38| Path | What |
39|------|------|
40| `GET /` | LiveView shell (`data-ls-*` + initial HTML) |
41| `WS /live` | Lightspeed protocol (`hello` / `event` / `diff` / `ack`) |
42| `GET /health` | Controller route (`ok`) |
43| `GET /assets/app.css` | Styles |
44| `GET /assets/lightspeed.js` | Client runtime |
45
46## Idioms used
47
48```gleam
49// verified route + live controller
50endpoint.new(contract.allow_all("owner-1"), "/live")
51|> endpoint.get_live(index, "star_view", fn(_conn) { initial_body() })
52
53// stateful component (mount / handle / render / routes)
54stateful.LifecycleComponent(
55 mount: mount,
56 update: update_assigns,
57 handle: handle,
58 render: render,
59 routes: routes(),
60)
61
62// typed event decoding
63stateful.route("greet", fn(e) {
64 event.decode_form(e, "greet", fn(data) { ... })
65})
66```
67
68Client hooks are LiveView-style attributes:
69
70```html
71<button data-ls-click="inc">+</button>
72<button data-ls-click="delete_note" data-ls-value="1">Delete</button>
73```
74
75## Development
76
77```sh
78gleam test
79```