A small composable Hono + htmx component backed by shared Yjs state. Each instance owns one boolean at toggle:<instance>.value and stays synchronized across clients through named Server-Sent Events.
| File | Purpose |
|---|---|
index.tsx | Toggle routes, rendered button fragments, Yjs mutations, SSE synchronization, and exports. |
toggle.meta.tsx | Machine-readable contract plus the handler and metadata UI mounted at the component root. |
README.md | Usage and endpoint reference. |
template.tsx | Parked fragment/template experiment; it is not mounted by index.tsx. |
GET / renders the component metadata UI with interactive GET routes.GET /list reads existing toggle:* maps from Yjs and returns their instance names as autocomplete options; it never seeds instances.GET /:instance renders a persistent wrapper with one SSE connection./:instance/on or /:instance/off based on the current Yjs value.value and swaps only the button with outerHTML.value change emits an SSE event named on or off, updating other connected buttons.No transition logic or client-side state store is required.
The paths below are relative to the component mount point. In the combined gallery, the handler is mounted at /toggle.
| Route | Behavior |
|---|---|
GET / | Render the metadata UI with route controls. |
GET /list | Return a datalist populated from existing Yjs toggle instances. |
GET /:instance | Render the persistent htmx/SSE wrapper. |
GET /:instance/on | Wait until the value is true, then render the ON button. Optional ?timeout=ms; default is 30 seconds. |
POST /:instance/on | Set the value to true and render the ON button. |
GET /:instance/off | Wait until the value is false, then render the OFF button. Optional ?timeout=ms; default is 30 seconds. |
POST /:instance/off | Set the value to false and render the OFF button. |
GET /:instance/stream | Stream named on and off events when value changes. |
GET /:instance/inspect | Return the shared Yjs document as JSON for debugging. |
import { handler as toggle } from "./components/toggle";
app.route("/toggle", toggle);
Open /toggle for the component contract, or navigate directly to an instance such as /toggle/job1.
The default export is a fetch handler. Its root renders the same metadata UI.
import toggle from "./components/toggle";
export default toggle;
The parent Yjs factory provides:
state("toggle") middleware for the instance map and long-poll helper.instancePath(c) for mount-safe URLs.changes(map, signal) for Yjs change observation.