import { type EditorCommand } from "./commands.js"; import type { EditorDocument, EditorVec3 } from "./types.js"; /** * One versioned document mutation on the live-sync stream. `snapshot` replaces the whole * document; `commands` replays structural editor commands onto the current document. * `baseRevision` must match the receiver's current revision unless `force` is set (document * authority from the editor). `revision` preserves the authority cursor when replaying: snapshots * may jump forward for reconnect recovery; commands must be the next revision. */ export type DocumentPatch = { type: "snapshot"; revision?: number; baseRevision: number; document: EditorDocument; } | { type: "commands"; revision?: number; baseRevision: number; commands: readonly EditorCommand[]; }; /** Result of applying a {@link DocumentPatch} to a document + revision pair. */ export type ApplyDocumentPatchResult = { ok: true; document: EditorDocument; revision: number; patch: DocumentPatch; } | { ok: false; error: string; commandIndex?: number; }; /** One live entity row the runtime may stream to the editor (play-mode inspector feed). */ export interface RuntimeEntityState { id: string; position?: EditorVec3; rotationY?: number; values?: Record; } /** Full ephemeral runtime view held on the reverse channel — never mutates the document. */ export interface RuntimeStateSnapshot { seq: number; entities: Record; tunables: Record; } /** * Incremental runtime state for the reverse channel. Entity rows upsert by id; `removeIds` * drop rows; `tunables` shallow-merge. Ephemeral unless written back as a document patch. */ export interface RuntimeStateDelta { seq: number; at: number; entities?: readonly RuntimeEntityState[]; removeIds?: readonly string[]; tunables?: Record; } /** Event emitted when the authoritative document changes on a {@link DocumentLiveSync}. */ export interface DocumentLiveEvent { document: EditorDocument; revision: number; patch: DocumentPatch; } /** * Applies a versioned document patch. Rejects base-revision mismatches unless `force` (document * is authoritative — the editor forces when publishing its own session state). * @capability editor-live-sync apply a versioned document patch onto a live scene document */ export declare function applyDocumentPatch(document: EditorDocument, revision: number, patch: DocumentPatch, options?: { force?: boolean; }): ApplyDocumentPatchResult; /** * Merges a runtime delta into a snapshot without touching the scene document — runtime overrides * stay ephemeral until an explicit write-back produces a document patch. * @capability editor-live-sync merge a runtime state delta into the reverse-channel snapshot */ export declare function applyRuntimeStateDelta(snapshot: RuntimeStateSnapshot, delta: Omit & { seq?: number; }): { snapshot: RuntimeStateSnapshot; delta: RuntimeStateDelta; }; /** * Builds an undoable document command from an ephemeral runtime entity row (write-back). Returns * null when there is nothing to promote. Does not mutate document or clear the override — the * caller dispatches the command and then clears the override. * @capability editor-live-sync promote a runtime entity override into a document write-back command */ export declare function runtimeEntityWriteBackCommand(document: EditorDocument, entity: RuntimeEntityState): EditorCommand | null; /** Two-way live-sync bus: document patches out, runtime state deltas back. */ export interface DocumentLiveSync { getDocument(): EditorDocument; getRevision(): number; applyPatch(patch: DocumentPatch, options?: { force?: boolean; }): ApplyDocumentPatchResult; /** Document-authoritative full replace (editor session mirror). */ replaceDocument(document: EditorDocument): DocumentLiveEvent; /** Returns a current snapshot when the requested revision predates retained history. */ pullPatches(sinceRevision: number): DocumentPatch[]; subscribeDocument(listener: (event: DocumentLiveEvent) => void): () => void; getRuntimeState(): RuntimeStateSnapshot; pushRuntimeDelta(delta: Omit): RuntimeStateDelta; pullRuntimeDeltas(sinceSeq: number): RuntimeStateDelta[]; subscribeRuntime(listener: (delta: RuntimeStateDelta, snapshot: RuntimeStateSnapshot) => void): () => void; setRuntimeOverride(entity: RuntimeEntityState): void; clearRuntimeOverride(id: string): void; getRuntimeOverrides(): Readonly>; /** * Promote an ephemeral override into a document command patch when the id exists in the * document. Clears the override only after a successful apply. */ writeBackOverride(id: string): ApplyDocumentPatchResult | { ok: false; error: string; }; } /** * Creates an in-memory two-way live-sync bus seeded from an initial document. Document is * authoritative; runtime overrides are ephemeral until {@link DocumentLiveSync.writeBackOverride}. * @capability editor-live-sync two-way document/runtime live-sync bus for editor↔game */ export declare function createDocumentLiveSync(initial: EditorDocument): DocumentLiveSync; /** Publishes a live-sync bus globally so AuthoredScene / games can subscribe without prop drilling. */ export declare function installDocumentLiveSync(sync: DocumentLiveSync): () => void; /** Returns the globally installed live-sync bus, or null when none is mounted. */ export declare function getDocumentLiveSync(): DocumentLiveSync | null; /** * Subscribe to install/uninstall of the global live-sync bus (AuthoredScene re-attaches when the * editor host mounts over a running game). */ export declare function subscribeDocumentLiveSyncInstall(listener: () => void): () => void;