Files
Endoleap/headless

Headless Canvas: portable ESM preview

Build from the Endoleap checkout with npm run build:headless. The generated .headless-dist directory is a private package; nothing is published to a registry. Copy it elsewhere, or use npm pack --offline --ignore-scripts inside that directory.

Public exports:

Import Responsibility
@endoleap/headless-canvas or /core Document, registry, capabilities, transactions, history, sessions, geometry and queries
/runtime Project/Workspace/Host, storage and service port types, recovery, scoped loader and compute/display pools
/service Foundry protocol codecs and transport adapters; credentials remain in the host
/browser Explicit IndexedDB/Web Locks and module Worker adapters

The portable entries have no React, Next, React Flow or other runtime package dependency. They use standard platform APIs such as AbortController, Blob, URL, TextEncoder and Web Crypto. The sample runs on Node 22+. Browser adapters require their browser APIs; importing /runtime does not import the browser adapter.

Run node consumer.mjs inside the generated package. It uses a custom counter component, rejects an atomic invalid transaction, commits edits, undoes/redoes, cancels a gesture preview, deep-copies through the runtime, and reopens the engine. The storage and protocol-2 transport are in-memory examples. Reopening demonstrates the codec and host contract, not cross-process crash durability or a deployed server.

npm run test:headless:package builds, packs/unpacks into an isolated directory, blocks framework imports and browser-only globals, runs the sample, checks Node TypeScript consumers without the DOM library, and exercises compiled browser adapters and module Worker URLs in isolated Chromium. The browser checks load the emitted JS directly, without TypeScript stripping or a Next bundler.

This preview does not yet package the React renderer/bindings. Their legacy projection DTO types still require an explicit adapter boundary. No registry publication, release support promise, server deployment or full-goal completion is implied by this local package.

Experimental partial-model runtime: pass a validated prefix plus loading in EngineOptions. The marker requires recovery format 7 and keeps the scheduler held. Loaded non-reference data fields and node geometry can be edited and undone; creation, deletions, ownership/reference changes, uploads, imports and AI admission wait. engine.loading.accept(document, versions, state) extends the captured prefix without replacing local edits. engine.loading.complete(document, versions, {sourceToken}) validates the full capture and releases scheduling only after its cut is durable. Use {fresh:true} only for an explicitly fresh complete read; conflicts require the existing reviewed recovery flow. engine.loading.resume() coalesces a fresh complete read through the project's persistence adapter and persists completion before resolving. workspace.resumeLoading(projectId) delegates to that owner and reports current-identity failures. Closing the project aborts the read and saves the recoverable prefix; detaching a view does not close its engine.

Endoleap's page now opens the same project engine for a validated prefix, allows the restricted field/geometry edits above, coalesces incoming prefixes, and preserves its textarea, history and viewport when the full model arrives. App navigation cancels the view's stream and asks the retained project owner to complete through a fresh read. Reload recovers the durable prefix when that project is opened again. This is not a persistent HTTP cursor or a workspace-wide startup scan; partial-scope ACK/chunk interleaving and broader structural permissions remain unfinished.