Skip to content

SyncTableEntry

Defined in: packages/contracts/src/registry.ts:128

TTable extends AnyPgTable = AnyPgTable

TLocalTable extends AnyPgTable = TTable

applyMode: "insert" | "upsert"

Defined in: packages/contracts/src/registry.ts:156

Backfill conflict policy (ADR-0045). Resolved to "insert" when omitted.

This no longer selects how steady-state changes apply. The engine emits upsert, which states a row’s value without claiming it is new, so every streamed change now applies as INSERT … ON CONFLICT (pk) DO UPDATE regardless of this setting. ADR-0014’s plain-INSERT collision surfacing went with the insert verb it depended on.

What survives is the initial load, which is a different question: a fresh subscription or a post-must-refetch re-snapshot lands on a table assumed empty, which is what lets it use COPY or a plain multi-row INSERT — neither of which can express ON CONFLICT. Set "upsert" when that assumption does not hold for this table, i.e. it legitimately receives locally-DERIVED provisional rows (e.g. a local trigger on another synced table inserts one here) that a backfill could meet. The backfill then takes the conflict-tolerant applier instead, at the cost of the faster path.


optional clientProjection?: ClientProjectionSpecForTable<TTable>

Defined in: packages/contracts/src/registry.ts:177


optional conflictPolicy?: ConflictPolicy

Defined in: packages/contracts/src/registry.ts:185

Conflict policy (ADR-0015): what happens to a stale write on this table. Required for writable tables (registry validation rejects an undeclared one — the third hard-require); ignored for readonly tables (they have no write path). See ConflictPolicy.


optional consistencyGroup?: string

Defined in: packages/contracts/src/registry.ts:194

Consistency group (ADR-0009 decision 2). Tables sharing a consistencyGroup are synced as one set of streams and committed atomically — held until every stream reports up-to-date, then applied in one transaction (ADR-0056) — so a local reader never sees one grouped table advanced past another for the same server transaction. Omitted → the table is its own singleton group (its own stream, no cross-table atomicity — the resolution for a table that declares no group). The latency cost (a group advances only as fast as its slowest shape) is contained to the tables that opt in.


optional governance?: TableGovernanceSpecForTable<TTable>

Defined in: packages/contracts/src/registry.ts:179


localTable: TLocalTable

Defined in: packages/contracts/src/registry.ts:135

Projected client-side table for pgwasm use. Columns listed in clientProjection.omitColumns (e.g. created_by_id) are absent from both the runtime table definition and the TypeScript shape of this table.


optional makeColumns?: () => Record<string, ColumnBuilderBase>

Defined in: packages/contracts/src/registry.ts:235

The column-builder factory that produced this entry’s table (set by defineSyncTable). Retained so defineReadProjection can reuse the owner’s column definitions to build a typed column subset without restating them, AND — since ADR-0029 P1 — so the client can derive every synced-table object (the local synced read cache, overlay, journal) via getSyncedLocalTable → projectedColumnBuilders. It is therefore read-derivation machinery, not a write handle: it is carried through every projection (asReadonly, withRetention, defineReadProjection), NOT fingerprinted (functions are invisible to the read-contract hash), and required on every registered entry — defineSyncRegistry/validateSyncTableEntry reject a hand-assembled entry that lacks it, since the client hard-requires it at boot.

Record<string, ColumnBuilderBase>


mode: TableMode

Defined in: packages/contracts/src/registry.ts:139


primaryKey: PrimaryKeySpec

Defined in: packages/contracts/src/registry.ts:140


optional readProjection?: boolean

Defined in: packages/contracts/src/registry.ts:223

True when this entry is a read PROJECTION over a table OWNED by another entry (built by defineReadProjection). Such an entry owns no physical table — its table is the owner’s, and only its localTable + shape are its own — so migration/apply/RLS generation skips it and a consumer’s schema barrel must never export a fresh table for it. Absent → the entry owns its table.


optional retention?: Retention

Defined in: packages/contracts/src/registry.ts:208

Retention (ADR-0021): persistent (default) | ephemeral. An ephemeral table’s whole local cluster is emitted as TEMP — no durable trace, no durable offline write queue. A property of the consistency group — every table sharing a consistencyGroup must agree (validated). See Retention.


optional rowClass?: string

Defined in: packages/contracts/src/registry.ts:175

Consumer-defined ROW CLASSIFICATION (ADR-0052) — documentation-as-code for what KIND of rows this entry carries. The vocabulary is entirely the CONSUMER’s: pgxsinkit defines no values and attaches no behaviour to any of them. Its two jobs:

  • Fail-closed enumeration. When the registry declares its vocabulary (SyncRegistryDefinition.rowClasses), EVERY entry must carry a rowClass drawn from that set — validated at defineSyncRegistry, i.e. at module eval. A new entry therefore cannot join the registry without its author classifying it, which is what stops a privacy/visibility obligation from being silently inherited by tables nobody remembered to enumerate.
  • The binding key for assertRegistryInvariant. An invariant binds to rowClass values rather than to a hand-maintained table list, so coverage grows with the registry instead of drifting behind it.

When the registry declares no rowClasses, this field is unconstrained (any string, or none). It is authoring metadata only: it is deliberately absent from the registry fingerprint and the read-contract fingerprint, so classifying a table never shifts a persisted cache key (ADR-0052).


optional serverProjection?: ServerProjectionSpec

Defined in: packages/contracts/src/registry.ts:178


optional shape?: ShapeSpec

Defined in: packages/contracts/src/registry.ts:176


optional subscription?: SubscriptionTiming

Defined in: packages/contracts/src/registry.ts:201

Subscription timing (ADR-0021): eager (default) | lazy. A lazy table is excluded from the boot subscription set and subscribed on first query-reference. A property of the consistency group — every table sharing a consistencyGroup must agree (validated). See SubscriptionTiming.


table: TTable

Defined in: packages/contracts/src/registry.ts:129


optional view?: AnyPgView

Defined in: packages/contracts/src/registry.ts:138


optional writeMode?: WriteMode

Defined in: packages/contracts/src/registry.ts:216

Write-mode (ADR-0022): optimistic (default) | pessimistic. A pessimistic consistency group is a standing server-authoritative write-unit — its writes flush-route to the authoritative endpoint and the UI shows success only after the server confirms. Write-mode is a property of the write-unit; the static write-unit is the consistency group, so every table sharing a consistencyGroup must agree (validated). See WriteMode.