Reference
Catalog tables
| Table | Purpose |
|---|---|
| viewmodel | One row per ViewModel: key columns, strategy, projector, auth scope, delete mode |
| view_source | Source tables, watched columns, key-map SQL |
| dependency_edge | Parent-child edges for DAG composition |
| write_binding | Field-to-source-column mapping for reverse projection |
| write_source | Source row location/insert/delete metadata for commit |
| change_log | Ordered, durable change feed from base tables (daily-partitioned) |
| refresh_queue | Work list: (view, key) pairs needing recompute |
| outbox | Transactional outbox for subscriber consumption |
| dead_letter | Failed refresh attempts past max_retries |
| subscriber_cursor | Per-subscriber ack cursor for at-least-once delivery |
Key functions
| Function | Signature |
|---|---|
| attach_capture | attach_capture(tbl regclass) → void |
| validate | validate(view text) → void |
| bootstrap | bootstrap(view text) → bigint |
| bootstrap_all | bootstrap_all() → void |
| refresh | refresh(view text, keys jsonb) → void |
| process_queue | process_queue(batch int DEFAULT 500) → int |
| fetch_since | fetch_since(view, scope, since, limit) → SETOF (seq, deleted, payload) |
| commit | commit(view, op, model, base, expectedSeq, trace) -> jsonb |
| reconcile_all | reconcile_all() -> TABLE(view, drift) |
| replay_dead_letter | replay_dead_letter(id bigint) -> void |
Monitoring views
| View | Contents |
|---|---|
| v_health | Queued / retrying / backing off / dead / oldest wait per view |
| v_perf | Runs, keys, avg/max ms per view (last hour) |
| v_backlog | Pending count + oldest wait per view |
| v_subscriptions | Live SSE connections, lag, high-water per user/scope |
| v_trace_segments | Per-trace breakdown by 7-hop segment (ms) |
TS subscriber API
import { createSynctable } from '@synctable/core/server'
const st = createSynctable({
connectionString: process.env.DATABASE_URL!,
models: [myModel],
authorize: (req, ctx) => ({ allowed: true, scope: { org_id: 1 } }),
otel: { export: false },
})
await st.start()
// Auto-starts outbox drain + Graphile Worker