@delali/sirannon-db 0.1.5 → 0.1.6
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 +2 -0
- package/dist/replication/index.d.ts +3 -2
- package/dist/replication/index.mjs +6 -1
- package/dist/transport/grpc.d.ts +2 -1
- package/dist/transport/grpc.mjs +22 -4
- package/dist/transport/memory.d.ts +1 -0
- package/dist/transport/memory.mjs +4 -1
- package/dist/{types-B2byqt0B.d.ts → types-Lc7ywFx7.d.ts} +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -580,6 +580,8 @@ When a new node joins a running cluster, it needs the full dataset before it can
|
|
|
580
580
|
|
|
581
581
|
The state machine is: `pending` -> `syncing` -> `catching-up` -> `ready`. You can monitor it via `engine.status().syncState`.
|
|
582
582
|
|
|
583
|
+
During `syncing`, `syncState.completedTables` lists the tables the joiner has finished and `syncState.totalTables` holds how many it will receive in all, so `completedTables.length / totalTables` gives you first-sync progress. A source that predates this field leaves `totalTables` at 0 until the sync finishes.
|
|
584
|
+
|
|
583
585
|
For large databases where a network transfer is impractical, the out-of-band path lets you copy the SQLite file directly and start from a known sequence:
|
|
584
586
|
|
|
585
587
|
```ts
|
|
@@ -1,5 +1,5 @@
|
|
|
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-
|
|
2
|
-
export { F as ForwardedTransaction, N as NodeInfo, q as ReplicationChange, f as ReplicationTransport, g as TransportConfig } from '../types-
|
|
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-Lc7ywFx7.js';
|
|
2
|
+
export { F as ForwardedTransaction, N as NodeInfo, q as ReplicationChange, f as ReplicationTransport, g as TransportConfig } from '../types-Lc7ywFx7.js';
|
|
3
3
|
import { c as ReplicationGroupState } from '../types-BEu1I_9_.js';
|
|
4
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';
|
|
5
5
|
import { EventEmitter } from 'node:events';
|
|
@@ -244,6 +244,7 @@ interface ActiveSyncSession {
|
|
|
244
244
|
readConn: SQLiteConnection;
|
|
245
245
|
snapshotSeq: bigint;
|
|
246
246
|
tables: string[];
|
|
247
|
+
totalTables: number;
|
|
247
248
|
completedTables: Set<string>;
|
|
248
249
|
startedAt: number;
|
|
249
250
|
timeoutTimer: ReturnType<typeof setTimeout>;
|
|
@@ -2322,6 +2322,9 @@ var SyncJoiner = class {
|
|
|
2322
2322
|
engine.expectedBatchIndex.set(batch.table, expectedIndex + 1);
|
|
2323
2323
|
try {
|
|
2324
2324
|
if (batch.table === "__schema__") {
|
|
2325
|
+
if (typeof batch.totalTables === "number" && Number.isInteger(batch.totalTables) && batch.totalTables >= 0) {
|
|
2326
|
+
engine.syncState.totalTables = batch.totalTables;
|
|
2327
|
+
}
|
|
2325
2328
|
if (batch.schema) {
|
|
2326
2329
|
for (const ddl of batch.schema) {
|
|
2327
2330
|
if (!isSyncSafeDdl(ddl)) {
|
|
@@ -2645,6 +2648,7 @@ var SyncServer = class {
|
|
|
2645
2648
|
readConn,
|
|
2646
2649
|
snapshotSeq,
|
|
2647
2650
|
tables,
|
|
2651
|
+
totalTables: allTables.length,
|
|
2648
2652
|
completedTables: new Set(request.completedTables),
|
|
2649
2653
|
startedAt: Date.now(),
|
|
2650
2654
|
timeoutTimer,
|
|
@@ -2770,7 +2774,8 @@ var SyncServer = class {
|
|
|
2770
2774
|
rows: [],
|
|
2771
2775
|
schema: schemaDdl,
|
|
2772
2776
|
checksum: schemaChecksum,
|
|
2773
|
-
isLastBatchForTable: true
|
|
2777
|
+
isLastBatchForTable: true,
|
|
2778
|
+
totalTables: session.totalTables
|
|
2774
2779
|
});
|
|
2775
2780
|
if (!schemaAck.success) {
|
|
2776
2781
|
this.abortSyncSession(session.requestId);
|
package/dist/transport/grpc.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BinaryWriter, BinaryReader } from '@bufbuild/protobuf/wire';
|
|
2
2
|
import { Client, ClientDuplexStream, CallOptions, Metadata, ServiceError, ClientUnaryCall, ChannelCredentials, ClientOptions, ServerDuplexStream, Server } from '@grpc/grpc-js';
|
|
3
3
|
import { HealthImplementation } from 'grpc-health-check';
|
|
4
|
-
import { R as ReplicationBatch, a as ReplicationAck, F as ForwardedTransaction, b as ForwardedTransactionResult, N as NodeInfo, S as SyncRequest, c as SyncBatch, d as SyncComplete, e as SyncAck, f as ReplicationTransport, T as TopologyRole, g as TransportConfig } from '../types-
|
|
4
|
+
import { R as ReplicationBatch, a as ReplicationAck, F as ForwardedTransaction, b as ForwardedTransactionResult, N as NodeInfo, S as SyncRequest, c as SyncBatch, d as SyncComplete, e as SyncAck, f as ReplicationTransport, T as TopologyRole, g as TransportConfig } from '../types-Lc7ywFx7.js';
|
|
5
5
|
import '../change-tracker-CFTQ9TSn.js';
|
|
6
6
|
import '../types-BFSsG77t.js';
|
|
7
7
|
import '../types-D-74JiXb.js';
|
|
@@ -92,6 +92,7 @@ interface SyncBatchPayload {
|
|
|
92
92
|
isLastBatchForTable: boolean;
|
|
93
93
|
groupId: string;
|
|
94
94
|
primaryTerm: bigint;
|
|
95
|
+
totalTables: number;
|
|
95
96
|
}
|
|
96
97
|
declare const SyncBatchPayload: MessageFns<SyncBatchPayload>;
|
|
97
98
|
interface SyncCompletePayload {
|
package/dist/transport/grpc.mjs
CHANGED
|
@@ -160,7 +160,8 @@ function toSyncBatchPayload(batch) {
|
|
|
160
160
|
checksum: batch.checksum,
|
|
161
161
|
isLastBatchForTable: batch.isLastBatchForTable,
|
|
162
162
|
groupId: batch.groupId ?? "",
|
|
163
|
-
primaryTerm: batch.primaryTerm ?? 0n
|
|
163
|
+
primaryTerm: batch.primaryTerm ?? 0n,
|
|
164
|
+
totalTables: batch.totalTables ?? 0
|
|
164
165
|
};
|
|
165
166
|
}
|
|
166
167
|
function fromSyncBatchPayload(p) {
|
|
@@ -173,7 +174,8 @@ function fromSyncBatchPayload(p) {
|
|
|
173
174
|
checksum: p.checksum,
|
|
174
175
|
isLastBatchForTable: p.isLastBatchForTable,
|
|
175
176
|
groupId: p.groupId || void 0,
|
|
176
|
-
primaryTerm: p.primaryTerm === 0n ? void 0 : p.primaryTerm
|
|
177
|
+
primaryTerm: p.primaryTerm === 0n ? void 0 : p.primaryTerm,
|
|
178
|
+
totalTables: p.totalTables === 0 ? void 0 : p.totalTables
|
|
177
179
|
};
|
|
178
180
|
}
|
|
179
181
|
function toSyncCompletePayload(complete) {
|
|
@@ -1455,7 +1457,8 @@ function createBaseSyncBatchPayload() {
|
|
|
1455
1457
|
checksum: "",
|
|
1456
1458
|
isLastBatchForTable: false,
|
|
1457
1459
|
groupId: "",
|
|
1458
|
-
primaryTerm: 0n
|
|
1460
|
+
primaryTerm: 0n,
|
|
1461
|
+
totalTables: 0
|
|
1459
1462
|
};
|
|
1460
1463
|
}
|
|
1461
1464
|
var SyncBatchPayload = {
|
|
@@ -1490,6 +1493,9 @@ var SyncBatchPayload = {
|
|
|
1490
1493
|
}
|
|
1491
1494
|
writer.uint32(72).int64(message.primaryTerm);
|
|
1492
1495
|
}
|
|
1496
|
+
if (message.totalTables !== 0) {
|
|
1497
|
+
writer.uint32(80).int32(message.totalTables);
|
|
1498
|
+
}
|
|
1493
1499
|
return writer;
|
|
1494
1500
|
},
|
|
1495
1501
|
decode(input, length) {
|
|
@@ -1562,6 +1568,13 @@ var SyncBatchPayload = {
|
|
|
1562
1568
|
message.primaryTerm = reader.int64();
|
|
1563
1569
|
continue;
|
|
1564
1570
|
}
|
|
1571
|
+
case 10: {
|
|
1572
|
+
if (tag !== 80) {
|
|
1573
|
+
break;
|
|
1574
|
+
}
|
|
1575
|
+
message.totalTables = reader.int32();
|
|
1576
|
+
continue;
|
|
1577
|
+
}
|
|
1565
1578
|
}
|
|
1566
1579
|
if ((tag & 7) === 4 || tag === 0) {
|
|
1567
1580
|
break;
|
|
@@ -1580,7 +1593,8 @@ var SyncBatchPayload = {
|
|
|
1580
1593
|
checksum: isSet(object.checksum) ? globalThis.String(object.checksum) : "",
|
|
1581
1594
|
isLastBatchForTable: isSet(object.isLastBatchForTable) ? globalThis.Boolean(object.isLastBatchForTable) : isSet(object.is_last_batch_for_table) ? globalThis.Boolean(object.is_last_batch_for_table) : false,
|
|
1582
1595
|
groupId: isSet(object.groupId) ? globalThis.String(object.groupId) : isSet(object.group_id) ? globalThis.String(object.group_id) : "",
|
|
1583
|
-
primaryTerm: isSet(object.primaryTerm) ? BigInt(object.primaryTerm) : isSet(object.primary_term) ? BigInt(object.primary_term) : 0n
|
|
1596
|
+
primaryTerm: isSet(object.primaryTerm) ? BigInt(object.primaryTerm) : isSet(object.primary_term) ? BigInt(object.primary_term) : 0n,
|
|
1597
|
+
totalTables: isSet(object.totalTables) ? globalThis.Number(object.totalTables) : isSet(object.total_tables) ? globalThis.Number(object.total_tables) : 0
|
|
1584
1598
|
};
|
|
1585
1599
|
},
|
|
1586
1600
|
toJSON(message) {
|
|
@@ -1612,6 +1626,9 @@ var SyncBatchPayload = {
|
|
|
1612
1626
|
if (message.primaryTerm !== 0n) {
|
|
1613
1627
|
obj.primaryTerm = message.primaryTerm.toString();
|
|
1614
1628
|
}
|
|
1629
|
+
if (message.totalTables !== 0) {
|
|
1630
|
+
obj.totalTables = Math.round(message.totalTables);
|
|
1631
|
+
}
|
|
1615
1632
|
return obj;
|
|
1616
1633
|
},
|
|
1617
1634
|
create(base) {
|
|
@@ -1628,6 +1645,7 @@ var SyncBatchPayload = {
|
|
|
1628
1645
|
message.isLastBatchForTable = object.isLastBatchForTable ?? false;
|
|
1629
1646
|
message.groupId = object.groupId ?? "";
|
|
1630
1647
|
message.primaryTerm = object.primaryTerm ?? 0n;
|
|
1648
|
+
message.totalTables = object.totalTables ?? 0;
|
|
1631
1649
|
return message;
|
|
1632
1650
|
}
|
|
1633
1651
|
};
|
|
@@ -66,7 +66,7 @@ function isValidSyncRequest(req) {
|
|
|
66
66
|
function isValidSyncBatch(batch) {
|
|
67
67
|
if (typeof batch !== "object" || batch === null) return false;
|
|
68
68
|
const b = batch;
|
|
69
|
-
return typeof b.requestId === "string" && typeof b.table === "string" && typeof b.batchIndex === "number" && Array.isArray(b.rows) && typeof b.checksum === "string" && typeof b.isLastBatchForTable === "boolean" && optionalString(b.groupId) && optionalBigint(b.primaryTerm);
|
|
69
|
+
return typeof b.requestId === "string" && typeof b.table === "string" && typeof b.batchIndex === "number" && Array.isArray(b.rows) && typeof b.checksum === "string" && typeof b.isLastBatchForTable === "boolean" && optionalNonNegativeInteger(b.totalTables) && optionalString(b.groupId) && optionalBigint(b.primaryTerm);
|
|
70
70
|
}
|
|
71
71
|
function isValidSyncComplete(complete) {
|
|
72
72
|
if (typeof complete !== "object" || complete === null) return false;
|
|
@@ -84,6 +84,9 @@ function optionalString(value) {
|
|
|
84
84
|
function optionalBigint(value) {
|
|
85
85
|
return value === void 0 || typeof value === "bigint";
|
|
86
86
|
}
|
|
87
|
+
function optionalNonNegativeInteger(value) {
|
|
88
|
+
return value === void 0 || typeof value === "number" && Number.isInteger(value) && value >= 0;
|
|
89
|
+
}
|
|
87
90
|
|
|
88
91
|
// src/transport/memory/transport.ts
|
|
89
92
|
var InMemoryTransport = class {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@delali/sirannon-db",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.6",
|
|
5
5
|
"description": "A production-grade library that turns SQLite databases into a networked data layer with real-time subscriptions.",
|
|
6
6
|
"author": "Delali (https://sondelali.com)",
|
|
7
7
|
"license": "Apache-2.0",
|