2026-08-18 00:05:57 +02:00
|
|
|
# CultMesh Browser
|
|
|
|
|
|
|
|
|
|
`cultmesh-browser` is the browser-safe CultMesh client boundary. It owns one
|
2026-08-18 10:42:33 +02:00
|
|
|
WebSocket session for a stable Verse/authority-runtime target, retains explicit raw
|
2026-08-18 00:05:57 +02:00
|
|
|
document leases across route replacement, and correlates typed CultNet
|
|
|
|
|
operations with provider receipts.
|
|
|
|
|
|
|
|
|
|
It does not own application state and it does not expose direct document
|
|
|
|
|
writes. A renderer watches provider-owned records and invokes provider-owned
|
|
|
|
|
operations.
|
|
|
|
|
|
|
|
|
|
```ts
|
2026-08-18 00:34:44 +02:00
|
|
|
const odin = new CultMeshBrowserOdinRendezvous({
|
|
|
|
|
endpoints: ["wss://odin.example/verse"],
|
|
|
|
|
runtimeId: "counter-browser.discovery",
|
|
|
|
|
});
|
|
|
|
|
|
2026-08-18 00:05:57 +02:00
|
|
|
const mesh = await CultMeshBrowserClient.connect({
|
|
|
|
|
verseId: "sample.counter",
|
2026-08-18 10:42:33 +02:00
|
|
|
authorityRuntimeId: "sample.counter-daemon",
|
2026-08-18 00:05:57 +02:00
|
|
|
runtimeId: "counter-browser",
|
2026-08-18 00:34:44 +02:00
|
|
|
rendezvous: odin,
|
2026-08-18 00:05:57 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const counter = await mesh.leaseRawDocument({
|
|
|
|
|
schemaId: "sample.counter_state.v1",
|
|
|
|
|
recordKey: "counter:main",
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
counter.watch(record => renderCounter(decodeCultNetPayload(record)));
|
|
|
|
|
```
|
|
|
|
|
|
2026-08-18 05:59:11 +02:00
|
|
|
`invoke(...)` returns the correlated provider response. Routing, schema, and
|
|
|
|
|
envelope failures reject immediately with `CultMeshBrowserOperationError`;
|
|
|
|
|
callers can branch on its stable `status` and `code` without parsing prose or
|
|
|
|
|
waiting for the request timeout. Domain rejections remain typed provider
|
|
|
|
|
responses because the domain still owns their receipt schema.
|
|
|
|
|
|
2026-08-18 00:34:44 +02:00
|
|
|
`CultMeshBrowserOdinRendezvous` speaks the canonical CultNet Verse-catalog
|
|
|
|
|
messages to one or more configured Odin WebSocket endpoints. Application code
|
2026-08-18 10:42:33 +02:00
|
|
|
supplies the Verse and authority-runtime identity; it does not own endpoint
|
|
|
|
|
selection, reconnect, or resubscription. This is deliberately distinct from an
|
|
|
|
|
Eve surface's `providerId`, which identifies the UI provider inside the Verse.
|
|
|
|
|
The physical socket is a replaceable route, not either stable identity.
|
2026-08-18 00:05:57 +02:00
|
|
|
|
2026-08-18 17:21:58 +02:00
|
|
|
Odin returns exact authority-route bindings. The browser selects only routes
|
|
|
|
|
bound to the requested authority and `cultmesh.documents.v1`, then performs a
|
|
|
|
|
session-open handshake. It does not report `connected` until the peer proves
|
|
|
|
|
the exact Verse, authority runtime, protocol, and route generation. Operation
|
|
|
|
|
responses must also name that authority. Legacy catalogs are accepted only
|
|
|
|
|
when one authority runtime makes the endpoint binding unambiguous.
|
|
|
|
|
|
2026-08-18 00:05:57 +02:00
|
|
|
The browser handshake carries authentication through the host application's
|
|
|
|
|
ordinary secure cookie or equivalent upgrade credential. The C# host adapter
|
|
|
|
|
rejects endpoints without an authorization predicate unless anonymous local
|
|
|
|
|
development is explicitly enabled.
|
|
|
|
|
|
|
|
|
|
Run `scripts/verify-eve-browser-network.mjs --eve-root <path-to-Eve>` for the
|
2026-08-18 17:21:58 +02:00
|
|
|
real Chromium + C# headless chronology. The witness publishes a lower-priority
|
|
|
|
|
decoy endpoint owned by another runtime and proves that neither client connects
|
|
|
|
|
to it before and after route rotation.
|