Skip to content

SyncedStoreClient Reference

Complete reference for the SyncedStoreClient public API.

Core Data Access

query(fn)

Execute a read-only query against the current local state (includes optimistic updates).

typescript
const user = await client.query((tx) => tx.table("users").get("user-123"));

subscribe(queryFn, callback)

Subscribe to changes in the local state. Callback invoked immediately, then on each change.

typescript
const unsubscribe = client.subscribe(
  (tx) => tx.table("users").get("user-123"),
  (user) => console.log("User changed:", user),
);

Returns: Unsubscribe function

mutate

Proxy object providing type-safe access to all registered mutators.

typescript
const { id, confirmed } = await client.mutate.setValue({
  key: "foo",
  value: "bar",
});
await confirmed; // Wait for server confirmation

Returns: { id: number, confirmed: Promise<void> }

action

Proxy object for calling server-side actions. Waits for pending mutations before executing.

typescript
const result = await client.action.calculateStats({ userId: "123" });

State & Connection

state

Current client state: 'initializing' | 'ready' | 'ended'

connectionStatus

Current connection status: 'connecting' | 'connected' | 'disconnected'

endReason

Why the client ended (null if not ended): 'kicked' | 'auth_failed' | 'application' | null

isOnline

Whether the client has an active WebSocket connection.

isReady()

Check if client is ready (initial sync completed).

waitForLocalData()

Returns promise that resolves when device storage has been loaded. Returns WaitForLocalDataResult (metadata about cached data) or null if fresh instance.

INFO

Not required — you do not need to call this before using query() or mutate().

waitForServerData()

Returns promise that resolves when the first server pull completes. Returns WaitForServerDataResult with the server version.

INFO

Not required — queries and mutations work without calling this.

waitForData()

Milestone: resolves when the client has data available (from device storage or server).

INFO

Not required — queries and mutations work without calling this.

getClientOrdinal()

Get the sequential ordinal assigned to this client by the server (0, 1, 2, ...). Creators always get ordinal 0.

typescript
const ordinal = await client.getClientOrdinal(); // e.g. 0, 1, 2

makeUniqueId()

Generate a unique ID within this store instance. Format: "{clientOrdinal}-{counter}" encoded with numberToSortableString for lexicographic sorting.

typescript
const id = await client.makeUniqueId();
// ordinal=0, counter=0 → "5-5"
// ordinal=0, counter=1 → "5-61"

isEnded()

Check if client has ended (disposed, kicked, etc.).

wasKicked()

Check if client was kicked by server. Equivalent to endReason === 'kicked'.

subscribeToConnectionStatus(callback)

Subscribe to connection status changes. Callback invoked immediately with current status.

typescript
const unsubscribe = client.subscribeToConnectionStatus((status) => {
  console.log("Connection status:", status);
});

Returns: Unsubscribe function

onOnlineChanged(callback)

Subscribe to online/offline changes as a boolean.

typescript
const unsubscribe = client.onOnlineChanged((isOnline) => {
  console.log("Online:", isOnline);
});

Returns: Unsubscribe function

Pending Mutations

getPendingMutations()

Get list of mutations awaiting server confirmation.

typescript
const pending = await client.getPendingMutations();
// [{ id: 1, name: "setValue", input: {...} }]

getPendingCount()

Get count of pending mutations (synchronous).

onPendingMutationsChanged(callback)

Subscribe to changes in pending mutations list. Useful for showing a "saving" indicator.

typescript
const unsubscribe = client.onPendingMutationsChanged((mutations) => {
  console.log("Pending:", mutations.length);
});

Returns: Unsubscribe function

waitForSync()

Wait for all currently pending mutations to be confirmed by server.

typescript
await client.mutate.setValue({ key: "foo", value: "bar" });
await client.waitForSync();

Network Operations

networkClient / network

The underlying network client for server communication. Alias: network.

pull()

Fetch all key-value modifications from server since last update. Usually called automatically.

typescript
await client.pull();

push()

Push pending mutations to server. Usually called automatically when autoPush: true (default).

typescript
await client.push();

Advanced Subscriptions

subscribeToScanEntries(prefix, onChange)

Subscribe to prefix-scanned entries with diff tracking (added/modified/removed).

typescript
const unsubscribe = client.subscribeToScanEntries(
  "user:",
  (entries, changes) => {
    console.log("Added:", changes.added);
    console.log("Modified:", changes.modified);
    console.log("Removed:", changes.removed);
  },
);

Returns: Unsubscribe function

subscribeToTable(tableName, onChange)

Subscribe to table entries with diff tracking (added/modified/removed).

typescript
const unsubscribe = client.subscribeToTable("users", (entries, changes) => {
  console.log("Table changed:", changes);
});

Returns: Unsubscribe function

Error Handling

onFailedMutation(callback)

Set callback to handle failed mutations (validation errors, conflicts, etc.).

typescript
const unsubscribe = client.onFailedMutation((info) => {
  console.error("Mutation failed:", info.mutation.name, info.error.message);
});

Returns: Unsubscribe function

Lifecycle Events

onKicked(callback)

Subscribe to kicked events (e.g., duplicate clientId).

typescript
const unsubscribe = client.onKicked((reason) => {
  console.error("Kicked:", reason);
});

Returns: Unsubscribe function

onAuthFailed(callback)

Subscribe to auth failed events (e.g., expired token).

typescript
const unsubscribe = client.onAuthFailed((reason) => {
  console.error("Auth failed:", reason);
});

Returns: Unsubscribe function

onDisposed(callback)

Subscribe to disposed events.

typescript
const unsubscribe = client.onDisposed(() => {
  console.log("Client disposed");
});

Returns: Unsubscribe function

dispose()

Dispose of client and release all resources. Closes WebSocket and clears timers. Cannot be reversed.

typescript
client.dispose();