/** * Durable Cell: independently-versioned mutation boundary * * A Cell is the smallest durable authority boundary in FeltDB. * Each cell owns its own version, state, and mutation serialization. */ import type { JsDb } from './feltdb.js'; export declare const NO_CHANGE: unique symbol; export type NoChange = typeof NO_CHANGE; export declare const AUTHORITY_CONFLICT: unique symbol; export type AuthorityConflict = typeof AUTHORITY_CONFLICT; export type CellLifecycle = 'active' | 'suspended' | 'retired'; export interface CellAuthority { readonly owner: string | null; readonly epoch: number; readonly lifecycle: CellLifecycle; } export interface CellPlacement { readonly nodeId: string | null; } export interface CellLease { readonly holder: string; readonly leaseId: string; readonly epoch: number; readonly expiresAt: number; } export interface CellSnapshot { readonly id: string; readonly version: number; readonly value: T; readonly updatedAt: string; readonly authority: CellAuthority; readonly placement: CellPlacement; readonly lease: CellLease | null; } export interface CellMutationEvent { readonly cellId: string; readonly version: number; readonly value: T; readonly timestamp: string; readonly epoch: number; } export interface AuthorityTransitionOptions { expectedEpoch: number; owner?: string | null; lifecycle?: CellLifecycle; } export interface CellDelegateOptions { expectedEpoch: number; from: string | null; to: string | null; } export interface PlacementUpdateOptions { nodeId: string | null; } export interface LeaseAcquireOptions { holder: string; durationMs: number; } export interface LeaseRenewOptions { leaseId: string; durationMs: number; } export interface LeaseReleaseOptions { leaseId: string; } export interface PromoteOptions { expectedVersion: number; expectedEpoch: number; newOwner: string; newNodeId?: string | null; } export interface CellFailureObservation { nodeId: string; observedAt: number; lastSeenAt: number; authorityEpoch: number; } export interface FailureEvaluationOptions { nodeId: string; now: number; suspectAfterMs: number; failedAfterMs: number; } export interface FailureEvaluationResult { status: 'healthy' | 'suspect' | 'failed'; authorityEpoch: number; nodeId: string; ageMs?: number; } export interface AutomaticFailoverOptions { failureEvaluationOptions: FailureEvaluationOptions; /** Already-observed failure evidence, avoiding a redundant managed read. */ failureObservation?: CellFailureObservation; /** Candidate's existing local replica snapshot; managed CAS remains authoritative. */ replicaSnapshot?: CellSnapshot; newOwner: string; } export interface AutomaticFailoverResult { attempted: boolean; promoted: boolean; reason?: string; diagnostics?: { isReplica: boolean; failureStatus?: 'healthy' | 'suspect' | 'failed'; eligibilityChecksPassed: boolean; promotionAttempted: boolean; promotionSucceeded: boolean; }; } export interface MutationOptions { authorityEpoch?: number; leaseId?: string; } export interface CellReplicationSnapshot { readonly cellId: string; readonly version: number; readonly value: T; readonly updatedAt: string; readonly authority: CellAuthority; readonly placement: CellPlacement; readonly lease: CellLease | null; } export interface CellReplica { readonly nodeId: string; readonly version: number; readonly receivedAt: number; } export interface ReplicationState { cellId: string; version: number; value: T; updatedAt: string; authority: { owner: string | null; epoch: number; lifecycle: CellLifecycle; }; placement: { nodeId: string | null; }; lease: { holder: string; leaseId: string; epoch: number; expiresAt: number; } | null; replica?: { nodeId: string; version: number; receivedAt: number; }; divergent?: boolean; conflictReason?: string; } export type CellUpdater = (current: T | null) => T | typeof NO_CHANGE; export type CellTransactor = (tx: CellTransaction) => Promise | R; export interface CellTransaction { get(): Promise | null>; set(value: T, options?: MutationOptions): Promise>; update(updater: CellUpdater, options?: MutationOptions): Promise>; } export interface Cell { readonly id: string; get(): Promise | null>; set(value: T, options?: MutationOptions): Promise>; update(updater: CellUpdater, options?: MutationOptions): Promise>; transact(fn: CellTransactor): Promise; transitionAuthority(options: AuthorityTransitionOptions): Promise>; delegate(options: CellDelegateOptions): Promise>; updatePlacement(options: PlacementUpdateOptions): Promise>; acquireLease(options: LeaseAcquireOptions): Promise>; renewLease(options: LeaseRenewOptions): Promise>; releaseLease(options: LeaseReleaseOptions): Promise>; promote(options: PromoteOptions): Promise>; observeHealth(observation: CellFailureObservation): Promise; evaluateFailure(options: FailureEvaluationOptions): Promise; attemptAutomaticFailover(options: AutomaticFailoverOptions): Promise; on(event: 'change', handler: (event: CellMutationEvent) => void): void; off(event: 'change', handler: (event: CellMutationEvent) => void): void; } /** * CellImpl implements the Cell interface with authority and lifecycle support. * Uses per-cell locking to serialize mutations and authority transitions. * Epoch-based fencing prevents stale authority from mutating. * * Replication: CellImpl can also track replica state separately. * A replica is read-only: replication transfers knowledge, not authority. */ export declare class CellImpl implements Cell { readonly id: string; private jsDb; private cellCollection; private replicaCollection; private failureObservationCollection; private mutationQueue; private isLocked; private changeHandlers; private isReplica; constructor(jsDb: JsDb, cellId: string); setReplica(isReplica: boolean): void; isReplicaCell(): boolean; applyReplication(snapshot: CellReplicationSnapshot): Promise; /** Removing an absent repair marker is an idempotent replication cleanup. */ private clearDivergenceMarker; private encodeKey; private hashId; get(): Promise | null>; set(value: T, options?: MutationOptions): Promise>; update(updater: CellUpdater, options?: MutationOptions): Promise>; transact(fn: CellTransactor): Promise; transitionAuthority(options: AuthorityTransitionOptions): Promise>; delegate(options: CellDelegateOptions): Promise>; updatePlacement(options: PlacementUpdateOptions): Promise>; acquireLease(options: LeaseAcquireOptions): Promise>; renewLease(options: LeaseRenewOptions): Promise>; releaseLease(options: LeaseReleaseOptions): Promise>; promote(options: PromoteOptions): Promise>; private promoteSnapshot; observeHealth(observation: CellFailureObservation): Promise; evaluateFailure(options: FailureEvaluationOptions): Promise; attemptAutomaticFailover(options: AutomaticFailoverOptions): Promise; private evaluateFailureSnapshot; private validateLifecycleTransition; private getUnlocked; private setUnlocked; private updateUnlocked; private snapshotFromState; on(event: 'change', handler: (event: CellMutationEvent) => void): void; off(event: 'change', handler: (event: CellMutationEvent) => void): void; private emitChange; private acquireLock; private processQueue; } //# sourceMappingURL=cell.d.ts.map