import type { ObserverStore } from '../../observe/store.ts'; import type { NamespaceStore } from '../mount/namespace/store.ts'; import { type SessionStore } from '../session/store.ts'; export type WorkspaceFields = Record; export interface WorkspaceStateStoreOverrides { namespace?: WorkspaceStateStore; observer?: WorkspaceStateStore; workspace?: WorkspaceStateStore; } /** * Provider for a workspace's whole control-plane state. * * One store, four planes, each scoped by workspace id: namespace nodes * (symlinks, attribute overlays), observer events (command history), * the session table (mount grants, cwd, env), and the workspace * metadata record (discovery: which sessions exist, which is the * default). Handing two processes the same store config plus a * workspace id gives them the same workspace state, which is the seam * that lets a kernel tier bind a session-bound mountpoint created by * another daemon. * * The planes keep their existing narrow interfaces (NamespaceStore, * ObserverStore, SessionStore); this provider only unifies their * construction, connection, and key scoping. Per-group overrides * redirect a plane group to a different provider (e.g. large observer * logs elsewhere while everything else stays on Redis). Sessions and * metadata form one inseparable group: the default-session pointer in * the metadata must never live on a different server than the session * table it points into. */ export declare abstract class WorkspaceStateStore { private readonly namespaceOverride; private readonly observerOverride; private readonly workspaceOverride; constructor(overrides?: WorkspaceStateStoreOverrides); /** The namespace plane (nodes) for one workspace. */ namespace(workspaceId: string): NamespaceStore; /** The observer plane (history events) for one workspace. */ observer(workspaceId: string): ObserverStore; /** The session table for one workspace. */ sessions(workspaceId: string): SessionStore; /** Read one workspace's metadata record; null when never written. */ loadMeta(workspaceId: string): Promise; /** Insert or update one workspace's metadata record. */ setMeta(workspaceId: string, fields: WorkspaceFields): Promise; /** * Write the metadata record iff its stored generation matches. * * Same optimistic-concurrency contract as SessionStore.casSet: a * missing record (and a legacy record without the field) counts as * generation 0, so create-if-absent is `expectedGeneration = 0`. * Resolves true when the write landed, false on conflict. */ casSetMeta(workspaceId: string, fields: WorkspaceFields, expectedGeneration: number): Promise; /** * CAS-write `fields` over the stored record, retrying on conflict. * * Ours-wins content (snapshot restore semantics): each attempt * merges `fields` over the stored record, preserves the stored * `created_at`, bumps the generation, and retries when another * writer got there first. Resolves with the record as written. */ replaceMeta(workspaceId: string, fields: WorkspaceFields): Promise; /** Release connections held by this provider and its overrides. */ close(): Promise; protected abstract makeNamespace(workspaceId: string): NamespaceStore; protected abstract makeObserver(workspaceId: string): ObserverStore; protected abstract makeSessions(workspaceId: string): SessionStore; protected abstract readMeta(workspaceId: string): Promise; protected abstract writeMeta(workspaceId: string, fields: WorkspaceFields): Promise; protected abstract casWriteMeta(workspaceId: string, fields: WorkspaceFields, expectedGeneration: number): Promise; protected abstract closeSelf(): Promise; } //# sourceMappingURL=base.d.ts.map