Live views
A live view keeps its state on the server and renders it there. The browser sends user events and gets back only the values that changed, often a few bytes.
Use it when the server should own the state: a register, a dashboard, a checkout. It isn’t meant for collaborative editing: two people typing in the same field overwrite each other, last write wins.
A view
A view is views/<name>.js in the app:
export const rule = "@request.auth.id != null";
export function mount(ctx) {
return { count: 0 };
}
export function render(state, html) {
return html`<button sluurp-click="bump">Clicked ${state.count} times</button>`;
}
export function handle(event, payload, state, ctx) {
if (event === "bump") return { ...state, count: state.count + 1 };
return state;
}rule: who may open it, in the rules language.mount: returns the initial state;ctxhas the user who opened the view.render: renders the state with thehtmltag.handle: takes an event and returns the next state.
On the page
import { mount } from "sluurp/live";
await mount("#counter", "counter");Attributes bind DOM events to view events:
<button sluurp-click="bump">+1</button>
<input sluurp-input="search" name="q">
<form sluurp-submit="save">…</form>The payload includes the element’s value, a form’s fields, and any sluurp-value-* attributes. Add sluurp-ignore to an element to leave its children untouched across updates, e.g. for a client-side widget.
Why so little goes over the wire
A tagged html template is already split by JavaScript into static strings and dynamic values. Only the values are diffed between renders, and only changed ones are sent. A counter going from 41 to 42 sends 42.
Auth is the regular browser client’s, so a view sees the same user the REST API does.