Browser displays

This package owns ordinary graph transactions for browser enrollment, assignment and reported mount state. Studio supplies the host adapter; the package contains no browser heartbeat, DOM code or private storage API.

A workspace entry conforms to WebStudioDisplayDirectory. Its conformance owns an enrollment edge, and enroll({nonce,label}) returns the same target for that nonce. Each directory currently permits 128 targets and rejects further enrollment explicitly. This is a bounded prototype, not an automatic device inventory GC.

WebStudioDisplayTarget.assign accepts an optional subject/presentation pair. The subject conforms to WebStudioPresentable, whose canPresent validates the selected registered presentation. This role does not require Canvas or placements; the example workspace adapters forward their existing presentation check. Named presentations have checked subject-only module contracts; callbacks cannot be stored in assignments. The target's subject is a graph edge, not a string ID in JSON. Changing the edge and desired generation is one transaction.

Assignments and observed outcomes are durable. acknowledge accepts a generation, monotonic report sequence, status (mounted, failed, empty) and bounded error. Old generations and reordered reports return false without modifying state. Reported success describes a client mount; it is not a claim of trusted execution.

The browser adapter uses a per-tab nonce and Web Lock. Duplicated tabs get distinct nonces; reloading resumes enrollment. Enrollment is a host startup/user action, never business-object creation from a component render. Multiple displays may mount the same subject. Losing the connection does not clear its desired state.

Studio's authenticated presence adapter validates target references against Camino before issuing an opaque connection lease. Leases expire after 45 seconds; recent connection observations remain for at most ten minutes, with a 256-record cap. A target ID is not a credential. There is no persistent heartbeat history.

Headless calls

A headless session uses the same generated descriptors and public operations as Studio. The caller supplies normal workspace authorization when opening its session; graph references alone grant no access.

const directory = await session.acquire(
  { enroll: interfaces.WebStudioDisplayDirectory.enroll },
  session.bootstrap.entry,
);
const enrollment = await directory.enroll.call({
  nonce: savedClientNonce,
  label: "Preview display",
}).settled;
if (enrollment.status !== "accepted") throw Error(enrollment.status);
const target = await session.acquire(interfaces.WebStudioDisplayTarget, enrollment.value);
const result = await target.assign.call({
  subject: presentableSubject,
  presentation: "presentation:studio:canvas",
}).settled;

tools/local-first/studio-session.test.mjs is the executable example, including reference rejection and stale-report tests. package.nix selects the server-only TypeScript artifact. Native fields and relationships remain queryable in browser replicas without bundling mutation implementations there.

S
Description
Quixos Workspace Template resource
Readme
476 KiB
Languages
TypeScript 65.9%
Nix 34.1%