@delali/sirannon-db 0.3.4-next.62 → 0.3.4
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/README.md +79 -56
- package/dist/backup/index.d.ts +44 -45
- package/dist/backup/index.mjs +7 -7
- package/dist/backup-scheduler/index.d.ts +42 -41
- package/dist/backup-scheduler/index.mjs +4 -4
- package/dist/baseline-Co3iIsN_.d.ts +19 -0
- package/dist/change-tracker-DqCdeEyx.d.ts +128 -0
- package/dist/{chunk-VOSJBZ6Q.mjs → chunk-2ES3DT4A.mjs} +71 -33
- package/dist/{chunk-6CMCO7S4.mjs → chunk-2O3PP4CF.mjs} +1 -1
- package/dist/{chunk-E7Q7HE46.mjs → chunk-3BZLZ47R.mjs} +26 -26
- package/dist/chunk-4KASJKKK.mjs +2501 -0
- package/dist/{chunk-MYNI2WFS.mjs → chunk-52XW3Z76.mjs} +40 -8
- package/dist/chunk-55YRLSM2.mjs +57 -0
- package/dist/{chunk-KDAHYFW7.mjs → chunk-6AOJCNRU.mjs} +5 -5
- package/dist/{chunk-KXTYR2OQ.mjs → chunk-A3PHCO6W.mjs} +39 -111
- package/dist/chunk-ADNWEHGZ.mjs +299 -0
- package/dist/{chunk-2QLXDHAP.mjs → chunk-BLMRNSUG.mjs} +11 -2
- package/dist/chunk-BVMZJOVM.mjs +5 -0
- package/dist/{chunk-IWGIYDMZ.mjs → chunk-BZWDPF4G.mjs} +1 -1
- package/dist/{chunk-YVF2ZJTE.mjs → chunk-CZL4D3BM.mjs} +1 -1
- package/dist/{chunk-7SC2TZAS.mjs → chunk-DX4WGJL7.mjs} +2 -2
- package/dist/{chunk-45MKELYA.mjs → chunk-ESTZZPT5.mjs} +132 -13
- package/dist/{chunk-QP5L5DFJ.mjs → chunk-FJPR2CJX.mjs} +3 -3
- package/dist/chunk-HR7K3GZW.mjs +36 -0
- package/dist/{chunk-LXCGPZPA.mjs → chunk-IEKIYO4V.mjs} +1 -1
- package/dist/{chunk-TUD5CJ76.mjs → chunk-KB4OLJAD.mjs} +26 -19
- package/dist/{chunk-PBRXXISQ.mjs → chunk-KINDFBQP.mjs} +3 -2
- package/dist/{chunk-E6IMX7RS.mjs → chunk-KJLNYOOL.mjs} +2 -2
- package/dist/{chunk-BTTFW4Z4.mjs → chunk-KU32OT4H.mjs} +2 -10
- package/dist/{chunk-JQWGHSEH.mjs → chunk-NVSQ2T5Q.mjs} +71 -70
- package/dist/{chunk-W4EUTJNT.mjs → chunk-NZGSDALX.mjs} +94 -96
- package/dist/{chunk-U445A3C4.mjs → chunk-QGVRRKB2.mjs} +1 -1
- package/dist/{chunk-GYCEJNU4.mjs → chunk-R7GBXNTO.mjs} +1 -1
- package/dist/{chunk-7C36BCSN.mjs → chunk-VDN6FHU4.mjs} +1 -1
- package/dist/{chunk-6IYS4WLH.mjs → chunk-VO3ZWA2G.mjs} +142 -115
- package/dist/chunk-WOMADPM4.mjs +12 -0
- package/dist/{chunk-OUSWVNWT.mjs → chunk-YCMB6GR4.mjs} +1 -1
- package/dist/{chunk-YNTDOFTN.mjs → chunk-YW7IKQ7T.mjs} +1 -1
- package/dist/{chunk-M2BEAH5I.mjs → chunk-ZN4HI5FK.mjs} +126 -72
- package/dist/{chunk-SBL6GN43.mjs → chunk-ZYWI45EN.mjs} +1 -1
- package/dist/client/index.d.ts +135 -137
- package/dist/client/index.mjs +177 -82
- package/dist/client/topology.d.ts +31 -31
- package/dist/client/topology.mjs +42 -23
- package/dist/client-base-BxTocU1x.d.ts +398 -0
- package/dist/client-streams-YKANXMWO.mjs +112 -0
- package/dist/codegen/cli.mjs +4 -4
- package/dist/codegen/index.d.ts +36 -29
- package/dist/codegen/index.mjs +4 -4
- package/dist/core/index.d.ts +130 -115
- package/dist/core/index.mjs +387 -297
- package/dist/core/writer-worker.mjs +3 -3
- package/dist/database-CGDsXW1K.d.ts +959 -0
- package/dist/database-backup-DcLhxoa1.d.ts +143 -0
- package/dist/driver/better-sqlite3.d.ts +11 -10
- package/dist/driver/better-sqlite3.mjs +11 -11
- package/dist/driver/bun.d.ts +9 -8
- package/dist/driver/expo.d.ts +6 -7
- package/dist/driver/node.d.ts +11 -10
- package/dist/driver/node.mjs +13 -11
- package/dist/driver/wa-sqlite.d.ts +6 -6
- package/dist/errors-CJUkQ-KL.d.ts +199 -0
- package/dist/file-migrations/index.d.ts +20 -18
- package/dist/file-migrations/index.mjs +3 -3
- package/dist/forward-rpc-VRWFZXHN.mjs +44 -0
- package/dist/operation-registry-CGhNT-Sn.d.ts +96 -0
- package/dist/primary-wins-CHNOYuN7.d.ts +81 -0
- package/dist/protocol-DFpNNsIT.d.ts +153 -0
- package/dist/query-types-5B02ixH0.d.ts +129 -0
- package/dist/react/index.d.ts +22 -22
- package/dist/replication/coordinator/etcd.d.ts +37 -31
- package/dist/replication/coordinator/etcd.mjs +296 -131
- package/dist/replication/index.d.ts +201 -161
- package/dist/replication/index.mjs +630 -529
- package/dist/restore-options-CH8mE-Tb.d.ts +84 -0
- package/dist/server/index.d.ts +201 -191
- package/dist/server/index.mjs +736 -619
- package/dist/server-options-aYtCkefX.d.ts +317 -0
- package/dist/server-streams-24XL4T43.mjs +254 -0
- package/dist/sirannon-J3EgPVD7.d.ts +179 -0
- package/dist/transport/grpc.d.ts +37 -24
- package/dist/transport/grpc.mjs +83 -3199
- package/dist/transport/memory.d.ts +25 -26
- package/dist/transport/memory.mjs +18 -9
- package/dist/types-BrAiDGOb.d.ts +505 -0
- package/dist/types-CEJG0eFS.d.ts +88 -0
- package/dist/types-Dc8oWlxj.d.ts +1580 -0
- package/dist/types-DqODKeOq.d.ts +123 -0
- package/dist/types-guEKSzMr.d.ts +367 -0
- package/package.json +7 -7
- package/dist/baseline-D93hcIEE.d.ts +0 -17
- package/dist/change-tracker-CjRFuZdB.d.ts +0 -144
- package/dist/client-base-Cmd9EVme.d.ts +0 -397
- package/dist/database-BLQvqjsw.d.ts +0 -917
- package/dist/database-backup-B7oszQ2n.d.ts +0 -141
- package/dist/errors-Dei4GdBb.d.ts +0 -196
- package/dist/operation-registry-oiPuSYI6.d.ts +0 -94
- package/dist/primary-wins-B0np8JS3.d.ts +0 -85
- package/dist/protocol-HI-nY8DD.d.ts +0 -152
- package/dist/query-types-p1liOP-b.d.ts +0 -127
- package/dist/restore-options-CksYsH1l.d.ts +0 -83
- package/dist/server-options-Bj5iJnjx.d.ts +0 -292
- package/dist/sirannon-BPxC5tC2.d.ts +0 -178
- package/dist/types-B0EhgDbr.d.ts +0 -340
- package/dist/types-CbjfRwrK.d.ts +0 -499
- package/dist/types-CjhxcjhA.d.ts +0 -123
- package/dist/types-DPSmjU54.d.ts +0 -1518
- package/dist/types-DTO4CYhW.d.ts +0 -88
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { tableColumnNames, tablePkColumns, selectMinChangeSeqSql, selectMaxChangeSeq, deleteChangesBeforeUpToSeqSql, deleteChangesBeforeSql, selectTableExists, ensureChangesTable, ensureMetaTable, insertMetaValueIfAbsent, selectMetaValue, selectChangesAfterSeqSql, selectTablesChangesInRangeSql } from './chunk-
|
|
2
|
-
import { CHANGES_TABLE, isReservedIdentifier, CDC_TRIGGER_PREFIX, encodeTaggedValues, changedAtToEventTimestamp, decodeTaggedValues, SAFE_INT_BOUND_TEXT } from './chunk-
|
|
3
|
-
import { synchronousPragmaValue } from './chunk-
|
|
1
|
+
import { tableColumnNames, tablePkColumns, selectMinChangeSeqSql, selectMaxChangeSeq, deleteChangesBeforeUpToSeqSql, deleteChangesBeforeSql, selectTableExists, ensureChangesTable, ensureMetaTable, insertMetaValueIfAbsent, selectMetaValue, selectChangesAfterSeqSql, selectTablesChangesInRangeSql, deleteExpiredDeviceCursors, selectMinDeviceCursorBoundary } from './chunk-ESTZZPT5.mjs';
|
|
2
|
+
import { CHANGES_TABLE, isReservedIdentifier, CDC_TRIGGER_PREFIX, encodeTaggedValues, changedAtToEventTimestamp, decodeTaggedValues, SAFE_INT_BOUND_TEXT, DEVICE_CURSORS_TABLE } from './chunk-2O3PP4CF.mjs';
|
|
3
|
+
import { synchronousPragmaValue } from './chunk-YCMB6GR4.mjs';
|
|
4
4
|
import { randomHex, invokeCallerCallback, reportCallerFailure, toError } from './chunk-QBBLSQHQ.mjs';
|
|
5
|
-
import { SirannonError, ForbiddenSqlError, CDCError, MigrationError } from './chunk-
|
|
5
|
+
import { SirannonError, ForbiddenSqlError, CDCError, MigrationError } from './chunk-KINDFBQP.mjs';
|
|
6
6
|
|
|
7
7
|
// src/core/bulk-load.ts
|
|
8
8
|
var DEFAULT_LOAD_DURABILITY = "off";
|
|
@@ -119,6 +119,38 @@ async function readSinceTables(conn, cache, changesTable, tables, afterSeq, upTo
|
|
|
119
119
|
return rows.map(rowToEvent);
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
+
// src/core/cdc/prune-boundaries.ts
|
|
123
|
+
var PruneBoundaries = class {
|
|
124
|
+
bySource = /* @__PURE__ */ new Map();
|
|
125
|
+
set(source, seq) {
|
|
126
|
+
this.bySource.set(source, seq);
|
|
127
|
+
}
|
|
128
|
+
clear(source) {
|
|
129
|
+
this.bySource.delete(source);
|
|
130
|
+
}
|
|
131
|
+
lowest() {
|
|
132
|
+
let lowest = null;
|
|
133
|
+
for (const boundary of this.bySource.values()) {
|
|
134
|
+
if (lowest === null || boundary < lowest) {
|
|
135
|
+
lowest = boundary;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return lowest;
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
function seqBoundFor(lowest, lastSeq) {
|
|
142
|
+
if (lastSeq > 0n && lowest !== null) {
|
|
143
|
+
return lastSeq < lowest ? lastSeq : lowest;
|
|
144
|
+
}
|
|
145
|
+
if (lowest !== null) {
|
|
146
|
+
return lowest;
|
|
147
|
+
}
|
|
148
|
+
if (lastSeq > 0n) {
|
|
149
|
+
return lastSeq;
|
|
150
|
+
}
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
|
|
122
154
|
// src/core/cdc/statement-cache.ts
|
|
123
155
|
var StatementCache = class {
|
|
124
156
|
cache = /* @__PURE__ */ new WeakMap();
|
|
@@ -216,7 +248,7 @@ var ChangeTracker = class {
|
|
|
216
248
|
changesTableEnsured = false;
|
|
217
249
|
watchedTablesCache = null;
|
|
218
250
|
stmtCache = new StatementCache();
|
|
219
|
-
|
|
251
|
+
pruneBoundaries = new PruneBoundaries();
|
|
220
252
|
lastPollAtTxBoundary = true;
|
|
221
253
|
constructor(options) {
|
|
222
254
|
this.retentionMs = options?.retention ?? DEFAULT_RETENTION_MS;
|
|
@@ -225,10 +257,10 @@ var ChangeTracker = class {
|
|
|
225
257
|
this.assertIdentifier(this.changesTable, "changes table name");
|
|
226
258
|
}
|
|
227
259
|
/**
|
|
228
|
-
*
|
|
260
|
+
* Installs change-capture triggers on a table, so that every later write to it adds a row to the change log.
|
|
229
261
|
*
|
|
230
|
-
* @param conn -
|
|
231
|
-
* @param table -
|
|
262
|
+
* @param conn - The writer connection on which the tracker creates the triggers.
|
|
263
|
+
* @param table - The name of the table to watch.
|
|
232
264
|
*/
|
|
233
265
|
async watch(conn, table) {
|
|
234
266
|
this.assertIdentifier(table, "table name");
|
|
@@ -261,10 +293,10 @@ var ChangeTracker = class {
|
|
|
261
293
|
this.watchedTablesCache = null;
|
|
262
294
|
}
|
|
263
295
|
/**
|
|
264
|
-
*
|
|
296
|
+
* Drops a table's change-capture triggers and removes the table from the watched set.
|
|
265
297
|
*
|
|
266
|
-
* @param conn -
|
|
267
|
-
* @param table -
|
|
298
|
+
* @param conn - The writer connection on which the tracker drops the triggers.
|
|
299
|
+
* @param table - The name of the table to stop watching.
|
|
268
300
|
*/
|
|
269
301
|
async unwatch(conn, table) {
|
|
270
302
|
if (!this.watched.has(table)) {
|
|
@@ -275,29 +307,17 @@ var ChangeTracker = class {
|
|
|
275
307
|
this.watchedTablesCache = null;
|
|
276
308
|
}
|
|
277
309
|
/**
|
|
278
|
-
* Rebuilds
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
* Required when a caller has already issued `BEGIN` on `conn` and runs a
|
|
282
|
-
* DDL statement that changes a watched table's column list: the next DML
|
|
283
|
-
* inside the same transaction must see triggers compiled against the new
|
|
284
|
-
* columns, otherwise CDC `new_data` silently omits them. Callers that are
|
|
285
|
-
* not inside an active transaction may also use this method; CREATE
|
|
286
|
-
* TRIGGER and DROP TRIGGER statements are committed individually by the
|
|
287
|
-
* driver in that case.
|
|
310
|
+
* Rebuilds the change-capture triggers on `conn` for every watched table
|
|
311
|
+
* whose column list has changed, without opening a nested transaction.
|
|
288
312
|
*
|
|
289
|
-
*
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
*
|
|
293
|
-
*
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
* the cached one, the existing triggers are dropped and reinstalled on
|
|
298
|
-
* `conn`. The cached column list is updated on success.
|
|
299
|
-
* - Any other error (driver failure, identifier validation failure) is
|
|
300
|
-
* rethrown so the caller's transaction can roll back deterministically.
|
|
313
|
+
* Call it after a DDL statement inside an open transaction, so that the next
|
|
314
|
+
* write in that transaction records the new columns in `new_data`. You can
|
|
315
|
+
* also call it outside a transaction, in which case SQLite commits each
|
|
316
|
+
* `CREATE TRIGGER` and `DROP TRIGGER` statement on its own. The method skips
|
|
317
|
+
* a watched table that no longer exists, and it leaves that table's entry for
|
|
318
|
+
* `pruneDroppedTables` to remove after the commit. A
|
|
319
|
+
* driver error or an invalid column name propagates to the caller, so that
|
|
320
|
+
* the caller can roll back its transaction.
|
|
301
321
|
*
|
|
302
322
|
* @internal
|
|
303
323
|
*/
|
|
@@ -329,24 +349,16 @@ var ChangeTracker = class {
|
|
|
329
349
|
}
|
|
330
350
|
}
|
|
331
351
|
/**
|
|
332
|
-
*
|
|
333
|
-
*
|
|
352
|
+
* Drops the change-capture triggers of each named table that the tracker
|
|
353
|
+
* watches, and removes that table from the watched set.
|
|
334
354
|
*
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
* twice in succession produces the same state.
|
|
343
|
-
*
|
|
344
|
-
* Defence in depth: even after a `DROP TABLE`, the in-transaction trigger
|
|
345
|
-
* refresh path may have observed a freshly-created table of the same name
|
|
346
|
-
* (the DROP and CREATE happened inside the same transaction) and
|
|
347
|
-
* re-installed triggers compiled against the new schema. Those triggers
|
|
348
|
-
* are dropped here so the recreated table starts with a clean slate and
|
|
349
|
-
* the caller must explicitly `watch` it again.
|
|
355
|
+
* Call it once a transaction that drops watched tables commits, and skip the
|
|
356
|
+
* call when that transaction rolls back. The method skips each table outside
|
|
357
|
+
* the watched set and issues `DROP TRIGGER IF EXISTS`, so a second call leaves
|
|
358
|
+
* the same state. When one transaction drops a table and creates another with
|
|
359
|
+
* the same name, `refreshAllTriggersUsingConnection` can
|
|
360
|
+
* install triggers on the new table. This method drops those triggers too, so
|
|
361
|
+
* you have to call `watch` again for the new table.
|
|
350
362
|
*
|
|
351
363
|
* @internal
|
|
352
364
|
*/
|
|
@@ -386,7 +398,7 @@ var ChangeTracker = class {
|
|
|
386
398
|
return this.lastPollAtTxBoundary;
|
|
387
399
|
}
|
|
388
400
|
/**
|
|
389
|
-
*
|
|
401
|
+
* Returns the sequence number of the last change that the tracker polled or skipped with `advanceToLatest`, so live subscribers receive only later changes.
|
|
390
402
|
*
|
|
391
403
|
* @internal
|
|
392
404
|
*/
|
|
@@ -405,7 +417,7 @@ var ChangeTracker = class {
|
|
|
405
417
|
return readSinceTables(conn, this.stmtCache, this.changesTable, tables, afterSeq, upToSeq, limit);
|
|
406
418
|
}
|
|
407
419
|
/**
|
|
408
|
-
*
|
|
420
|
+
* Returns the lowest sequence number in the change log, or `null` when the log is empty or missing.
|
|
409
421
|
*
|
|
410
422
|
* @internal
|
|
411
423
|
*/
|
|
@@ -461,12 +473,16 @@ var ChangeTracker = class {
|
|
|
461
473
|
return result.changes;
|
|
462
474
|
}
|
|
463
475
|
/** @internal */
|
|
464
|
-
setPruneBoundary(seq) {
|
|
465
|
-
this.
|
|
476
|
+
setPruneBoundary(source, seq) {
|
|
477
|
+
this.pruneBoundaries.set(source, seq);
|
|
478
|
+
}
|
|
479
|
+
/** @internal */
|
|
480
|
+
clearPruneBoundary(source) {
|
|
481
|
+
this.pruneBoundaries.clear(source);
|
|
466
482
|
}
|
|
467
483
|
/** @internal */
|
|
468
|
-
|
|
469
|
-
this.
|
|
484
|
+
get changeLogTable() {
|
|
485
|
+
return this.changesTable;
|
|
470
486
|
}
|
|
471
487
|
/** @internal */
|
|
472
488
|
get watchedTables() {
|
|
@@ -476,17 +492,7 @@ var ChangeTracker = class {
|
|
|
476
492
|
return this.watchedTablesCache;
|
|
477
493
|
}
|
|
478
494
|
computeSeqBound() {
|
|
479
|
-
|
|
480
|
-
if (this.lastSeq > 0n && boundary !== null) {
|
|
481
|
-
return this.lastSeq < boundary ? this.lastSeq : boundary;
|
|
482
|
-
}
|
|
483
|
-
if (boundary !== null) {
|
|
484
|
-
return boundary;
|
|
485
|
-
}
|
|
486
|
-
if (this.lastSeq > 0n) {
|
|
487
|
-
return this.lastSeq;
|
|
488
|
-
}
|
|
489
|
-
return null;
|
|
495
|
+
return seqBoundFor(this.pruneBoundaries.lowest(), this.lastSeq);
|
|
490
496
|
}
|
|
491
497
|
assertIdentifier(name, label) {
|
|
492
498
|
if (!IDENTIFIER_RE.test(name)) {
|
|
@@ -550,6 +556,42 @@ function reconcileMigrationChecksums(migrations, applied) {
|
|
|
550
556
|
return backfills;
|
|
551
557
|
}
|
|
552
558
|
|
|
559
|
+
// src/core/cdc/device-retention.ts
|
|
560
|
+
var DEFAULT_DEVICE_CURSOR_RETENTION_MS = 30 * 24 * 36e5;
|
|
561
|
+
function resolveDeviceRetentionPolicy(options, fallback) {
|
|
562
|
+
return {
|
|
563
|
+
cursorRetentionMs: options?.deviceCursorRetention ?? fallback?.deviceCursorRetention ?? DEFAULT_DEVICE_CURSOR_RETENTION_MS,
|
|
564
|
+
maxChangesHeldForDevice: options?.maxChangesHeldForDevice ?? fallback?.maxChangesHeldForDevice ?? 0
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
async function bothTablesExist(conn, changesTable) {
|
|
568
|
+
if (!await selectTableExists(conn, DEVICE_CURSORS_TABLE)) return false;
|
|
569
|
+
return selectTableExists(conn, changesTable);
|
|
570
|
+
}
|
|
571
|
+
async function dropExpiredDeviceCursors(conn, policy, changesTable = CHANGES_TABLE) {
|
|
572
|
+
if (!await bothTablesExist(conn, changesTable)) return 0;
|
|
573
|
+
const cutoff = Date.now() / 1e3 - policy.cursorRetentionMs / 1e3;
|
|
574
|
+
return deleteExpiredDeviceCursors(conn, changesTable, {
|
|
575
|
+
idleCutoff: cutoff,
|
|
576
|
+
changeAgeCutoff: cutoff,
|
|
577
|
+
maxChangesHeldForDevice: policy.maxChangesHeldForDevice
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
async function resolveMinDeviceCursorBoundary(conn, changesTable = CHANGES_TABLE) {
|
|
581
|
+
if (!await bothTablesExist(conn, changesTable)) return null;
|
|
582
|
+
return selectMinDeviceCursorBoundary(conn, changesTable);
|
|
583
|
+
}
|
|
584
|
+
async function applyDeviceCursorBoundary(conn, tracker, policy) {
|
|
585
|
+
const changesTable = tracker.changeLogTable;
|
|
586
|
+
await dropExpiredDeviceCursors(conn, policy, changesTable);
|
|
587
|
+
const boundary = await resolveMinDeviceCursorBoundary(conn, changesTable);
|
|
588
|
+
if (boundary === null) {
|
|
589
|
+
tracker.clearPruneBoundary("device-cursors");
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
tracker.setPruneBoundary("device-cursors", boundary);
|
|
593
|
+
}
|
|
594
|
+
|
|
553
595
|
// src/core/cdc/epoch.ts
|
|
554
596
|
var EPOCH_KEY = "cdc_epoch";
|
|
555
597
|
async function ensureCdcEpoch(conn) {
|
|
@@ -563,7 +605,11 @@ async function ensureCdcEpoch(conn) {
|
|
|
563
605
|
}
|
|
564
606
|
|
|
565
607
|
// src/core/cdc/subscription.ts
|
|
608
|
+
var NO_SUBSCRIBERS = /* @__PURE__ */ new Set();
|
|
566
609
|
var SubscriptionManager = class {
|
|
610
|
+
constructor(onDispatched) {
|
|
611
|
+
this.onDispatched = onDispatched;
|
|
612
|
+
}
|
|
567
613
|
nextId = 1;
|
|
568
614
|
subscriptions = /* @__PURE__ */ new Map();
|
|
569
615
|
byTable = /* @__PURE__ */ new Map();
|
|
@@ -592,15 +638,17 @@ var SubscriptionManager = class {
|
|
|
592
638
|
}
|
|
593
639
|
dispatch(events) {
|
|
594
640
|
for (const event of events) {
|
|
595
|
-
const ids = this.byTable.get(event.table);
|
|
596
|
-
|
|
641
|
+
const ids = this.byTable.get(event.table) ?? NO_SUBSCRIBERS;
|
|
642
|
+
let deliveredTo = 0;
|
|
597
643
|
for (const id of ids) {
|
|
598
644
|
const sub = this.subscriptions.get(id);
|
|
599
645
|
if (!sub) continue;
|
|
600
646
|
const delivered = sub.filter === void 0 ? event : filteredChange(event, sub.filter);
|
|
601
647
|
if (delivered === null) continue;
|
|
648
|
+
deliveredTo++;
|
|
602
649
|
invokeCallerCallback(() => sub.callback(delivered), sub.onError);
|
|
603
650
|
}
|
|
651
|
+
this.onDispatched?.(event, deliveredTo);
|
|
604
652
|
}
|
|
605
653
|
}
|
|
606
654
|
reportError(error) {
|
|
@@ -640,7 +688,10 @@ var SubscriptionBuilderImpl = class {
|
|
|
640
688
|
return this.manager.subscribe(this.table, this.conditions, callback, options);
|
|
641
689
|
}
|
|
642
690
|
};
|
|
643
|
-
function startPolling(conn, tracker, manager, intervalMs, onError, runExclusive
|
|
691
|
+
function startPolling(conn, tracker, manager, intervalMs, onError, runExclusive, deviceRetention = {
|
|
692
|
+
cursorRetentionMs: DEFAULT_DEVICE_CURSOR_RETENTION_MS,
|
|
693
|
+
maxChangesHeldForDevice: 0
|
|
694
|
+
}) {
|
|
644
695
|
let consecutiveErrors = 0;
|
|
645
696
|
let tickCount = 0;
|
|
646
697
|
let polling = false;
|
|
@@ -661,7 +712,10 @@ function startPolling(conn, tracker, manager, intervalMs, onError, runExclusive)
|
|
|
661
712
|
tickCount++;
|
|
662
713
|
if (tickCount >= CLEANUP_INTERVAL_TICKS) {
|
|
663
714
|
tickCount = 0;
|
|
664
|
-
await exclusive(() =>
|
|
715
|
+
await exclusive(async () => {
|
|
716
|
+
await applyDeviceCursorBoundary(conn, tracker, deviceRetention);
|
|
717
|
+
await tracker.cleanup(conn);
|
|
718
|
+
});
|
|
665
719
|
}
|
|
666
720
|
} catch (err) {
|
|
667
721
|
consecutiveErrors++;
|
|
@@ -850,4 +904,4 @@ var TransactionGrouper = class {
|
|
|
850
904
|
}
|
|
851
905
|
};
|
|
852
906
|
|
|
853
|
-
export { ChangeTracker, PrimedSubscription, SubscriptionBuilderImpl, SubscriptionManager, TransactionGrouper, ensureCdcEpoch, filteredChange, isBulkLoadDurability, migrationChecksum, migrationContentChecksum, needsResync, reconcileMigrationChecksums, runBulkLoad, startPolling };
|
|
907
|
+
export { ChangeTracker, PrimedSubscription, SubscriptionBuilderImpl, SubscriptionManager, TransactionGrouper, applyDeviceCursorBoundary, ensureCdcEpoch, filteredChange, isBulkLoadDurability, migrationChecksum, migrationContentChecksum, needsResync, reconcileMigrationChecksums, resolveDeviceRetentionPolicy, runBulkLoad, startPolling };
|