Skip to content

CreateSyncClientOptions

Defined in: packages/client/src/index.ts:1053

TRegistry extends SyncTableRegistry

optional autoSync?: ConvergenceTrigger

Defined in: packages/client/src/index.ts:1267

Opt-in convergence driver (ADR-0005). Supply a ConvergenceTrigger (e.g. createBrowserConvergenceTrigger()) and the client drives flush/reconcile/retryFailed on the trigger’s schedule, started once sync is ready and stopped on stop()/destroy(). Omit it for fully-manual convergence (the mechanism primitives stay public either way).


optional batchEventUrl?: string

Defined in: packages/client/src/index.ts:1277

The Event lane’s ingestion endpoint (ADR-0053 decision 3) — "/api/events", or an absolute deployment URL ending in it, under the same hard-required-path rule as batchWriteUrl. Omit it and the client DERIVES it from batchWriteUrl (…/api/mutations → …/api/events), which is correct for the ordinary deployment where one createSyncServer mounts both; set it explicitly when the two endpoints are not siblings.


batchWriteUrl: string

Defined in: packages/client/src/index.ts:1072


optional build?: PostgresBuild

Defined in: packages/client/src/index.ts:1145

The Postgres build a client-owned store runs on; defaults to cBuild. To hide the ~2.5s cold boot pgwasm.create cost — dominated by the WASM fetch+compile — behind user think-time, pass createCBuild({ assets }) from @pgxsinkit/pgwasm-c, where assets is a Promise<CBuildAssets> the host started fetching/compiling on an earlier screen (e.g. the login/identity picker): by the time a store is opened the assets are resolved and the build skips its own lazy asset load. Ignored when pgwasmInstance is supplied (the caller owns that instance’s boot). A rejected/failed warm never fails the boot — the build falls back to loading its own assets, so the warm is a pure best-effort accelerator. The boot waits for the build’s prepare() (the warm) before its boot pgwasm.create stamp, so pgwasmCreateMs measures the create alone.

The build must be the registry’s declared storage.build (default "c", ADR-0063): a mismatch throws StorageBuildMismatchError before any store is touched. An adopted pgwasmInstance / precreatedPgwasm is checked the same way, against its own pg.build.


controlPlaneUrl: string

Defined in: packages/client/src/index.ts:1063

The pgxsinkit control plane: where a client subscribes, re-mints its stream token, and reads the engine convergence barrier (ADR-0055). Required, with streamBaseUrl.

The client does not CONSTRUCT stream URLs, it asks and is told. Which shapes a subject may read — and, on the shared tier, which scopes each expands to — is not something the client can express at all, which is what removes shape selection from the wire.


optional events?: EventLaneOptions

Defined in: packages/client/src/index.ts:1285

The Event lane’s client-level flush policy (ADR-0053): batch caps, the fallback interval, backoff tuning, the acked ledger’s retention (ADR-0060), and per-Event-stream overrides. NEVER on the registry — the registry is the contract, cadence is deployment tuning, and a batch-size tweak must not surface as a registry diff. Client batching is additionally clamped by the contracts-level request-shape limits the server enforces independently.


optional freshStore?: boolean

Defined in: packages/client/src/index.ts:1231

PROVABLY-fresh store hint (ADR-0032 S4 / backlog-0003): the caller guarantees this store is brand-new and schemaless — no prior schema, no synced rows, no persisted subscription state. When set (and sync is enabled, and the client owns schema exec — i.e. not the pgwasmInstance path), the shape catch-up is started BEFORE the local boot phases (schema exec, journal recovery, and registry reconciliation) and buffered in memory, with commits gated until those phases finish — so the network catch-up overlaps them instead of running strictly after. On a far-from-database caller this collapses boot from local-phases + catch-up toward max(local-phases, catch-up).

MUST be set only when freshness is proven, never derived by probing — a claimed schemaless spare (the board’s claim path knows: a claimed spare is always fresh; a mapped/returning store never is). A wrong true on a warm store would start the streams from offset 0 and skip the subscription-state read, re-snapshotting instead of resuming. Absent/false → the exact sequential path (the default, correct for every warm store).


optional getAuthToken?: () => Promise<string | undefined>

Defined in: packages/client/src/index.ts:1073

Promise<string | undefined>


optional hasOpfsSyncAccess?: boolean

Defined in: packages/client/src/index.ts:1129

ADR-0049 D1: the placement probe’s OPFS-sync-access grant, threaded from the SharedWorker’s engine home (defineSyncWorker’s SW-direct bootstrap) into this boot so the client-owned create opens the OPFS-repacked backend. Absent/false is the honest IDBFS home — the declared backend: "idbfs" mode or a capability-absence fallback (a main thread can never hold handles either). Forwarded verbatim to createPgwasmClient, which resolves the actual dataDir from it.


optional liveQueries?: object

Defined in: packages/client/src/index.ts:1335

Bounded zero-subscriber keep-alive for the live-query manager (ADR-0040 decision 4) — same block as DefineSyncWorkerOptions.liveQueries. Takes effect in BOTH client forms: the in-process client now owns its own manager (decision 6), so this policy governs its live-query dedup and retention just as it does the worker’s. Defaults: defaultKeepAliveMs 0 (tear a query down the instant its last consumer leaves), maxRetainedQueries 16, maxRetainedRows 50_000.

optional defaultKeepAliveMs?: number

optional maxRetainedQueries?: number

optional maxRetainedRows?: number


optional maxMutationAttempts?: number

Defined in: packages/client/src/index.ts:1236

Hard cap on send attempts before a still-failing mutation is quarantined (ADR-0005 congestion policy). Defaults to the library’s built-in cap.


optional onBootReport?: (report) => void

Defined in: packages/client/src/index.ts:1298

Boot observability (ADR-0034): invoked exactly once, at boot completion, with the finalized BootReport. The push counterpart of SyncClient.bootReport (the pull) for consumers that want the numbers without polling — dashboards, CI budget gates. Never fired before initial sync; a stop()/destroy() before then means it never fires.

BootReport

void


optional onConflict?: (conflicted) => void | Promise<void>

Defined in: packages/client/src/index.ts:1249

Invoked when mutations are conflicted — a stale write the server declined under the reject-if-stale Conflict policy (ADR-0015). The optimistic Overlay is kept, so the app shows a resolution/diff UI and resolves each as a new write (mutate.update) or discardConflicts it.

MutationDetail[]

void | Promise<void>


optional onConvergencePass?: (error) => void

Defined in: packages/client/src/index.ts:1269

Invoked after each automatic convergence pass with its error, or null on success (only when autoSync is set).

unknown

void


optional onQuarantine?: (quarantined) => void | Promise<void>

Defined in: packages/client/src/index.ts:1243

Invoked when mutations are quarantined (permanently rejected by the server, terminal). The library surfaces them here rather than silently dropping or retry-looping (ADR-0006). Surface, then either re-author + resubmit or roll back via SyncClient.discardQuarantined — which clears the kept overlay + quarantined journal rows so the entity accepts new mutations again.

MutationDetail[]

void | Promise<void>


optional onReject?: (rejected) => void | Promise<void>

Defined in: packages/client/src/index.ts:1255

Invoked when a pessimistic write-unit is rejected (ADR-0022) — a business decline from the authoritative endpoint (capacity/quota/uniqueness). The inverse of onConflict: the optimistic Overlay was auto-discarded for the whole unit, so the app surfaces the typed reason rather than a resolve UI.

MutationDetail[]

void | Promise<void>


optional onSchemaChange?: (event) => void | Promise<void>

Defined in: packages/client/src/index.ts:1260

Invoked when a supported store’s registry fingerprint changes. rebuilt means the clean read cache was rebuilt at the new shape; deferred means local mutations are still owed and must drain first.

LocalStoreVersionEvent

void | Promise<void>


optional onStatusChange?: (status) => void

Defined in: packages/client/src/index.ts:1149

SyncRuntimeStatus

void


optional onSyncError?: (error) => void

Defined in: packages/client/src/index.ts:1291

Invoked when a read-path sync commit fails after exhausting its retries (ADR-0009 decision 5). The runtime enters the degraded phase and holds the read cache at the last applied commit instead of silently diverging from the server; recovery is a later commit or a restart/refetch.

Error

void


optional onTableInitialSync?: (tableKey) => void

Defined in: packages/client/src/index.ts:1150

string

void


optional pgwasmInstance?: PgwasmWithLive

Defined in: packages/client/src/index.ts:1169

A fully-provisioned pgwasm instance the CALLER owns end-to-end. The client runs NONE of its post-create boot steps against it — no schema exec, prepare hooks, or registry reconciliation (journal recovery still runs, as it does on every path). Use it only when the caller has already applied the registry schema itself. Contrast the three store-provenance seams:

  • storePath (default) — the client creates the store AND runs every post-create step.
  • precreatedPgwasm — the caller creates the raw store (via createPgwasmClient), but the client still runs every post-create step (schema, prepare hooks, and reconciliation), exactly as storePath does.
  • pgwasmInstance — the caller creates AND provisions the store; the client runs none of them.

A caller-owned instance is REFUSED with NonPersistentStoreError if it is provably non-persistent (a new pgwasm() default, or an in-memory store) — pgxsinkit’s durability semantics assume a persisted store (ADR-0036). Acknowledge a deliberate test store by spreading testStoreAcknowledgment() from @pgxsinkit/client/testing.

Mutually exclusive with precreatedPgwasm (supplying both throws).


optional precreatedPgwasm?: Promise<PgwasmWithLive>

Defined in: packages/client/src/index.ts:1189

A raw pgwasm instance the caller created EAGERLY (via createPgwasmClient) — typically on an earlier screen, to hide the ~1.9s cold initdb/IDBFS open behind user think-time — but for which the client still owns EVERYTHING else: schema exec, prepare hooks, journal recovery, and registry reconciliation all run exactly as on the storePath path. This is the difference from pgwasmInstance (which skips schema, prepare hooks, and reconciliation because the caller owns them); see that option’s JSDoc for the three-way distinction.

The promise form lets the still-pending eager create be handed straight in. Precedence/validation:

  • Supplying both this and pgwasmInstance throws — they claim different ownership.
  • storePath is used ONLY as the fallback store name if this promise REJECTS: a failed eager create is caught, logged on the boot rail, and the normal storePath create path runs instead (also consuming build if provided). The pattern is a pure accelerator, never a boot dependency.
  • A successfully-adopted instance is subject to the same NonPersistentStoreError refusal as pgwasmInstance (checked after resolution, so the refusal propagates rather than being swallowed by the reject-fallback).

optional prepareLocalDbAfterSchema?: (pgwasm) => Promise<void>

Defined in: packages/client/src/index.ts:1148

PgwasmWithLive

Promise<void>


optional prepareLocalDbBeforeSchema?: (pgwasm) => Promise<void>

Defined in: packages/client/src/index.ts:1147

PgwasmWithLive

Promise<void>


optional readSilenceMs?: number

Defined in: packages/client/src/index.ts:1102

The read-silence window (ms) after which a runtime claiming ready drops to degraded (reason “stream”). A pulled cable HANGS the live long-poll — nothing fails, nothing delivers — so without this a session that once reached ready would report “up to date” for as long as the outage lasts. A healthy stream is never silent: durable-streams answers every long-poll hold that times out with a bare up-to-date response, so the default of 45s spans several cycles. Self-recovering: the next delivered batch returns ready. Status honesty only — nothing is retired or torn down.


registry: TRegistry

Defined in: packages/client/src/index.ts:1054


optional requestHeaders?: Record<string, string>

Defined in: packages/client/src/index.ts:1080

Static headers added to every read-shape and write request, alongside the per-request Authorization (which always wins). The toolkit is agnostic about deployment-gateway credentials, so this is the seam for them — e.g. a Supabase Cloud apikey header the platform function gateway expects. Sent even when no getAuthToken is supplied.


optional resetSubscriptionKeys?: string[]

Defined in: packages/client/src/index.ts:1146


optional restoreFrom?: Blob | File

Defined in: packages/client/src/index.ts:1215

Restore the store from a store backup (ADR-0035 decision 6) — a File/Blob tarball as produced by SyncClient.exportStore. The client creates its store with the backup handed to pgwasm’s loadDataDir, so it boots ON the backup’s datadir (synced cache + Overlay + Mutation journal, all the bytes that travelled inside it). Three restore-only rules apply, none of them optional:

  • Fresh target only. Refused with RestoreTargetExistsError if a store already exists at the resolved storePath — restore never overlays a live store (that would corrupt the datadir); the remedy is a deliberate SyncClient.destroy of the existing store first.
  • Comes online iff the recovered journal is clean (ADR-0046). If journal recovery found NOTHING to quarantine — an empty recovered journal, the guaranteed-clean server-built bootstrap-artifact case — the restore boots ONLINE, honouring syncEnabled/autoSync exactly as a normal boot (streams, flush, convergence). If recovered mutations were quarantined, the boot stays OFFLINE (no shape streams, no read fetch, no flush): the app inspects SyncClient.diagnostics, releases/discards the quarantined rows, then a subsequent NORMAL boot of the (now-persisted) store brings sync online. loadDataDir happens exactly once, on this restore boot. An explicit syncEnabled: false keeps it offline.
  • Journal quarantined. Every non-terminal recovered row (pending/sending/failed) is moved to quarantined — nothing recovered from a backup auto-flushes (the write path has no mutationId dedupe ledger, so replay is unsafe on last-write-wins tables). Release (retryFailed) or discard (discardQuarantined) them explicitly. When this pass quarantines nothing, the restore comes online (above).

Mutually exclusive with pgwasmInstance AND precreatedPgwasm — restore owns the store’s creation (loadDataDir is a create-time seed), so a caller-supplied instance conflicts (supplying either with restoreFrom throws).


optional storePath?: string

Defined in: packages/client/src/index.ts:1112

The local store’s name (ADR-0036) — a PLAIN path/name, never a pgwasm storage URL. The storage backend is DERIVED from the engine home (capability-selected opfs-repacked with IndexedDB fallback in a browser, or the filesystem on Bun/Node); a scheme-bearing string (anything containing ://) is rejected with InvalidStorePathError at boot. Defaults to a built-in overlay store name when omitted. A memory-backed store is not a product configuration — for the test/ephemeral lane, spread memoryStoreForTests(...) from @pgxsinkit/client/testing instead of naming one here.


streamBaseUrl: string

Defined in: packages/client/src/index.ts:1071

The edge that serves durable-streams reads. Granted stream paths are appended to it.

Separate from controlPlaneUrl because they are different deployments: the control plane is a small authenticated origin, and this is the CDN-frontable read surface the shared tier exists to make cacheable.


optional syncEnabled?: boolean

Defined in: packages/client/src/index.ts:1093


optional writeRequestHeaders?: Record<string, string>

Defined in: packages/client/src/index.ts:1092

Extra static headers sent on the write path only (the mutation-flush POST), merged over requestHeaders ({...requestHeaders, ...writeRequestHeaders}). Control-plane and stream requests never see these. The seam exists because the two ingress points have opposite geometry: the write function is DB-bound, so pinning it to the database’s region (e.g. an x-region header) keeps its chatty function→DB protocol on a ~1ms loop; the read path terminates on the stream edge in front of durable-streams, so pinning reads to the database’s region rather than the caller’s pays an intercontinental round trip on every catch-up hop and every long-poll cycle. Put region/DB-affinity headers here; keep gateway credentials the reads also need (e.g. apikey) in the shared requestHeaders.