Skip to content

createSyncClientHooks

createSyncClientHooks<TRegistry>(): object

Defined in: create-hooks.tsx:87

Creates a set of React hooks and a context provider bound to a specific SyncTableRegistry type. Call this once at the module level in your app:

export const { SyncClientProvider, useSyncClient, useLiveRows, useLiveDrizzleRows, useLiveQueryRaw } =
createSyncClientHooks<typeof mySyncRegistry>();

TRegistry extends SyncTableRegistry

SyncClientProvider: (__namedParameters) => Element

ReactNode

SyncClient<TRegistry> | null

Element

useLiveDrizzleRow: <TRows>(buildQuery, deps, options?) => object

TRows extends readonly unknown[]

(client) => DrizzleSqlBuilder<TRows>

DependencyList

number

boolean

object

error: Error | null

hydrating: boolean

loading: boolean

row: TRows[number] | null

useLiveDrizzleRows: <TRows>(buildQuery, deps, options?) => LiveRowsState<TRows>

Reactive query using a Drizzle select builder. The builder is re-created whenever deps changes (same contract as useEffect). pgxsinkit scans the compiled SQL and auto-activates any lazy relation the query reads — anywhere it appears (FROM, JOIN, subquery, WHERE) — before subscribing. use (see useLiveQueryRaw) is an optional pre-activation hint, not a requirement (ADR-0021).

const { rows } = useLiveDrizzleRows(
(c) => c.drizzle.select().from(c.views.todos).orderBy(c.views.todos.createdAtUs),
[],
);
// rows is fully typed from the view definition — no casts needed

TRows extends readonly unknown[]

(client) => DrizzleSqlBuilder<TRows>

DependencyList

number

boolean

LiveRowsState<TRows>

useLiveQueryRaw: <TRows>(args) => LiveRowsState<TRows>

The reactive query for a builder that embeds a raw sql fragment (ADR-0021): use names the lazy relations it reads that the compiled-SQL scan can’t see (a bare identifier inside raw SQL), so they are guaranteed activated before it subscribes. The non-live counterpart of client.queryRaw({ use, build }). Pure-Drizzle reads use useLiveDrizzleRows / client.query((c) => …), which auto-detect every relation and need no use.

const { rows, hydrating } = useLiveQueryRaw({
use: ["archive"],
build: (c) => c.drizzle.select().from(archiveTable).where(inArray(archiveTable.id, recentIds)),
deps: [recentIds],
});

TRows extends readonly unknown[]

(client) => DrizzleSqlBuilder<TRows>

DependencyList

number

boolean

readonly SyncTableName<TRegistry>[]

LiveRowsState<TRows>

useLiveQueryRawRow: <TRows>(args) => object

TRows extends readonly unknown[]

(client) => DrizzleSqlBuilder<TRows>

DependencyList

number

boolean

readonly SyncTableName<TRegistry>[]

object

error: Error | null

hydrating: boolean

loading: boolean

row: TRows[number] | null

useLiveRow: <TRow>(query, options?) => object

TRow extends Record<string, unknown> = Record<string, unknown>

string

readonly unknown[]

ClientPGlite

boolean

object

error: Error | null

loading: boolean

row: TRow | null

useLiveRows: <TRow>(query, options?) => object

Reactive raw-SQL query. This is the unguarded escape hatch: it does not participate in the lazy-relation safety net (ADR-0021) — a raw string is not parameterised/quoted predictably, so a lazy relation referenced here will read empty/stale unless you client.ensureSynced([...]) first. Prefer useLiveDrizzleRows / useLiveQueryRaw for anything touching lazy relations.

TRow extends Record<string, unknown> = Record<string, unknown>

string

readonly unknown[]

ClientPGlite

Explicit PGlite instance — overrides the context client. Useful in tests or multi-db scenarios.

boolean

object

error: Error | null

loading: boolean

rows: TRow[]

useMutationList: (options?) => object

Reactive filtered mutation detail list (client.mutations.subscribe): normalized journal rows across every writable table, filtered by table / entityKey / statuses / limit, ordered newest-first. Route/feature-scoped — mount it where a diagnostics view is open, not app-wide (prefer useMutationSummary for a global indicator). No hydrating flag (journals are local).

MutationListOptions<TRegistry> & object

object

error: Error | null

loading: boolean

rows: MutationDetail[]

useMutationSummary: (options?) => object

Reactive registry-wide mutation summary (client.mutations.subscribeSummary): per-status counts across EVERY writable journal, folded to one MutationSummary. ONE subscription drives a global sync indicator — no hydrating flag, because journals are local and never network-hydrated. Cheap enough to mount permanently (ADR-0040 dedup: one registration regardless of subscriber count).

boolean

object

error: Error | null

loading: boolean

summary: MutationSummary

useSyncClient: () => SyncClient<TRegistry>

SyncClient<TRegistry>