@delali/sirannon-db 0.3.4-next.62 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/README.md +79 -56
  2. package/dist/backup/index.d.ts +44 -45
  3. package/dist/backup/index.mjs +7 -7
  4. package/dist/backup-scheduler/index.d.ts +42 -41
  5. package/dist/backup-scheduler/index.mjs +4 -4
  6. package/dist/baseline-Co3iIsN_.d.ts +19 -0
  7. package/dist/change-tracker-DqCdeEyx.d.ts +128 -0
  8. package/dist/{chunk-VOSJBZ6Q.mjs → chunk-2ES3DT4A.mjs} +71 -33
  9. package/dist/{chunk-6CMCO7S4.mjs → chunk-2O3PP4CF.mjs} +1 -1
  10. package/dist/{chunk-E7Q7HE46.mjs → chunk-3BZLZ47R.mjs} +26 -26
  11. package/dist/chunk-4KASJKKK.mjs +2501 -0
  12. package/dist/{chunk-MYNI2WFS.mjs → chunk-52XW3Z76.mjs} +40 -8
  13. package/dist/chunk-55YRLSM2.mjs +57 -0
  14. package/dist/{chunk-KDAHYFW7.mjs → chunk-6AOJCNRU.mjs} +5 -5
  15. package/dist/{chunk-KXTYR2OQ.mjs → chunk-A3PHCO6W.mjs} +39 -111
  16. package/dist/chunk-ADNWEHGZ.mjs +299 -0
  17. package/dist/{chunk-2QLXDHAP.mjs → chunk-BLMRNSUG.mjs} +11 -2
  18. package/dist/chunk-BVMZJOVM.mjs +5 -0
  19. package/dist/{chunk-IWGIYDMZ.mjs → chunk-BZWDPF4G.mjs} +1 -1
  20. package/dist/{chunk-YVF2ZJTE.mjs → chunk-CZL4D3BM.mjs} +1 -1
  21. package/dist/{chunk-7SC2TZAS.mjs → chunk-DX4WGJL7.mjs} +2 -2
  22. package/dist/{chunk-45MKELYA.mjs → chunk-ESTZZPT5.mjs} +132 -13
  23. package/dist/{chunk-QP5L5DFJ.mjs → chunk-FJPR2CJX.mjs} +3 -3
  24. package/dist/chunk-HR7K3GZW.mjs +36 -0
  25. package/dist/{chunk-LXCGPZPA.mjs → chunk-IEKIYO4V.mjs} +1 -1
  26. package/dist/{chunk-TUD5CJ76.mjs → chunk-KB4OLJAD.mjs} +26 -19
  27. package/dist/{chunk-PBRXXISQ.mjs → chunk-KINDFBQP.mjs} +3 -2
  28. package/dist/{chunk-E6IMX7RS.mjs → chunk-KJLNYOOL.mjs} +2 -2
  29. package/dist/{chunk-BTTFW4Z4.mjs → chunk-KU32OT4H.mjs} +2 -10
  30. package/dist/{chunk-JQWGHSEH.mjs → chunk-NVSQ2T5Q.mjs} +71 -70
  31. package/dist/{chunk-W4EUTJNT.mjs → chunk-NZGSDALX.mjs} +94 -96
  32. package/dist/{chunk-U445A3C4.mjs → chunk-QGVRRKB2.mjs} +1 -1
  33. package/dist/{chunk-GYCEJNU4.mjs → chunk-R7GBXNTO.mjs} +1 -1
  34. package/dist/{chunk-7C36BCSN.mjs → chunk-VDN6FHU4.mjs} +1 -1
  35. package/dist/{chunk-6IYS4WLH.mjs → chunk-VO3ZWA2G.mjs} +142 -115
  36. package/dist/chunk-WOMADPM4.mjs +12 -0
  37. package/dist/{chunk-OUSWVNWT.mjs → chunk-YCMB6GR4.mjs} +1 -1
  38. package/dist/{chunk-YNTDOFTN.mjs → chunk-YW7IKQ7T.mjs} +1 -1
  39. package/dist/{chunk-M2BEAH5I.mjs → chunk-ZN4HI5FK.mjs} +126 -72
  40. package/dist/{chunk-SBL6GN43.mjs → chunk-ZYWI45EN.mjs} +1 -1
  41. package/dist/client/index.d.ts +135 -137
  42. package/dist/client/index.mjs +177 -82
  43. package/dist/client/topology.d.ts +31 -31
  44. package/dist/client/topology.mjs +42 -23
  45. package/dist/client-base-BxTocU1x.d.ts +398 -0
  46. package/dist/client-streams-YKANXMWO.mjs +112 -0
  47. package/dist/codegen/cli.mjs +4 -4
  48. package/dist/codegen/index.d.ts +36 -29
  49. package/dist/codegen/index.mjs +4 -4
  50. package/dist/core/index.d.ts +130 -115
  51. package/dist/core/index.mjs +387 -297
  52. package/dist/core/writer-worker.mjs +3 -3
  53. package/dist/database-CGDsXW1K.d.ts +959 -0
  54. package/dist/database-backup-DcLhxoa1.d.ts +143 -0
  55. package/dist/driver/better-sqlite3.d.ts +11 -10
  56. package/dist/driver/better-sqlite3.mjs +11 -11
  57. package/dist/driver/bun.d.ts +9 -8
  58. package/dist/driver/expo.d.ts +6 -7
  59. package/dist/driver/node.d.ts +11 -10
  60. package/dist/driver/node.mjs +13 -11
  61. package/dist/driver/wa-sqlite.d.ts +6 -6
  62. package/dist/errors-CJUkQ-KL.d.ts +199 -0
  63. package/dist/file-migrations/index.d.ts +20 -18
  64. package/dist/file-migrations/index.mjs +3 -3
  65. package/dist/forward-rpc-VRWFZXHN.mjs +44 -0
  66. package/dist/operation-registry-CGhNT-Sn.d.ts +96 -0
  67. package/dist/primary-wins-CHNOYuN7.d.ts +81 -0
  68. package/dist/protocol-DFpNNsIT.d.ts +153 -0
  69. package/dist/query-types-5B02ixH0.d.ts +129 -0
  70. package/dist/react/index.d.ts +22 -22
  71. package/dist/replication/coordinator/etcd.d.ts +37 -31
  72. package/dist/replication/coordinator/etcd.mjs +296 -131
  73. package/dist/replication/index.d.ts +201 -161
  74. package/dist/replication/index.mjs +630 -529
  75. package/dist/restore-options-CH8mE-Tb.d.ts +84 -0
  76. package/dist/server/index.d.ts +201 -191
  77. package/dist/server/index.mjs +736 -619
  78. package/dist/server-options-aYtCkefX.d.ts +317 -0
  79. package/dist/server-streams-24XL4T43.mjs +254 -0
  80. package/dist/sirannon-J3EgPVD7.d.ts +179 -0
  81. package/dist/transport/grpc.d.ts +37 -24
  82. package/dist/transport/grpc.mjs +83 -3199
  83. package/dist/transport/memory.d.ts +25 -26
  84. package/dist/transport/memory.mjs +18 -9
  85. package/dist/types-BrAiDGOb.d.ts +505 -0
  86. package/dist/types-CEJG0eFS.d.ts +88 -0
  87. package/dist/types-Dc8oWlxj.d.ts +1580 -0
  88. package/dist/types-DqODKeOq.d.ts +123 -0
  89. package/dist/types-guEKSzMr.d.ts +367 -0
  90. package/package.json +7 -7
  91. package/dist/baseline-D93hcIEE.d.ts +0 -17
  92. package/dist/change-tracker-CjRFuZdB.d.ts +0 -144
  93. package/dist/client-base-Cmd9EVme.d.ts +0 -397
  94. package/dist/database-BLQvqjsw.d.ts +0 -917
  95. package/dist/database-backup-B7oszQ2n.d.ts +0 -141
  96. package/dist/errors-Dei4GdBb.d.ts +0 -196
  97. package/dist/operation-registry-oiPuSYI6.d.ts +0 -94
  98. package/dist/primary-wins-B0np8JS3.d.ts +0 -85
  99. package/dist/protocol-HI-nY8DD.d.ts +0 -152
  100. package/dist/query-types-p1liOP-b.d.ts +0 -127
  101. package/dist/restore-options-CksYsH1l.d.ts +0 -83
  102. package/dist/server-options-Bj5iJnjx.d.ts +0 -292
  103. package/dist/sirannon-BPxC5tC2.d.ts +0 -178
  104. package/dist/types-B0EhgDbr.d.ts +0 -340
  105. package/dist/types-CbjfRwrK.d.ts +0 -499
  106. package/dist/types-CjhxcjhA.d.ts +0 -123
  107. package/dist/types-DPSmjU54.d.ts +0 -1518
  108. package/dist/types-DTO4CYhW.d.ts +0 -88
@@ -1,6 +1,6 @@
1
1
  // src/client/types.ts
2
2
  var RemoteError = class extends Error {
3
- /** Machine-readable code the server sent with the error. */
3
+ /** The machine-readable error code, from the server's error response or from the client. */
4
4
  code;
5
5
  constructor(code, message) {
6
6
  super(message);
@@ -62,13 +62,13 @@ var RemoteLiveQuery = class _RemoteLiveQuery {
62
62
  return query;
63
63
  }
64
64
  /**
65
- * Returns the rows the query holds right now.
65
+ * Returns the query's current state, which is its status with either its rows or its error.
66
66
  */
67
67
  getState() {
68
68
  return this.state;
69
69
  }
70
70
  /**
71
- * Calls back on each update and returns a function that stops the listener.
71
+ * Calls the listener with each update, and returns a function that removes it.
72
72
  *
73
73
  * @param listener - Receives each update.
74
74
  * @returns A function that removes the listener.
@@ -80,7 +80,7 @@ var RemoteLiveQuery = class _RemoteLiveQuery {
80
80
  };
81
81
  }
82
82
  /**
83
- * Ends the query and releases its subscription.
83
+ * Ends the query and unsubscribes it from the server.
84
84
  */
85
85
  async close() {
86
86
  if (this.closed) return;
@@ -206,11 +206,11 @@ var RemoteDatabase = class {
206
206
  );
207
207
  }
208
208
  /**
209
- * Execute multiple statements as a single atomic transaction.
210
- * Returns an array of results, one per statement.
209
+ * Executes several statements as one atomic transaction and returns one result
210
+ * per statement.
211
211
  *
212
- * The whole list is sent in one request and commits or rolls back as a
213
- * unit, so the client is never in the loop between statements.
212
+ * The client sends the whole list in one request, and the server commits or
213
+ * rolls it back as a unit, with no round trip between statements.
214
214
  */
215
215
  async transaction(statements) {
216
216
  await this.capabilities.assertSqlAccepted();
@@ -218,10 +218,10 @@ var RemoteDatabase = class {
218
218
  return response.results;
219
219
  }
220
220
  /**
221
- * Run the same statement once per parameter set as a single atomic
222
- * transaction that commits with one fsync. Returns one result per
223
- * parameter set, in order. Use this for a burst of same-shape writes
224
- * (an import, a bulk insert) that must all commit or all roll back.
221
+ * Executes the same statement once for each parameter set, in one atomic
222
+ * transaction that commits with one fsync, and returns one result per
223
+ * parameter set, in order. Use it for a burst of writes with the same shape,
224
+ * such as an import or a bulk insert, that must all commit or all roll back.
225
225
  */
226
226
  async batch(sql, paramsBatch, writeConcern) {
227
227
  await this.capabilities.assertSqlAccepted();
@@ -229,16 +229,16 @@ var RemoteDatabase = class {
229
229
  return response.results;
230
230
  }
231
231
  /**
232
- * Load a whole dataset through the same statement, batching it into requests
233
- * for you and paying the one fsyncing WAL checkpoint once, after the final
234
- * batch. The configured durability is restored after every batch, so an
235
- * import that stops partway never leaves the writer at the relaxed level.
236
- * Prefer this over {@link RemoteDatabase.load} for anything larger than a single request:
237
- * it finalises the load itself, so there is no checkpoint flag to forget.
232
+ * Loads a whole dataset through one statement in requests of `batchSize` rows,
233
+ * and asks the server to perform the fsyncing WAL checkpoint once, after the final
234
+ * batch. The server restores the configured durability after every batch, so an
235
+ * import that stops partway leaves the writer at its configured level. Use this
236
+ * in place of {@link RemoteDatabase.load} for anything larger than one request,
237
+ * because it sets the `checkpoint` flag itself.
238
238
  *
239
- * Accepts a synchronous or asynchronous iterable of parameter sets so that rows
240
- * can stream from a file or the network without being held in memory at
241
- * once. Returns the total rows loaded and changes applied.
239
+ * It accepts a synchronous or asynchronous iterable of parameter sets, so rows can
240
+ * stream from a file or the network while the client holds at most two batches in
241
+ * memory. It returns the total number of rows loaded and changes applied.
242
242
  *
243
243
  * ```ts
244
244
  * const summary = await db.loadAll(
@@ -288,25 +288,24 @@ var RemoteDatabase = class {
288
288
  return total;
289
289
  }
290
290
  /**
291
- * Load one batch of rows through the same statement with writer durability
292
- * relaxed for the duration, then restored before this resolves. This is the
293
- * low-level primitive; prefer {@link RemoteDatabase.loadAll} for a dataset that spans more
294
- * than one request, since it finalises the load itself rather than relying on
295
- * a `checkpoint` flag.
291
+ * Loads one batch of rows through one statement, while the server relaxes the
292
+ * writer's durability for this call and restores it before the call resolves.
293
+ * For a dataset that spans more than one request, use {@link RemoteDatabase.loadAll},
294
+ * which sets the `checkpoint` flag itself.
296
295
  *
297
- * Returns the total rows loaded and changes applied. When splitting a dataset
298
- * across many `load` calls by hand, pass `checkpoint: false` on every call
299
- * but the last so the one fsyncing WAL checkpoint runs once at the end; the
300
- * configured durability is restored after each call regardless.
296
+ * It returns the total number of rows loaded and changes applied. When you split
297
+ * a dataset across many `load` calls yourself, pass `checkpoint: false` on every
298
+ * call except the last, so that the server performs the fsyncing WAL checkpoint once
299
+ * at the end. The server restores the configured durability after each call.
301
300
  */
302
301
  async load(sql, paramsBatch, durability, checkpoint) {
303
302
  await this.capabilities.assertSqlAccepted();
304
303
  return this.transport.load(sql, paramsBatch, durability, checkpoint);
305
304
  }
306
305
  /**
307
- * Start building a CDC subscription for the given table.
306
+ * Returns a builder for a change subscription on one table.
308
307
  * Chain `.filter()` to narrow the events, then call `.subscribe()`
309
- * with a callback to begin receiving real-time change events.
308
+ * with a callback to start receiving change events.
310
309
  *
311
310
  * ```ts
312
311
  * const sub = await db
@@ -318,17 +317,15 @@ var RemoteDatabase = class {
318
317
  * sub.unsubscribe()
319
318
  * ```
320
319
  *
321
- * Begins a change subscription on a watched table.
322
- *
323
- * @param table - Name of the watched table.
324
- * @returns A builder you narrow with a filter and then subscribe to.
320
+ * @param table - The name of the table.
321
+ * @returns A builder that you narrow with a filter and then subscribe to.
325
322
  */
326
323
  on(table) {
327
324
  return new RemoteSubscriptionBuilderImpl(table, this.transport);
328
325
  }
329
326
  /**
330
- * Close the transport for this database. After calling `close()`,
331
- * all pending requests are rejected and new calls will throw.
327
+ * Closes the transport for this database, so every later call throws.
328
+ * With the WebSocket transport, it also rejects every pending request.
332
329
  */
333
330
  close() {
334
331
  this.transport.close();
@@ -566,6 +563,12 @@ async function verifyDeviceSyncCapabilities(options) {
566
563
  }
567
564
  const announced = new Set(capabilities);
568
565
  const missing = REQUIRED_DEVICE_SYNC_CAPABILITIES.filter((name) => !announced.has(name));
566
+ if (missing.length === REQUIRED_DEVICE_SYNC_CAPABILITIES.length) {
567
+ throw new RemoteError(
568
+ "DEVICE_SYNC_NOT_ACCEPTED",
569
+ "The server keeps device sync off; the server has to set acceptDeviceSync before a device can sync."
570
+ );
571
+ }
569
572
  if (missing.length > 0) {
570
573
  throw new RemoteError(
571
574
  "SYNC_UNSUPPORTED",
@@ -652,13 +655,13 @@ var HttpTransport = class {
652
655
  async execute(sql, params) {
653
656
  return this.post("/execute", { sql, params: encodeTaggedValues(params) });
654
657
  }
655
- /** Sends several statements the server runs in one transaction. */
658
+ /** Sends several statements that the server executes in one transaction. */
656
659
  async transaction(statements) {
657
660
  return this.post("/transaction", {
658
661
  statements: statements.map((stmt) => ({ sql: stmt.sql, params: encodeTaggedValues(stmt.params) }))
659
662
  });
660
663
  }
661
- /** Sends one statement over many parameter sets, which the server runs in one transaction. */
664
+ /** Sends one statement with many parameter sets, which the server executes in one transaction. */
662
665
  async batch(sql, paramsBatch, writeConcern) {
663
666
  return this.post("/batch", {
664
667
  sql,
@@ -666,7 +669,7 @@ var HttpTransport = class {
666
669
  writeConcern
667
670
  });
668
671
  }
669
- /** Sends a bulk load, which the server runs at relaxed durability. */
672
+ /** Sends a bulk load, which the server executes at relaxed durability. */
670
673
  async load(sql, paramsBatch, durability, checkpoint) {
671
674
  return this.post("/load", {
672
675
  sql,
@@ -675,7 +678,7 @@ var HttpTransport = class {
675
678
  checkpoint
676
679
  });
677
680
  }
678
- /** Runs a registered read by name and returns its rows. */
681
+ /** Executes a registered read by name and returns its rows. */
679
682
  async queryNamed(name, args, readConcern) {
680
683
  const response = await this.post(`/query/${encodeURIComponent(name)}`, {
681
684
  args: encodeTaggedValues(args),
@@ -683,28 +686,28 @@ var HttpTransport = class {
683
686
  });
684
687
  return { rows: decodeTaggedValues(response.rows ?? []) };
685
688
  }
686
- /** Runs a registered write by name. */
689
+ /** Executes a registered write by name. */
687
690
  async executeNamed(name, args, writeConcern) {
688
691
  return this.post(`/execute/${encodeURIComponent(name)}`, {
689
692
  args: encodeTaggedValues(args),
690
693
  writeConcern
691
694
  });
692
695
  }
693
- /** Opens a live query on a registered read and delivers its updates to the handlers. */
696
+ /** Throws a `RemoteError` with code `TRANSPORT_ERROR`, because live queries need the WebSocket transport. */
694
697
  async liveSubscribe() {
695
698
  throw new RemoteError(
696
699
  "TRANSPORT_ERROR",
697
700
  'Live queries require WebSocket transport. Create the client with { transport: "websocket" } to use them.'
698
701
  );
699
702
  }
700
- /** Opens a change subscription on a watched table. */
703
+ /** Throws a `RemoteError` with code `TRANSPORT_ERROR`, because change subscriptions need the WebSocket transport. */
701
704
  async subscribe(_table, _filter, _callback) {
702
705
  throw new RemoteError(
703
706
  "TRANSPORT_ERROR",
704
707
  'Subscriptions require WebSocket transport. Create the client with { transport: "websocket" } to use real-time subscriptions.'
705
708
  );
706
709
  }
707
- /** Closes the transport and every subscription running on it. */
710
+ /** Closes the transport, so every later request throws a `RemoteError` with code `TRANSPORT_ERROR`. */
708
711
  close() {
709
712
  this.closed = true;
710
713
  }
@@ -1139,6 +1142,66 @@ var PendingRequests = class {
1139
1142
  }
1140
1143
  };
1141
1144
 
1145
+ // src/client/transport/ws-request-frames.ts
1146
+ function encodedParams(params) {
1147
+ return encodeTaggedValues(params);
1148
+ }
1149
+ function encodedArgs(args) {
1150
+ return args === void 0 ? void 0 : encodeTaggedValues(args);
1151
+ }
1152
+ function queryFrame(id, sql, params, readConcern) {
1153
+ return { type: "query", id, sql, params: encodedParams(params), ...readConcern ? { readConcern } : {} };
1154
+ }
1155
+ function executeFrame(id, sql, params) {
1156
+ return { type: "execute", id, sql, params: encodedParams(params) };
1157
+ }
1158
+ function transactionFrame(id, statements) {
1159
+ return {
1160
+ type: "transaction",
1161
+ id,
1162
+ statements: statements.map((statement) => ({ sql: statement.sql, params: encodedParams(statement.params) }))
1163
+ };
1164
+ }
1165
+ function batchFrame(id, sql, paramsBatch, writeConcern) {
1166
+ return {
1167
+ type: "batch",
1168
+ id,
1169
+ sql,
1170
+ paramsBatch: paramsBatch.map((entry) => encodeTaggedValues(entry)),
1171
+ ...writeConcern ? { writeConcern } : {}
1172
+ };
1173
+ }
1174
+ function loadFrame(id, sql, paramsBatch, durability, checkpoint) {
1175
+ return {
1176
+ type: "load",
1177
+ id,
1178
+ sql,
1179
+ paramsBatch: paramsBatch.map((entry) => encodeTaggedValues(entry)),
1180
+ ...durability ? { durability } : {},
1181
+ ...checkpoint !== void 0 ? { checkpoint } : {}
1182
+ };
1183
+ }
1184
+ function namedQueryFrame(id, name, args, readConcern) {
1185
+ const encoded = encodedArgs(args);
1186
+ return {
1187
+ type: "query",
1188
+ id,
1189
+ name,
1190
+ ...encoded === void 0 ? {} : { args: encoded },
1191
+ ...readConcern ? { readConcern } : {}
1192
+ };
1193
+ }
1194
+ function namedExecuteFrame(id, name, args, writeConcern) {
1195
+ const encoded = encodedArgs(args);
1196
+ return {
1197
+ type: "execute",
1198
+ id,
1199
+ name,
1200
+ ...encoded === void 0 ? {} : { args: encoded },
1201
+ ...writeConcern ? { writeConcern } : {}
1202
+ };
1203
+ }
1204
+
1142
1205
  // src/client/transport/ws.ts
1143
1206
  var DEFAULT_REQUEST_TIMEOUT = 3e4;
1144
1207
  var WebSocketTransport = class {
@@ -1163,6 +1226,8 @@ var WebSocketTransport = class {
1163
1226
  closed = false;
1164
1227
  connectPromise = null;
1165
1228
  reconnectTimer = null;
1229
+ subscriptionsRestored = true;
1230
+ restorePromise = null;
1166
1231
  constructor(url, options) {
1167
1232
  this.url = url;
1168
1233
  this.autoReconnect = options?.autoReconnect ?? true;
@@ -1175,96 +1240,46 @@ var WebSocketTransport = class {
1175
1240
  /** Sends a read and returns its rows. */
1176
1241
  async query(sql, params, readConcern) {
1177
1242
  await this.ensureConnected();
1178
- const id = this.nextId();
1179
- const response = await this.request({
1180
- type: "query",
1181
- id,
1182
- sql,
1183
- params: encodeTaggedValues(params),
1184
- ...readConcern ? { readConcern } : {}
1185
- });
1243
+ const response = await this.request(queryFrame(this.nextId(), sql, params, readConcern));
1186
1244
  return { rows: decodeTaggedValues(response.rows ?? []) };
1187
1245
  }
1188
1246
  /** Sends one write. */
1189
1247
  async execute(sql, params) {
1190
1248
  await this.ensureConnected();
1191
- const id = this.nextId();
1192
- return this.request({
1193
- type: "execute",
1194
- id,
1195
- sql,
1196
- params: encodeTaggedValues(params)
1197
- });
1249
+ return this.request(executeFrame(this.nextId(), sql, params));
1198
1250
  }
1199
- /** Sends several statements the server runs in one transaction. */
1251
+ /** Sends several statements that the server executes in one transaction. */
1200
1252
  async transaction(statements) {
1201
1253
  await this.ensureConnected();
1202
- const id = this.nextId();
1203
- return this.request({
1204
- type: "transaction",
1205
- id,
1206
- statements: statements.map((stmt) => ({
1207
- sql: stmt.sql,
1208
- params: encodeTaggedValues(stmt.params)
1209
- }))
1210
- });
1254
+ return this.request(transactionFrame(this.nextId(), statements));
1211
1255
  }
1212
- /** Sends one statement over many parameter sets, which the server runs in one transaction. */
1256
+ /** Sends one statement with many parameter sets, which the server executes in one transaction. */
1213
1257
  async batch(sql, paramsBatch, writeConcern) {
1214
1258
  await this.ensureConnected();
1215
- const id = this.nextId();
1216
- return this.request({
1217
- type: "batch",
1218
- id,
1219
- sql,
1220
- paramsBatch: paramsBatch.map((entry) => encodeTaggedValues(entry)),
1221
- ...writeConcern ? { writeConcern } : {}
1222
- });
1259
+ return this.request(batchFrame(this.nextId(), sql, paramsBatch, writeConcern));
1223
1260
  }
1224
- /** Sends a bulk load, which the server runs at relaxed durability. */
1261
+ /** Sends a bulk load, which the server executes at relaxed durability. */
1225
1262
  async load(sql, paramsBatch, durability, checkpoint) {
1226
1263
  await this.ensureConnected();
1227
- const id = this.nextId();
1228
- return this.request({
1229
- type: "load",
1230
- id,
1231
- sql,
1232
- paramsBatch: paramsBatch.map((entry) => encodeTaggedValues(entry)),
1233
- ...durability ? { durability } : {},
1234
- ...checkpoint !== void 0 ? { checkpoint } : {}
1235
- });
1264
+ return this.request(loadFrame(this.nextId(), sql, paramsBatch, durability, checkpoint));
1236
1265
  }
1237
- /** Runs a registered read by name and returns its rows. */
1266
+ /** Executes a registered read by name and returns its rows. */
1238
1267
  async queryNamed(name, args, readConcern) {
1239
1268
  await this.ensureConnected();
1240
- const id = this.nextId();
1241
- const response = await this.request({
1242
- type: "query",
1243
- id,
1244
- name,
1245
- ...args === void 0 ? {} : { args: encodeTaggedValues(args) },
1246
- ...readConcern ? { readConcern } : {}
1247
- });
1269
+ const response = await this.request(namedQueryFrame(this.nextId(), name, args, readConcern));
1248
1270
  return { rows: decodeTaggedValues(response.rows ?? []) };
1249
1271
  }
1250
- /** Runs a registered write by name. */
1272
+ /** Executes a registered write by name. */
1251
1273
  async executeNamed(name, args, writeConcern) {
1252
1274
  await this.ensureConnected();
1253
- const id = this.nextId();
1254
- return this.request({
1255
- type: "execute",
1256
- id,
1257
- name,
1258
- ...args === void 0 ? {} : { args: encodeTaggedValues(args) },
1259
- ...writeConcern ? { writeConcern } : {}
1260
- });
1275
+ return this.request(namedExecuteFrame(this.nextId(), name, args, writeConcern));
1261
1276
  }
1262
- /** Opens a live query on a registered read and delivers its updates to the handlers. */
1277
+ /** Opens a live query on a registered read and passes its updates to the handlers. */
1263
1278
  async liveSubscribe(name, args, handlers, registryDigest) {
1264
1279
  await this.ensureConnected();
1265
1280
  return this.liveQueries.open(this.nextId(), name, args, handlers, registryDigest);
1266
1281
  }
1267
- /** Opens a change subscription on a watched table. */
1282
+ /** Opens a change subscription on a table. */
1268
1283
  async subscribe(table, filter, callback, options) {
1269
1284
  await this.ensureConnected();
1270
1285
  const id = this.nextId();
@@ -1316,10 +1331,11 @@ var WebSocketTransport = class {
1316
1331
  /** @internal */
1317
1332
  async ack(deviceId, seq) {
1318
1333
  await this.ensureConnected();
1334
+ await this.restoreSubscriptions();
1319
1335
  const id = this.nextId();
1320
1336
  return this.request({ type: "ack", id, deviceId, seq: seq.toString() });
1321
1337
  }
1322
- /** Closes the transport and every subscription running on it. */
1338
+ /** Closes the transport and ends every subscription on it. */
1323
1339
  close() {
1324
1340
  this.closed = true;
1325
1341
  this.cancelReconnect();
@@ -1379,6 +1395,9 @@ var WebSocketTransport = class {
1379
1395
  this.pending.rejectAll(this.refusal ?? new RemoteError("CONNECTION_ERROR", "WebSocket disconnected"));
1380
1396
  this.liveQueries.markDisconnected();
1381
1397
  const restorable = this.activeSubscriptions.size + this.liveQueries.size;
1398
+ if (restorable > 0) {
1399
+ this.subscriptionsRestored = false;
1400
+ }
1382
1401
  if (this.autoReconnect && !this.closed && this.refusal === null && restorable > 0) {
1383
1402
  this.scheduleReconnect();
1384
1403
  }
@@ -1392,7 +1411,7 @@ var WebSocketTransport = class {
1392
1411
  if (this.closed) return;
1393
1412
  try {
1394
1413
  await this.ensureConnected();
1395
- await this.resubscribeAll();
1414
+ await this.restoreSubscriptions();
1396
1415
  } catch {
1397
1416
  if (!this.closed && this.refusal === null && this.activeSubscriptions.size + this.liveQueries.size > 0) {
1398
1417
  this.scheduleReconnect();
@@ -1400,7 +1419,15 @@ var WebSocketTransport = class {
1400
1419
  }
1401
1420
  }, this.reconnectInterval);
1402
1421
  }
1422
+ restoreSubscriptions() {
1423
+ if (this.subscriptionsRestored) return Promise.resolve();
1424
+ this.restorePromise ??= this.resubscribeAll().finally(() => {
1425
+ this.restorePromise = null;
1426
+ });
1427
+ return this.restorePromise;
1428
+ }
1403
1429
  async resubscribeAll() {
1430
+ this.subscriptionsRestored = true;
1404
1431
  const entries = [...this.activeSubscriptions.entries()];
1405
1432
  for (const [id, sub] of entries) {
1406
1433
  if (this.closed) break;
@@ -1467,9 +1494,9 @@ var DatabaseClient = class {
1467
1494
  this.settings = resolveTransportSettings(options);
1468
1495
  }
1469
1496
  /**
1470
- * Returns the handle a caller queries and writes one database through, opening it on the first call for that identifier.
1497
+ * Returns the handle that you use to query and write one database, and opens it on the first call for that identifier.
1471
1498
  *
1472
- * @param id - Identifier the server registered the database under.
1499
+ * @param id - The identifier under which the server registered the database.
1473
1500
  * @returns The database handle, which stays open until the caller closes it.
1474
1501
  */
1475
1502
  database(id) {
@@ -1495,7 +1522,7 @@ var DatabaseClient = class {
1495
1522
  );
1496
1523
  }
1497
1524
  /**
1498
- * Closes every database this client opened, which ends their transports and stops their subscriptions.
1525
+ * Closes every database that this client opened, which closes their transports and stops their subscriptions.
1499
1526
  */
1500
1527
  close() {
1501
1528
  this.closed = true;
@@ -0,0 +1,12 @@
1
+ import { SirannonError } from './chunk-KINDFBQP.mjs';
2
+
3
+ // src/core/optional-dependency.ts
4
+ function optionalDependencyError(dependency, loadFailure) {
5
+ const reported = loadFailure instanceof Error ? loadFailure.message : String(loadFailure);
6
+ return new SirannonError(
7
+ `${dependency.neededBy} needs the '${dependency.packageName}' package, which this process could not load. Install it with \`${dependency.installCommand}\`, or fix the failure that the loader reported: ${reported}`,
8
+ dependency.code
9
+ );
10
+ }
11
+
12
+ export { optionalDependencyError };
@@ -1,4 +1,4 @@
1
- import { SirannonError } from './chunk-PBRXXISQ.mjs';
1
+ import { SirannonError } from './chunk-KINDFBQP.mjs';
2
2
 
3
3
  // src/core/driver/synchronous.ts
4
4
  var DEFAULT_SYNCHRONOUS = "normal";
@@ -1,4 +1,4 @@
1
- import { SirannonError } from './chunk-PBRXXISQ.mjs';
1
+ import { SirannonError } from './chunk-KINDFBQP.mjs';
2
2
 
3
3
  // src/core/backup/chain-queries.ts
4
4
  function chainError(message) {