import { TreePath } from '@elaraai/e3-types'; /** A staged entry as held in the in-memory cache. */ export interface StagedEntry { /** Server value at the moment staging began. Pinned across writes; * used as the snapshot side of the eventual 3-way merge at commit. */ snapshot: Uint8Array; /** Current locally-edited value. Updates on every `write`. */ buffered: Uint8Array; } /** Persisted form. Identical to {@link StagedEntry} — kept distinct so * future persistence-layer fields (e.g. compression metadata) don't * leak into the in-memory shape. */ export interface PersistedStagedEntry { snapshot: Uint8Array; buffered: Uint8Array; } /** Pluggable persistence adapter. Production uses IndexedDB; tests / SSR * use the in-memory adapter. */ export interface StagedPersistenceAdapter { /** Load every persisted entry. Called once when the store is constructed. */ loadAll(): Promise>; /** Persist (or replace) an entry by key. */ save(key: string, entry: PersistedStagedEntry): Promise; /** Remove a single persisted entry by key. */ remove(key: string): Promise; /** Remove all persisted entries. */ clear(): Promise; } export interface StagedStoreInterface { /** Resolves when the initial hydrate from persistence has completed. * Reactive subscribers are notified per-key as entries hydrate. */ ready(): Promise; /** Resolves when every in-flight persistence write has completed. * Used by tests and by host code that needs to ensure durability * before a navigation / unload event. */ flushPending(): Promise; /** True iff this path has a pending staged change. */ hasPending(workspace: string, path: TreePath): boolean; /** Get the buffered (locally-edited) value, or undefined if not staged. */ getBuffered(workspace: string, path: TreePath): Uint8Array | undefined; /** Get the pinned snapshot value, or undefined if not staged. */ getSnapshot(workspace: string, path: TreePath): Uint8Array | undefined; /** Get the full staged entry, or undefined if not staged. */ getEntry(workspace: string, path: TreePath): StagedEntry | undefined; /** Write a buffered value. Snapshot is pinned on the first call for a * given path; subsequent writes update only the buffered value. */ write(workspace: string, path: TreePath, snapshotIfNew: Uint8Array, buffered: Uint8Array): void; /** Drop the staged entry for a path. Returns true if there was one. */ discard(workspace: string, path: TreePath): boolean; /** All currently-staged keys (workspace+path combinations). */ listKeys(): string[]; subscribe(key: string, callback: () => void): () => void; getKeyVersion(key: string): number; /** Register a listener for durable-persistence failures (save / remove / * hydrate), keyed by the affected `datasetCacheKey` (empty string for a * whole-store hydrate failure). Returns an unsubscribe. With no listener, * failures fall back to a console warning. Lets a host surface a * 'not durably saved' state, mirroring `BindRuntime.onWriteError`. */ onPersistError(cb: (key: string, err: unknown) => void): () => void; } /** * IndexedDB-backed persistence adapter. Stores entries as native * structured-clone shapes; no base64 encoding — `Uint8Array` fields * survive structured clone losslessly. */ export declare class IndexedDBStagedAdapter implements StagedPersistenceAdapter { private dbPromise; private getDB; loadAll(): Promise>; save(key: string, entry: PersistedStagedEntry): Promise; remove(key: string): Promise; clear(): Promise; } /** * Trivial in-memory implementation. Used by tests directly and as the * fallback when IndexedDB isn't available (e.g. SSR, very locked-down * iframes). The "persistence" is process-lifetime only. */ export declare class MemoryStagedAdapter implements StagedPersistenceAdapter { private map; loadAll(): Promise>; save(key: string, entry: PersistedStagedEntry): Promise; remove(key: string): Promise; clear(): Promise; } export declare class StagedStore implements StagedStoreInterface { private entries; private subscribers; private versions; private adapter; private hydrated; private inFlight; private saveChains; private errorListeners; constructor(adapter: StagedPersistenceAdapter); ready(): Promise; flushPending(): Promise; hasPending(workspace: string, path: TreePath): boolean; getBuffered(workspace: string, path: TreePath): Uint8Array | undefined; getSnapshot(workspace: string, path: TreePath): Uint8Array | undefined; getEntry(workspace: string, path: TreePath): StagedEntry | undefined; write(workspace: string, path: TreePath, snapshotIfNew: Uint8Array, buffered: Uint8Array): void; discard(workspace: string, path: TreePath): boolean; listKeys(): string[]; subscribe(key: string, callback: () => void): () => void; getKeyVersion(key: string): number; onPersistError(cb: (key: string, err: unknown) => void): () => void; /** Test-only: clear in-memory + persisted state. */ clear(): Promise; private notify; /** * Serialize a persistence op behind any prior op for the same key, so they * land in IndexedDB in call order (last write wins) rather than racing. * Tracks the op for {@link flushPending} and routes failures to * {@link onPersistError} listeners (falling back to a console warning). */ private persist; private emitPersistError; private hydrate; } export declare function getStagedStore(): StagedStoreInterface; export declare function initializeStagedStore(store: StagedStoreInterface): void; export declare function clearStagedStoreSingleton(): void; //# sourceMappingURL=staged-store.d.ts.map