Skip to content
Shamar

Overview

@shamar/wire is the live-component layer the rest of Shamar is built on. A request still returns HTML. Wire is how a piece of that page keeps its state on the server: typing in global search, marking a notification read, or clicking increment on a counter. Alpine.js can still open a menu that never needs the server. $wire is the bridge when Alpine and a Wire island share a page.

You write a class whose public fields are the state and whose methods are the actions. The browser holds an HTML island and a signed snapshot of that state. An action posts the snapshot back. The server checks the signature, runs the method, and returns new HTML. The browser morphs the island in place so focus and surrounding page stay put.

A normal Adonis page can use Wire with no admin panel at all. The panel is one host on top of the same runtime: resources, forms, and tables describe the back office, and Wire carries the pieces that have to round-trip. Install is where the files live. Components is discovery and hooks. SPA navigation is moving between whole pages without a full reload. After that, Introduction is how the panel is built on this layer, and Installation is how you mount it.

GET / mount() → HTML island + signed snapshot
user input browser → POST /wire { snapshot, updates, calls }
server update() → verify, hooks, methods, new HTML
browser morph → same DOM node, or follow effects.redirect

The endpoint in kernel.mount('counter', '/wire') must be the POST URL you registered. The script URL can be different. registerWire uses /wire for POST and /wire.js for the script. A Shamar panel uses POST /admin/wire and GET /admin/assets/wire.js.

{
"snapshot": {
"id": "a1b2c3d4e5f67890",
"name": "counter",
"data": { "count": 0 },
"checksum": "hex hmac"
},
"updates": { "count": 1 },
"calls": [{ "method": "increment", "params": [] }]
}
{
"snapshot": {
"id": "a1b2c3d4e5f67890",
"name": "counter",
"data": { "count": 2 },
"checksum": "new hmac"
},
"html": "<div wire:id=\"…\" wire:snapshot=\"…\" wire:endpoint=\"/wire\"><button type=\"button\" wire:click=\"increment\">2</button></div>"
}

effects is added only when the component set one. A redirect is not stored in the snapshot.

{ "effects": { "redirect": "/orders/4" } }

Continue with Install. The kernel protocol on this page is what the provider does for you. Build it by hand only in Without Adonis.