@delali/sirannon-db 0.1.7 → 0.2.0

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 (72) hide show
  1. package/README.md +117 -969
  2. package/dist/backup-scheduler/index.d.ts +1 -1
  3. package/dist/backup-scheduler/index.mjs +2 -2
  4. package/dist/baseline-Br77Fnhb.d.ts +6 -0
  5. package/dist/{change-tracker-CbmaMO-N.d.ts → change-tracker-DKRVUC3l.d.ts} +5 -8
  6. package/dist/{chunk-DJLX6CAE.mjs → chunk-4ISB7XMA.mjs} +2 -1
  7. package/dist/chunk-5NOIGN5Y.mjs +18 -0
  8. package/dist/chunk-67M7KAH6.mjs +90 -0
  9. package/dist/{chunk-GEZUUIKV.mjs → chunk-D7LAYTKN.mjs} +5 -2
  10. package/dist/{chunk-4IGMIJQK.mjs → chunk-EBJXPQQO.mjs} +59 -20
  11. package/dist/{chunk-BNUTBHHH.mjs → chunk-FHWTZFI4.mjs} +1 -1
  12. package/dist/chunk-GVCNMPOS.mjs +130 -0
  13. package/dist/chunk-H237TXZW.mjs +1407 -0
  14. package/dist/{chunk-HHRMRFFR.mjs → chunk-H6PIVVDN.mjs} +353 -142
  15. package/dist/chunk-HR5CWTLC.mjs +661 -0
  16. package/dist/chunk-JU64Y7HM.mjs +299 -0
  17. package/dist/{chunk-CW6S3WL5.mjs → chunk-JZGINXTN.mjs} +7 -5
  18. package/dist/{chunk-CJLYFDP5.mjs → chunk-LFZ37BSX.mjs} +1 -1
  19. package/dist/chunk-LNY2VVHE.mjs +18 -0
  20. package/dist/chunk-NVQS53NT.mjs +665 -0
  21. package/dist/{chunk-H5AB6NIR.mjs → chunk-O7SLN3GI.mjs} +2 -15
  22. package/dist/chunk-OQVZBEBY.mjs +283 -0
  23. package/dist/{chunk-VLTICJOD.mjs → chunk-PIKHN33N.mjs} +1 -1
  24. package/dist/chunk-TJF5GZSV.mjs +187 -0
  25. package/dist/chunk-TUD5CJ76.mjs +126 -0
  26. package/dist/{chunk-YPYVQJ4C.mjs → chunk-UC3SCMIN.mjs} +9 -1
  27. package/dist/client/index.d.ts +216 -321
  28. package/dist/client/index.mjs +1192 -1342
  29. package/dist/client/topology.d.ts +61 -0
  30. package/dist/client/topology.mjs +682 -0
  31. package/dist/client-base-CLWmH5Ln.d.ts +234 -0
  32. package/dist/codegen/cli.d.ts +2 -0
  33. package/dist/codegen/cli.mjs +11 -0
  34. package/dist/codegen/index.d.ts +30 -0
  35. package/dist/codegen/index.mjs +5 -0
  36. package/dist/core/index.d.ts +37 -16
  37. package/dist/core/index.mjs +2322 -298
  38. package/dist/core/writer-worker.mjs +28 -6
  39. package/dist/{database-DuGp0Rtr.d.ts → database-BY0L5Q2n.d.ts} +59 -14
  40. package/dist/driver/better-sqlite3.d.ts +1 -1
  41. package/dist/driver/better-sqlite3.mjs +6 -6
  42. package/dist/driver/node.d.ts +1 -1
  43. package/dist/driver/node.mjs +6 -6
  44. package/dist/driver/wa-sqlite.d.ts +1 -136
  45. package/dist/{errors-5Nf5ZAEC.d.ts → errors-Bw5MdNCu.d.ts} +5 -1
  46. package/dist/file-migrations/index.d.ts +7 -5
  47. package/dist/file-migrations/index.mjs +42 -37
  48. package/dist/operation-registry-9DcvxcE5.d.ts +45 -0
  49. package/dist/primary-wins-DPAm2AKG.d.ts +61 -0
  50. package/dist/protocol-6KrSq2Hy.d.ts +66 -0
  51. package/dist/react/index.d.ts +20 -0
  52. package/dist/react/index.mjs +137 -0
  53. package/dist/replication/coordinator/etcd.d.ts +5 -3
  54. package/dist/replication/coordinator/etcd.mjs +554 -462
  55. package/dist/replication/index.d.ts +51 -105
  56. package/dist/replication/index.mjs +1415 -2061
  57. package/dist/server/index.d.ts +111 -87
  58. package/dist/server/index.mjs +1917 -489
  59. package/dist/server-options-1JHu8pid.d.ts +191 -0
  60. package/dist/{sirannon-4SspRvP5.d.ts → sirannon-DaQSyhbJ.d.ts} +7 -2
  61. package/dist/transport/grpc.d.ts +7 -4
  62. package/dist/transport/grpc.mjs +191 -97
  63. package/dist/transport/memory.d.ts +5 -134
  64. package/dist/transport/memory.mjs +3 -1
  65. package/dist/{types-BsjobKbl.d.ts → types-B7gmEsZW.d.ts} +8 -61
  66. package/dist/{types-BEu1I_9_.d.ts → types-BsVabqSI.d.ts} +1 -1
  67. package/dist/types-CL6piSnD.d.ts +43 -0
  68. package/dist/types-C_D8IhpO.d.ts +60 -0
  69. package/dist/{types-D_hQW1hr.d.ts → types-zhnRXrsb.d.ts} +55 -165
  70. package/package.json +44 -6
  71. package/dist/chunk-TKGHYWQ6.mjs +0 -35
  72. package/dist/types-D4p4UyDK.d.ts +0 -26
@@ -1,68 +1,18 @@
1
- import { C as ConflictResolver, h as ConflictContext, i as ConflictResolution, H as HLCTimestamp, R as ReplicationBatch, A as ApplyResult, j as SyncPhase, k as SyncTableManifest, I as InFlightBatch, P as PeerState, b as ForwardedTransactionResult, c as SyncBatch, d as SyncComplete, e as SyncAck, S as SyncRequest, l as ReplicationConfig, m as SyncState, n as ReplicationStatus, o as ReplicationErrorEvent, a as ReplicationAck, p as Topology, T as TopologyRole } from '../types-BsjobKbl.js';
2
- export { F as ForwardedTransaction, N as NodeInfo, q as ReplicationChange, f as ReplicationTransport, g as TransportConfig } from '../types-BsjobKbl.js';
3
- import { c as ReplicationGroupState } from '../types-BEu1I_9_.js';
4
- export { A as AcquireControllerLeaseInput, a as AcquireControllerLeaseResult, h as AdmitNodeToInSyncSetInput, C as ClusterCoordinator, f as CompareAndAdvancePrimaryTermInput, g as CompareAndAdvancePrimaryTermResult, j as CoordinatorCompatibilityMetadata, k as CoordinatorLease, b as CoordinatorNodeSession, l as CoordinatorPrimary, e as CoordinatorWatchDisposer, P as PromoteEligibleReplicaInput, R as RegisterNodeSessionInput, d as ReplicationGroupWatcher, S as SetReplicationGroupStateInput, U as UpdateInSyncSetInput, i as UpdateNodeMaintenanceInput } from '../types-BEu1I_9_.js';
1
+ export { F as FieldMergeResolver, L as LWWResolver, P as PrimaryWinsResolver } from '../primary-wins-DPAm2AKG.js';
2
+ import { H as HLCTimestamp, R as ReplicationBatch, C as ConflictResolver, A as ApplyResult, S as SyncTableManifest } from '../types-C_D8IhpO.js';
3
+ export { a as ConflictContext, b as ConflictResolution, c as ReplicationChange } from '../types-C_D8IhpO.js';
4
+ import { R as ReplicationGroupState, f as CoordinatorWatchDisposer } from '../types-BsVabqSI.js';
5
+ export { A as AcquireControllerLeaseInput, b as AcquireControllerLeaseResult, i as AdmitNodeToInSyncSetInput, C as ClusterCoordinator, g as CompareAndAdvancePrimaryTermInput, h as CompareAndAdvancePrimaryTermResult, a as CoordinatorCompatibilityMetadata, k as CoordinatorLease, d as CoordinatorNodeSession, l as CoordinatorPrimary, P as PromoteEligibleReplicaInput, c as RegisterNodeSessionInput, e as ReplicationGroupWatcher, S as SetReplicationGroupStateInput, U as UpdateInSyncSetInput, j as UpdateNodeMaintenanceInput } from '../types-BsVabqSI.js';
5
6
  import { EventEmitter } from 'node:events';
6
- import { C as ChangeTracker } from '../change-tracker-CbmaMO-N.js';
7
- import { D as Database } from '../database-DuGp0Rtr.js';
8
- import { e as SQLiteConnection, P as Params, p as QueryOptions, T as Transaction, E as ExecuteResult } from '../types-D_hQW1hr.js';
9
- import { S as SirannonError } from '../errors-5Nf5ZAEC.js';
10
- import '../types-D4p4UyDK.js';
11
-
12
- type ColumnVersionGetter = (table: string, rowId: string) => Promise<Map<string, {
13
- hlc: string;
14
- nodeId: string;
15
- }>>;
16
- /**
17
- * Per-column conflict resolver that merges non-overlapping field changes.
18
- *
19
- * Given a conflict between a local and remote write on the same row, this
20
- * resolver computes the set of columns each side changed relative to the
21
- * common ancestor (oldData). If the changed column sets don't overlap, both
22
- * sides' changes are merged into a single row, avoiding unnecessary data
23
- * loss. When columns do overlap, per-column HLC versions (retrieved via the
24
- * injected `getColumnVersions` callback) determine which side's value wins
25
- * for each contested column. If no column version metadata exists, the
26
- * resolver falls back to whole-row LWW.
27
- */
28
- declare class FieldMergeResolver implements ConflictResolver {
29
- private readonly getColumnVersions;
30
- private readonly lww;
31
- constructor(getColumnVersions: ColumnVersionGetter);
32
- resolve(ctx: ConflictContext): Promise<ConflictResolution>;
33
- }
34
-
35
- /**
36
- * Last-Writer-Wins conflict resolver.
37
- *
38
- * Compares the remote HLC against the local HLC. The higher timestamp wins.
39
- * When both timestamps are equal (concurrent writes within the same
40
- * millisecond and logical tick), the tie is broken deterministically by
41
- * comparing node IDs lexicographically, so that every node reaches the same
42
- * resolution without coordination. This is the default resolver and the
43
- * fallback used by PrimaryWinsResolver and FieldMergeResolver when they
44
- * cannot make a more specific decision.
45
- */
46
- declare class LWWResolver implements ConflictResolver {
47
- resolve(ctx: ConflictContext): ConflictResolution;
48
- }
49
-
50
- /**
51
- * Conflict resolver that unconditionally favors the designated primary node.
52
- *
53
- * If the remote change originated from the primary, it is accepted. If the
54
- * local change originated from the primary, the remote is rejected. When
55
- * neither side is the primary (e.g., two replicas syncing through a relay),
56
- * the decision falls back to LWW ordering. This resolver is designed for
57
- * primary-replica topologies where the primary is the authoritative source of
58
- * truth and replica-side writes should never override it.
59
- */
60
- declare class PrimaryWinsResolver implements ConflictResolver {
61
- private readonly primaryNodeId;
62
- private readonly lww;
63
- constructor(primaryNodeId: string);
64
- resolve(ctx: ConflictContext): ConflictResolution;
65
- }
7
+ import { C as ChangeTracker } from '../change-tracker-DKRVUC3l.js';
8
+ import { D as Database } from '../database-BY0L5Q2n.js';
9
+ import { e as SQLiteConnection, P as Params, Q as QueryOptions, T as Transaction, E as ExecuteResult } from '../types-zhnRXrsb.js';
10
+ import { g as SyncPhase, I as InFlightBatch, P as PeerState, a as ForwardedTransactionResult, b as SyncBatch, c as SyncComplete, d as SyncAck, S as SyncRequest, h as ReplicationConfig, i as SyncState, j as ReplicationStatus, k as ReplicationErrorEvent, R as ReplicationAck, l as Topology, f as TopologyRole } from '../types-B7gmEsZW.js';
11
+ export { F as ForwardedTransaction, N as NodeInfo, e as ReplicationTransport, T as TransportConfig } from '../types-B7gmEsZW.js';
12
+ import { S as SirannonError } from '../errors-Bw5MdNCu.js';
13
+ import '../server-options-1JHu8pid.js';
14
+ import '../operation-registry-9DcvxcE5.js';
15
+ import '../types-CL6piSnD.js';
66
16
 
67
17
  /**
68
18
  * Hybrid Logical Clock (HLC) for causal ordering of events across nodes.
@@ -92,7 +42,7 @@ declare class HLC {
92
42
  static compare(a: string, b: string): number;
93
43
  /** Parse an encoded HLC string into its wall-clock, logical, and nodeId components. */
94
44
  static decode(hlc: string): HLCTimestamp;
95
- private encode;
45
+ static encode(wallMs: number, logical: number, nodeId: string): string;
96
46
  }
97
47
 
98
48
  /**
@@ -111,6 +61,7 @@ declare class ReplicationLog {
111
61
  private readonly schema;
112
62
  private readonly batchReader;
113
63
  private readonly batchApplier;
64
+ private readonly stampOps;
114
65
  private readonly dump;
115
66
  constructor(conn: SQLiteConnection, localNodeId: string, hlc: HLC, changesTable?: string, tracker?: ChangeTracker);
116
67
  ensureReplicationTables(): Promise<void>;
@@ -227,16 +178,26 @@ declare class SenderLoop {
227
178
  declare class SyncJoiner {
228
179
  private readonly engine;
229
180
  private catchUpCheckTimer;
181
+ private readonly recovery;
230
182
  constructor(engine: ReplicationEngine);
231
183
  initiateSync(): Promise<void>;
232
184
  handleSyncBatchReceived(batch: SyncBatch, fromPeerId: string): Promise<void>;
233
185
  handleSyncCompleteReceived(complete: SyncComplete, fromPeerId: string): Promise<void>;
234
186
  startCatchUpCheck(): void;
235
187
  stopCatchUpCheck(): void;
188
+ stopTimers(): void;
189
+ isSourceRejection(ack: SyncAck, fromPeerId: string): boolean;
190
+ handleSourceRejection(ack: SyncAck, fromPeerId: string): void;
191
+ private retryInitiateSync;
236
192
  private sendSyncAck;
237
193
  private finishCatchUpAsReady;
238
194
  }
239
195
 
196
+ interface TableStreamDigest {
197
+ rowCount: number;
198
+ digest: string;
199
+ }
200
+
240
201
  interface ActiveSyncSession {
241
202
  requestId: string;
242
203
  joinerNodeId: string;
@@ -248,6 +209,8 @@ interface ActiveSyncSession {
248
209
  startedAt: number;
249
210
  timeoutTimer: ReturnType<typeof setTimeout>;
250
211
  aborted: boolean;
212
+ streamVerification: boolean;
213
+ tableDigests: Map<string, TableStreamDigest>;
251
214
  }
252
215
  interface SyncAckWaiter {
253
216
  resolve: (ack: SyncAck) => void;
@@ -259,6 +222,7 @@ declare class SyncServer {
259
222
  readonly activeSyncs: Map<string, ActiveSyncSession>;
260
223
  readonly syncAckWaiters: Map<string, SyncAckWaiter>;
261
224
  constructor(engine: ReplicationEngine);
225
+ private rejectSyncRequest;
262
226
  handleSyncRequest(request: SyncRequest, fromPeerId: string): Promise<void>;
263
227
  handleSyncAckReceived(ack: SyncAck): void;
264
228
  abortSyncSession(requestId: string): void;
@@ -266,6 +230,7 @@ declare class SyncServer {
266
230
  abortSessionsForPeer(peerId: string): void;
267
231
  private waitForSyncAck;
268
232
  private sendSyncBatchAndWaitForAck;
233
+ private refreshSessionDeadline;
269
234
  private serveSyncSession;
270
235
  }
271
236
 
@@ -274,8 +239,9 @@ declare class SyncServer {
274
239
  *
275
240
  * State and dependencies are exposed as readable properties so that the
276
241
  * collaborating modules in `./engine/` (LocalExecutor, SyncServer, SyncJoiner,
277
- * SenderLoop, transport wiring) can operate against a shared, mutable engine
278
- * instance without duplicating constructor wiring.
242
+ * SenderLoop, transport wiring, coordinator lifecycle/authority/membership)
243
+ * can operate against a shared, mutable engine instance without duplicating
244
+ * constructor wiring.
279
245
  */
280
246
  declare class ReplicationEngine extends EventEmitter {
281
247
  readonly database: Database;
@@ -306,17 +272,22 @@ declare class ReplicationEngine extends EventEmitter {
306
272
  coordinatorState: ReplicationGroupState | null;
307
273
  coordinatorAuthority: boolean;
308
274
  controllerState: 'disabled' | 'standby' | 'active' | 'lost';
309
- private nodeSessionLeaseId;
310
- private controllerLeaseId;
311
- private coordinatorWatchDisposer;
312
- private coordinatorLeaseTimer;
313
- private controllerTimer;
314
- private coordinatorRejoinSyncStarting;
275
+ nodeSessionLeaseId: string | null;
276
+ controllerLeaseId: string | null;
277
+ coordinatorWatchDisposer: CoordinatorWatchDisposer | null;
278
+ coordinatorLeaseTimer: ReturnType<typeof setInterval> | null;
279
+ controllerTimer: ReturnType<typeof setInterval> | null;
280
+ coordinatorRejoinSyncStarting: boolean;
281
+ coordinatorSessionRestoring: boolean;
282
+ coordinatorLastContactMs: number;
283
+ inSyncReconcileTimer: ReturnType<typeof setInterval> | null;
284
+ inSyncReconciling: boolean;
315
285
  lastSentSeq: bigint;
316
286
  lastLocalSeq: bigint;
317
287
  highestSourceSeqSeen: bigint;
318
288
  readonly appliedSeqByPeer: Map<string, bigint>;
319
289
  readonly expectedBatchIndex: Map<string, number>;
290
+ readonly syncTableDigests: Map<string, TableStreamDigest>;
320
291
  syncState: SyncState;
321
292
  readonly localExecutor: LocalExecutor;
322
293
  readonly syncServer: SyncServer;
@@ -335,7 +306,7 @@ declare class ReplicationEngine extends EventEmitter {
335
306
  forwardStatements(statements: Array<{
336
307
  sql: string;
337
308
  params?: Params;
338
- }>, _options?: QueryOptions): Promise<ForwardedTransactionResult>;
309
+ }>, options?: QueryOptions): Promise<ForwardedTransactionResult>;
339
310
  startSenderLoop(): void;
340
311
  emitError(event: ReplicationErrorEvent): void;
341
312
  getResolver(table?: string): ConflictResolver;
@@ -353,7 +324,6 @@ declare class ReplicationEngine extends EventEmitter {
353
324
  requiresCoordinatorRejoinSync(state?: ReplicationGroupState | null): boolean;
354
325
  markCoordinatorSyncReady(): Promise<void>;
355
326
  handleCoordinatorAckProgress(nodeId: string, ackedSeq: bigint): Promise<void>;
356
- private removeLocalNodeFromCoordinatorInSyncSet;
357
327
  verifyPrimaryAuthority(): Promise<ReplicationGroupState>;
358
328
  assertInboundCoordinatorMessage(message: {
359
329
  groupId?: string;
@@ -374,31 +344,6 @@ declare class ReplicationEngine extends EventEmitter {
374
344
  timeoutMs?: number;
375
345
  } | undefined;
376
346
  getCurrentPrimaryPeerId(): string | null;
377
- private canAcceptLocalWrite;
378
- private throwNotCurrentPrimary;
379
- private assertReadConcern;
380
- private refreshCoordinatorState;
381
- private hasCurrentPrimaryAuthorityFor;
382
- private getCoordinatorMessageFields;
383
- private getForwardingPrimaryPeerId;
384
- private updateCoordinatorProgressAfterWrite;
385
- private startCoordinatorLeaseRenewal;
386
- private startControllerLoop;
387
- private controllerTick;
388
- private runControllerPromotionCheck;
389
- private handleCoordinatorStateUpdate;
390
- private startCoordinatorRejoinSyncIfReady;
391
- private handleFormerPrimaryDemotion;
392
- private markLocalNodeRepairing;
393
- private requiresCoordinatorRejoin;
394
- private assertLocalCompatibility;
395
- private evaluateFormerPrimaryHistory;
396
- private stopCoordinatorTimers;
397
- private stopCoordinatorMode;
398
- private localCoordinatorPrimary;
399
- private unrefTimer;
400
- private getCoordinatorRuntimeStatus;
401
- private errorDetails;
402
347
  }
403
348
 
404
349
  /** Base error for all replication-related failures. */
@@ -406,6 +351,11 @@ declare class ReplicationError extends SirannonError {
406
351
  readonly details?: Record<string, unknown> | undefined;
407
352
  constructor(message: string, code?: string, details?: Record<string, unknown> | undefined);
408
353
  }
354
+ /** Thrown when an incoming replication batch fails integrity checks (checksum, schema, clock drift). */
355
+ declare class BatchValidationError extends ReplicationError {
356
+ constructor(message: string);
357
+ }
358
+
409
359
  /** Thrown when a write conflict cannot be resolved automatically. */
410
360
  declare class ConflictError extends ReplicationError {
411
361
  readonly table: string;
@@ -416,10 +366,6 @@ declare class ConflictError extends ReplicationError {
416
366
  declare class TransportError extends ReplicationError {
417
367
  constructor(message: string);
418
368
  }
419
- /** Thrown when an incoming replication batch fails integrity checks (checksum, schema, clock drift). */
420
- declare class BatchValidationError extends ReplicationError {
421
- constructor(message: string);
422
- }
423
369
  /** Thrown when a write-concern quorum is not met within the configured timeout. */
424
370
  declare class WriteConcernError extends ReplicationError {
425
371
  constructor(message: string);
@@ -488,4 +434,4 @@ declare class PrimaryReplicaTopology implements Topology {
488
434
  requiresConflictResolution(): boolean;
489
435
  }
490
436
 
491
- export { ApplyResult, AuthorityError, BatchValidationError, ConflictContext, ConflictError, ConflictResolution, ConflictResolver, CoordinatorError, FailoverError, FieldMergeResolver, ForwardedTransactionResult, HLC, HLCTimestamp, LWWResolver, NoSafePrimaryError, NodeDrainingError, NodeNotInSyncError, PeerState, PeerTracker, PrimaryReplicaTopology, PrimaryWinsResolver, 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, generateNodeId, validateNodeId };
437
+ export { ApplyResult, AuthorityError, BatchValidationError, ConflictError, ConflictResolver, CoordinatorError, CoordinatorWatchDisposer, FailoverError, ForwardedTransactionResult, HLC, HLCTimestamp, 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, generateNodeId, validateNodeId };