import { parseEveCommandReceipt, parseEveProviderAdvertisement, parseEveSurfaceDocument } from "@gamecult/eve-contracts"; import { renderEveSurface } from "@gamecult/eve-browser-lowering"; import { CultMeshBrowserClient, CultMeshBrowserOdinRendezvous, decodeCultNetOperationPayload, decodeCultNetPayload, } from "cultmesh-browser"; // CounterState is an integer-keyed MessagePack object: [counterId, count, receipts]. const counterCount = (record: Parameters[0]) => decodeCultNetPayload<[string, number, unknown]>(record)[1]; declare global { interface Window { __sampleReady?: boolean; __sampleCount?: number; __sampleReceipt?: { receiptId: string; count: number }; __sampleCommandId?: string; __sampleConnectionStates?: string[]; __sampleError?: string; } } const params = new URLSearchParams(location.search); const odinEndpoint = params.get("odin"); const token = params.get("token") || "sample-session"; if (!odinEndpoint) throw new Error("The sample requires an Odin endpoint query parameter."); document.cookie = `cultnet_session=${encodeURIComponent(token)}; Path=/; SameSite=Strict`; const host = document.querySelector("#surface")!; const receiptOutput = document.querySelector("#receipt")!; try { const mesh = await CultMeshBrowserClient.connect({ verseId: "sample.counter", authorityRuntimeId: "sample.counter-daemon", runtimeId: "sample.chromium", trust: { mode: "local-development" }, rendezvous: new CultMeshBrowserOdinRendezvous({ endpoints: [odinEndpoint], runtimeId: "sample.chromium.discovery", transportVersion: "cultmesh.v0", }), }); window.__sampleConnectionStates = []; mesh.watchState(state => window.__sampleConnectionStates!.push(state)); window.__sampleCommandId = "browser-click-1"; const counter = await mesh.leaseRawDocument({ schemaId: "sample.counter_state.v1", recordKey: "counter:main", subscriptionId: "browser-counter", }); const surface = await mesh.leaseRawDocument({ schemaId: "gamecult.eve.surface.v1", recordKey: "sample.counter", subscriptionId: "browser-surface", }); // The provider owns the declaration of where this surface's commands go and // what comes back; the page reads it rather than restating it. const advertisement = await mesh.leaseRawDocument({ schemaId: "gamecult.eve.provider_advertisement.v1", recordKey: "sample.counter-ui", subscriptionId: "browser-provider", }); const provider = parseEveProviderAdvertisement(decodeCultNetPayload(advertisement.current!)); const currentSurface = parseEveSurfaceDocument(decodeCultNetPayload(surface.current!)); renderEveSurface(currentSurface, host, { activeSurfaceId: "sample.counter", clientId: "sample.chromium", provider, commandSink: async intent => { const response = await mesh.invoke({ serviceId: "sample.counter", operation: intent.operation.operationId, payloadSchema: "sample.increment.v1", payload: { amount: 1 }, idempotencyKey: window.__sampleCommandId, }); const receipt = parseEveCommandReceipt(decodeCultNetOperationPayload(response)) as { receiptId: string; count: number; }; window.__sampleReceipt = receipt; receiptOutput.textContent = receipt.receiptId; }, stateBindingResolver: async binding => { if (binding.pointerId !== "sample.counter.count") return undefined; return { latest: async () => counterCount(counter.current!), watch: callback => counter.watch(record => { if (!record) return; const count = counterCount(record); window.__sampleCount = count; callback(count); }), }; }, }); window.__sampleCount = counterCount(counter.current!); window.__sampleReady = true; } catch (error) { const details = error instanceof AggregateError ? error.errors.map(inner => inner instanceof Error ? inner.stack || inner.message : String(inner)).join("\n---\n") : ""; window.__sampleError = (error instanceof Error ? error.stack || error.message : String(error)) + (details ? `\n${details}` : ""); host.textContent = window.__sampleError; throw error; }