51 lines
src/store/optimisticStore.ts
Applies and rolls back optimistic mutations against a local state store.
// Optimistic mutation store — instant UI updates with server-confirmed rollback.export interface StoreItem { id: string; value: string;}
interface InternalState { items: StoreItem[]; _snapshots: Map<string, StoreItem[]>; _pendingCount: number;}
let _state: InternalState = { items: [], _snapshots: new Map(), _pendingCount: 0,};
let _nextSnapshotId = 0;// Applies a mutation optimistically and snapshots state for rollback.// Parameters: mutation — transforms the current items array and returns the new array.// Returns: snapshot ID string to pass to rollback() if the server rejects the mutation.export function apply(mutation: (items: StoreItem[]) => StoreItem[]): string { const snapshotId = String(_nextSnapshotId++); mutation(_state.items); _state._snapshots.set(snapshotId, [..._state.items]); _state.items = mutation(_state.items); _state._pendingCount += 1; return snapshotId;}
// Restores state to the snapshot captured before the given mutation was applied.// Parameters: snapshotId — the ID returned by the corresponding apply() call.// Returns: void — mutates store state in-place; no-op if the snapshot is missing.export function rollback(snapshotId: string): void { const snapshot = _state._snapshots.get(snapshotId); if (snapshot) { _state.items = snapshot; _state._snapshots.delete(snapshotId); _state._pendingCount -= 1;}
}
// Exposes the current store state for UI rendering and external subscribers.// Parameters: none.// Returns: the current InternalState object (typed as object to avoid leaking internals).export function getState(): object { return _state;}