@delali/sirannon-db 0.2.0 → 0.2.1

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 (75) hide show
  1. package/dist/backup-scheduler/index.d.ts +15 -1
  2. package/dist/backup-scheduler/index.mjs +2 -2
  3. package/dist/baseline-D93hcIEE.d.ts +17 -0
  4. package/dist/{change-tracker-DKRVUC3l.d.ts → change-tracker-DDmXB754.d.ts} +56 -8
  5. package/dist/{chunk-5NOIGN5Y.mjs → chunk-2QLXDHAP.mjs} +1 -1
  6. package/dist/{chunk-LNY2VVHE.mjs → chunk-7C36BCSN.mjs} +1 -1
  7. package/dist/{chunk-NVQS53NT.mjs → chunk-7FQRQH5Z.mjs} +53 -64
  8. package/dist/{chunk-D7LAYTKN.mjs → chunk-7R4ER4FB.mjs} +1 -1
  9. package/dist/{chunk-FHWTZFI4.mjs → chunk-BQFQ65OL.mjs} +1 -1
  10. package/dist/{chunk-O7SLN3GI.mjs → chunk-BTTFW4Z4.mjs} +1 -1
  11. package/dist/{chunk-H6PIVVDN.mjs → chunk-CCZK6LCB.mjs} +38 -25
  12. package/dist/{chunk-JZGINXTN.mjs → chunk-HCCGEIZ2.mjs} +2 -2
  13. package/dist/{chunk-67M7KAH6.mjs → chunk-IWGIYDMZ.mjs} +1 -1
  14. package/dist/{chunk-LFZ37BSX.mjs → chunk-OUSWVNWT.mjs} +1 -1
  15. package/dist/{chunk-HR5CWTLC.mjs → chunk-P2VJYRVY.mjs} +60 -7
  16. package/dist/{chunk-UC3SCMIN.mjs → chunk-PBRXXISQ.mjs} +3 -0
  17. package/dist/{chunk-JU64Y7HM.mjs → chunk-SBL6GN43.mjs} +1 -1
  18. package/dist/{chunk-EBJXPQQO.mjs → chunk-UPKKSUPA.mjs} +2 -2
  19. package/dist/{chunk-TJF5GZSV.mjs → chunk-VOSJBZ6Q.mjs} +1 -1
  20. package/dist/{chunk-PIKHN33N.mjs → chunk-VOYGMAU7.mjs} +9 -1
  21. package/dist/{chunk-H237TXZW.mjs → chunk-WJ67DTD6.mjs} +48 -6
  22. package/dist/{chunk-OQVZBEBY.mjs → chunk-XF2HH5E6.mjs} +4 -61
  23. package/dist/client/index.d.ts +211 -12
  24. package/dist/client/index.mjs +155 -67
  25. package/dist/client/topology.d.ts +55 -7
  26. package/dist/client/topology.mjs +20 -1
  27. package/dist/{client-base-CLWmH5Ln.d.ts → client-base-CmZO0v3m.d.ts} +133 -24
  28. package/dist/codegen/cli.mjs +3 -3
  29. package/dist/codegen/index.d.ts +92 -2
  30. package/dist/codegen/index.mjs +3 -3
  31. package/dist/core/index.d.ts +177 -15
  32. package/dist/core/index.mjs +2481 -2226
  33. package/dist/core/writer-worker.mjs +3 -3
  34. package/dist/database-B5Qv1-cU.d.ts +380 -0
  35. package/dist/driver/better-sqlite3.d.ts +18 -1
  36. package/dist/driver/better-sqlite3.mjs +5 -5
  37. package/dist/driver/bun.d.ts +28 -0
  38. package/dist/driver/expo.d.ts +17 -0
  39. package/dist/driver/node.d.ts +18 -1
  40. package/dist/driver/node.mjs +5 -5
  41. package/dist/driver/wa-sqlite.d.ts +18 -1
  42. package/dist/{errors-Bw5MdNCu.d.ts → errors-Dei4GdBb.d.ts} +80 -7
  43. package/dist/file-migrations/index.d.ts +54 -2
  44. package/dist/file-migrations/index.mjs +3 -3
  45. package/dist/{operation-registry-9DcvxcE5.d.ts → operation-registry-hlbhqu7q.d.ts} +50 -1
  46. package/dist/{primary-wins-DPAm2AKG.d.ts → primary-wins-B0np8JS3.d.ts} +25 -1
  47. package/dist/protocol-rqANt-9Q.d.ts +152 -0
  48. package/dist/query-types-DL3LtPvY.d.ts +95 -0
  49. package/dist/react/index.d.ts +58 -3
  50. package/dist/replication/coordinator/etcd.d.ts +63 -3
  51. package/dist/replication/coordinator/etcd.mjs +82 -46
  52. package/dist/replication/index.d.ts +329 -95
  53. package/dist/replication/index.mjs +256 -141
  54. package/dist/server/index.d.ts +230 -12
  55. package/dist/server/index.mjs +63 -50
  56. package/dist/{server-options-1JHu8pid.d.ts → server-options-Dab_Jvd_.d.ts} +96 -12
  57. package/dist/sirannon-CMhiJa5Y.d.ts +111 -0
  58. package/dist/transport/grpc.d.ts +93 -9
  59. package/dist/transport/grpc.mjs +63 -20
  60. package/dist/transport/memory.d.ts +50 -20
  61. package/dist/transport/memory.mjs +25 -0
  62. package/dist/{types-CL6piSnD.d.ts → types-BCejqzNA.d.ts} +20 -0
  63. package/dist/types-CMBcFPhb.d.ts +336 -0
  64. package/dist/types-CjhxcjhA.d.ts +123 -0
  65. package/dist/types-DyrCiWuc.d.ts +499 -0
  66. package/dist/types-rVZKnKN-.d.ts +591 -0
  67. package/package.json +7 -1
  68. package/dist/baseline-Br77Fnhb.d.ts +0 -6
  69. package/dist/database-BY0L5Q2n.d.ts +0 -172
  70. package/dist/protocol-6KrSq2Hy.d.ts +0 -66
  71. package/dist/sirannon-DaQSyhbJ.d.ts +0 -36
  72. package/dist/types-B7gmEsZW.d.ts +0 -221
  73. package/dist/types-BsVabqSI.d.ts +0 -139
  74. package/dist/types-C_D8IhpO.d.ts +0 -60
  75. package/dist/types-zhnRXrsb.d.ts +0 -384
@@ -1,5 +1,5 @@
1
- import { DatabaseClient, createEndpointTransport, toBaseUrl, DEFAULT_HTTP_REQUEST_TIMEOUT_MS, postJson, decodeTaggedValues, RemoteError, encodeTaggedValues, toWsUrl, STAGED_STREAM_CAPABILITY, verifyDeviceSyncCapabilities, unrefTimer, WebSocketTransport } from '../chunk-H237TXZW.mjs';
2
- export { HttpTransport, RemoteDatabase, RemoteError, RemoteLiveQuery, RemoteSubscriptionBuilderImpl, SQL_REFUSED_MESSAGE, ServerCapabilities, WebSocketTransport } from '../chunk-H237TXZW.mjs';
1
+ import { DatabaseClient, createEndpointTransport, toBaseUrl, DEFAULT_HTTP_REQUEST_TIMEOUT_MS, postJson, decodeTaggedValues, RemoteError, encodeTaggedValues, STAGED_STREAM_CAPABILITY, verifyDeviceSyncCapabilities, unrefTimer, toWsUrl, WebSocketTransport } from '../chunk-WJ67DTD6.mjs';
2
+ export { HttpTransport, RemoteDatabase, RemoteError, RemoteLiveQuery, RemoteSubscriptionBuilderImpl, SQL_REFUSED_MESSAGE, ServerCapabilities, WebSocketTransport } from '../chunk-WJ67DTD6.mjs';
3
3
 
4
4
  // src/core/sync/canonicalise.ts
5
5
  function canonicaliseForChecksum(value) {
@@ -74,7 +74,11 @@ var HLC = class _HLC {
74
74
  this.wallMs = 0;
75
75
  this.logical = 0;
76
76
  }
77
- /** Generate a new HLC timestamp, advancing the clock. */
77
+ /**
78
+ * Generate a new HLC timestamp, advancing the clock.
79
+ *
80
+ * @internal
81
+ */
78
82
  now() {
79
83
  const physicalMs = Date.now();
80
84
  if (physicalMs > this.wallMs) {
@@ -88,7 +92,11 @@ var HLC = class _HLC {
88
92
  }
89
93
  return _HLC.encode(this.wallMs, this.logical, this.nodeId);
90
94
  }
91
- /** Merge a remote HLC timestamp into the local clock and return the updated value. */
95
+ /**
96
+ * Merge a remote HLC timestamp into the local clock and return the updated value.
97
+ *
98
+ * @internal
99
+ */
92
100
  receive(remote) {
93
101
  const r = _HLC.decode(remote);
94
102
  const physicalMs = Date.now();
@@ -126,6 +134,14 @@ var HLC = class _HLC {
126
134
  nodeId: parts.slice(2).join("-")
127
135
  };
128
136
  }
137
+ /**
138
+ * Builds the string form of a clock reading, which sorts in the same order as the reading itself.
139
+ *
140
+ * @param wallMs - Wall-clock milliseconds since the Unix epoch.
141
+ * @param logical - Counter that orders events sharing one millisecond.
142
+ * @param nodeId - Identifier of the node taking the reading.
143
+ * @returns The encoded stamp.
144
+ */
129
145
  static encode(wallMs, logical, nodeId) {
130
146
  const wallHex = wallMs.toString(16).padStart(12, "0");
131
147
  const logicalHex = logical.toString(16).padStart(4, "0");
@@ -135,6 +151,12 @@ var HLC = class _HLC {
135
151
 
136
152
  // src/core/sync/conflict/lww.ts
137
153
  var LWWResolver = class {
154
+ /**
155
+ * Takes the incoming row when its stamp is higher, and keeps the local row otherwise.
156
+ *
157
+ * @param ctx - The local and incoming versions of one row.
158
+ * @returns Which version to write.
159
+ */
138
160
  resolve(ctx) {
139
161
  if (ctx.remoteChange.operation === "delete") {
140
162
  return { action: "accept_remote" };
@@ -163,6 +185,12 @@ var FieldMergeResolver = class {
163
185
  constructor(getColumnVersions) {
164
186
  this.getColumnVersions = getColumnVersions;
165
187
  }
188
+ /**
189
+ * Merges columns only one side changed, and settles overlapping columns by their per-column stamps.
190
+ *
191
+ * @param ctx - The local and incoming versions of one row.
192
+ * @returns Which version to write, or the merged row.
193
+ */
166
194
  async resolve(ctx) {
167
195
  const columnVersions = await this.getColumnVersions(ctx.table, ctx.rowId);
168
196
  if (columnVersions.size === 0) {
@@ -237,6 +265,12 @@ var PrimaryWinsResolver = class {
237
265
  constructor(primaryNodeId) {
238
266
  this.primaryNodeId = primaryNodeId;
239
267
  }
268
+ /**
269
+ * Takes the version authored by the configured primary node, and falls back to last-writer-wins otherwise.
270
+ *
271
+ * @param ctx - The local and incoming versions of one row.
272
+ * @returns Which version to write.
273
+ */
240
274
  resolve(ctx) {
241
275
  if (ctx.remoteChange.nodeId === this.primaryNodeId) {
242
276
  return { action: "accept_remote" };
@@ -266,9 +300,20 @@ var SirannonClient = class extends DatabaseClient {
266
300
  super(options);
267
301
  this.baseUrl = normaliseClientUrl(url);
268
302
  }
303
+ /**
304
+ * Builds the transport a database's requests travel over.
305
+ *
306
+ * @param databaseId - Identifier of the database.
307
+ * @returns A transport bound to that database.
308
+ */
269
309
  createTransport(databaseId) {
270
310
  return createEndpointTransport(this.settings, this.baseUrl, databaseId);
271
311
  }
312
+ /**
313
+ * Returns the address requests are sent to.
314
+ *
315
+ * @returns The server's base address.
316
+ */
272
317
  resolveServerUrl() {
273
318
  return this.baseUrl;
274
319
  }
@@ -875,7 +920,7 @@ var PushLoop = class {
875
920
  this.timer = null;
876
921
  }
877
922
  /**
878
- * Empties the outbox before a snapshot replaces the database, so local work
923
+ * Empties the outbox before a snapshot replaces the database so that local work
879
924
  * reaches the server before the copy overwrites it. A schema refusal is
880
925
  * reconciled once; a device that still cannot push returns rather than
881
926
  * looping, leaving the snapshot to bring it back into line.
@@ -1007,13 +1052,75 @@ var ResyncScheduler = class {
1007
1052
  }
1008
1053
  };
1009
1054
 
1010
- // src/client/sync-controller.ts
1055
+ // src/client/sync-controller-wiring.ts
1011
1056
  var DEFAULT_BATCH_SIZE = 100;
1012
1057
  var DEFAULT_PUSH_INTERVAL_MS = 1e3;
1013
1058
  var DEFAULT_ACK_INTERVAL_MS = 2e3;
1014
1059
  var DEFAULT_MAX_PUSH_RETRY_DELAY_MS = 3e4;
1015
1060
  var DEFAULT_SNAPSHOT_RETRY_DELAY_MS = 5e3;
1016
1061
  var DEFAULT_MAX_SNAPSHOT_RETRY_DELAY_MS = 3e5;
1062
+ function createSyncCollaborators(baseUrl, options, host) {
1063
+ const isRunning = () => host.state() === "running";
1064
+ const push = new PushLoop(
1065
+ {
1066
+ baseUrl,
1067
+ databaseId: options.databaseId,
1068
+ headers: options.headers,
1069
+ requestTimeout: options.requestTimeout,
1070
+ batchSize: options.batchSize ?? DEFAULT_BATCH_SIZE,
1071
+ intervalMs: options.pushIntervalMs ?? DEFAULT_PUSH_INTERVAL_MS,
1072
+ maxRetryDelayMs: options.maxPushRetryDelayMs ?? DEFAULT_MAX_PUSH_RETRY_DELAY_MS
1073
+ },
1074
+ {
1075
+ isRunning,
1076
+ port: () => host.port(),
1077
+ schemaVersion: () => host.schemaVersion(),
1078
+ reconcileSchema: () => host.reconcileSchema(),
1079
+ recordError: (err) => host.recordError(err),
1080
+ onDrained: () => host.clearError()
1081
+ }
1082
+ );
1083
+ const pull = new PullStream(
1084
+ {
1085
+ wsBaseUrl: toWsUrl(baseUrl),
1086
+ databaseId: options.databaseId,
1087
+ tables: options.tables,
1088
+ headers: options.headers,
1089
+ ackIntervalMs: options.ackIntervalMs ?? DEFAULT_ACK_INTERVAL_MS,
1090
+ requestTimeout: options.requestTimeout,
1091
+ immediateAckAfterChanges: options.immediateAckAfterChanges,
1092
+ resolver: options.resolver
1093
+ },
1094
+ {
1095
+ isRunning,
1096
+ port: () => host.port(),
1097
+ onChange: options.onChange,
1098
+ onResyncRequired: () => host.markResyncRequired(),
1099
+ onApplyFailure: (err) => host.onApplyFailure(err),
1100
+ onApplySuccess: () => host.onApplySuccess(),
1101
+ recordError: (err) => host.recordError(err)
1102
+ }
1103
+ );
1104
+ const resync = new ResyncScheduler(
1105
+ {
1106
+ autoResync: options.autoResync,
1107
+ retryDelayMs: options.snapshotRetryDelayMs ?? DEFAULT_SNAPSHOT_RETRY_DELAY_MS,
1108
+ maxRetryDelayMs: options.maxSnapshotRetryDelayMs ?? DEFAULT_MAX_SNAPSHOT_RETRY_DELAY_MS,
1109
+ onResyncRequired: options.onResyncRequired,
1110
+ onSnapshotComplete: options.onSnapshotComplete
1111
+ },
1112
+ {
1113
+ isRunning,
1114
+ isSnapshotting: () => host.state() === "snapshotting",
1115
+ port: () => host.port(),
1116
+ recordError: (err) => host.recordError(err),
1117
+ download: () => host.download()
1118
+ }
1119
+ );
1120
+ return { push, pull, resync };
1121
+ }
1122
+
1123
+ // src/client/sync-controller.ts
1017
1124
  var SyncController = class {
1018
1125
  constructor(db, options) {
1019
1126
  this.db = db;
@@ -1021,69 +1128,25 @@ var SyncController = class {
1021
1128
  this.baseUrl = toBaseUrl(options.url);
1022
1129
  this.pushIntervalMs = options.pushIntervalMs ?? DEFAULT_PUSH_INTERVAL_MS;
1023
1130
  this.maxPushRetryDelayMs = options.maxPushRetryDelayMs ?? DEFAULT_MAX_PUSH_RETRY_DELAY_MS;
1024
- this.push = new PushLoop(
1025
- {
1026
- baseUrl: this.baseUrl,
1027
- databaseId: options.databaseId,
1028
- headers: options.headers,
1029
- requestTimeout: options.requestTimeout,
1030
- batchSize: options.batchSize ?? DEFAULT_BATCH_SIZE,
1031
- intervalMs: this.pushIntervalMs,
1032
- maxRetryDelayMs: this.maxPushRetryDelayMs
1033
- },
1034
- {
1035
- isRunning: () => this.state === "running",
1036
- port: () => this.port,
1037
- schemaVersion: () => this.schemaVersion ?? 0,
1038
- reconcileSchema: () => this.reconcileSchema(),
1039
- recordError: (err) => this.recordError(err),
1040
- onDrained: () => {
1041
- this.lastError = null;
1042
- }
1043
- }
1044
- );
1045
- this.pull = new PullStream(
1046
- {
1047
- wsBaseUrl: toWsUrl(this.baseUrl),
1048
- databaseId: options.databaseId,
1049
- tables: options.tables,
1050
- headers: options.headers,
1051
- ackIntervalMs: options.ackIntervalMs ?? DEFAULT_ACK_INTERVAL_MS,
1052
- requestTimeout: options.requestTimeout,
1053
- immediateAckAfterChanges: options.immediateAckAfterChanges,
1054
- resolver: options.resolver
1131
+ const collaborators = createSyncCollaborators(this.baseUrl, options, {
1132
+ state: () => this.state,
1133
+ port: () => this.port,
1134
+ schemaVersion: () => this.schemaVersion ?? 0,
1135
+ reconcileSchema: () => this.reconcileSchema(),
1136
+ recordError: (err) => this.recordError(err),
1137
+ clearError: () => {
1138
+ this.lastError = null;
1055
1139
  },
1056
- {
1057
- isRunning: () => this.state === "running",
1058
- port: () => this.port,
1059
- onChange: options.onChange,
1060
- onResyncRequired: () => this.markResyncRequired(),
1061
- onApplyFailure: (err) => this.handleApplyFailure(err),
1062
- onApplySuccess: () => {
1063
- this.consecutivePullFailures = 0;
1064
- },
1065
- recordError: (err) => this.recordError(err)
1066
- }
1067
- );
1068
- this.resync = new ResyncScheduler(
1069
- {
1070
- autoResync: options.autoResync,
1071
- retryDelayMs: options.snapshotRetryDelayMs ?? DEFAULT_SNAPSHOT_RETRY_DELAY_MS,
1072
- maxRetryDelayMs: options.maxSnapshotRetryDelayMs ?? DEFAULT_MAX_SNAPSHOT_RETRY_DELAY_MS,
1073
- onResyncRequired: options.onResyncRequired,
1074
- onSnapshotComplete: options.onSnapshotComplete
1140
+ markResyncRequired: () => this.markResyncRequired(),
1141
+ onApplyFailure: (err) => this.handleApplyFailure(err),
1142
+ onApplySuccess: () => {
1143
+ this.consecutivePullFailures = 0;
1075
1144
  },
1076
- {
1077
- isRunning: () => this.state === "running",
1078
- isSnapshotting: () => this.state === "snapshotting",
1079
- port: () => this.port,
1080
- recordError: (err) => this.recordError(err),
1081
- download: () => this.downloadSnapshot({
1082
- pageSize: options.snapshotPageSize,
1083
- onProgress: options.onSnapshotProgress
1084
- })
1085
- }
1086
- );
1145
+ download: () => this.downloadSnapshot({ pageSize: options.snapshotPageSize, onProgress: options.onSnapshotProgress })
1146
+ });
1147
+ this.push = collaborators.push;
1148
+ this.pull = collaborators.pull;
1149
+ this.resync = collaborators.resync;
1087
1150
  }
1088
1151
  baseUrl;
1089
1152
  pushIntervalMs;
@@ -1099,6 +1162,9 @@ var SyncController = class {
1099
1162
  pullRetryTimer = null;
1100
1163
  consecutivePullFailures = 0;
1101
1164
  lastError = null;
1165
+ /**
1166
+ * Connects to the server and starts pushing and pulling changes.
1167
+ */
1102
1168
  async start() {
1103
1169
  if (this.state === "running" || this.state === "starting") return;
1104
1170
  this.state = "starting";
@@ -1138,23 +1204,37 @@ var SyncController = class {
1138
1204
  this.resync.schedule();
1139
1205
  }
1140
1206
  }
1207
+ /**
1208
+ * Holds pushing and pulling without disconnecting.
1209
+ */
1141
1210
  pause() {
1142
1211
  if (this.state !== "running") return;
1143
1212
  this.teardownStream();
1144
1213
  this.state = "paused";
1145
1214
  void this.pull.persist();
1146
1215
  }
1216
+ /**
1217
+ * Resumes pushing and pulling after a pause.
1218
+ */
1147
1219
  async resume() {
1148
1220
  if (this.state !== "paused") return;
1149
1221
  this.state = "stopped";
1150
1222
  await this.start();
1151
1223
  }
1224
+ /**
1225
+ * Stops syncing and closes the connection to the server.
1226
+ */
1152
1227
  async stop() {
1153
1228
  if (this.state === "stopped") return;
1154
1229
  this.teardownStream();
1155
1230
  this.state = "stopped";
1156
1231
  await this.pull.persist();
1157
1232
  }
1233
+ /**
1234
+ * Reports where this device stands against the server.
1235
+ *
1236
+ * @returns The device's state, cursors, pending push count, and last failure.
1237
+ */
1158
1238
  async status() {
1159
1239
  const pendingPushCount = this.port ? await this.port.countOutboxPending(this.push.cursor) : 0;
1160
1240
  return {
@@ -1170,6 +1250,9 @@ var SyncController = class {
1170
1250
  lastError: this.lastError
1171
1251
  };
1172
1252
  }
1253
+ /**
1254
+ * Pushes local changes now instead of waiting for the next interval.
1255
+ */
1173
1256
  triggerPush() {
1174
1257
  void this.push.drain();
1175
1258
  }
@@ -1211,6 +1294,11 @@ var SyncController = class {
1211
1294
  this.resync.markRequired();
1212
1295
  this.resync.schedule();
1213
1296
  }
1297
+ /**
1298
+ * Replaces the local database with a fresh copy from the server and resumes syncing from it.
1299
+ *
1300
+ * @param options - Page size and the progress callback for this download.
1301
+ */
1214
1302
  async downloadSnapshot(options) {
1215
1303
  if (this.state === "snapshotting") {
1216
1304
  throw new Error("A snapshot download is already in progress");
@@ -1,10 +1,11 @@
1
- import { g as ReadConcernLevel } from '../types-zhnRXrsb.js';
2
- import { T as Transport, D as DatabaseClient } from '../client-base-CLWmH5Ln.js';
3
- import { C as ClientOptions } from '../server-options-1JHu8pid.js';
4
- import '../types-CL6piSnD.js';
5
- import '../operation-registry-9DcvxcE5.js';
6
- import '../protocol-6KrSq2Hy.js';
7
- import '../types-C_D8IhpO.js';
1
+ import { a as ReadConcernLevel } from '../query-types-DL3LtPvY.js';
2
+ import { C as ClientOptions } from '../server-options-Dab_Jvd_.js';
3
+ import { T as Transport, D as DatabaseClient } from '../client-base-CmZO0v3m.js';
4
+ import '../operation-registry-hlbhqu7q.js';
5
+ import '../types-CjhxcjhA.js';
6
+ import '../types-rVZKnKN-.js';
7
+ import '../types-BCejqzNA.js';
8
+ import '../protocol-rqANt-9Q.js';
8
9
 
9
10
  interface TopologyRouting {
10
11
  _getReadEndpoint(databaseId?: string, readConcern?: ReadConcernLevel): Promise<string>;
@@ -16,14 +17,42 @@ interface TopologyRouting {
16
17
  _createTransportForEndpoint(url: string, databaseId: string): Transport;
17
18
  }
18
19
 
20
+ /**
21
+ * @public
22
+ *
23
+ * Which nodes the client holds, how it finds the rest, and where it sends each read.
24
+ */
19
25
  interface TopologyAwareClientOptions extends ClientOptions {
26
+ /**
27
+ * Nodes the client starts from when it discovers the group through the coordinator.
28
+ */
20
29
  endpoints?: string[];
30
+ /**
31
+ * Address of the primary, for a group you list by hand.
32
+ */
21
33
  primary?: string;
34
+ /**
35
+ * Addresses of the replicas, for a group you list by hand.
36
+ */
22
37
  replicas?: string[];
38
+ /**
39
+ * Where reads go. Default: 'primary'.
40
+ */
23
41
  readPreference?: 'primary' | 'replica' | 'nearest';
42
+ /**
43
+ * Whether the client uses the nodes you listed or asks the group for them. Default: 'static'.
44
+ */
24
45
  discovery?: 'static' | 'coordinator';
46
+ /**
47
+ * Currency every read requires, which the client uses to choose a node.
48
+ */
25
49
  readConcern?: ReadConcernLevel;
26
50
  }
51
+ /**
52
+ * @public
53
+ *
54
+ * Connects to a replication group rather than one server: it routes each read to a node that meets its read concern, and each write to the primary.
55
+ */
27
56
  declare class TopologyAwareClient extends DatabaseClient implements TopologyRouting {
28
57
  private readonly baseUrl;
29
58
  private readonly primaryUrl;
@@ -39,15 +68,34 @@ declare class TopologyAwareClient extends DatabaseClient implements TopologyRout
39
68
  private latencyMeasuring;
40
69
  private readonly removedReplicas;
41
70
  constructor(options: TopologyAwareClientOptions);
71
+ /**
72
+ * Builds the routing transport a database's requests travel over.
73
+ *
74
+ * @param databaseId - Identifier of the database.
75
+ * @returns A transport that picks a node per request.
76
+ */
42
77
  protected createTransport(databaseId: string): Transport;
78
+ /** @internal */
43
79
  _createTransportForEndpoint(url: string, databaseId: string): Transport;
80
+ /**
81
+ * Returns the address writes are sent to, which is the current primary.
82
+ *
83
+ * @param databaseId - Identifier of the database.
84
+ * @returns Address of the node that accepts writes.
85
+ */
44
86
  protected resolveServerUrl(databaseId: string): Promise<string>;
87
+ /** @internal */
45
88
  _getReadEndpoint(databaseId?: string, readConcern?: ReadConcernLevel): Promise<string>;
46
89
  private routedReadEndpoint;
90
+ /** @internal */
47
91
  _getWriteEndpoint(databaseId?: string): Promise<string>;
92
+ /** @internal */
48
93
  _getReadConcern(): ReadConcernLevel | undefined;
94
+ /** @internal */
49
95
  _usesCoordinatorDiscovery(): boolean;
96
+ /** @internal */
50
97
  _removeReplica(url: string): void;
98
+ /** @internal */
51
99
  _refreshClusterRouting(databaseId: string): Promise<void>;
52
100
  private fetchClusterRouting;
53
101
  private ensureClusterRouting;
@@ -1,4 +1,4 @@
1
- import { DatabaseClient, toBaseUrl, createEndpointTransport, RemoteError, toServerBaseUrl, unrefTimer } from '../chunk-H237TXZW.mjs';
1
+ import { DatabaseClient, toBaseUrl, createEndpointTransport, RemoteError, toServerBaseUrl, unrefTimer } from '../chunk-WJ67DTD6.mjs';
2
2
 
3
3
  // src/client/cluster-routing.ts
4
4
  function clusterRoutingFingerprint(state) {
@@ -484,6 +484,12 @@ var TopologyAwareClient = class extends DatabaseClient {
484
484
  this.starterEndpoints = (options.endpoints ?? []).map(toBaseUrl);
485
485
  this.baseUrl = this.primaryUrl ?? this.replicaUrls[0] ?? this.starterEndpoints[0] ?? "";
486
486
  }
487
+ /**
488
+ * Builds the routing transport a database's requests travel over.
489
+ *
490
+ * @param databaseId - Identifier of the database.
491
+ * @returns A transport that picks a node per request.
492
+ */
487
493
  createTransport(databaseId) {
488
494
  const transport = new TopologyAwareTransport(
489
495
  databaseId,
@@ -493,12 +499,20 @@ var TopologyAwareClient = class extends DatabaseClient {
493
499
  this.topologyTransports.set(databaseId, transport);
494
500
  return transport;
495
501
  }
502
+ /** @internal */
496
503
  _createTransportForEndpoint(url, databaseId) {
497
504
  return createEndpointTransport(this.settings, url, databaseId);
498
505
  }
506
+ /**
507
+ * Returns the address writes are sent to, which is the current primary.
508
+ *
509
+ * @param databaseId - Identifier of the database.
510
+ * @returns Address of the node that accepts writes.
511
+ */
499
512
  async resolveServerUrl(databaseId) {
500
513
  return this._getWriteEndpoint(databaseId);
501
514
  }
515
+ /** @internal */
502
516
  async _getReadEndpoint(databaseId, readConcern) {
503
517
  if (this.discovery === "coordinator" && databaseId) {
504
518
  return this.routedReadEndpoint(databaseId, readConcern);
@@ -541,6 +555,7 @@ var TopologyAwareClient = class extends DatabaseClient {
541
555
  if (localReadable) return localReadable.url;
542
556
  throw new RemoteError("ROUTING_ERROR", "No usable read endpoint is available");
543
557
  }
558
+ /** @internal */
544
559
  async _getWriteEndpoint(databaseId) {
545
560
  if (this.discovery === "coordinator" && databaseId) {
546
561
  const routing = await this.ensureClusterRouting(databaseId);
@@ -551,15 +566,19 @@ var TopologyAwareClient = class extends DatabaseClient {
551
566
  }
552
567
  return this.primaryUrl ?? this.baseUrl;
553
568
  }
569
+ /** @internal */
554
570
  _getReadConcern() {
555
571
  return this.readConcern;
556
572
  }
573
+ /** @internal */
557
574
  _usesCoordinatorDiscovery() {
558
575
  return this.discovery === "coordinator";
559
576
  }
577
+ /** @internal */
560
578
  _removeReplica(url) {
561
579
  this.removedReplicas.add(url);
562
580
  }
581
+ /** @internal */
563
582
  async _refreshClusterRouting(databaseId) {
564
583
  const encodedId = encodeURIComponent(databaseId);
565
584
  for (const endpoint of this.clusterDiscoveryCandidates(databaseId)) {