Rindle

API index and search · Build metadata

Source snapshot

packages/optimistic/src/index.ts

Source revision 05d0bf2c2e56 · build details
Source revision: 05d0bf2c2e56.
TypeScript input SHA-256: aabe6cfcc4172b870d5e272142958e9ea8d8784c2aa23133156e5a7ee633318e
Generated 2026-09-04T23:58:25.590Z with TypeScript 6.0.3. Public TypeScript checks and declaration emit passed. Package runtime tests are separate.
1// @rindle/optimistic — optimistic writes over the local-first wasm engine2// (OPTIMISTIC-WRITES-DESIGN.md): named client mutators (invoked optimistically,3// RE-INVOKED on every rebase), the cv-buffered coherent release (§8.5), and the4// engine-side fork/rebase reconcile cycle (§1.3) behind the ordinary `Backend` seam.56import { Store } from "@rindle/client";7import type { ColsMap, Schema, OptimisticSource } from "@rindle/client";89import {10  OptimisticBackend,11  type ClientRegistry,12  type FoldHandle,13  type FoldOptions,14  type OptimisticBackendOptions,15} from "./backend.ts";1617/** One entry of the {@link createOptimisticStore} `mutate` facade: call it for a normal optimistic18 *  write (returns the `mid`), or `.folded(opts, args)` for a debounced, last-value-wins folded write19 *  (returns a {@link FoldHandle} — the `mid` is assigned at flush, FOLDED-MUTATIONS-DESIGN §3). */20export type MutateFn<Args> = ((args: Args) => number) & {21  folded(opts: FoldOptions, args: Args): FoldHandle;22};2324export { OptimisticBackend } from "./backend.ts";25export type {26  ClientMutator,27  ClientRegistry,28  DowngradeStuckEvent,29  FoldClock,30  FoldHandle,31  FoldInspect,32  FoldOptions,33  KeyedRow,34  MutationTx,35  OptimisticBackendOptions,36  OptimisticInspect,37  PendingInspect,38  QueryArg,39  QueryResultRow,40  ReadLog,41  ReadOutcome,42  ReadRecord,43  ResultType,44  ScopeSessionsEvent,45  SystemStreamSpec,46  SystemStreamTable,47  WriteRecord,48  WriteSet,49} from "./backend.ts";50// The §4 lifecycle system-stream leaf vocabulary (Slice I-iii): table names + wire schemas +51// the reserved system-sub query name (see ./system-streams.ts).52export {53  LIFECYCLE_QUERY_NAME,54  LIFECYCLE_TABLE_SCHEMAS,55  ROOM_CLIENT_MUTATIONS_TABLE,56  ROOM_MUTATION_OUTCOMES_TABLE,57  ROOM_WATERMARK_TABLE,58  roomDomainKey,59  SCOPE_SESSIONS_TABLE,60} from "./system-streams.ts";61export type {62  EnsureQueryOptions,63  EnsureQueryUntil,64  MutationEnvelope,65  OptimisticSource,66  ProgressFrame,67} from "@rindle/client";68// The shared (generator) mutator seam — a registry may hold plain client mutators OR these isomorphic69// generators (the SAME body the API server runs); re-exported here so an app registers from one import.70export { isoTx } from "@rindle/client";71export type { IsoTx, MutationGen, MutatorCtx, SharedMutator, YieldEffect } from "@rindle/client";7273// The one-call client for the daemon/serverless topology (API server + daemon ws).74export { createRindleClient } from "./client.ts";75export type { RindleClient, RindleClientOptions } from "./client.ts";76// Rindle Realtime client surface (G-v resolve-then-register): the lease-wire mirror types, the77// loud anomaly channel, and the `__realtimeInspect` snapshot shape.78export type {79  LifecycleLeaseBlock,80  LifecycleLeaseEntry,81  RealtimeAnomaly,82  RealtimeAnomalyKind,83  RealtimeClientOptions,84  RealtimeInspect,85  RealtimeLeaseBlock,86  RealtimeLeaseTableSpec,87} from "./client.ts";88export { resetStableClientID, stableClientID } from "./client-id.ts";8990// Local-table persistence (207-LOCAL-TABLE-PERSISTENCE-DESIGN.md): durable, cross-tab `local: true`91// tables. `createRindleClient` wires it via the `persistLocal` option; a standalone backend attaches92// with `attachLocalPersistence`; `deleteLocalPersistence` is the sanctioned logout hook (§3.2).93export { attachLocalPersistence, deleteLocalPersistence } from "./local-persist.ts";94export type {95  LocalPersistence,96  PersistChannel,97  PersistDb,98  PersistEnv,99  PersistLocalOptions,100  PersistMeta,101  RowState,102  StoredRow,103} from "./local-persist.ts";104105/** A {@link Store} over an {@link OptimisticBackend}, plus the named-mutator entry106 *  (`mutate.createIssue(args)` — the §9 dream shape) and the §6 lifecycle surface. */107export function createOptimisticStore<S extends ColsMap, R extends ClientRegistry>(108  schema: Schema<S>,109  source: OptimisticSource,110  registry: R,111  opts: OptimisticBackendOptions,112): {113  store: Store<S>;114  backend: OptimisticBackend<S>;115  mutate: { [K in keyof R]: MutateFn<Parameters<R[K]>[1]> };116} {117  const backend = new OptimisticBackend(schema, source, registry, opts);118  const store = new Store(schema, backend);119  const mutate = new Proxy(120    {},121    {122      get: (_t, name: string) => {123        const fn = ((args: unknown) => backend.invoke(name, args)) as MutateFn<unknown>;124        fn.folded = (foldOpts: FoldOptions, args: unknown) => backend.invokeFolded(name, foldOpts, args);125        return fn;126      },127    },128  ) as { [K in keyof R]: MutateFn<Parameters<R[K]>[1]> };129  return { store, backend, mutate };130}131