@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
package/dist/client/topology.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DatabaseClient, toBaseUrl, createEndpointTransport, RemoteError, toServerBaseUrl, unrefTimer } from '../chunk-
|
|
1
|
+
import { DatabaseClient, toBaseUrl, createEndpointTransport, RemoteError, toServerBaseUrl, unrefTimer } from '../chunk-VO3ZWA2G.mjs';
|
|
2
2
|
import '../chunk-3LXXH3RA.mjs';
|
|
3
3
|
|
|
4
4
|
// src/client/cluster-routing.ts
|
|
@@ -370,6 +370,9 @@ function toSubscriptionRoutingError(err, databaseId) {
|
|
|
370
370
|
}
|
|
371
371
|
|
|
372
372
|
// src/client/topology-transport.ts
|
|
373
|
+
function isEndpointUnreachable(err) {
|
|
374
|
+
return err instanceof Error && (err.name !== "RemoteError" || err.code === "CONNECTION_ERROR");
|
|
375
|
+
}
|
|
373
376
|
var TopologyAwareTransport = class {
|
|
374
377
|
constructor(databaseId, routing, onClose) {
|
|
375
378
|
this.databaseId = databaseId;
|
|
@@ -386,33 +389,41 @@ var TopologyAwareTransport = class {
|
|
|
386
389
|
currentReadUrl = "";
|
|
387
390
|
currentWriteUrl = "";
|
|
388
391
|
async query(sql, params) {
|
|
392
|
+
return this.onReadTransport((transport, level) => transport.query(sql, params, level ? { level } : void 0));
|
|
393
|
+
}
|
|
394
|
+
async onReadTransport(read) {
|
|
389
395
|
const readConcern = this.routing._getReadConcern();
|
|
390
396
|
const transport = await this.getReadTransport(readConcern);
|
|
391
397
|
const endpointUsed = this.currentReadUrl;
|
|
392
398
|
try {
|
|
393
|
-
return await transport
|
|
399
|
+
return await read(transport, readConcern);
|
|
394
400
|
} catch (err) {
|
|
401
|
+
const unreachable = isEndpointUnreachable(err);
|
|
395
402
|
if (this.routing._usesCoordinatorDiscovery() && shouldRefreshRouting(err)) {
|
|
403
|
+
if (unreachable && endpointUsed) {
|
|
404
|
+
this.routing._setEndpointAside(endpointUsed);
|
|
405
|
+
}
|
|
396
406
|
await this.routing._refreshClusterRouting(this.databaseId);
|
|
397
|
-
this.
|
|
398
|
-
this.currentReadUrl = "";
|
|
407
|
+
this.clearReadTransport();
|
|
399
408
|
const refreshed = await this.getReadTransport(readConcern);
|
|
400
|
-
return refreshed
|
|
409
|
+
return read(refreshed, readConcern);
|
|
401
410
|
}
|
|
402
|
-
const isTransportError = err instanceof Error && (err.name !== "RemoteError" || err.code === "CONNECTION_ERROR");
|
|
403
411
|
const writeEndpoint = await this.routing._getWriteEndpoint(this.databaseId);
|
|
404
|
-
if (
|
|
405
|
-
this.routing.
|
|
412
|
+
if (unreachable && endpointUsed && endpointUsed !== writeEndpoint) {
|
|
413
|
+
this.routing._setEndpointAside(endpointUsed);
|
|
406
414
|
if (this.currentReadUrl === endpointUsed) {
|
|
407
|
-
this.
|
|
408
|
-
this.currentReadUrl = "";
|
|
415
|
+
this.clearReadTransport();
|
|
409
416
|
}
|
|
410
417
|
const fallback = await this.getReadTransport();
|
|
411
|
-
return fallback
|
|
418
|
+
return read(fallback, void 0);
|
|
412
419
|
}
|
|
413
420
|
throw err;
|
|
414
421
|
}
|
|
415
422
|
}
|
|
423
|
+
clearReadTransport() {
|
|
424
|
+
this.readTransport = null;
|
|
425
|
+
this.currentReadUrl = "";
|
|
426
|
+
}
|
|
416
427
|
async execute(sql, params) {
|
|
417
428
|
return this.onWriteTransport((transport) => transport.execute(sql, params));
|
|
418
429
|
}
|
|
@@ -439,9 +450,7 @@ var TopologyAwareTransport = class {
|
|
|
439
450
|
}
|
|
440
451
|
}
|
|
441
452
|
async queryNamed(name, args) {
|
|
442
|
-
|
|
443
|
-
const transport = await this.getReadTransport(readConcern);
|
|
444
|
-
return transport.queryNamed(name, args, readConcern ? { level: readConcern } : void 0);
|
|
453
|
+
return this.onReadTransport((transport, level) => transport.queryNamed(name, args, level ? { level } : void 0));
|
|
445
454
|
}
|
|
446
455
|
async executeNamed(name, args, writeConcern) {
|
|
447
456
|
return this.onWriteTransport((transport) => transport.executeNamed(name, args, writeConcern));
|
|
@@ -541,6 +550,7 @@ var TopologyAwareTransport = class {
|
|
|
541
550
|
// src/client/topology.ts
|
|
542
551
|
var CLUSTER_DISCOVERY_FETCH_TIMEOUT_MS = 2e3;
|
|
543
552
|
var LATENCY_TTL_MS = 6e4;
|
|
553
|
+
var UNREACHABLE_ENDPOINT_TTL_MS = 5e3;
|
|
544
554
|
var LATENCY_PROBE_TIMEOUT_MS = 5e3;
|
|
545
555
|
var TopologyAwareClient = class extends DatabaseClient {
|
|
546
556
|
baseUrl;
|
|
@@ -555,7 +565,7 @@ var TopologyAwareClient = class extends DatabaseClient {
|
|
|
555
565
|
latencies = [];
|
|
556
566
|
latencyMeasuredAt = 0;
|
|
557
567
|
latencyMeasuring = null;
|
|
558
|
-
|
|
568
|
+
endpointsSetAside = /* @__PURE__ */ new Map();
|
|
559
569
|
constructor(options) {
|
|
560
570
|
super(options);
|
|
561
571
|
this.primaryUrl = options.primary ? toBaseUrl(options.primary) : void 0;
|
|
@@ -567,10 +577,10 @@ var TopologyAwareClient = class extends DatabaseClient {
|
|
|
567
577
|
this.baseUrl = this.primaryUrl ?? this.replicaUrls[0] ?? this.starterEndpoints[0] ?? "";
|
|
568
578
|
}
|
|
569
579
|
/**
|
|
570
|
-
* Builds the routing transport
|
|
580
|
+
* Builds the routing transport that sends one database's requests.
|
|
571
581
|
*
|
|
572
582
|
* @param databaseId - Identifier of the database.
|
|
573
|
-
* @returns A transport that picks a node
|
|
583
|
+
* @returns A transport that picks a node for each request.
|
|
574
584
|
*/
|
|
575
585
|
createTransport(databaseId) {
|
|
576
586
|
const transport = new TopologyAwareTransport(
|
|
@@ -586,7 +596,7 @@ var TopologyAwareClient = class extends DatabaseClient {
|
|
|
586
596
|
return createEndpointTransport(this.settings, url, databaseId);
|
|
587
597
|
}
|
|
588
598
|
/**
|
|
589
|
-
* Returns the address
|
|
599
|
+
* Returns the address that the client sends writes to, which is the current primary.
|
|
590
600
|
*
|
|
591
601
|
* @param databaseId - Identifier of the database.
|
|
592
602
|
* @returns Address of the node that accepts writes.
|
|
@@ -602,7 +612,7 @@ var TopologyAwareClient = class extends DatabaseClient {
|
|
|
602
612
|
if (this.readPreference === "primary") {
|
|
603
613
|
return this.primaryUrl ?? this.baseUrl;
|
|
604
614
|
}
|
|
605
|
-
const availableReplicas = this.replicaUrls.filter((url) =>
|
|
615
|
+
const availableReplicas = this.replicaUrls.filter((url) => this.isReachable(url));
|
|
606
616
|
if (this.readPreference === "replica") {
|
|
607
617
|
if (availableReplicas.length === 0) {
|
|
608
618
|
return this.primaryUrl ?? this.baseUrl;
|
|
@@ -610,7 +620,7 @@ var TopologyAwareClient = class extends DatabaseClient {
|
|
|
610
620
|
return availableReplicas[Math.floor(Math.random() * availableReplicas.length)];
|
|
611
621
|
}
|
|
612
622
|
await this.ensureLatencyMeasured();
|
|
613
|
-
const reachable = this.latencies.filter((entry) => entry.reachable &&
|
|
623
|
+
const reachable = this.latencies.filter((entry) => entry.reachable && this.isReachable(entry.url));
|
|
614
624
|
if (reachable.length === 0) {
|
|
615
625
|
return this.primaryUrl ?? this.baseUrl;
|
|
616
626
|
}
|
|
@@ -624,7 +634,9 @@ var TopologyAwareClient = class extends DatabaseClient {
|
|
|
624
634
|
if (routing.currentPrimary) return routing.currentPrimary;
|
|
625
635
|
throw new RemoteError("NO_SAFE_PRIMARY", "No current primary is available for linearizable reads");
|
|
626
636
|
}
|
|
627
|
-
const readable = routing.readEndpoints.filter(
|
|
637
|
+
const readable = routing.readEndpoints.filter(
|
|
638
|
+
(endpoint) => endpoint.readConcerns.includes(concern) && this.isReachable(endpoint.url)
|
|
639
|
+
);
|
|
628
640
|
const preferredReadable = this.readPreference === "replica" && routing.currentPrimary ? readable.filter((endpoint) => endpoint.url !== routing.currentPrimary) : readable;
|
|
629
641
|
if (this.readPreference !== "primary" && preferredReadable.length > 0) {
|
|
630
642
|
if (this.readPreference === "nearest") {
|
|
@@ -657,8 +669,15 @@ var TopologyAwareClient = class extends DatabaseClient {
|
|
|
657
669
|
return this.discovery === "coordinator";
|
|
658
670
|
}
|
|
659
671
|
/** @internal */
|
|
660
|
-
|
|
661
|
-
this.
|
|
672
|
+
_setEndpointAside(url) {
|
|
673
|
+
this.endpointsSetAside.set(url, Date.now() + UNREACHABLE_ENDPOINT_TTL_MS);
|
|
674
|
+
}
|
|
675
|
+
isReachable(url) {
|
|
676
|
+
const usableFrom = this.endpointsSetAside.get(url);
|
|
677
|
+
if (usableFrom === void 0) return true;
|
|
678
|
+
if (Date.now() < usableFrom) return false;
|
|
679
|
+
this.endpointsSetAside.delete(url);
|
|
680
|
+
return true;
|
|
662
681
|
}
|
|
663
682
|
/** @internal */
|
|
664
683
|
async _refreshClusterRouting(databaseId) {
|
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
import { B as BulkLoadDurability, a as BulkLoadResult, C as ClientOptions } from './server-options-aYtCkefX.js';
|
|
2
|
+
import { R as ResultOp, L as LiveQueryOptions, a as LiveQuery } from './types-CEJG0eFS.js';
|
|
3
|
+
import { O as OperationRef, b as OperationArguments } from './operation-registry-CGhNT-Sn.js';
|
|
4
|
+
import { P as Params, R as ReadConcern, W as WriteConcern, C as ChangeEvent, Q as QueryOptions } from './query-types-5B02ixH0.js';
|
|
5
|
+
import { Q as QueryResponse, E as ExecuteResponse, T as TransactionResponse, B as BatchResponse, L as LoadResponse } from './protocol-DFpNNsIT.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The message that the client throws when the server accepts no SQL over the network.
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
declare const SQL_REFUSED_MESSAGE = "This server does not accept SQL over the network. Call a registered operation by name, or start the server with acceptSql: true.";
|
|
13
|
+
/**
|
|
14
|
+
* The capability checks that the client performs before a remote database sends a statement.
|
|
15
|
+
*
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
interface ServerCapabilityCheck {
|
|
19
|
+
/** Throws unless the server announces that it accepts SQL over the network, so the client sends SQL only to a server that accepts it. */
|
|
20
|
+
assertSqlAccepted(): Promise<void>;
|
|
21
|
+
/** Returns the digest of the server's operation registry, or `undefined` when the server announces none. */
|
|
22
|
+
registryDigest(refresh?: boolean): Promise<string | undefined>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Fetches and caches the capability report that a server announces.
|
|
26
|
+
*
|
|
27
|
+
* @internal
|
|
28
|
+
*/
|
|
29
|
+
declare class ServerCapabilities implements ServerCapabilityCheck {
|
|
30
|
+
private readonly resolveUrl;
|
|
31
|
+
private readonly headers;
|
|
32
|
+
private readonly requestTimeoutMs;
|
|
33
|
+
private pending;
|
|
34
|
+
constructor(resolveUrl: () => string | Promise<string>, headers: Record<string, string> | undefined, requestTimeoutMs?: number);
|
|
35
|
+
private read;
|
|
36
|
+
registryDigest(refresh?: boolean): Promise<string | undefined>;
|
|
37
|
+
assertSqlAccepted(): Promise<void>;
|
|
38
|
+
private fetch;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Optional behaviours for a CDC subscription.
|
|
42
|
+
* @public
|
|
43
|
+
*/
|
|
44
|
+
interface SubscribeOptions {
|
|
45
|
+
/**
|
|
46
|
+
* Receives the error when the change callback, `onReset`, or `onSubscribed` throws or
|
|
47
|
+
* rejects, and the error for a change frame that the client cannot decode. The subscription
|
|
48
|
+
* does not await a callback, so this handler receives both a throw and a rejection.
|
|
49
|
+
* Sirannon discards any error that this handler throws itself.
|
|
50
|
+
*/
|
|
51
|
+
onError?: (error: Error) => void;
|
|
52
|
+
/**
|
|
53
|
+
* Called when the server answers a subscribe with `resync: true` and skips the replay,
|
|
54
|
+
* because the changes after the resume point are older than the history that it
|
|
55
|
+
* retains, the resume cursor comes from another change-log epoch, or its replay fails.
|
|
56
|
+
* The subscription continues from the server's current position, so treat any earlier
|
|
57
|
+
* state as stale and read it again.
|
|
58
|
+
*/
|
|
59
|
+
onReset?: () => void;
|
|
60
|
+
/** The identifier of the device that opens this subscription, so that the server can leave that device's own writes out of the stream. */
|
|
61
|
+
deviceId?: string;
|
|
62
|
+
/** The tables that one subscription covers, so the client receives a transaction that spans them as one stream in ascending order. */
|
|
63
|
+
tables?: readonly string[];
|
|
64
|
+
/** The highest migration version in the device's local database, which the server checks before it accepts the subscription. */
|
|
65
|
+
schemaVersion?: number;
|
|
66
|
+
/** Returns the sequence to resume from; the transport calls it again on each reconnect, so that the resume point matches the durable cursor. */
|
|
67
|
+
getResumeSeq?: () => bigint | undefined;
|
|
68
|
+
/** The sequence after which the first subscribe resumes. When it is absent, the subscription starts from the server's current position. */
|
|
69
|
+
sinceSeq?: bigint;
|
|
70
|
+
/** The change-log epoch of the resume cursor, so that the server answers with a resync when the cursor comes from another database file. */
|
|
71
|
+
epoch?: string;
|
|
72
|
+
/**
|
|
73
|
+
* Set to true when this device stages pulled changes durably and
|
|
74
|
+
* acknowledges staged sequences, so that the server can pack several events
|
|
75
|
+
* into each frame and pace the delivery window continuously. Set it only for
|
|
76
|
+
* a server that announces the `sync.staged-stream` capability.
|
|
77
|
+
*/
|
|
78
|
+
stagedStream?: boolean;
|
|
79
|
+
/** Receives the values that the server confirms on subscribe, which are the baseline sequence, the epoch, whether a resync is due, and the delivery window. */
|
|
80
|
+
onSubscribed?: (info: {
|
|
81
|
+
seq: bigint | undefined;
|
|
82
|
+
epoch: string | undefined;
|
|
83
|
+
resync: boolean;
|
|
84
|
+
maxUnacknowledgedChanges: number | undefined;
|
|
85
|
+
}) => void;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The callbacks through which a transport passes a live query's updates.
|
|
89
|
+
*
|
|
90
|
+
* @public
|
|
91
|
+
*/
|
|
92
|
+
interface LiveHandlers<T = Record<string, unknown>> {
|
|
93
|
+
/** Receives a complete replacement result set. */
|
|
94
|
+
onRows(rows: T[]): void;
|
|
95
|
+
/** Receives the individual edits that move the result set to its new state. */
|
|
96
|
+
onOps(ops: ResultOp<T>[]): void;
|
|
97
|
+
/** Called when the server starts re-reading the query. */
|
|
98
|
+
onRevalidating(): void;
|
|
99
|
+
/** Called when the query fails. */
|
|
100
|
+
onError(error: RemoteError): void;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Returns the digest of the server's operation registry, so that the client can detect
|
|
104
|
+
* a change to the registered operations that a live query uses.
|
|
105
|
+
*
|
|
106
|
+
* @public
|
|
107
|
+
*/
|
|
108
|
+
type RegistryDigestSource = (refresh: boolean) => Promise<string | undefined>;
|
|
109
|
+
/**
|
|
110
|
+
* The connection through which a client sends requests to a sirannon-db server.
|
|
111
|
+
* Each transport sends requests for one database.
|
|
112
|
+
*
|
|
113
|
+
* @public
|
|
114
|
+
*/
|
|
115
|
+
interface Transport {
|
|
116
|
+
/**
|
|
117
|
+
* Whether the transport sends a read concern passed to {@link Transport.query} or
|
|
118
|
+
* {@link Transport.queryNamed} to the server. Topology routing applies the
|
|
119
|
+
* client-wide setting when it chooses a node, so it leaves this unset, and the
|
|
120
|
+
* client throws for a per-read concern, so that it sends a read only at the
|
|
121
|
+
* level that the caller asked for.
|
|
122
|
+
*/
|
|
123
|
+
readonly carriesReadConcern?: boolean;
|
|
124
|
+
/** Sends a read and returns its rows. */
|
|
125
|
+
query(sql: string, params?: Params, readConcern?: ReadConcern): Promise<QueryResponse>;
|
|
126
|
+
/** Sends one write. */
|
|
127
|
+
execute(sql: string, params?: Params): Promise<ExecuteResponse>;
|
|
128
|
+
/** Sends several statements that the server executes in one transaction. */
|
|
129
|
+
transaction(statements: Array<{
|
|
130
|
+
sql: string;
|
|
131
|
+
params?: Params;
|
|
132
|
+
}>): Promise<TransactionResponse>;
|
|
133
|
+
/** Sends one statement with many parameter sets, which the server executes in one transaction. */
|
|
134
|
+
batch(sql: string, paramsBatch: Params[], writeConcern?: WriteConcern): Promise<BatchResponse>;
|
|
135
|
+
/** Sends a bulk load, which the server executes at relaxed durability. */
|
|
136
|
+
load(sql: string, paramsBatch: Params[], durability?: BulkLoadDurability, checkpoint?: boolean): Promise<LoadResponse>;
|
|
137
|
+
/** Executes a registered read by name and returns its rows. */
|
|
138
|
+
queryNamed(name: string, args?: Record<string, unknown>, readConcern?: ReadConcern): Promise<QueryResponse>;
|
|
139
|
+
/** Executes a registered write by name. */
|
|
140
|
+
executeNamed(name: string, args?: Record<string, unknown>, writeConcern?: WriteConcern): Promise<TransactionResponse>;
|
|
141
|
+
/** Opens a live query on a registered read and passes its updates to the handlers. */
|
|
142
|
+
liveSubscribe(name: string, args: Record<string, unknown> | undefined, handlers: LiveHandlers, registryDigest?: RegistryDigestSource): Promise<RemoteSubscription>;
|
|
143
|
+
/** Opens a change subscription on a table. */
|
|
144
|
+
subscribe(table: string, filter: Record<string, unknown> | undefined, callback: (event: ChangeEvent) => void, options?: SubscribeOptions): Promise<RemoteSubscription>;
|
|
145
|
+
/** Closes the transport and ends every subscription on it. */
|
|
146
|
+
close(): void;
|
|
147
|
+
}
|
|
148
|
+
/** Handle for an active remote subscription.
|
|
149
|
+
* @public
|
|
150
|
+
*/
|
|
151
|
+
interface RemoteSubscription {
|
|
152
|
+
/** Ends the subscription, so the callback receives no further events. */
|
|
153
|
+
unsubscribe(): void;
|
|
154
|
+
}
|
|
155
|
+
/** Builder for creating remote CDC subscriptions with optional filters.
|
|
156
|
+
* @public
|
|
157
|
+
*/
|
|
158
|
+
interface RemoteSubscriptionBuilder {
|
|
159
|
+
/**
|
|
160
|
+
* Narrows the subscription to rows whose columns equal the given values.
|
|
161
|
+
*
|
|
162
|
+
* The subscription reports changes to the set of matching rows. When an update moves
|
|
163
|
+
* a row into the set, your callback receives an insert with no `oldRow`, and when an
|
|
164
|
+
* update moves a row out, it receives a delete with the old row in `oldRow` and an
|
|
165
|
+
* empty `row`. It receives an update that keeps the row in the set as an ordinary
|
|
166
|
+
* update, and nothing for an update outside the set. These insert and delete events look the
|
|
167
|
+
* same as real ones, so read `type` as the row entering or leaving the set.
|
|
168
|
+
*
|
|
169
|
+
* The subscriber sets this filter, so the subscriber controls which changes the server sends. An
|
|
170
|
+
* operator who needs to limit which rows a caller can subscribe to checks the table
|
|
171
|
+
* and the filter in an `onBeforeSubscribe` hook.
|
|
172
|
+
*/
|
|
173
|
+
filter(conditions: Record<string, unknown>): RemoteSubscriptionBuilder;
|
|
174
|
+
/**
|
|
175
|
+
* Starts the subscription and calls your callback with each change.
|
|
176
|
+
*
|
|
177
|
+
* The subscription does not await your callback, so two calls to an asynchronous
|
|
178
|
+
* callback can overlap. When each change has to finish before the next one starts,
|
|
179
|
+
* chain the work onto one promise. `options.onError` receives both a throw and a
|
|
180
|
+
* rejection from the callback.
|
|
181
|
+
*
|
|
182
|
+
* @typeParam T - The shape of this table's rows, which sets the type of `row` and `oldRow`.
|
|
183
|
+
* @param callback - Receives each change that matches this subscription.
|
|
184
|
+
* @param options - The `onError` handler and the device-sync fields.
|
|
185
|
+
* @returns A handle whose `unsubscribe` ends the subscription.
|
|
186
|
+
*/
|
|
187
|
+
subscribe<T = Record<string, unknown>>(callback: (event: ChangeEvent<T>) => void, options?: SubscribeOptions): Promise<RemoteSubscription>;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* An error from a sirannon-db server, or from the client when it cannot complete a request.
|
|
191
|
+
* Its `code` holds the machine-readable code from the server's error response, or a code
|
|
192
|
+
* that the client sets, such as `TIMEOUT` or `CONNECTION_ERROR`.
|
|
193
|
+
*
|
|
194
|
+
* @public
|
|
195
|
+
*/
|
|
196
|
+
declare class RemoteError extends Error {
|
|
197
|
+
/** The machine-readable error code, from the server's error response or from the client. */
|
|
198
|
+
readonly code: string;
|
|
199
|
+
constructor(code: string, message: string);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** Options for {@link RemoteDatabase.loadAll}.
|
|
203
|
+
* @public
|
|
204
|
+
*/
|
|
205
|
+
interface LoadAllOptions {
|
|
206
|
+
/**
|
|
207
|
+
* The number of rows in each batch that the client sends to the server. Each
|
|
208
|
+
* batch is one request that must fit under the server's `maxBodyBytes`, so for
|
|
209
|
+
* wide rows, raise that limit or lower this value. Defaults to 1000.
|
|
210
|
+
*/
|
|
211
|
+
batchSize?: number;
|
|
212
|
+
/** The writer's durability level during the load. Defaults to 'off'. */
|
|
213
|
+
durability?: BulkLoadDurability;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* A handle to one database on a sirannon-db server. Its async methods match
|
|
217
|
+
* the core `Database` query methods and send each request through the
|
|
218
|
+
* configured transport.
|
|
219
|
+
*
|
|
220
|
+
* @public
|
|
221
|
+
*/
|
|
222
|
+
declare class RemoteDatabase {
|
|
223
|
+
/**
|
|
224
|
+
* The identifier of the database on the server.
|
|
225
|
+
*/
|
|
226
|
+
readonly id: string;
|
|
227
|
+
private readonly transport;
|
|
228
|
+
private readonly capabilities;
|
|
229
|
+
private readonly onDispose?;
|
|
230
|
+
constructor(
|
|
231
|
+
/**
|
|
232
|
+
* The identifier of the database on the server.
|
|
233
|
+
*/
|
|
234
|
+
id: string, transport: Transport, capabilities: ServerCapabilityCheck, onDispose?: (() => void) | undefined);
|
|
235
|
+
/**
|
|
236
|
+
* Sends a read to the server and returns its rows.
|
|
237
|
+
*
|
|
238
|
+
* @param sql - The statement to execute, which the client sends only to a server that accepts SQL.
|
|
239
|
+
* @param params - The values to bind to the statement, by name or by position.
|
|
240
|
+
* @param options - The read concern for this statement.
|
|
241
|
+
* @returns The rows that the server returns.
|
|
242
|
+
*/
|
|
243
|
+
query<T = Record<string, unknown>>(sql: string, params?: Params, options?: QueryOptions): Promise<T[]>;
|
|
244
|
+
/**
|
|
245
|
+
* Executes a registered read by name and returns its rows.
|
|
246
|
+
*
|
|
247
|
+
* @param operation - A reference to the registered read, typed with its arguments and rows.
|
|
248
|
+
* @param args - The arguments that the read takes.
|
|
249
|
+
* @param options - The read concern for this statement.
|
|
250
|
+
* @returns The rows that the server returns.
|
|
251
|
+
*/
|
|
252
|
+
query<Args, Row>(operation: OperationRef<Args, Row>, args: Args, options?: QueryOptions): Promise<Row[]>;
|
|
253
|
+
private assertReadConcernReaches;
|
|
254
|
+
/**
|
|
255
|
+
* Sends one write to the server.
|
|
256
|
+
*
|
|
257
|
+
* @param sql - The statement to execute, which the client sends only to a server that accepts SQL.
|
|
258
|
+
* @param params - The values to bind to the statement, by name or by position.
|
|
259
|
+
* @returns How many rows changed, and the last inserted row id.
|
|
260
|
+
*/
|
|
261
|
+
execute(sql: string, params?: Params): Promise<ExecuteResponse>;
|
|
262
|
+
/**
|
|
263
|
+
* Executes a registered write by name.
|
|
264
|
+
*
|
|
265
|
+
* @param operation - A reference to the registered write, typed with its arguments.
|
|
266
|
+
* @param args - The arguments that the write takes.
|
|
267
|
+
* @param writeConcern - The acknowledgements that the server waits for before it confirms the write.
|
|
268
|
+
* @returns One result for each statement that the operation executes.
|
|
269
|
+
*/
|
|
270
|
+
execute<Args>(operation: OperationRef<Args, unknown>, args: Args, writeConcern?: WriteConcern): Promise<ExecuteResponse[]>;
|
|
271
|
+
/**
|
|
272
|
+
* Opens a live query on a registered read, and keeps its rows current as rows change in the tables that the read selects from.
|
|
273
|
+
*
|
|
274
|
+
* @param name - The name of the registered read.
|
|
275
|
+
* @param args - The arguments that the read takes.
|
|
276
|
+
* @param options - Options with `onError`, which receives the error when any listener on this query fails.
|
|
277
|
+
* @returns The live query, which is already subscribed.
|
|
278
|
+
*/
|
|
279
|
+
live<T = Record<string, unknown>>(name: string, args?: OperationArguments, options?: LiveQueryOptions): Promise<LiveQuery<T>>;
|
|
280
|
+
/**
|
|
281
|
+
* Opens a live query on a registered read, and keeps its rows current as rows change in the tables that the read selects from.
|
|
282
|
+
*
|
|
283
|
+
* @param operation - A reference to the registered read, typed with its arguments and rows.
|
|
284
|
+
* @param args - The arguments that the read takes.
|
|
285
|
+
* @param options - Options with `onError`, which receives the error when any listener on this query fails.
|
|
286
|
+
* @returns The live query, which is already subscribed.
|
|
287
|
+
*/
|
|
288
|
+
live<Args, Row>(operation: OperationRef<Args, Row>, args: Args, options?: LiveQueryOptions): Promise<LiveQuery<Row>>;
|
|
289
|
+
/**
|
|
290
|
+
* Executes several statements as one atomic transaction and returns one result
|
|
291
|
+
* per statement.
|
|
292
|
+
*
|
|
293
|
+
* The client sends the whole list in one request, and the server commits or
|
|
294
|
+
* rolls it back as a unit, with no round trip between statements.
|
|
295
|
+
*/
|
|
296
|
+
transaction(statements: Array<{
|
|
297
|
+
sql: string;
|
|
298
|
+
params?: Params;
|
|
299
|
+
}>): Promise<ExecuteResponse[]>;
|
|
300
|
+
/**
|
|
301
|
+
* Executes the same statement once for each parameter set, in one atomic
|
|
302
|
+
* transaction that commits with one fsync, and returns one result per
|
|
303
|
+
* parameter set, in order. Use it for a burst of writes with the same shape,
|
|
304
|
+
* such as an import or a bulk insert, that must all commit or all roll back.
|
|
305
|
+
*/
|
|
306
|
+
batch(sql: string, paramsBatch: Params[], writeConcern?: WriteConcern): Promise<ExecuteResponse[]>;
|
|
307
|
+
/**
|
|
308
|
+
* Loads a whole dataset through one statement in requests of `batchSize` rows,
|
|
309
|
+
* and asks the server to perform the fsyncing WAL checkpoint once, after the final
|
|
310
|
+
* batch. The server restores the configured durability after every batch, so an
|
|
311
|
+
* import that stops partway leaves the writer at its configured level. Use this
|
|
312
|
+
* in place of {@link RemoteDatabase.load} for anything larger than one request,
|
|
313
|
+
* because it sets the `checkpoint` flag itself.
|
|
314
|
+
*
|
|
315
|
+
* It accepts a synchronous or asynchronous iterable of parameter sets, so rows can
|
|
316
|
+
* stream from a file or the network while the client holds at most two batches in
|
|
317
|
+
* memory. It returns the total number of rows loaded and changes applied.
|
|
318
|
+
*
|
|
319
|
+
* ```ts
|
|
320
|
+
* const summary = await db.loadAll(
|
|
321
|
+
* 'INSERT INTO events (id, payload) VALUES (?, ?)',
|
|
322
|
+
* rowStream,
|
|
323
|
+
* { batchSize: 5000, durability: 'off' },
|
|
324
|
+
* )
|
|
325
|
+
* ```
|
|
326
|
+
*/
|
|
327
|
+
loadAll(sql: string, rows: Iterable<Params> | AsyncIterable<Params>, options?: LoadAllOptions): Promise<BulkLoadResult>;
|
|
328
|
+
/**
|
|
329
|
+
* Loads one batch of rows through one statement, while the server relaxes the
|
|
330
|
+
* writer's durability for this call and restores it before the call resolves.
|
|
331
|
+
* For a dataset that spans more than one request, use {@link RemoteDatabase.loadAll},
|
|
332
|
+
* which sets the `checkpoint` flag itself.
|
|
333
|
+
*
|
|
334
|
+
* It returns the total number of rows loaded and changes applied. When you split
|
|
335
|
+
* a dataset across many `load` calls yourself, pass `checkpoint: false` on every
|
|
336
|
+
* call except the last, so that the server performs the fsyncing WAL checkpoint once
|
|
337
|
+
* at the end. The server restores the configured durability after each call.
|
|
338
|
+
*/
|
|
339
|
+
load(sql: string, paramsBatch: Params[], durability?: BulkLoadDurability, checkpoint?: boolean): Promise<BulkLoadResult>;
|
|
340
|
+
/**
|
|
341
|
+
* Returns a builder for a change subscription on one table.
|
|
342
|
+
* Chain `.filter()` to narrow the events, then call `.subscribe()`
|
|
343
|
+
* with a callback to start receiving change events.
|
|
344
|
+
*
|
|
345
|
+
* ```ts
|
|
346
|
+
* const sub = await db
|
|
347
|
+
* .on('orders')
|
|
348
|
+
* .filter({ status: 'pending' })
|
|
349
|
+
* .subscribe(event => console.log(event))
|
|
350
|
+
*
|
|
351
|
+
* // Later:
|
|
352
|
+
* sub.unsubscribe()
|
|
353
|
+
* ```
|
|
354
|
+
*
|
|
355
|
+
* @param table - The name of the table.
|
|
356
|
+
* @returns A builder that you narrow with a filter and then subscribe to.
|
|
357
|
+
*/
|
|
358
|
+
on(table: string): RemoteSubscriptionBuilder;
|
|
359
|
+
/**
|
|
360
|
+
* Closes the transport for this database, so every later call throws.
|
|
361
|
+
* With the WebSocket transport, it also rejects every pending request.
|
|
362
|
+
*/
|
|
363
|
+
close(): void;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
interface TransportSettings {
|
|
367
|
+
transport: 'websocket' | 'http';
|
|
368
|
+
headers: Record<string, string> | undefined;
|
|
369
|
+
webSocketProtocols: string | string[] | undefined;
|
|
370
|
+
autoReconnect: boolean;
|
|
371
|
+
reconnectInterval: number;
|
|
372
|
+
requestTimeout: number | undefined;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Opens one database handle per identifier and keeps it, so a later call for the same identifier returns the handle that is already open.
|
|
376
|
+
*/
|
|
377
|
+
declare abstract class DatabaseClient {
|
|
378
|
+
protected readonly settings: TransportSettings;
|
|
379
|
+
private readonly databases;
|
|
380
|
+
private closed;
|
|
381
|
+
constructor(options?: ClientOptions);
|
|
382
|
+
/**
|
|
383
|
+
* Returns the handle that you use to query and write one database, and opens it on the first call for that identifier.
|
|
384
|
+
*
|
|
385
|
+
* @param id - The identifier under which the server registered the database.
|
|
386
|
+
* @returns The database handle, which stays open until the caller closes it.
|
|
387
|
+
*/
|
|
388
|
+
database(id: string): RemoteDatabase;
|
|
389
|
+
protected createCapabilities(databaseId: string): ServerCapabilities;
|
|
390
|
+
/**
|
|
391
|
+
* Closes every database that this client opened, which closes their transports and stops their subscriptions.
|
|
392
|
+
*/
|
|
393
|
+
close(): void;
|
|
394
|
+
protected abstract createTransport(databaseId: string): Transport;
|
|
395
|
+
protected abstract resolveServerUrl(databaseId: string): string | Promise<string>;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
export { DatabaseClient as D, type LiveHandlers as L, type RemoteSubscription as R, type SubscribeOptions as S, type Transport as T, type RemoteSubscriptionBuilder as a, type RegistryDigestSource as b, type LoadAllOptions as c, RemoteDatabase as d, RemoteError as e, SQL_REFUSED_MESSAGE as f, ServerCapabilities as g, type ServerCapabilityCheck as h };
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { claimEndpoint, registerEndpointAbort, noteEndpointReachable, releaseEndpoint, scheduleEndpointRedial } from './chunk-55YRLSM2.mjs';
|
|
2
|
+
import { buildChannelCreds, ReplicationClient } from './chunk-4KASJKKK.mjs';
|
|
3
|
+
import { registerPeer, removePeer } from './chunk-HR7K3GZW.mjs';
|
|
4
|
+
import { fromBatchPayload, fromAckPayload, fromSyncRequestPayload, fromSyncBatchPayload, fromSyncCompletePayload, fromSyncAckPayload } from './chunk-ADNWEHGZ.mjs';
|
|
5
|
+
import './chunk-KU32OT4H.mjs';
|
|
6
|
+
import './chunk-BLMRNSUG.mjs';
|
|
7
|
+
import './chunk-KINDFBQP.mjs';
|
|
8
|
+
|
|
9
|
+
// src/transport/grpc/client-streams.ts
|
|
10
|
+
function cancelQuietly(stream) {
|
|
11
|
+
try {
|
|
12
|
+
stream.cancel();
|
|
13
|
+
} catch {
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function connectToEndpoint(t, endpoint) {
|
|
17
|
+
if (!t.connected) return;
|
|
18
|
+
if (!claimEndpoint(t, endpoint)) return;
|
|
19
|
+
const channelCreds = buildChannelCreds(t.options);
|
|
20
|
+
const clientOpts = {};
|
|
21
|
+
const client = new ReplicationClient(endpoint, channelCreds, clientOpts);
|
|
22
|
+
const replicateStream = client.replicate();
|
|
23
|
+
const syncStream = client.sync();
|
|
24
|
+
const entry = {
|
|
25
|
+
client,
|
|
26
|
+
replicateStream,
|
|
27
|
+
syncStream
|
|
28
|
+
};
|
|
29
|
+
let replicatePeerId = null;
|
|
30
|
+
let syncPeerId = null;
|
|
31
|
+
let closed = false;
|
|
32
|
+
const teardown = () => {
|
|
33
|
+
if (closed) return;
|
|
34
|
+
closed = true;
|
|
35
|
+
releaseEndpoint(t, endpoint);
|
|
36
|
+
const peerId = replicatePeerId ?? syncPeerId;
|
|
37
|
+
if (peerId !== null && t.clientPeerStreams.get(peerId) === entry) {
|
|
38
|
+
t.clientPeerStreams.delete(peerId);
|
|
39
|
+
removePeer(t.connectedPeers, t.serverPeerStreams, t.peerDisconnectedHandler, peerId);
|
|
40
|
+
}
|
|
41
|
+
entry.replicateStream = null;
|
|
42
|
+
entry.syncStream = null;
|
|
43
|
+
cancelQuietly(replicateStream);
|
|
44
|
+
cancelQuietly(syncStream);
|
|
45
|
+
client.close();
|
|
46
|
+
scheduleEndpointRedial(t, endpoint, () => {
|
|
47
|
+
connectToEndpoint(t, endpoint);
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
registerEndpointAbort(t, endpoint, teardown);
|
|
51
|
+
const hello = {
|
|
52
|
+
nodeId: t.localNodeId,
|
|
53
|
+
role: t.localRole,
|
|
54
|
+
groupId: t.localGroupId ?? "",
|
|
55
|
+
primaryTerm: t.localPrimaryTerm ?? 0n,
|
|
56
|
+
protocolVersion: t.localProtocolVersion ?? ""
|
|
57
|
+
};
|
|
58
|
+
replicateStream.write({ hello });
|
|
59
|
+
syncStream.write({ hello });
|
|
60
|
+
replicateStream.on("data", (msg) => {
|
|
61
|
+
if (replicatePeerId === null) {
|
|
62
|
+
if (!msg.hello) {
|
|
63
|
+
teardown();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
replicatePeerId = msg.hello.nodeId;
|
|
67
|
+
const peerRole = msg.hello.role;
|
|
68
|
+
t.clientPeerStreams.set(replicatePeerId, entry);
|
|
69
|
+
noteEndpointReachable(t, endpoint);
|
|
70
|
+
registerPeer(t.connectedPeers, t.peerConnectedHandler, replicatePeerId, peerRole, {
|
|
71
|
+
groupId: msg.hello.groupId || void 0,
|
|
72
|
+
primaryTerm: msg.hello.primaryTerm === 0n ? void 0 : msg.hello.primaryTerm,
|
|
73
|
+
protocolVersion: msg.hello.protocolVersion || void 0
|
|
74
|
+
});
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (msg.batch) {
|
|
78
|
+
t.batchHandler?.(fromBatchPayload(msg.batch), replicatePeerId).catch(() => {
|
|
79
|
+
});
|
|
80
|
+
} else if (msg.ack) {
|
|
81
|
+
t.ackHandler?.(fromAckPayload(msg.ack), replicatePeerId);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
replicateStream.on("end", teardown);
|
|
85
|
+
replicateStream.on("error", teardown);
|
|
86
|
+
syncStream.on("data", (msg) => {
|
|
87
|
+
if (syncPeerId === null) {
|
|
88
|
+
if (!msg.hello) {
|
|
89
|
+
teardown();
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
syncPeerId = msg.hello.nodeId;
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (msg.syncRequest) {
|
|
96
|
+
t.syncRequestHandler?.(fromSyncRequestPayload(msg.syncRequest), syncPeerId).catch(() => {
|
|
97
|
+
});
|
|
98
|
+
} else if (msg.syncBatch) {
|
|
99
|
+
t.syncBatchHandler?.(fromSyncBatchPayload(msg.syncBatch), syncPeerId).catch(() => {
|
|
100
|
+
});
|
|
101
|
+
} else if (msg.syncComplete) {
|
|
102
|
+
t.syncCompleteHandler?.(fromSyncCompletePayload(msg.syncComplete), syncPeerId).catch(() => {
|
|
103
|
+
});
|
|
104
|
+
} else if (msg.syncAck) {
|
|
105
|
+
t.syncAckHandler?.(fromSyncAckPayload(msg.syncAck), syncPeerId);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
syncStream.on("end", teardown);
|
|
109
|
+
syncStream.on("error", teardown);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export { connectToEndpoint };
|