@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.
Files changed (108) hide show
  1. package/README.md +79 -56
  2. package/dist/backup/index.d.ts +44 -45
  3. package/dist/backup/index.mjs +7 -7
  4. package/dist/backup-scheduler/index.d.ts +42 -41
  5. package/dist/backup-scheduler/index.mjs +4 -4
  6. package/dist/baseline-Co3iIsN_.d.ts +19 -0
  7. package/dist/change-tracker-DqCdeEyx.d.ts +128 -0
  8. package/dist/{chunk-VOSJBZ6Q.mjs → chunk-2ES3DT4A.mjs} +71 -33
  9. package/dist/{chunk-6CMCO7S4.mjs → chunk-2O3PP4CF.mjs} +1 -1
  10. package/dist/{chunk-E7Q7HE46.mjs → chunk-3BZLZ47R.mjs} +26 -26
  11. package/dist/chunk-4KASJKKK.mjs +2501 -0
  12. package/dist/{chunk-MYNI2WFS.mjs → chunk-52XW3Z76.mjs} +40 -8
  13. package/dist/chunk-55YRLSM2.mjs +57 -0
  14. package/dist/{chunk-KDAHYFW7.mjs → chunk-6AOJCNRU.mjs} +5 -5
  15. package/dist/{chunk-KXTYR2OQ.mjs → chunk-A3PHCO6W.mjs} +39 -111
  16. package/dist/chunk-ADNWEHGZ.mjs +299 -0
  17. package/dist/{chunk-2QLXDHAP.mjs → chunk-BLMRNSUG.mjs} +11 -2
  18. package/dist/chunk-BVMZJOVM.mjs +5 -0
  19. package/dist/{chunk-IWGIYDMZ.mjs → chunk-BZWDPF4G.mjs} +1 -1
  20. package/dist/{chunk-YVF2ZJTE.mjs → chunk-CZL4D3BM.mjs} +1 -1
  21. package/dist/{chunk-7SC2TZAS.mjs → chunk-DX4WGJL7.mjs} +2 -2
  22. package/dist/{chunk-45MKELYA.mjs → chunk-ESTZZPT5.mjs} +132 -13
  23. package/dist/{chunk-QP5L5DFJ.mjs → chunk-FJPR2CJX.mjs} +3 -3
  24. package/dist/chunk-HR7K3GZW.mjs +36 -0
  25. package/dist/{chunk-LXCGPZPA.mjs → chunk-IEKIYO4V.mjs} +1 -1
  26. package/dist/{chunk-TUD5CJ76.mjs → chunk-KB4OLJAD.mjs} +26 -19
  27. package/dist/{chunk-PBRXXISQ.mjs → chunk-KINDFBQP.mjs} +3 -2
  28. package/dist/{chunk-E6IMX7RS.mjs → chunk-KJLNYOOL.mjs} +2 -2
  29. package/dist/{chunk-BTTFW4Z4.mjs → chunk-KU32OT4H.mjs} +2 -10
  30. package/dist/{chunk-JQWGHSEH.mjs → chunk-NVSQ2T5Q.mjs} +71 -70
  31. package/dist/{chunk-W4EUTJNT.mjs → chunk-NZGSDALX.mjs} +94 -96
  32. package/dist/{chunk-U445A3C4.mjs → chunk-QGVRRKB2.mjs} +1 -1
  33. package/dist/{chunk-GYCEJNU4.mjs → chunk-R7GBXNTO.mjs} +1 -1
  34. package/dist/{chunk-7C36BCSN.mjs → chunk-VDN6FHU4.mjs} +1 -1
  35. package/dist/{chunk-6IYS4WLH.mjs → chunk-VO3ZWA2G.mjs} +142 -115
  36. package/dist/chunk-WOMADPM4.mjs +12 -0
  37. package/dist/{chunk-OUSWVNWT.mjs → chunk-YCMB6GR4.mjs} +1 -1
  38. package/dist/{chunk-YNTDOFTN.mjs → chunk-YW7IKQ7T.mjs} +1 -1
  39. package/dist/{chunk-M2BEAH5I.mjs → chunk-ZN4HI5FK.mjs} +126 -72
  40. package/dist/{chunk-SBL6GN43.mjs → chunk-ZYWI45EN.mjs} +1 -1
  41. package/dist/client/index.d.ts +135 -137
  42. package/dist/client/index.mjs +177 -82
  43. package/dist/client/topology.d.ts +31 -31
  44. package/dist/client/topology.mjs +42 -23
  45. package/dist/client-base-BxTocU1x.d.ts +398 -0
  46. package/dist/client-streams-YKANXMWO.mjs +112 -0
  47. package/dist/codegen/cli.mjs +4 -4
  48. package/dist/codegen/index.d.ts +36 -29
  49. package/dist/codegen/index.mjs +4 -4
  50. package/dist/core/index.d.ts +130 -115
  51. package/dist/core/index.mjs +387 -297
  52. package/dist/core/writer-worker.mjs +3 -3
  53. package/dist/database-CGDsXW1K.d.ts +959 -0
  54. package/dist/database-backup-DcLhxoa1.d.ts +143 -0
  55. package/dist/driver/better-sqlite3.d.ts +11 -10
  56. package/dist/driver/better-sqlite3.mjs +11 -11
  57. package/dist/driver/bun.d.ts +9 -8
  58. package/dist/driver/expo.d.ts +6 -7
  59. package/dist/driver/node.d.ts +11 -10
  60. package/dist/driver/node.mjs +13 -11
  61. package/dist/driver/wa-sqlite.d.ts +6 -6
  62. package/dist/errors-CJUkQ-KL.d.ts +199 -0
  63. package/dist/file-migrations/index.d.ts +20 -18
  64. package/dist/file-migrations/index.mjs +3 -3
  65. package/dist/forward-rpc-VRWFZXHN.mjs +44 -0
  66. package/dist/operation-registry-CGhNT-Sn.d.ts +96 -0
  67. package/dist/primary-wins-CHNOYuN7.d.ts +81 -0
  68. package/dist/protocol-DFpNNsIT.d.ts +153 -0
  69. package/dist/query-types-5B02ixH0.d.ts +129 -0
  70. package/dist/react/index.d.ts +22 -22
  71. package/dist/replication/coordinator/etcd.d.ts +37 -31
  72. package/dist/replication/coordinator/etcd.mjs +296 -131
  73. package/dist/replication/index.d.ts +201 -161
  74. package/dist/replication/index.mjs +630 -529
  75. package/dist/restore-options-CH8mE-Tb.d.ts +84 -0
  76. package/dist/server/index.d.ts +201 -191
  77. package/dist/server/index.mjs +736 -619
  78. package/dist/server-options-aYtCkefX.d.ts +317 -0
  79. package/dist/server-streams-24XL4T43.mjs +254 -0
  80. package/dist/sirannon-J3EgPVD7.d.ts +179 -0
  81. package/dist/transport/grpc.d.ts +37 -24
  82. package/dist/transport/grpc.mjs +83 -3199
  83. package/dist/transport/memory.d.ts +25 -26
  84. package/dist/transport/memory.mjs +18 -9
  85. package/dist/types-BrAiDGOb.d.ts +505 -0
  86. package/dist/types-CEJG0eFS.d.ts +88 -0
  87. package/dist/types-Dc8oWlxj.d.ts +1580 -0
  88. package/dist/types-DqODKeOq.d.ts +123 -0
  89. package/dist/types-guEKSzMr.d.ts +367 -0
  90. package/package.json +7 -7
  91. package/dist/baseline-D93hcIEE.d.ts +0 -17
  92. package/dist/change-tracker-CjRFuZdB.d.ts +0 -144
  93. package/dist/client-base-Cmd9EVme.d.ts +0 -397
  94. package/dist/database-BLQvqjsw.d.ts +0 -917
  95. package/dist/database-backup-B7oszQ2n.d.ts +0 -141
  96. package/dist/errors-Dei4GdBb.d.ts +0 -196
  97. package/dist/operation-registry-oiPuSYI6.d.ts +0 -94
  98. package/dist/primary-wins-B0np8JS3.d.ts +0 -85
  99. package/dist/protocol-HI-nY8DD.d.ts +0 -152
  100. package/dist/query-types-p1liOP-b.d.ts +0 -127
  101. package/dist/restore-options-CksYsH1l.d.ts +0 -83
  102. package/dist/server-options-Bj5iJnjx.d.ts +0 -292
  103. package/dist/sirannon-BPxC5tC2.d.ts +0 -178
  104. package/dist/types-B0EhgDbr.d.ts +0 -340
  105. package/dist/types-CbjfRwrK.d.ts +0 -499
  106. package/dist/types-CjhxcjhA.d.ts +0 -123
  107. package/dist/types-DPSmjU54.d.ts +0 -1518
  108. package/dist/types-DTO4CYhW.d.ts +0 -88
@@ -1,48 +1,51 @@
1
- export { F as FieldMergeResolver, L as LWWResolver, P as PrimaryWinsResolver } from '../primary-wins-B0np8JS3.js';
2
- import { m as HLC, D as Database } from '../database-BLQvqjsw.js';
3
- import { r as BackupGroupSource, a2 as ClusterReadEndpointInfo, H as ClusterStatusInfo, I as SQLiteConnection, T as Transaction } from '../types-DPSmjU54.js';
4
- import { C as ClusterCoordinator, c as ReplicationGroupState, e as CoordinatorWatchDisposer } from '../types-B0EhgDbr.js';
5
- export { A as AcquireControllerLeaseInput, a as AcquireControllerLeaseResult, h as AdmitNodeToInSyncSetInput, f as CompareAndAdvancePrimaryTermInput, g as CompareAndAdvancePrimaryTermResult, j as CoordinatorCompatibilityMetadata, k as CoordinatorLease, b as CoordinatorNodeSession, l as CoordinatorPrimary, P as PromoteEligibleReplicaInput, R as RegisterNodeSessionInput, d as ReplicationGroupWatcher, S as SetReplicationGroupStateInput, U as UpdateInSyncSetInput, i as UpdateNodeMaintenanceInput } from '../types-B0EhgDbr.js';
6
- import { f as ReplicationStatusInfo } from '../server-options-Bj5iJnjx.js';
7
- import { C as CoordinatorRuntimeStatus, g as ReplicationStatus, h as SyncPhase, I as InFlightBatch, P as PeerState, a as ForwardedTransactionResult, b as SyncBatch, c as SyncComplete, d as SyncAck, S as SyncRequest, i as ReplicationConfig, j as SyncState, k as ReplicationErrorEvent, R as ReplicationAck, l as Topology, f as TopologyRole } from '../types-CbjfRwrK.js';
8
- export { F as ForwardedTransaction, N as NodeInfo, e as ReplicationTransport, T as TransportConfig } from '../types-CbjfRwrK.js';
1
+ export { F as FieldMergeResolver, L as LWWResolver, P as PrimaryWinsResolver } from '../primary-wins-CHNOYuN7.js';
2
+ import { m as HLC, D as Database } from '../database-CGDsXW1K.js';
3
+ import { r as BackupGroupSource, a3 as ClusterReadEndpointInfo, H as ClusterStatusInfo, I as SQLiteConnection, T as Transaction } from '../types-Dc8oWlxj.js';
4
+ import { C as ClusterCoordinator, e as ReplicationGroupState, c as CoordinatorWatchDisposer, l as CoordinatorLease } from '../types-guEKSzMr.js';
5
+ export { A as AcquireControllerLeaseInput, a as AcquireControllerLeaseResult, i as AdmitNodeToInSyncSetInput, g as CompareAndAdvancePrimaryTermInput, h as CompareAndAdvancePrimaryTermResult, b as ControllerLeaseWatcher, k as CoordinatorCompatibilityMetadata, d as CoordinatorNodeSession, m as CoordinatorPrimary, N as NodeSessionWatcher, P as PromoteEligibleReplicaInput, R as RegisterNodeSessionInput, f as ReplicationGroupWatcher, S as SetReplicationGroupStateInput, U as UpdateInSyncSetInput, j as UpdateNodeMaintenanceInput } from '../types-guEKSzMr.js';
6
+ import { f as ReplicationStatusInfo } from '../server-options-aYtCkefX.js';
7
+ import { C as CoordinatorRuntimeStatus, g as ReplicationStatus, h as SyncPhase, I as InFlightBatch, P as PeerState, a as ForwardedTransactionResult, b as SyncBatch, c as SyncComplete, d as SyncAck, S as SyncRequest, i as ReplicationConfig, j as SyncState, k as ReplicationErrorEvent, R as ReplicationAck, l as Topology, f as TopologyRole } from '../types-BrAiDGOb.js';
8
+ export { F as ForwardedTransaction, N as NodeInfo, e as ReplicationTransport, T as TransportConfig } from '../types-BrAiDGOb.js';
9
9
  import { EventEmitter } from 'node:events';
10
- import { C as ChangeTracker } from '../change-tracker-CjRFuZdB.js';
11
- import { P as Params, Q as QueryOptions, E as ExecuteResult } from '../query-types-p1liOP-b.js';
12
- import { R as ReplicationBatch, C as ConflictResolver, A as ApplyResult, S as SyncTableManifest } from '../types-CjhxcjhA.js';
13
- export { a as ConflictContext, b as ConflictResolution, H as HLCTimestamp, c as ReplicationChange } from '../types-CjhxcjhA.js';
14
- import { S as SirannonError } from '../errors-Dei4GdBb.js';
15
- import '../database-backup-B7oszQ2n.js';
16
- import '../types-DTO4CYhW.js';
17
- import '../operation-registry-oiPuSYI6.js';
10
+ import { C as ChangeTracker } from '../change-tracker-DqCdeEyx.js';
11
+ import { P as Params, Q as QueryOptions, E as ExecuteResult, W as WriteConcern } from '../query-types-5B02ixH0.js';
12
+ import { R as ReplicationBatch, C as ConflictResolver, A as ApplyResult, S as SyncTableManifest } from '../types-DqODKeOq.js';
13
+ export { a as ConflictContext, b as ConflictResolution, H as HLCTimestamp, c as ReplicationChange } from '../types-DqODKeOq.js';
14
+ import { S as SirannonError } from '../errors-CJUkQ-KL.js';
15
+ import '../database-backup-DcLhxoa1.js';
16
+ import '../types-CEJG0eFS.js';
17
+ import '../operation-registry-CGhNT-Sn.js';
18
18
 
19
19
  /**
20
- * Which group a node reads its backup membership from, and where that group's
21
- * state is kept.
20
+ * Configures {@link coordinatorBackupGroup} with the coordinator that stores the
21
+ * group's state, the replication group to read backup membership from, and this
22
+ * node's ID.
22
23
  *
23
24
  * @public
24
25
  */
25
26
  interface CoordinatorBackupGroupOptions {
26
- /** Where primary authority, node sessions, and group state are stored. */
27
+ /** Holds the coordinator that stores primary authority, node sessions, and the group state. */
27
28
  coordinator: ClusterCoordinator;
28
- /** Identifier of the cluster the group belongs to. */
29
+ /** Identifies the cluster that contains the group. */
29
30
  clusterId: string;
30
- /** Identifier of the replication group. */
31
+ /** Identifies the replication group. */
31
32
  groupId: string;
32
- /** Identifier of this node, which must match the one it replicates under. */
33
+ /** Identifies this node. Pass the same node ID that this node's replication engine uses. */
33
34
  nodeId: string;
34
35
  }
35
36
  /**
36
- * Builds the group source a backup cycle asks before it copies anything, over
37
- * the coordinator the group already uses for failover.
37
+ * Returns a backup group source that reads the group's membership from the
38
+ * coordinator that the group already uses for failover. The backup cycle calls
39
+ * `readMembership` on the source before the cycle copies anything.
38
40
  *
39
- * Every node of the group passes one of these to its `backups` option, and each
40
- * scheduled turn reads the same membership from it. One node finds itself named
41
- * and takes the backup; the others stand down. A failover changes which node is
42
- * named, but it changes no schedule.
41
+ * Every node of the group passes one of these sources to its `backups` option.
42
+ * On each scheduled turn, every node reads the same membership and picks the
43
+ * same node to take the backup, while the other nodes skip that turn. A
44
+ * failover can change which node takes the backups, but you keep the same
45
+ * schedule on every node.
43
46
  *
44
- * This offers the nodes the group counts as in sync, less any node being
45
- * drained, rebuilt, or held out as faulted.
47
+ * The membership lists the nodes in the group's in-sync set, minus any node
48
+ * that the group state marks as draining, repairing, or faulted.
46
49
  *
47
50
  * @param options - The coordinator, the cluster, the group, and this node's identifier.
48
51
  * @returns The source, ready to pass as `replicationGroup`.
@@ -52,60 +55,64 @@ interface CoordinatorBackupGroupOptions {
52
55
  declare function coordinatorBackupGroup(options: CoordinatorBackupGroupOptions): BackupGroupSource;
53
56
 
54
57
  /**
55
- * What a node needs to know beyond its own engine state to describe its group.
58
+ * Holds the database ID and the node addresses that {@link toClusterStatusInfo} takes in addition to the engine
59
+ * status.
56
60
  *
57
61
  * @public
58
62
  */
59
63
  interface ClusterStatusOptions {
60
- /** Identifier of the database the reported status describes. */
64
+ /** Identifies the database that the status reports on. */
61
65
  databaseId: string;
62
- /** Address a client reaches each node on, keyed by node id. */
66
+ /** Maps each node ID to the address that a client uses to reach that node. */
63
67
  endpoints: Readonly<Record<string, string>>;
64
68
  }
65
69
  /**
66
- * Turns one node's engine status into the figures its readiness endpoint reports.
70
+ * Converts one node's engine status into the replication figures that the node's readiness endpoint reports.
67
71
  *
68
- * @param status - Status the replication engine reports for this node.
72
+ * @param status - The status that the replication engine reports for this node.
69
73
  * @returns The replication figures, ready to return from `getReplicationStatus`.
70
74
  *
71
75
  * @public
72
76
  */
73
77
  declare function toReplicationStatusInfo(status: ReplicationStatus): ReplicationStatusInfo;
74
78
  /**
75
- * Turns one node's engine status into what `GET /db/{id}/cluster` reports about its group.
79
+ * Converts one node's engine status into the group status that `GET /db/{id}/cluster` returns.
76
80
  *
77
- * @param status - Status the replication engine reports for this node.
78
- * @param options - The database this status describes and the address of each node.
81
+ * @param status - The status that the replication engine reports for this node.
82
+ * @param options - The database that this status reports on and the address of each node.
79
83
  * @returns The group status, ready to return from `getClusterStatus`.
80
84
  *
81
85
  * @public
82
86
  */
83
87
  declare function toClusterStatusInfo(status: ReplicationStatus, options: ClusterStatusOptions): ClusterStatusInfo;
84
88
  /**
85
- * Lists every node a client can read from, with the read concerns each one serves.
89
+ * Returns every node that a client can read from, with the read concerns that each node serves.
86
90
  *
87
- * A node counts towards majority and is neither quarantined, being taken out of
88
- * service, nor being rebuilt to appear at all. A node the group counts as in
89
- * sync serves both `local` and `majority`; one that has fallen behind serves
90
- * `local` alone, because the engine answers a `local` read without any in-sync
91
- * check.
91
+ * The list holds the group's voting data-bearing nodes, minus any node that the
92
+ * group state marks as faulted, draining, or repairing. When the coordinator
93
+ * status includes the IDs of the nodes with a live session, the list keeps only
94
+ * those nodes. A node in the in-sync set serves both `local` and `majority`
95
+ * reads, while any other node serves `local` reads alone, because the engine
96
+ * answers a `local` read without checking the in-sync set.
92
97
  *
93
- * @param coordinator - Group state this node last read from the coordinator.
94
- * @param endpoints - Address a client reaches each node on, keyed by node id.
95
- * @returns One entry per node a client can read from.
98
+ * @param coordinator - The group state that this node last read from the coordinator.
99
+ * @param endpoints - Maps each node ID to the address that a client uses to reach that node.
100
+ * @returns One entry per node that a client can read from.
96
101
  *
97
102
  * @public
98
103
  */
99
104
  declare function toClusterReadEndpoints(coordinator: CoordinatorRuntimeStatus, endpoints: Readonly<Record<string, string>>): ClusterReadEndpointInfo[];
100
105
 
101
106
  /**
102
- * Persistent change log that bridges CDC events and the replication protocol.
107
+ * Gives the replication engine one object for every read and write that it
108
+ * makes against the change log and the sync state that this node stores in
109
+ * SQLite.
103
110
  *
104
- * Composes specialised helpers: BatchReader (outbound batches), BatchApplier
105
- * (inbound batches and conflict resolution), DumpOps (table dumps and
106
- * manifests), SchemaOps (replication-table bootstrap, schema dump, wipe),
107
- * StateOps (sequence and sync metadata), and PkResolver (cached primary-key
108
- * lookups).
111
+ * Each method passes the call to one helper: BatchReader for outbound batches,
112
+ * BatchApplier for inbound batches and conflict resolution, StampOps for
113
+ * stamping local changes, DumpOps for table dumps and manifests, SchemaOps for
114
+ * the replication tables, the schema dump, and table wipes, StateOps for
115
+ * sequence and sync metadata, and PkResolver for cached primary-key lookups.
109
116
  *
110
117
  * @internal
111
118
  */
@@ -154,19 +161,21 @@ declare class ReplicationLog {
154
161
  }
155
162
 
156
163
  /**
157
- * Maintains in-memory state for every peer the local node communicates with.
158
- *
159
- * For each peer, PeerTracker records the last acknowledged sequence number,
160
- * the last sent sequence number, pending batch count, and connection status.
161
- * This state drives two key mechanisms:
162
- *
163
- * - **Back-pressure**: the sender loop in ReplicationEngine checks
164
- * `pendingBatches` against the configured max before queuing more work
165
- * for a given peer.
166
- * - **Write concern**: callers can await `waitForMajority` or `waitForAll`
167
- * with a sequence number and timeout. These methods resolve once enough
168
- * peers have acknowledged that sequence, or reject with a
169
- * WriteConcernError on timeout.
164
+ * Keeps in memory the replication state of every peer that this node connects to.
165
+ *
166
+ * For each peer, the tracker records the last sequence number that the peer
167
+ * acknowledged, the last sequence number that this node sent, the number of
168
+ * pending batches, the batches in flight, and whether the peer is connected.
169
+ * The engine uses that state in two places.
170
+ *
171
+ * - Back-pressure: the sender loop skips a peer whose `pendingBatches` has
172
+ * reached the configured maximum.
173
+ * - Write concern: a caller awaits `waitForMajority`, `waitForAll`,
174
+ * `waitForConfiguredMajority`, or `waitForConfiguredAll` with a sequence
175
+ * number and a timeout, and the promise resolves once enough peers
176
+ * acknowledge that sequence. It rejects with a `WriteConcernError` when the
177
+ * timeout expires, and a `waitForMajority` or `waitForAll` promise also
178
+ * rejects early when too few peers are connected to reach the count.
170
179
  *
171
180
  * @internal
172
181
  */
@@ -176,6 +185,7 @@ declare class PeerTracker {
176
185
  addPeer(nodeId: string): void;
177
186
  removePeer(nodeId: string): void;
178
187
  onAckReceived(nodeId: string, ackedSeq: bigint): void;
188
+ onBatchApplied(nodeId: string, highestHlc: string): void;
179
189
  recordInFlightBatch(nodeId: string, batch: InFlightBatch): void;
180
190
  expireTimedOutBatches(nodeId: string, nowMs: number, timeoutMs: number): boolean;
181
191
  getPeerState(nodeId: string): PeerState | undefined;
@@ -192,24 +202,23 @@ declare class PeerTracker {
192
202
  }
193
203
 
194
204
  /**
195
- * Runs a statement on the local node and records the resulting changes in the replication log.
205
+ * Executes a write on this node and stamps the changes that it makes into the replication log inside the same SQLite
206
+ * transaction.
196
207
  *
197
208
  * @internal
198
209
  */
199
210
  declare class LocalExecutor {
200
211
  private readonly engine;
201
212
  /**
202
- * Serialises every `executeTransactionLocally` call against itself.
213
+ * Makes each `executeTransactionLocally` call wait until the previous one finishes.
203
214
  *
204
- * Reason: SQLite only allows one active transaction per connection; the
205
- * writer pool exposes a single writer connection (see `ConnectionPool`).
206
- * Two parallel `engine.transaction(fn)` callers therefore both reach
207
- * `await conn.exec('BEGIN')` on the same connection, and the second
208
- * `BEGIN` errors with "cannot start a transaction within a transaction".
209
- * Chaining onto this promise turns the second caller into a strict
210
- * follow-on without changing the public API. A rejection is swallowed at
211
- * the chain level so a failed transaction never poisons the queue; the
212
- * original error still surfaces to the caller that initiated it.
215
+ * The engine writes through the single connection `engine.writerConn`,
216
+ * which SQLite limits to one open transaction. Without this queue, two
217
+ * concurrent `engine.transaction(fn)` calls would both send `BEGIN` on that
218
+ * connection, so SQLite would reject the second with 'cannot start a
219
+ * transaction within a transaction'. The queue catches each rejection so
220
+ * that a later transaction still starts after an earlier one fails, while
221
+ * the caller that started the failed transaction still receives its error.
213
222
  */
214
223
  private transactionQueue;
215
224
  constructor(engine: ReplicationEngine);
@@ -217,16 +226,20 @@ declare class LocalExecutor {
217
226
  changes: number;
218
227
  lastInsertRowId: number | bigint;
219
228
  }>;
229
+ executeBatchLocally(sql: string, paramsBatch: Params[], options?: QueryOptions): Promise<ExecuteResult[]>;
220
230
  executeForwardedLocally(statements: Array<{
221
231
  sql: string;
222
232
  params?: Params;
223
- }>): Promise<ForwardedTransactionResult>;
233
+ }>, statedWriteConcern?: WriteConcern): Promise<ForwardedTransactionResult>;
234
+ private waitForWriteConcernOf;
235
+ private executeInOneTransaction;
224
236
  executeTransactionLocally<T>(fn: (tx: Transaction) => Promise<T>, options?: QueryOptions): Promise<T>;
225
237
  private runTransaction;
226
238
  }
227
239
 
228
240
  /**
229
- * Batches locally recorded changes and pushes them to the peers the topology accepts.
241
+ * Sends the changes in this node's replication log to its peers in batches, on a timer. In coordinator mode, the
242
+ * loop sends only while this node holds primary authority; otherwise, the topology's `shouldReplicateTo` picks the peers.
230
243
  *
231
244
  * @internal
232
245
  */
@@ -242,7 +255,8 @@ declare class SenderLoop {
242
255
  }
243
256
 
244
257
  /**
245
- * Drives a joining node through first sync and the catch-up that follows it.
258
+ * Copies a source node's tables onto a joining node through a first sync, then marks the node ready once its catch-up
259
+ * lag falls within the configured limit or the catch-up deadline passes.
246
260
  *
247
261
  * @internal
248
262
  */
@@ -265,7 +279,8 @@ declare class SyncJoiner {
265
279
  }
266
280
 
267
281
  /**
268
- * Serves first-sync requests from joining nodes by streaming schema, table pages, and a manifest.
282
+ * Answers a joining node's first-sync request by streaming the schema, then each table's rows in batches, and last a
283
+ * manifest for every table that it streamed.
269
284
  *
270
285
  * @internal
271
286
  */
@@ -295,8 +310,8 @@ type CoordinatorStampedMessage = ReplicationBatch | ReplicationAck | ForwardedTr
295
310
  /**
296
311
  * Coordinates replication for a single database node.
297
312
  *
298
- * Its state and dependencies are readable properties so that the collaborating
299
- * modules in `./engine/` share one mutable engine instance.
313
+ * The engine exposes its state and dependencies as properties, so that the
314
+ * helper modules that implement it can share one mutable instance.
300
315
  *
301
316
  * @public
302
317
  */
@@ -308,7 +323,7 @@ declare class ReplicationEngine extends EventEmitter {
308
323
  /** @internal */
309
324
  readonly config: ReplicationConfig;
310
325
  /**
311
- * Identifier of this node, which every change it authors carries.
326
+ * Identifies this node, and the engine stamps it on every change that this node writes.
312
327
  */
313
328
  readonly nodeId: string;
314
329
  /** @internal */
@@ -366,6 +381,16 @@ declare class ReplicationEngine extends EventEmitter {
366
381
  /** @internal */
367
382
  coordinatorWatchDisposer: CoordinatorWatchDisposer | null;
368
383
  /** @internal */
384
+ nodeSessionWatchDisposer: CoordinatorWatchDisposer | null;
385
+ /** @internal */
386
+ controllerLeaseWatchDisposer: CoordinatorWatchDisposer | null;
387
+ /** @internal */
388
+ observedControllerLease: CoordinatorLease | null;
389
+ /** @internal */
390
+ controllerBidding: boolean;
391
+ /** @internal */
392
+ liveNodeIds: string[] | null;
393
+ /** @internal */
369
394
  coordinatorLeaseTimer: ReturnType<typeof setInterval> | null;
370
395
  /** @internal */
371
396
  controllerTimer: ReturnType<typeof setInterval> | null;
@@ -403,73 +428,78 @@ declare class ReplicationEngine extends EventEmitter {
403
428
  readonly senderLoop: SenderLoop;
404
429
  constructor(database: Database, writerConn: SQLiteConnection, config: ReplicationConfig);
405
430
  /**
406
- * Connects the transport, pulls a full copy when this node needs one, and starts replicating.
431
+ * Connects the transport and starts replicating. When this node is a replica without a complete, current copy, it
432
+ * also requests a full copy from a source peer, and the returned promise resolves before that copy finishes.
407
433
  */
408
434
  start(): Promise<void>;
409
435
  /**
410
- * Stops replicating, abandons any sync in flight, and disconnects the transport.
436
+ * Stops replicating, aborts every first sync that this node serves, and disconnects the transport.
411
437
  */
412
438
  stop(): Promise<void>;
413
439
  /**
414
- * Reports where this node stands.
440
+ * Returns this node's replication status.
415
441
  *
416
- * @returns The node's role, its peers, its progress, its health, and its group state.
442
+ * @returns The node's role, peers, sequence position, sync state, health, and coordinator group state.
417
443
  */
418
444
  status(): ReplicationStatus;
419
445
  /**
420
- * Returns the highest change-log position this node has recorded locally.
446
+ * Returns the highest position in this node's local change log.
421
447
  *
422
- * @returns That position, which a caller waits for a replica to reach.
448
+ * @returns That position, which a caller can wait for a replica to reach.
423
449
  */
424
450
  getCurrentSeq(): bigint;
425
451
  /**
426
- * Returns how far this node has applied one peer's changes.
452
+ * Returns the highest applied position from one peer's change log.
427
453
  *
428
- * @param peerId - Identifier of the peer.
429
- * @returns The highest position from that peer this node has applied.
454
+ * @param peerId - The peer's node ID.
455
+ * @returns That position, or `0n` before this node applies any change from that peer.
430
456
  */
431
457
  getAppliedSeq(peerId: string): bigint;
432
458
  /**
433
- * Runs a read, refusing it when the node cannot meet the read concern.
459
+ * Executes a read, and throws when this node is still syncing or cannot meet the read concern.
434
460
  *
435
- * @param sql - The statement to run.
436
- * @param params - Values bound to the statement, named or positional.
437
- * @param options - Read concern for this statement.
438
- * @returns The rows the statement produced.
461
+ * @param sql - The statement to execute.
462
+ * @param params - The values to bind to the statement, named or positional.
463
+ * @param options - The read concern for this statement.
464
+ * @returns The rows that the statement returns.
439
465
  */
440
466
  query<T>(sql: string, params?: Params, options?: QueryOptions): Promise<T[]>;
441
467
  /**
442
- * Runs one write, forwarding it to the primary when this node accepts no writes and forwarding is on.
468
+ * Executes one write on this node, or forwards it to the primary when this node cannot accept writes and
469
+ * `writeForwarding` is on.
443
470
  *
444
- * @param sql - The statement to run.
445
- * @param params - Values bound to the statement, named or positional.
446
- * @param options - Write concern for this statement.
447
- * @returns How many rows changed, and the last inserted row id.
471
+ * @param sql - The statement to execute.
472
+ * @param params - The values to bind to the statement, named or positional.
473
+ * @param options - The write concern for this statement, which the primary also applies to a forwarded write before it answers.
474
+ * @returns The number of rows that changed and the ID of the last inserted row.
448
475
  */
449
476
  execute(sql: string, params?: Params, options?: QueryOptions): Promise<ExecuteResult>;
450
477
  /**
451
- * Runs one statement over many parameter sets in a single transaction.
478
+ * Executes one statement once for each parameter set and commits every set in one transaction, on this node or, when
479
+ * this node forwards the batch, on the primary.
452
480
  *
453
- * @param sql - The statement to run for each parameter set.
454
- * @param paramsBatch - One parameter set per run.
455
- * @param options - Write concern for the transaction.
481
+ * @param sql - The statement to execute for each parameter set.
482
+ * @param paramsBatch - One parameter set per execution.
483
+ * @param options - The write concern for the batch, which the primary also applies to a forwarded batch before it answers.
456
484
  * @returns One result per parameter set, in order.
457
485
  */
458
486
  executeBatch(sql: string, paramsBatch: Params[], options?: QueryOptions): Promise<ExecuteResult[]>;
459
487
  /**
460
- * Runs a function inside one transaction on this node.
488
+ * Calls `fn` inside one transaction on this node. On a node that cannot accept writes, it throws a `TopologyError`,
489
+ * since the engine forwards only `execute` and `executeBatch` writes to the primary.
461
490
  *
462
- * @param fn - Receives the transaction and runs statements on it.
463
- * @param options - Write concern for the transaction.
464
- * @returns Whatever the function returned.
491
+ * @param fn - The function that receives the transaction and executes statements on it.
492
+ * @param options - The write concern to wait for after the transaction commits.
493
+ * @returns The value that `fn` resolves to.
465
494
  */
466
495
  transaction<T>(fn: (tx: Transaction) => Promise<T>, options?: QueryOptions): Promise<T>;
467
496
  /**
468
- * Sends a write to the primary and waits for its result.
497
+ * Sends the statements to the primary, which executes them in one transaction, and returns the primary's result.
498
+ * When this node is the primary, it executes them here in the same way.
469
499
  *
470
- * @param statements - The statements to run, in order, each with its own parameters.
471
- * @param options - Write concern the primary applies.
472
- * @returns What the primary reported for each statement.
500
+ * @param statements - The statements to execute, in order, each with its own parameters.
501
+ * @param options - The write concern that the primary applies to the statements before it answers.
502
+ * @returns The result of each statement, in order, and the request ID.
473
503
  */
474
504
  forwardStatements(statements: Array<{
475
505
  sql: string;
@@ -486,80 +516,82 @@ declare class ReplicationEngine extends EventEmitter {
486
516
  /** @internal */
487
517
  getCurrentPrimaryPeerId(): string | null;
488
518
  /**
489
- * Stamps an outgoing replication message with this node's group and primary term.
519
+ * Returns a copy of an outgoing replication message with this node's group ID and primary term added.
490
520
  *
491
521
  * @internal
492
522
  */
493
523
  decorate<T extends CoordinatorStampedMessage>(message: T): T;
494
524
  }
495
525
 
496
- /** Base error for all replication-related failures.
526
+ /** Reports a replication failure, and more specific replication errors such as {@link BatchValidationError} extend it.
497
527
  * @public
498
528
  */
499
529
  declare class ReplicationError extends SirannonError {
500
- /** Anything the failing operation attached, such as the peer or the batch involved. */
530
+ /** Extra context from the code that throws the error, such as the peer or the batch involved. */
501
531
  readonly details?: Record<string, unknown> | undefined;
502
532
  constructor(message: string, code?: string,
503
- /** Anything the failing operation attached, such as the peer or the batch involved. */
533
+ /** Extra context from the code that throws the error, such as the peer or the batch involved. */
504
534
  details?: Record<string, unknown> | undefined);
505
535
  }
506
- /** Thrown when an incoming replication batch fails integrity checks (checksum, schema, clock drift).
507
- * @public
508
- */
509
- declare class BatchValidationError extends ReplicationError {
510
- constructor(message: string);
511
- }
512
-
513
- /** Thrown when a write conflict cannot be resolved automatically.
536
+ /** Sirannon throws this error when a conflict resolver fails on a replicated change, and it names the table and row; `cause` holds the resolver's own error.
514
537
  * @public
515
538
  */
516
539
  declare class ConflictError extends ReplicationError {
517
540
  /**
518
- * Table the conflicting row belongs to.
541
+ * Names the table that contains the conflicting row.
519
542
  */
520
543
  readonly table: string;
521
544
  /**
522
- * Primary key of the conflicting row, encoded as a string.
545
+ * Holds the primary key of the conflicting row, encoded as a string.
523
546
  */
524
547
  readonly rowId: string;
525
548
  constructor(message: string,
526
549
  /**
527
- * Table the conflicting row belongs to.
550
+ * Names the table that contains the conflicting row.
528
551
  */
529
552
  table: string,
530
553
  /**
531
- * Primary key of the conflicting row, encoded as a string.
554
+ * Holds the primary key of the conflicting row, encoded as a string.
532
555
  */
533
- rowId: string);
556
+ rowId: string, cause?: unknown);
534
557
  }
535
- /** Thrown when inter-node communication fails.
558
+ /** Sirannon throws this error when an incoming replication batch fails a validation check, such as a checksum mismatch, an invalid table name, an unsafe DDL statement, or too much clock drift.
559
+ * @public
560
+ */
561
+ declare class BatchValidationError extends ReplicationError {
562
+ constructor(message: string);
563
+ }
564
+
565
+ /** Sirannon throws this error when a transport call fails, such as a send to a disconnected peer or a send of a malformed message.
536
566
  * @public
537
567
  */
538
568
  declare class TransportError extends ReplicationError {
539
569
  constructor(message: string);
540
570
  }
541
- /** Thrown when a write-concern quorum is not met within the configured timeout.
571
+ /** Sirannon throws this error when too few peers acknowledge a write before the write-concern timeout expires, or when too few peers are connected to reach the required count.
542
572
  * @public
543
573
  */
544
574
  declare class WriteConcernError extends ReplicationError {
545
575
  constructor(message: string);
546
576
  }
547
577
  /**
548
- * Thrown when a node cannot prove a read is as current as the caller required.
578
+ * Sirannon throws this error when a node cannot serve a read at the requested read concern, such as a `majority` read
579
+ * on a draining or repairing node, or a read at an unsupported level.
549
580
  *
550
581
  * @public
551
582
  */
552
583
  declare class ReadConcernError extends ReplicationError {
553
584
  constructor(message: string, details?: Record<string, unknown>);
554
585
  }
555
- /** Thrown when a write or routing operation violates the configured topology rules.
586
+ /** Sirannon throws this error when a node that cannot accept writes receives a write that it cannot forward to a primary.
556
587
  * @public
557
588
  */
558
589
  declare class TopologyError extends ReplicationError {
559
590
  constructor(message: string);
560
591
  }
561
592
  /**
562
- * Thrown when a node cannot reach its cluster coordinator.
593
+ * Sirannon throws this error when a coordinator call fails, such as when the coordinator is unreachable, holds no state
594
+ * for the group, or refuses an update after concurrent writes.
563
595
  *
564
596
  * @public
565
597
  */
@@ -567,7 +599,8 @@ declare class CoordinatorError extends ReplicationError {
567
599
  constructor(message: string, details?: Record<string, unknown>);
568
600
  }
569
601
  /**
570
- * Thrown when a node cannot prove it holds write authority for the current term.
602
+ * Sirannon throws this error when a node cannot prove that it holds write authority for the current term, such as
603
+ * while the node is repairing or faulted.
571
604
  *
572
605
  * @public
573
606
  */
@@ -575,7 +608,8 @@ declare class AuthorityError extends ReplicationError {
575
608
  constructor(message: string, code?: string, details?: Record<string, unknown>);
576
609
  }
577
610
  /**
578
- * Thrown when a node believing itself primary finds the group has moved to a later term.
611
+ * Sirannon throws this error when a node other than the group's current primary receives a write or another request
612
+ * that only the primary serves, or when a replication message has an old term or the wrong group.
579
613
  *
580
614
  * @public
581
615
  */
@@ -583,7 +617,8 @@ declare class StalePrimaryError extends AuthorityError {
583
617
  constructor(message: string, details?: Record<string, unknown>);
584
618
  }
585
619
  /**
586
- * Thrown when failover cannot complete safely.
620
+ * Reports a failover that cannot complete safely, and {@link NoSafePrimaryError} and
621
+ * {@link UnsafeRecoveryRequiredError} extend it.
587
622
  *
588
623
  * @public
589
624
  */
@@ -591,7 +626,9 @@ declare class FailoverError extends ReplicationError {
591
626
  constructor(message: string, code?: string, details?: Record<string, unknown>);
592
627
  }
593
628
  /**
594
- * Thrown when no replica is in sync enough to take over as primary, so writes stay unavailable rather than risking loss.
629
+ * Sirannon throws this error when no in-sync replica is eligible for promotion, or when the group has fewer than three
630
+ * voting nodes. In that case the coordinator promotes no node, since promoting a replica outside the in-sync set could
631
+ * lose acknowledged writes.
595
632
  *
596
633
  * @public
597
634
  */
@@ -599,7 +636,7 @@ declare class NoSafePrimaryError extends FailoverError {
599
636
  constructor(message: string, details?: Record<string, unknown>);
600
637
  }
601
638
  /**
602
- * Thrown when a node cannot meet a read concern because the group does not count it as in sync.
639
+ * Sirannon throws this error for a `majority` read on a node outside the group's in-sync set.
603
640
  *
604
641
  * @public
605
642
  */
@@ -607,7 +644,7 @@ declare class NodeNotInSyncError extends ReplicationError {
607
644
  constructor(message: string, details?: Record<string, unknown>);
608
645
  }
609
646
  /**
610
- * Thrown when a node is being taken out of service and refuses new work.
647
+ * Sirannon throws this error when a draining node receives a write.
611
648
  *
612
649
  * @public
613
650
  */
@@ -615,7 +652,8 @@ declare class NodeDrainingError extends ReplicationError {
615
652
  constructor(message: string, details?: Record<string, unknown>);
616
653
  }
617
654
  /**
618
- * Thrown when a peer speaks a replication protocol version this node cannot work with.
655
+ * Sirannon throws this error when this node's package, specification, or protocol major version differs from a version
656
+ * that the replication group requires.
619
657
  *
620
658
  * @public
621
659
  */
@@ -623,52 +661,53 @@ declare class ProtocolVersionMismatchError extends ReplicationError {
623
661
  constructor(message: string, details?: Record<string, unknown>);
624
662
  }
625
663
  /**
626
- * Thrown when recovery would lose acknowledged writes, so an operator must rebuild or restore the node first.
664
+ * Signals that recovery would lose acknowledged writes, so an operator has to rebuild or restore the node first.
627
665
  *
628
666
  * @public
629
667
  */
630
668
  declare class UnsafeRecoveryRequiredError extends FailoverError {
631
669
  constructor(message: string, details?: Record<string, unknown>);
632
670
  }
633
- /** Thrown for initial sync failures.
671
+ /** Sirannon throws this error when a first sync fails, or when a node that is still syncing receives a read or a write.
634
672
  * @public
635
673
  */
636
674
  declare class SyncError extends ReplicationError {
637
675
  /**
638
- * Identifier of the sync that failed.
676
+ * Identifies the sync request that failed, when the error concerns one.
639
677
  */
640
678
  readonly requestId?: string | undefined;
641
679
  constructor(message: string,
642
680
  /**
643
- * Identifier of the sync that failed.
681
+ * Identifies the sync request that failed, when the error concerns one.
644
682
  */
645
683
  requestId?: string | undefined);
646
684
  }
647
685
 
648
- /** Generate a cryptographically random 32-hex-character node identifier.
686
+ /** Returns a new node ID of 32 lowercase hex characters, drawn from a cryptographically secure random source.
649
687
  * @public
650
688
  */
651
689
  declare function generateNodeId(): string;
652
- /** Throw a ReplicationError if the given string is not a valid 32-hex-character node ID.
690
+ /** Returns when `id` is exactly 32 lowercase hex characters, and throws a {@link ReplicationError} for any other string.
653
691
  * @public
654
692
  */
655
693
  declare function validateNodeId(id: string): void;
656
694
 
657
695
  /**
658
- * Single-writer topology with one primary and one or more read-only replicas.
696
+ * Sets the replication rules for a group with one writable primary and one or more read-only replicas.
659
697
  *
660
- * Only the primary node accepts writes; replicas reject writes with a
661
- * TopologyError (or forward them when writeForwarding is enabled on the
662
- * engine). The primary replicates outbound batches only to peers whose role
663
- * is 'replica', and replicas only accept inbound batches from a peer whose
664
- * role is 'primary'. Conflict resolution is not required because a single
665
- * writer eliminates concurrent write conflicts by design.
698
+ * Only the primary accepts writes. A replica rejects a write with a
699
+ * `TopologyError`, or forwards it to the primary when you turn on
700
+ * `writeForwarding` in the engine's config. The primary sends batches only to
701
+ * peers whose role is 'replica', and a replica applies batches only from a peer
702
+ * whose role is 'primary'. Since only one node writes, no two nodes can change
703
+ * the same row at once, so {@link PrimaryReplicaTopology.requiresConflictResolution}
704
+ * returns false.
666
705
  *
667
706
  * @public
668
707
  */
669
708
  declare class PrimaryReplicaTopology implements Topology {
670
709
  /**
671
- * Whether this node accepts writes or serves reads.
710
+ * Records whether this node is the primary, which accepts writes, or a replica, which serves reads.
672
711
  */
673
712
  readonly role: TopologyRole;
674
713
  constructor(role: 'primary' | 'replica');
@@ -687,7 +726,7 @@ declare class PrimaryReplicaTopology implements Topology {
687
726
  */
688
727
  shouldReplicateTo(_peerId: string, peerRole: TopologyRole): boolean;
689
728
  /**
690
- * Reports whether this node applies changes arriving from a given peer.
729
+ * Reports whether this node applies the changes that a given peer sends.
691
730
  *
692
731
  * @param _peerId - Identifier of the peer, which this topology ignores.
693
732
  * @param peerRole - Role of the peer.
@@ -695,11 +734,12 @@ declare class PrimaryReplicaTopology implements Topology {
695
734
  */
696
735
  shouldAcceptFrom(_peerId: string, peerRole: TopologyRole): boolean;
697
736
  /**
698
- * Reports whether incoming changes need a resolver, which a single writer removes the need for.
737
+ * Reports whether the engine has to resolve conflicts for this topology. Only the primary writes, so the answer is
738
+ * always false.
699
739
  *
700
740
  * @returns False.
701
741
  */
702
742
  requiresConflictResolution(): boolean;
703
743
  }
704
744
 
705
- export { ApplyResult, AuthorityError, BatchValidationError, ClusterCoordinator, type ClusterStatusOptions, ConflictError, ConflictResolver, type CoordinatorBackupGroupOptions, CoordinatorError, CoordinatorWatchDisposer, FailoverError, ForwardedTransactionResult, HLC, NoSafePrimaryError, NodeDrainingError, NodeNotInSyncError, PeerState, PeerTracker, PrimaryReplicaTopology, ProtocolVersionMismatchError, ReadConcernError, ReplicationAck, ReplicationBatch, ReplicationConfig, ReplicationEngine, ReplicationError, ReplicationErrorEvent, ReplicationGroupState, ReplicationLog, ReplicationStatus, StalePrimaryError, SyncAck, SyncBatch, SyncComplete, SyncError, SyncPhase, SyncRequest, SyncState, SyncTableManifest, Topology, TopologyError, TopologyRole, TransportError, UnsafeRecoveryRequiredError, WriteConcernError, coordinatorBackupGroup, generateNodeId, toClusterReadEndpoints, toClusterStatusInfo, toReplicationStatusInfo, validateNodeId };
745
+ export { ApplyResult, AuthorityError, BatchValidationError, ClusterCoordinator, type ClusterStatusOptions, ConflictError, ConflictResolver, type CoordinatorBackupGroupOptions, CoordinatorError, CoordinatorLease, CoordinatorWatchDisposer, FailoverError, ForwardedTransactionResult, HLC, NoSafePrimaryError, NodeDrainingError, NodeNotInSyncError, PeerState, PeerTracker, PrimaryReplicaTopology, ProtocolVersionMismatchError, ReadConcernError, ReplicationAck, ReplicationBatch, ReplicationConfig, ReplicationEngine, ReplicationError, ReplicationErrorEvent, ReplicationGroupState, ReplicationLog, ReplicationStatus, StalePrimaryError, SyncAck, SyncBatch, SyncComplete, SyncError, SyncPhase, SyncRequest, SyncState, SyncTableManifest, Topology, TopologyError, TopologyRole, TransportError, UnsafeRecoveryRequiredError, WriteConcernError, coordinatorBackupGroup, generateNodeId, toClusterReadEndpoints, toClusterStatusInfo, toReplicationStatusInfo, validateNodeId };