@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,4 +1,4 @@
|
|
|
1
|
-
import { SirannonError } from './chunk-
|
|
1
|
+
import { SirannonError } from './chunk-KINDFBQP.mjs';
|
|
2
2
|
|
|
3
3
|
// src/core/sync/errors.ts
|
|
4
4
|
var ReplicationError = class extends SirannonError {
|
|
@@ -8,6 +8,15 @@ var ReplicationError = class extends SirannonError {
|
|
|
8
8
|
this.name = "ReplicationError";
|
|
9
9
|
}
|
|
10
10
|
};
|
|
11
|
+
var ConflictError = class extends ReplicationError {
|
|
12
|
+
constructor(message, table, rowId, cause) {
|
|
13
|
+
super(message, "CONFLICT_ERROR");
|
|
14
|
+
this.table = table;
|
|
15
|
+
this.rowId = rowId;
|
|
16
|
+
this.name = "ConflictError";
|
|
17
|
+
if (cause !== void 0) this.cause = cause;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
11
20
|
var BatchValidationError = class extends ReplicationError {
|
|
12
21
|
constructor(message) {
|
|
13
22
|
super(message, "BATCH_VALIDATION_ERROR");
|
|
@@ -15,4 +24,4 @@ var BatchValidationError = class extends ReplicationError {
|
|
|
15
24
|
}
|
|
16
25
|
};
|
|
17
26
|
|
|
18
|
-
export { BatchValidationError, ReplicationError };
|
|
27
|
+
export { BatchValidationError, ConflictError, ReplicationError };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { listStoredFilePieces, fetchStoredFile } from './chunk-
|
|
2
|
-
import { SirannonError } from './chunk-
|
|
1
|
+
import { listStoredFilePieces, fetchStoredFile } from './chunk-QGVRRKB2.mjs';
|
|
2
|
+
import { SirannonError } from './chunk-KINDFBQP.mjs';
|
|
3
3
|
|
|
4
4
|
// src/core/backup/verify.ts
|
|
5
5
|
function findRecord(chains, name) {
|
|
@@ -1,5 +1,92 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { ReplicationError } from './chunk-BLMRNSUG.mjs';
|
|
2
|
+
import { META_TABLE, CHANGES_TABLE, MIGRATIONS_TABLE, APPLIED_CHANGES_TABLE, COLUMN_VERSIONS_TABLE, DEVICE_CURSORS_TABLE, PEER_STATE_TABLE, SYNC_STATE_TABLE, STAGED_CHANGES_TABLE, isReservedIdentifier } from './chunk-2O3PP4CF.mjs';
|
|
3
|
+
import { SirannonError } from './chunk-KINDFBQP.mjs';
|
|
4
|
+
|
|
5
|
+
// src/core/sync/hlc.ts
|
|
6
|
+
var MAX_LOGICAL = 65535;
|
|
7
|
+
var HLC = class _HLC {
|
|
8
|
+
wallMs;
|
|
9
|
+
logical;
|
|
10
|
+
nodeId;
|
|
11
|
+
constructor(nodeId) {
|
|
12
|
+
this.nodeId = nodeId;
|
|
13
|
+
this.wallMs = 0;
|
|
14
|
+
this.logical = 0;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Returns a new timestamp and advances the clock.
|
|
18
|
+
*
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
now() {
|
|
22
|
+
const physicalMs = Date.now();
|
|
23
|
+
if (physicalMs > this.wallMs) {
|
|
24
|
+
this.wallMs = physicalMs;
|
|
25
|
+
this.logical = 0;
|
|
26
|
+
} else {
|
|
27
|
+
this.logical += 1;
|
|
28
|
+
if (this.logical > MAX_LOGICAL) {
|
|
29
|
+
throw new ReplicationError("HLC logical counter overflow");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return _HLC.encode(this.wallMs, this.logical, this.nodeId);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Merges a remote timestamp into the clock and returns the new local timestamp.
|
|
36
|
+
*
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
receive(remote) {
|
|
40
|
+
const r = _HLC.decode(remote);
|
|
41
|
+
const physicalMs = Date.now();
|
|
42
|
+
if (physicalMs > this.wallMs && physicalMs > r.wallMs) {
|
|
43
|
+
this.wallMs = physicalMs;
|
|
44
|
+
this.logical = 0;
|
|
45
|
+
} else if (r.wallMs > this.wallMs) {
|
|
46
|
+
this.wallMs = r.wallMs;
|
|
47
|
+
this.logical = r.logical + 1;
|
|
48
|
+
} else if (this.wallMs > r.wallMs) {
|
|
49
|
+
this.logical += 1;
|
|
50
|
+
} else {
|
|
51
|
+
this.logical = Math.max(this.logical, r.logical) + 1;
|
|
52
|
+
}
|
|
53
|
+
if (this.logical > MAX_LOGICAL) {
|
|
54
|
+
throw new ReplicationError("HLC logical counter overflow");
|
|
55
|
+
}
|
|
56
|
+
return _HLC.encode(this.wallMs, this.logical, this.nodeId);
|
|
57
|
+
}
|
|
58
|
+
/** Compares two encoded timestamps as strings and returns -1, 0, or 1. */
|
|
59
|
+
static compare(a, b) {
|
|
60
|
+
if (a < b) return -1;
|
|
61
|
+
if (a > b) return 1;
|
|
62
|
+
return 0;
|
|
63
|
+
}
|
|
64
|
+
/** Parses an encoded timestamp into its wall-clock, logical, and node ID parts. */
|
|
65
|
+
static decode(hlc) {
|
|
66
|
+
const parts = hlc.split("-");
|
|
67
|
+
if (parts.length < 3) {
|
|
68
|
+
throw new ReplicationError(`Invalid HLC format: ${hlc}`);
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
wallMs: Number.parseInt(parts[0], 16),
|
|
72
|
+
logical: Number.parseInt(parts[1], 16),
|
|
73
|
+
nodeId: parts.slice(2).join("-")
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Returns the string form of a clock reading, padded so that string order matches clock order.
|
|
78
|
+
*
|
|
79
|
+
* @param wallMs - The wall-clock milliseconds since the Unix epoch.
|
|
80
|
+
* @param logical - The counter that orders events within one millisecond.
|
|
81
|
+
* @param nodeId - The ID of the node that takes the reading.
|
|
82
|
+
* @returns The encoded stamp.
|
|
83
|
+
*/
|
|
84
|
+
static encode(wallMs, logical, nodeId) {
|
|
85
|
+
const wallHex = wallMs.toString(16).padStart(12, "0");
|
|
86
|
+
const logicalHex = logical.toString(16).padStart(4, "0");
|
|
87
|
+
return `${wallHex}-${logicalHex}-${nodeId}`;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
3
90
|
|
|
4
91
|
// src/core/system-catalog/sqlite-catalog.ts
|
|
5
92
|
async function selectTableExists(conn, table) {
|
|
@@ -156,9 +243,6 @@ function updateUnstampedChangeStampsSql(tableName) {
|
|
|
156
243
|
function selectMinChangeSeqSql(tableName) {
|
|
157
244
|
return `SELECT MIN(seq) AS seq FROM "${tableName}"`;
|
|
158
245
|
}
|
|
159
|
-
function selectMinForeignChangeSeqSql(tableName) {
|
|
160
|
-
return `SELECT MIN(seq) AS seq FROM "${tableName}" WHERE seq > ? AND node_id != ?`;
|
|
161
|
-
}
|
|
162
246
|
function deleteChangesBeforeSql(tableName) {
|
|
163
247
|
return `DELETE FROM "${tableName}" WHERE changed_at < ?`;
|
|
164
248
|
}
|
|
@@ -367,15 +451,50 @@ async function upsertDeviceCursor(conn, deviceId, ackedSeq, updatedAt) {
|
|
|
367
451
|
);
|
|
368
452
|
await stmt.run(deviceId, ackedSeq.toString(), updatedAt);
|
|
369
453
|
}
|
|
370
|
-
async function
|
|
371
|
-
|
|
372
|
-
const
|
|
454
|
+
async function deleteExpiredDeviceCursors(conn, changesTable, bounds) {
|
|
455
|
+
assertSafeIdentifier(changesTable);
|
|
456
|
+
const stmt = await conn.prepare(
|
|
457
|
+
`DELETE FROM "${DEVICE_CURSORS_TABLE}"
|
|
458
|
+
WHERE updated_at < ?
|
|
459
|
+
OR (? > 0 AND (
|
|
460
|
+
SELECT COUNT(*) FROM "${changesTable}" AS held
|
|
461
|
+
WHERE held.seq > "${DEVICE_CURSORS_TABLE}".acked_seq
|
|
462
|
+
AND held.node_id != "${DEVICE_CURSORS_TABLE}".device_id
|
|
463
|
+
) > ?)
|
|
464
|
+
OR EXISTS (
|
|
465
|
+
SELECT 1 FROM "${changesTable}" AS oldest
|
|
466
|
+
WHERE oldest.seq = (
|
|
467
|
+
SELECT MIN(later.seq) FROM "${changesTable}" AS later
|
|
468
|
+
WHERE later.seq > "${DEVICE_CURSORS_TABLE}".acked_seq
|
|
469
|
+
AND later.node_id != "${DEVICE_CURSORS_TABLE}".device_id
|
|
470
|
+
)
|
|
471
|
+
AND oldest.changed_at < ?
|
|
472
|
+
)`
|
|
473
|
+
);
|
|
474
|
+
const result = await stmt.run(
|
|
475
|
+
bounds.idleCutoff,
|
|
476
|
+
bounds.maxChangesHeldForDevice,
|
|
477
|
+
bounds.maxChangesHeldForDevice,
|
|
478
|
+
bounds.changeAgeCutoff
|
|
479
|
+
);
|
|
373
480
|
return result.changes;
|
|
374
481
|
}
|
|
375
|
-
async function
|
|
376
|
-
|
|
377
|
-
const
|
|
378
|
-
|
|
482
|
+
async function selectMinDeviceCursorBoundary(conn, changesTable) {
|
|
483
|
+
assertSafeIdentifier(changesTable);
|
|
484
|
+
const stmt = await conn.prepare(
|
|
485
|
+
`SELECT MIN(
|
|
486
|
+
COALESCE(
|
|
487
|
+
(SELECT MIN(later.seq) FROM "${changesTable}" AS later
|
|
488
|
+
WHERE later.seq > cursors.acked_seq AND later.node_id != cursors.device_id) - 1,
|
|
489
|
+
(SELECT COALESCE(MAX(seq), 0) FROM "${changesTable}")
|
|
490
|
+
)
|
|
491
|
+
) AS boundary
|
|
492
|
+
FROM "${DEVICE_CURSORS_TABLE}" AS cursors`
|
|
493
|
+
);
|
|
494
|
+
const row = await stmt.get();
|
|
495
|
+
const boundary = row?.boundary;
|
|
496
|
+
if (boundary === void 0 || boundary === null) return null;
|
|
497
|
+
return typeof boundary === "bigint" ? boundary : BigInt(String(boundary));
|
|
379
498
|
}
|
|
380
499
|
|
|
381
500
|
// src/core/system-catalog/peer-state-table.ts
|
|
@@ -663,4 +782,4 @@ function extractDroppedTable(sql) {
|
|
|
663
782
|
return m?.[1] ?? null;
|
|
664
783
|
}
|
|
665
784
|
|
|
666
|
-
export { IDENTIFIER_RE, PkResolver, SEQ_STRING_RE, UPSERT_META_VALUE_SQL, assertSafeIdentifier, canonicaliseForChecksum, deleteAllStagedChanges, deleteChangesBeforeSql, deleteChangesBeforeUpToSeqSql,
|
|
785
|
+
export { HLC, IDENTIFIER_RE, PkResolver, SEQ_STRING_RE, UPSERT_META_VALUE_SQL, assertSafeIdentifier, canonicaliseForChecksum, deleteAllStagedChanges, deleteChangesBeforeSql, deleteChangesBeforeUpToSeqSql, deleteExpiredDeviceCursors, deleteMetaValue, deleteStagedChangesUpToSeq, deleteSyncTableStates, ensureBatchApplyTables, ensureChangesTable, ensureDeviceCursorsTable, ensureMetaTable, ensureMigrationsTable, ensureReplicationStateTables, ensureStagedChangesTable, extractDroppedTable, highestMigrationVersion, insertDdlChange, insertMetaValueIfAbsent, prepareDeleteMigration, prepareDeleteRowColumnVersions, prepareDeleteRowColumnVersionsUpToHlc, prepareInsertAppliedChange, prepareInsertMigration, prepareUpdateMigrationChecksum, prepareUpsertColumnVersion, prepareUpsertNewerColumnVersion, referencedTables, replaceMigrationHistory, selectAppliedMigrations, selectAppliedMigrationsNewestFirst, selectAppliedSourceSeqsInRange, selectChangesAfterSeqSql, selectCompletedSyncTableNames, selectCountOutboundChanges, selectCountTableRows, selectFirstStagedTransactionEnd, selectMaxAppliedSourceSeq, selectMaxAppliedSourceSeqByNode, selectMaxChangeHlc, selectMaxChangeSeq, selectMaxColumnVersionHlc, selectMaxColumnVersionHlcForRow, selectMaxRowChangeHlc, selectMaxStagedSeq, selectMetaValue, selectMinChangeSeqSql, selectMinDeviceCursorBoundary, selectMinPeerAckedSeq, selectNodeChangesAfterSeqSql, selectOutboundChangesSql, selectPeerAckedSeq, selectStagedChangesInRange, selectSyncMetaRow, selectTableExists, selectTableSql, selectTablesChangesInRangeSql, selectUserSchemaObjects, selectUserTableNames, setForeignKeysEnabled, tableColumnNames, tableInfoRows, tablePkColumns, updateChangeStampsAfterSeqSql, updateUnstampedChangeStampsSql, upsertDeviceCursor, upsertMetaValue, upsertPeerAckedSeq, upsertStagedChangeSql, upsertSyncMeta, upsertSyncTableStatus, validateDdlSafety, validateIdentifier };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { IDENTIFIER_RE, selectCountTableRows, canonicaliseForChecksum, selectUserSchemaObjects, validateDdlSafety, selectUserTableNames, referencedTables } from './chunk-
|
|
2
|
-
import { ReplicationError } from './chunk-
|
|
3
|
-
import { INTERNAL_TABLE_PREFIX } from './chunk-
|
|
1
|
+
import { IDENTIFIER_RE, selectCountTableRows, canonicaliseForChecksum, selectUserSchemaObjects, validateDdlSafety, selectUserTableNames, referencedTables } from './chunk-ESTZZPT5.mjs';
|
|
2
|
+
import { ReplicationError } from './chunk-BLMRNSUG.mjs';
|
|
3
|
+
import { INTERNAL_TABLE_PREFIX } from './chunk-2O3PP4CF.mjs';
|
|
4
4
|
import { createHash } from 'crypto';
|
|
5
5
|
|
|
6
6
|
var DumpOps = class {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// src/transport/grpc/peer-streams.ts
|
|
2
|
+
function replicateWriteStream(serverPeerStreams, clientPeerStreams, peerId) {
|
|
3
|
+
return serverPeerStreams.get(peerId)?.replicateStream ?? clientPeerStreams.get(peerId)?.replicateStream ?? null;
|
|
4
|
+
}
|
|
5
|
+
function syncWriteStream(serverPeerStreams, clientPeerStreams, peerId) {
|
|
6
|
+
return serverPeerStreams.get(peerId)?.syncStream ?? clientPeerStreams.get(peerId)?.syncStream ?? null;
|
|
7
|
+
}
|
|
8
|
+
function peerIdForServerStream(serverPeerStreams, entry) {
|
|
9
|
+
for (const [peerId, candidate] of serverPeerStreams) {
|
|
10
|
+
if (candidate === entry) return peerId;
|
|
11
|
+
}
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
function registerPeer(connectedPeers, peerConnectedHandler, nodeId, role, metadata = {}) {
|
|
15
|
+
if (connectedPeers.has(nodeId)) return;
|
|
16
|
+
const peerInfo = {
|
|
17
|
+
id: nodeId,
|
|
18
|
+
groupId: metadata.groupId,
|
|
19
|
+
role,
|
|
20
|
+
primaryTerm: metadata.primaryTerm,
|
|
21
|
+
protocolVersion: metadata.protocolVersion,
|
|
22
|
+
joinedAt: Date.now(),
|
|
23
|
+
lastSeenAt: Date.now(),
|
|
24
|
+
lastAckedSeq: 0n
|
|
25
|
+
};
|
|
26
|
+
connectedPeers.set(nodeId, peerInfo);
|
|
27
|
+
peerConnectedHandler?.(peerInfo);
|
|
28
|
+
}
|
|
29
|
+
function removePeer(connectedPeers, serverPeerStreams, peerDisconnectedHandler, nodeId) {
|
|
30
|
+
if (!connectedPeers.has(nodeId)) return;
|
|
31
|
+
connectedPeers.delete(nodeId);
|
|
32
|
+
serverPeerStreams.delete(nodeId);
|
|
33
|
+
peerDisconnectedHandler?.(nodeId);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { peerIdForServerStream, registerPeer, removePeer, replicateWriteStream, syncWriteStream };
|
|
@@ -13,12 +13,12 @@ function ownEntry(group, key) {
|
|
|
13
13
|
if (group === void 0 || !Object.hasOwn(group, key)) return void 0;
|
|
14
14
|
return group[key];
|
|
15
15
|
}
|
|
16
|
-
function findRead(
|
|
17
|
-
const operation = ownEntry(ownEntry(registry, databaseId)?.reads, name);
|
|
16
|
+
function findRead(sets, databaseId, name) {
|
|
17
|
+
const operation = ownEntry(ownEntry(sets.registry, databaseId)?.reads, name) ?? ownEntry(sets.shared?.reads, name);
|
|
18
18
|
return operation ?? unknownOperation(name, databaseId);
|
|
19
19
|
}
|
|
20
|
-
function findWrite(
|
|
21
|
-
const operation = ownEntry(ownEntry(registry, databaseId)?.writes, name);
|
|
20
|
+
function findWrite(sets, databaseId, name) {
|
|
21
|
+
const operation = ownEntry(ownEntry(sets.registry, databaseId)?.writes, name) ?? ownEntry(sets.shared?.writes, name);
|
|
22
22
|
return operation ?? unknownOperation(name, databaseId);
|
|
23
23
|
}
|
|
24
24
|
function isRefusal(value) {
|
|
@@ -76,11 +76,12 @@ function resolveArguments(operation, supplied, identity) {
|
|
|
76
76
|
}
|
|
77
77
|
return { ok: true, value: resolved };
|
|
78
78
|
}
|
|
79
|
-
function createOperationSource(registry) {
|
|
79
|
+
function createOperationSource(registry, shared) {
|
|
80
|
+
const sets = { registry, shared };
|
|
80
81
|
return {
|
|
81
|
-
digest: operationRegistryDigest(registry),
|
|
82
|
+
digest: operationRegistryDigest(sets.registry, sets.shared),
|
|
82
83
|
resolve: (kind, databaseId, name, supplied, identity) => {
|
|
83
|
-
const operation = kind === "read" ? findRead(
|
|
84
|
+
const operation = kind === "read" ? findRead(sets, databaseId, name) : findWrite(sets, databaseId, name);
|
|
84
85
|
if (isRefusal(operation)) return { ok: false, refusal: operation };
|
|
85
86
|
const args = resolveArguments(operation, supplied, identity);
|
|
86
87
|
if (!args.ok) return { ok: false, refusal: args.refusal };
|
|
@@ -106,20 +107,26 @@ function operationLine(databaseId, kind, name, operation) {
|
|
|
106
107
|
).sort();
|
|
107
108
|
return [databaseId, kind, name, declared.join(","), identityFields.join(",")].join(DIGEST_FIELD_SEPARATOR);
|
|
108
109
|
}
|
|
109
|
-
function
|
|
110
|
-
if (registry === void 0) return void 0;
|
|
110
|
+
function databaseLines(databaseId, operations, kindPrefix) {
|
|
111
111
|
const lines = [];
|
|
112
|
-
for (const
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
112
|
+
for (const name of Object.keys(operations.reads ?? {}).sort()) {
|
|
113
|
+
const read = operations.reads?.[name];
|
|
114
|
+
if (read) lines.push(operationLine(databaseId, `${kindPrefix}read`, name, read));
|
|
115
|
+
}
|
|
116
|
+
for (const name of Object.keys(operations.writes ?? {}).sort()) {
|
|
117
|
+
const write = operations.writes?.[name];
|
|
118
|
+
if (write) lines.push(operationLine(databaseId, `${kindPrefix}write`, name, write));
|
|
119
|
+
}
|
|
120
|
+
return lines;
|
|
121
|
+
}
|
|
122
|
+
var SHARED_KIND_PREFIX = "shared-";
|
|
123
|
+
function operationRegistryDigest(registry, shared) {
|
|
124
|
+
if (registry === void 0 && shared === void 0) return void 0;
|
|
125
|
+
const lines = [];
|
|
126
|
+
for (const databaseId of Object.keys(registry ?? {}).sort()) {
|
|
127
|
+
lines.push(...databaseLines(databaseId, registry?.[databaseId] ?? {}, ""));
|
|
122
128
|
}
|
|
129
|
+
if (shared !== void 0) lines.push(...databaseLines("", shared, SHARED_KIND_PREFIX));
|
|
123
130
|
return sha256Hex(lines.join("\n"));
|
|
124
131
|
}
|
|
125
132
|
|
|
@@ -32,9 +32,10 @@ var QueryError = class extends SirannonError {
|
|
|
32
32
|
}
|
|
33
33
|
};
|
|
34
34
|
var TransactionError = class extends SirannonError {
|
|
35
|
-
constructor(message) {
|
|
35
|
+
constructor(message, cause) {
|
|
36
36
|
super(message, "TRANSACTION_ERROR");
|
|
37
37
|
this.name = "TransactionError";
|
|
38
|
+
if (cause !== void 0) this.cause = cause;
|
|
38
39
|
}
|
|
39
40
|
};
|
|
40
41
|
var MigrationError = class extends SirannonError {
|
|
@@ -55,7 +56,7 @@ var HookDeniedError = class extends SirannonError {
|
|
|
55
56
|
};
|
|
56
57
|
var RequestDeniedError = class extends SirannonError {
|
|
57
58
|
/**
|
|
58
|
-
* HTTP status the server
|
|
59
|
+
* The HTTP status that the server responds to the rejected request with.
|
|
59
60
|
*/
|
|
60
61
|
status;
|
|
61
62
|
constructor(status, code, message) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { LOG_HEADER_BYTES, readLogHeader, logFrameOffset, readValidLogFrame } from './chunk-
|
|
2
|
-
import { SirannonError } from './chunk-
|
|
1
|
+
import { LOG_HEADER_BYTES, readLogHeader, logFrameOffset, readValidLogFrame } from './chunk-R7GBXNTO.mjs';
|
|
2
|
+
import { SirannonError } from './chunk-KINDFBQP.mjs';
|
|
3
3
|
import { open } from 'fs/promises';
|
|
4
4
|
|
|
5
5
|
var READ_CHUNK_BYTES = 4 * 1024 * 1024;
|
|
@@ -1,14 +1,6 @@
|
|
|
1
|
-
import { ReplicationError } from './chunk-
|
|
1
|
+
import { ReplicationError } from './chunk-BLMRNSUG.mjs';
|
|
2
2
|
|
|
3
3
|
// src/replication/errors.ts
|
|
4
|
-
var ConflictError = class extends ReplicationError {
|
|
5
|
-
constructor(message, table, rowId) {
|
|
6
|
-
super(message, "CONFLICT_ERROR");
|
|
7
|
-
this.table = table;
|
|
8
|
-
this.rowId = rowId;
|
|
9
|
-
this.name = "ConflictError";
|
|
10
|
-
}
|
|
11
|
-
};
|
|
12
4
|
var TransportError = class extends ReplicationError {
|
|
13
5
|
constructor(message) {
|
|
14
6
|
super(message, "TRANSPORT_ERROR");
|
|
@@ -95,4 +87,4 @@ var SyncError = class extends ReplicationError {
|
|
|
95
87
|
}
|
|
96
88
|
};
|
|
97
89
|
|
|
98
|
-
export { AuthorityError,
|
|
90
|
+
export { AuthorityError, CoordinatorError, FailoverError, NoSafePrimaryError, NodeDrainingError, NodeNotInSyncError, ProtocolVersionMismatchError, ReadConcernError, StalePrimaryError, SyncError, TopologyError, TransportError, UnsafeRecoveryRequiredError, WriteConcernError };
|