Skip to content

SyncedStoreClient Reference ​

Complete reference for the SyncedStoreClient public API.

Typed Client from Schema ​

Use InferSyncedStoreClient to derive a fully typed SyncedStoreClient from your schema. This gives you typed mutate, subscribe, action, query, and makeUniqueId — all inferred from the schema's tables, mutators, and actions.

typescript
import type { InferSyncedStoreClient } from "@synced-store/client";
import type { TodoSchema } from "./schema";

// Fully typed: mutate.setTodo, subscribe with typed QueryContext, etc.
export type TodoStoreClient = InferSyncedStoreClient<TodoSchema>;

Each app package exports its typed client (e.g., ChatStoreClient from @poe-app/chat, TodoStoreClient from @ai-app/poe-app-todo-list).

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();