@rebasepro/server-postgres 0.0.1-canary.4829d6e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +86 -0
- package/dist/PostgresAdapter.d.ts +6 -0
- package/dist/PostgresBackendDriver.d.ts +150 -0
- package/dist/PostgresBootstrapper.d.ts +51 -0
- package/dist/auth/ensure-tables.d.ts +10 -0
- package/dist/auth/services.d.ts +250 -0
- package/dist/backup/backup-cli.d.ts +3 -0
- package/dist/backup/backup-cron.d.ts +53 -0
- package/dist/backup/backup-service.d.ts +85 -0
- package/dist/backup/index.d.ts +12 -0
- package/dist/backup/pg-tools.d.ts +110 -0
- package/dist/backup/retention.d.ts +35 -0
- package/dist/chunk-DSJWtz9O.js +40 -0
- package/dist/cli-errors.d.ts +42 -0
- package/dist/cli-helpers.d.ts +7 -0
- package/dist/cli.d.ts +1 -0
- package/dist/collections/PostgresCollectionRegistry.d.ts +47 -0
- package/dist/connection.d.ts +65 -0
- package/dist/data-transformer.d.ts +55 -0
- package/dist/databasePoolManager.d.ts +20 -0
- package/dist/history/HistoryService.d.ts +71 -0
- package/dist/history/ensure-history-table.d.ts +7 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.es.js +23535 -0
- package/dist/index.es.js.map +1 -0
- package/dist/interfaces.d.ts +18 -0
- package/dist/schema/auth-bootstrap-sql.d.ts +24 -0
- package/dist/schema/auth-default-policies.d.ts +10 -0
- package/dist/schema/auth-schema.d.ts +2376 -0
- package/dist/schema/doctor-cli.d.ts +2 -0
- package/dist/schema/doctor.d.ts +58 -0
- package/dist/schema/dynamic-tables.d.ts +31 -0
- package/dist/schema/generate-drizzle-schema-logic.d.ts +2 -0
- package/dist/schema/generate-drizzle-schema.d.ts +1 -0
- package/dist/schema/generate-postgres-ddl-logic.d.ts +5 -0
- package/dist/schema/generate-postgres-ddl.d.ts +1 -0
- package/dist/schema/introspect-db-inference.d.ts +5 -0
- package/dist/schema/introspect-db-logic.d.ts +118 -0
- package/dist/schema/introspect-db.d.ts +1 -0
- package/dist/schema/introspect-runtime.d.ts +57 -0
- package/dist/schema/test-schema.d.ts +24 -0
- package/dist/security/policy-drift.d.ts +57 -0
- package/dist/security/rls-enforcement.d.ts +122 -0
- package/dist/services/BranchService.d.ts +47 -0
- package/dist/services/FetchService.d.ts +214 -0
- package/dist/services/PersistService.d.ts +39 -0
- package/dist/services/RelationService.d.ts +109 -0
- package/dist/services/cdc/CdcListener.d.ts +54 -0
- package/dist/services/cdc/trigger-cdc.d.ts +64 -0
- package/dist/services/collection-helpers.d.ts +38 -0
- package/dist/services/dataService.d.ts +110 -0
- package/dist/services/index.d.ts +4 -0
- package/dist/services/realtimeService.d.ts +298 -0
- package/dist/src-Eh-CZosp.js +595 -0
- package/dist/src-Eh-CZosp.js.map +1 -0
- package/dist/types.d.ts +3 -0
- package/dist/utils/drizzle-conditions.d.ts +138 -0
- package/dist/utils/pg-array-null-patch.d.ts +16 -0
- package/dist/utils/pg-error-utils.d.ts +65 -0
- package/dist/utils/table-classification.d.ts +8 -0
- package/dist/websocket.d.ts +18 -0
- package/package.json +113 -0
- package/src/PostgresAdapter.ts +58 -0
- package/src/PostgresBackendDriver.ts +1387 -0
- package/src/PostgresBootstrapper.ts +581 -0
- package/src/auth/ensure-tables.ts +367 -0
- package/src/auth/services.ts +1321 -0
- package/src/backup/backup-cli.ts +383 -0
- package/src/backup/backup-cron.ts +189 -0
- package/src/backup/backup-service.ts +299 -0
- package/src/backup/index.ts +12 -0
- package/src/backup/pg-tools.ts +231 -0
- package/src/backup/retention.ts +75 -0
- package/src/cli-errors.ts +265 -0
- package/src/cli-helpers.ts +196 -0
- package/src/cli.ts +786 -0
- package/src/collections/PostgresCollectionRegistry.ts +103 -0
- package/src/connection.ts +166 -0
- package/src/data-transformer.ts +733 -0
- package/src/databasePoolManager.ts +87 -0
- package/src/history/HistoryService.ts +272 -0
- package/src/history/ensure-history-table.ts +46 -0
- package/src/index.ts +15 -0
- package/src/interfaces.ts +60 -0
- package/src/schema/auth-bootstrap-sql.ts +41 -0
- package/src/schema/auth-default-policies.ts +125 -0
- package/src/schema/auth-schema.ts +233 -0
- package/src/schema/doctor-cli.ts +113 -0
- package/src/schema/doctor.ts +733 -0
- package/src/schema/dynamic-tables.test.ts +302 -0
- package/src/schema/dynamic-tables.ts +293 -0
- package/src/schema/generate-drizzle-schema-logic.ts +850 -0
- package/src/schema/generate-drizzle-schema.ts +131 -0
- package/src/schema/generate-postgres-ddl-logic.ts +490 -0
- package/src/schema/generate-postgres-ddl.ts +92 -0
- package/src/schema/introspect-db-inference.ts +238 -0
- package/src/schema/introspect-db-logic.ts +910 -0
- package/src/schema/introspect-db.ts +266 -0
- package/src/schema/introspect-runtime.test.ts +212 -0
- package/src/schema/introspect-runtime.ts +293 -0
- package/src/schema/test-schema.ts +11 -0
- package/src/security/policy-drift.test.ts +122 -0
- package/src/security/policy-drift.ts +159 -0
- package/src/security/rls-enforcement.ts +295 -0
- package/src/services/BranchService.ts +251 -0
- package/src/services/FetchService.ts +1661 -0
- package/src/services/PersistService.ts +329 -0
- package/src/services/RelationService.ts +1306 -0
- package/src/services/cdc/CdcListener.ts +167 -0
- package/src/services/cdc/trigger-cdc.ts +169 -0
- package/src/services/collection-helpers.ts +151 -0
- package/src/services/dataService.ts +246 -0
- package/src/services/index.ts +13 -0
- package/src/services/realtimeService.ts +1502 -0
- package/src/types.ts +4 -0
- package/src/utils/drizzle-conditions.ts +1162 -0
- package/src/utils/pg-array-null-patch.ts +42 -0
- package/src/utils/pg-error-utils.ts +227 -0
- package/src/utils/table-classification.ts +16 -0
- package/src/websocket.ts +640 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { WebSocket } from "ws";
|
|
2
|
+
import { EventEmitter } from "events";
|
|
3
|
+
import { DataDriver, WebSocketMessage } from "@rebasepro/types";
|
|
4
|
+
import { NodePgDatabase } from "drizzle-orm/node-postgres";
|
|
5
|
+
import { RealtimeProvider, CollectionSubscriptionConfig, SingleSubscriptionConfig } from "../interfaces";
|
|
6
|
+
import { PostgresCollectionRegistry } from "../collections/PostgresCollectionRegistry";
|
|
7
|
+
/**
|
|
8
|
+
* Auth context stored per-subscription so real-time refetches respect RLS.
|
|
9
|
+
* Mirrors the session variables set by PostgresBackendDriver.withAuth().
|
|
10
|
+
*/
|
|
11
|
+
export interface SubscriptionAuthContext {
|
|
12
|
+
userId: string;
|
|
13
|
+
roles: string[];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* PostgreSQL-specific realtime service.
|
|
17
|
+
* Handles WebSocket connections and subscriptions for real-time row updates.
|
|
18
|
+
*
|
|
19
|
+
* Implements the RealtimeProvider interface for database abstraction.
|
|
20
|
+
*/
|
|
21
|
+
export declare class RealtimeService extends EventEmitter implements RealtimeProvider {
|
|
22
|
+
private db;
|
|
23
|
+
private registry;
|
|
24
|
+
private clients;
|
|
25
|
+
private channels;
|
|
26
|
+
private presence;
|
|
27
|
+
private presenceInterval?;
|
|
28
|
+
private static readonly PRESENCE_TIMEOUT_MS;
|
|
29
|
+
private dataService;
|
|
30
|
+
private _subscriptions;
|
|
31
|
+
private subscriptionCallbacks;
|
|
32
|
+
private driver?;
|
|
33
|
+
/** Unique identifier for this process instance, used to skip own notifications. */
|
|
34
|
+
private readonly instanceId;
|
|
35
|
+
/** Dedicated pg.Client for LISTEN (outside the Drizzle pool). */
|
|
36
|
+
private listenClient?;
|
|
37
|
+
/** Connection string used for reconnecting the LISTEN client. */
|
|
38
|
+
private listenConnectionString?;
|
|
39
|
+
/** Whether cross-instance broadcasting is active. */
|
|
40
|
+
private broadcasting;
|
|
41
|
+
/** Reconnection timer handle. */
|
|
42
|
+
private reconnectTimer?;
|
|
43
|
+
/** Debounce timers for collection refetches to prevent refetch storms. */
|
|
44
|
+
private refetchTimers;
|
|
45
|
+
/** Debounce window (ms) for coalescing rapid row updates into a single correctness refetch. */
|
|
46
|
+
private static readonly REFETCH_DEBOUNCE_MS;
|
|
47
|
+
/** Dedicated LISTEN client for DB-level change events (undefined unless CDC is enabled). */
|
|
48
|
+
private cdcListener?;
|
|
49
|
+
/** Whether database-level CDC is the active cross-instance change source. */
|
|
50
|
+
private cdcActive;
|
|
51
|
+
/** Reverse lookup: `schema.table` (and bare `table`) → collection, built when CDC starts. */
|
|
52
|
+
private cdcTableMap?;
|
|
53
|
+
/**
|
|
54
|
+
* Short-lived record of `path/id` keys this instance just fanned out via the
|
|
55
|
+
* app path (a Rebase-API mutation). When CDC echoes the same committed change
|
|
56
|
+
* back to *this* instance, we suppress the duplicate — the change was already
|
|
57
|
+
* delivered locally. Other instances have no such record, so they still
|
|
58
|
+
* deliver the CDC event. External writes (psql, cron, SQL editor) never match
|
|
59
|
+
* and always flow through. Keyed → expiry timestamp (ms).
|
|
60
|
+
*/
|
|
61
|
+
private recentAppEmits;
|
|
62
|
+
/** How long an app-emit key suppresses its own CDC echo. Covers NOTIFY round-trip latency. */
|
|
63
|
+
private static readonly CDC_DEDUP_WINDOW_MS;
|
|
64
|
+
constructor(db: NodePgDatabase<any>, registry: PostgresCollectionRegistry);
|
|
65
|
+
/**
|
|
66
|
+
* Restricted role that auth-scoped refetches run as (via `SET LOCAL ROLE`)
|
|
67
|
+
* so RLS `select` policies bind. Set by the bootstrapper alongside
|
|
68
|
+
* `PostgresBackendDriver.rlsUserRole`; undefined when the connection
|
|
69
|
+
* is already subject to RLS natively. Without this, realtime refetches
|
|
70
|
+
* would leak rows the initial (isolated) fetch correctly hid.
|
|
71
|
+
*/
|
|
72
|
+
rlsUserRole?: string;
|
|
73
|
+
/** Whether to emit verbose debug logs (disabled in production). */
|
|
74
|
+
private static readonly DEBUG;
|
|
75
|
+
private debugLog;
|
|
76
|
+
setDataDriver(driver: DataDriver): void;
|
|
77
|
+
get subscriptions(): Map<string, {
|
|
78
|
+
clientId: string;
|
|
79
|
+
type: "collection" | "single";
|
|
80
|
+
path: string;
|
|
81
|
+
id?: string | number;
|
|
82
|
+
collectionRequest?: {
|
|
83
|
+
filter?: Record<string, unknown>;
|
|
84
|
+
orderBy?: string;
|
|
85
|
+
order?: "desc" | "asc";
|
|
86
|
+
limit?: number;
|
|
87
|
+
offset?: number;
|
|
88
|
+
startAfter?: Record<string, unknown>;
|
|
89
|
+
databaseId?: string;
|
|
90
|
+
searchString?: string;
|
|
91
|
+
};
|
|
92
|
+
authContext?: SubscriptionAuthContext;
|
|
93
|
+
}>;
|
|
94
|
+
registerDataDriverSubscription(subscriptionId: string, subscription: {
|
|
95
|
+
clientId: string;
|
|
96
|
+
type: "collection" | "single";
|
|
97
|
+
path: string;
|
|
98
|
+
id?: string | number;
|
|
99
|
+
collectionRequest?: {
|
|
100
|
+
filter?: Record<string, unknown>;
|
|
101
|
+
orderBy?: string;
|
|
102
|
+
order?: "desc" | "asc";
|
|
103
|
+
limit?: number;
|
|
104
|
+
offset?: number;
|
|
105
|
+
startAfter?: Record<string, unknown>;
|
|
106
|
+
databaseId?: string;
|
|
107
|
+
searchString?: string;
|
|
108
|
+
};
|
|
109
|
+
authContext?: SubscriptionAuthContext;
|
|
110
|
+
}): void;
|
|
111
|
+
addSubscriptionCallback(subscriptionId: string, callback: (data: Record<string, unknown>[] | Record<string, unknown> | null) => void): void;
|
|
112
|
+
removeSubscriptionCallback(subscriptionId: string): void;
|
|
113
|
+
/**
|
|
114
|
+
* Subscribe to collection changes (RealtimeProvider interface)
|
|
115
|
+
*/
|
|
116
|
+
subscribeToCollection(subscriptionId: string, config: CollectionSubscriptionConfig, callback?: (rows: Record<string, unknown>[]) => void): void;
|
|
117
|
+
/**
|
|
118
|
+
* Subscribe to single row changes (RealtimeProvider interface)
|
|
119
|
+
*/
|
|
120
|
+
subscribeToOne(subscriptionId: string, config: SingleSubscriptionConfig, callback?: (row: Record<string, unknown> | null) => void): void;
|
|
121
|
+
/**
|
|
122
|
+
* Unsubscribe from a subscription (RealtimeProvider interface)
|
|
123
|
+
*/
|
|
124
|
+
unsubscribe(subscriptionId: string): void;
|
|
125
|
+
addClient(clientId: string, ws: WebSocket): void;
|
|
126
|
+
handleClientMessage(clientId: string, message: WebSocketMessage, authContext?: SubscriptionAuthContext): Promise<void>;
|
|
127
|
+
removeClient(clientId: string): Promise<void>;
|
|
128
|
+
private handleMessage;
|
|
129
|
+
private handleCollectionSubscription;
|
|
130
|
+
private handleEntitySubscription;
|
|
131
|
+
private handleUnsubscribe;
|
|
132
|
+
/**
|
|
133
|
+
* Enhanced notification method that handles nested relation updates.
|
|
134
|
+
* @param broadcast When true (default), also sends a pg_notify so other instances
|
|
135
|
+
* pick up the change. Set to false when handling an incoming
|
|
136
|
+
* cross-instance notification to avoid infinite loops.
|
|
137
|
+
* @param origin `"app"` (default) — a Rebase-API mutation on this instance;
|
|
138
|
+
* `"cdc"` — a database-level change observed via CDC (any writer,
|
|
139
|
+
* any instance). The origin drives de-duplication: an app emit
|
|
140
|
+
* records the change so this instance can suppress the matching
|
|
141
|
+
* CDC echo, while an unmatched CDC event is delivered normally.
|
|
142
|
+
*/
|
|
143
|
+
notifyUpdate(path: string, id: string, row: Record<string, unknown> | null, databaseId?: string, broadcast?: boolean, origin?: "app" | "cdc"): Promise<void>;
|
|
144
|
+
/**
|
|
145
|
+
* Notify subscriptions for a specific path
|
|
146
|
+
*/
|
|
147
|
+
private notifyPathUpdate;
|
|
148
|
+
/**
|
|
149
|
+
* Debounce a collection refetch for a WebSocket subscription.
|
|
150
|
+
* Coalesces rapid row mutations into a single database query.
|
|
151
|
+
*/
|
|
152
|
+
private debouncedCollectionRefetch;
|
|
153
|
+
/**
|
|
154
|
+
* Debounce a collection refetch for a DataDriver callback subscription.
|
|
155
|
+
*/
|
|
156
|
+
private debouncedDriverRefetch;
|
|
157
|
+
/**
|
|
158
|
+
* Fetch a collection with optional RLS auth context.
|
|
159
|
+
* When authContext is provided, the fetch runs inside a transaction
|
|
160
|
+
* with set_config calls so PostgreSQL RLS policies are enforced.
|
|
161
|
+
*/
|
|
162
|
+
private fetchCollectionWithAuth;
|
|
163
|
+
/**
|
|
164
|
+
* Debounce an row refetch for a WebSocket subscription.
|
|
165
|
+
*/
|
|
166
|
+
private debouncedSingleRefetch;
|
|
167
|
+
/**
|
|
168
|
+
* Debounce an row refetch for a Driver callback subscription.
|
|
169
|
+
*/
|
|
170
|
+
private debouncedSingleDriverRefetch;
|
|
171
|
+
/**
|
|
172
|
+
* Fetch a single row with optional RLS auth context.
|
|
173
|
+
*/
|
|
174
|
+
private fetchEntityWithAuth;
|
|
175
|
+
private sendCollectionUpdate;
|
|
176
|
+
private sendSingleUpdate;
|
|
177
|
+
/**
|
|
178
|
+
* Send a lightweight row-level patch to a collection subscriber.
|
|
179
|
+
* The client can merge this into its cached data for instant feedback.
|
|
180
|
+
*/
|
|
181
|
+
private sendCollectionPatch;
|
|
182
|
+
private sendError;
|
|
183
|
+
private sendMessage;
|
|
184
|
+
/**
|
|
185
|
+
* Extract parent paths from a nested path like "posts/70/tags"
|
|
186
|
+
* Returns ["posts", "posts/70"] for the example above
|
|
187
|
+
*/
|
|
188
|
+
private getParentPaths;
|
|
189
|
+
/** Join a broadcast channel */
|
|
190
|
+
joinChannel(clientId: string, channel: string): void;
|
|
191
|
+
/** Leave a broadcast channel */
|
|
192
|
+
leaveChannel(clientId: string, channel: string): void;
|
|
193
|
+
/** Broadcast a message to all clients in a channel except sender */
|
|
194
|
+
broadcastToChannel(clientId: string, channel: string, event: string, payload: unknown): void;
|
|
195
|
+
/** Track presence in a channel */
|
|
196
|
+
trackPresence(clientId: string, channel: string, state: Record<string, unknown>): void;
|
|
197
|
+
/** Remove presence from a channel */
|
|
198
|
+
removePresence(clientId: string, channel: string): void;
|
|
199
|
+
/** Send full presence state to a specific client */
|
|
200
|
+
sendPresenceState(clientId: string, channel: string): void;
|
|
201
|
+
/** Broadcast presence diff (joins/leaves) to channel */
|
|
202
|
+
private broadcastPresenceDiff;
|
|
203
|
+
/** Periodic cleanup for stale presences */
|
|
204
|
+
private ensurePresenceCleanup;
|
|
205
|
+
/**
|
|
206
|
+
* Gracefully tear down all realtime resources.
|
|
207
|
+
*
|
|
208
|
+
* This MUST be called during process shutdown, **before** `pool.end()`.
|
|
209
|
+
* It ensures:
|
|
210
|
+
* 1. All debounced refetch timers are cancelled (prevents queries after pool closes).
|
|
211
|
+
* 2. All subscription state and callbacks are cleared.
|
|
212
|
+
* 3. The dedicated LISTEN client (outside the pool) is disconnected.
|
|
213
|
+
* 4. All WebSocket clients are removed (but not forcefully closed — the
|
|
214
|
+
* HTTP server close will handle that).
|
|
215
|
+
*/
|
|
216
|
+
destroy(): Promise<void>;
|
|
217
|
+
/** Whether database-level change capture is currently the active source. */
|
|
218
|
+
isCdcActive(): boolean;
|
|
219
|
+
/**
|
|
220
|
+
* Enable database-level change capture as the realtime source.
|
|
221
|
+
*
|
|
222
|
+
* A dedicated LISTEN client consumes committed changes from the `rebase_cdc`
|
|
223
|
+
* channel (fed by CDC triggers — see {@link provisionTriggerCdc}) and routes
|
|
224
|
+
* them into the same {@link notifyUpdate} pipeline used by API mutations. The
|
|
225
|
+
* effect: subscribers see a change no matter how it was written — psql, a
|
|
226
|
+
* cron in another service, raw SQL, or the Studio SQL editor — exactly like
|
|
227
|
+
* Supabase Realtime tailing the WAL.
|
|
228
|
+
*
|
|
229
|
+
* Because CDC observes every commit on every instance, it also *replaces* the
|
|
230
|
+
* legacy per-mutation cross-instance broadcast (see the guard in
|
|
231
|
+
* {@link notifyUpdate}); callers should not also call {@link startListening}.
|
|
232
|
+
*
|
|
233
|
+
* @param connectionString Direct Postgres connection for the LISTEN client
|
|
234
|
+
* (bypass PgBouncer — LISTEN needs a session connection).
|
|
235
|
+
*/
|
|
236
|
+
enableCdc(connectionString: string): Promise<void>;
|
|
237
|
+
/** Stop the CDC listener and clear its state. */
|
|
238
|
+
stopCdc(): Promise<void>;
|
|
239
|
+
/**
|
|
240
|
+
* Build the reverse map from database table → collection. A change event
|
|
241
|
+
* carries `schema` + `table`; realtime subscriptions are keyed by collection
|
|
242
|
+
* path (slug). We index by both `schema.table` and bare `table` so the lookup
|
|
243
|
+
* works whether or not the collection declares an explicit schema.
|
|
244
|
+
*/
|
|
245
|
+
private buildCdcTableMap;
|
|
246
|
+
private resolveCollectionForTable;
|
|
247
|
+
/**
|
|
248
|
+
* Route a captured database change into the realtime pipeline.
|
|
249
|
+
*
|
|
250
|
+
* Delivery is RLS-safe by construction: the raw tuple from the WAL/trigger is
|
|
251
|
+
* NOT forwarded to subscribers. Instead the change is marked invalidated, so
|
|
252
|
+
* every matching subscription re-reads the row under its own auth context via
|
|
253
|
+
* {@link fetchCollectionWithAuth} / {@link fetchEntityWithAuth}. A subscriber
|
|
254
|
+
* therefore only ever receives rows its RLS policies permit — filtering is per
|
|
255
|
+
* subscriber, never per publisher.
|
|
256
|
+
*/
|
|
257
|
+
private handleCdcEvent;
|
|
258
|
+
/** Compute the canonical (possibly composite) id string from a captured row. */
|
|
259
|
+
private extractIdFromCdcRow;
|
|
260
|
+
private dedupKey;
|
|
261
|
+
/** Record that this instance just delivered `key` via the app path. */
|
|
262
|
+
private markAppEmit;
|
|
263
|
+
/** Consume a matching app-emit record if present and unexpired; true ⇒ suppress the CDC echo. */
|
|
264
|
+
private consumeAppEmit;
|
|
265
|
+
/**
|
|
266
|
+
* Enable cross-instance realtime broadcasting via Postgres LISTEN/NOTIFY.
|
|
267
|
+
* Creates a dedicated pg.Client (outside the Drizzle pool) that stays
|
|
268
|
+
* connected and listens for change notifications from other instances.
|
|
269
|
+
*
|
|
270
|
+
* This is an **optional** feature — if never called, the backend operates
|
|
271
|
+
* in single-instance mode (the default, perfectly fine for most setups).
|
|
272
|
+
*
|
|
273
|
+
* @param connectionString Raw Postgres connection string for the LISTEN client.
|
|
274
|
+
*/
|
|
275
|
+
startListening(connectionString: string): Promise<void>;
|
|
276
|
+
/**
|
|
277
|
+
* Stop listening and clean up the dedicated LISTEN connection.
|
|
278
|
+
*/
|
|
279
|
+
stopListening(): Promise<void>;
|
|
280
|
+
/**
|
|
281
|
+
* Broadcast a change notification to other instances via pg_notify.
|
|
282
|
+
* Uses the main Drizzle connection (pooled) — NOT the LISTEN client.
|
|
283
|
+
*/
|
|
284
|
+
private broadcastChange;
|
|
285
|
+
/**
|
|
286
|
+
* Create and connect the dedicated LISTEN client with auto-reconnect.
|
|
287
|
+
*/
|
|
288
|
+
private connectListenClient;
|
|
289
|
+
/**
|
|
290
|
+
* Schedule a reconnection attempt with a fixed 3s delay.
|
|
291
|
+
*/
|
|
292
|
+
private scheduleReconnect;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Alias for RealtimeService for consistent naming with other database implementations.
|
|
296
|
+
* This allows code to use PostgresRealtimeProvider alongside future MongoRealtimeProvider, etc.
|
|
297
|
+
*/
|
|
298
|
+
export declare const PostgresRealtimeProvider: typeof RealtimeService;
|