/** * EphemeralPatchManager — manages ephemeral (temporary) state patches. * * Handles storing patches in EphemeralStore, composing ephemeral overlay * on top of base state, tracking local writes, resolving container paths, * and finalizing (committing) patches to LoroDoc. */ import { ContainerID, EphemeralStore, LoroDoc } from "loro-crdt"; import type { Change } from "./mirror.js"; /** * A Change that has been validated as eligible for ephemeral storage. * Guarantees: `container` is a valid ContainerID (not ""), `key` is a string. */ export interface EphemeralEligibleChange { kind: "set" | "insert"; container: ContainerID; key: string; value: unknown; } /** * Context needed from Mirror for path resolution. */ export interface PathResolverContext { doc: LoroDoc; decodeField?: (containerId: ContainerID, key: string, value: unknown) => unknown; } type EphemeralPatch = Record; export interface EphemeralPatchDelta { containerId: ContainerID; previous: EphemeralPatch | undefined; next: EphemeralPatch | undefined; } export interface EphemeralStoreChangeEvent { by: "local" | "import" | "timeout"; added: ContainerID[]; updated: ContainerID[]; removed: ContainerID[]; deltas: EphemeralPatchDelta[]; } /** * Manages ephemeral patches: storage, composition, path resolution, and finalization. */ export declare class EphemeralPatchManager { private store; /** Latest patch snapshot by container id */ private patches; /** Tracks what the local peer last wrote, keyed by ContainerID -> fieldKey -> value */ private localValues; private debounce; constructor(store: EphemeralStore); /** Subscribe to EphemeralStore changes. Returns unsubscribe function. */ subscribe(listener: (event: EphemeralStoreChangeEvent) => void): () => void; get hasLocalPatches(): boolean; /** * Check if a change is eligible for ephemeral storage. * Must be a primitive value change on an existing Map key. * Acts as a type guard — narrowing to {@link EphemeralEligibleChange}. */ isEligible(change: Change, doc: LoroDoc): change is EphemeralEligibleChange; /** * Write a set of ephemeral-eligible changes to the EphemeralStore. */ writeChanges(changes: EphemeralEligibleChange[]): EphemeralPatchDelta[]; /** * Fast path for directly patching a single primitive field. */ writeValue(containerId: ContainerID, key: string, value: unknown): EphemeralPatchDelta[]; /** * Compose state by overlaying all ephemeral patches on top of base state. * Returns the base unchanged if no patches exist. */ compose(base: T, ctx: PathResolverContext): T; /** * Incrementally apply patch deltas to a previously composed state. */ applyDelta(currentState: T, baseState: T, deltas: readonly EphemeralPatchDelta[], ctx: PathResolverContext): T; /** * Finalize: commit locally-written ephemeral values to LoroDoc. * Only commits values that still match what we last wrote (not overwritten by remote). * Returns true if any changes were committed. */ finalize(doc: LoroDoc): boolean; /** * Schedule a debounced finalize via the deadline-based DebounceTimer. */ scheduleFinalizeAfter(timeout: number | undefined, callback: () => void): void; clearTimer(): void; /** * Clean up all state. */ dispose(): void; /** * Resolve a ContainerID to a path of keys/indices from the state root. * Delegates to LoroDoc's built-in `getPathToContainer`. */ resolvePath(containerId: ContainerID, ctx: PathResolverContext): (string | number)[] | undefined; private syncAllPatchesFromStore; private syncFromStoreEvent; private toPatch; private clonePatch; private updateLocalValues; private navigateToObject; private clonePath; private cloneNode; } export {}; //# sourceMappingURL=ephemeral.d.ts.map