@geodedb/client 1.0.0-alpha.25 → 1.0.2

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/dist/index.js CHANGED
@@ -195,7 +195,7 @@ function defaultConfig() {
195
195
  connectTimeout: 3e4,
196
196
  requestTimeout: 12e4,
197
197
  keepAliveInterval: 1e4,
198
- maxIdleTime: 3e4,
198
+ maxIdleTime: 12e4,
199
199
  tls: true
200
200
  };
201
201
  }
@@ -294,6 +294,10 @@ function parseURLDSN(dsn, cfg, scheme) {
294
294
  if (url.password) {
295
295
  cfg.password = decodeURIComponent(url.password);
296
296
  }
297
+ const urlPath = url.pathname;
298
+ if (urlPath && urlPath !== "/") {
299
+ cfg.graph = urlPath.replace(/^\//, "");
300
+ }
297
301
  applyQueryParams(url.searchParams, cfg);
298
302
  return cfg;
299
303
  }
@@ -454,6 +458,9 @@ function applyQueryParams(params, cfg) {
454
458
  }
455
459
  break;
456
460
  }
461
+ case "graph":
462
+ cfg.graph = value;
463
+ break;
457
464
  }
458
465
  }
459
466
  if (cfg.tlsCert && !cfg.tlsKey || !cfg.tlsCert && cfg.tlsKey) {
@@ -1938,17 +1945,17 @@ function decodeLengthPrefix(data) {
1938
1945
  }
1939
1946
  return data.readUInt32BE(0);
1940
1947
  }
1941
- function buildHelloRequest(username, password, clientName, clientVersion, conformance, tenantId) {
1942
- return {
1943
- hello: {
1944
- username,
1945
- password,
1946
- tenantId,
1947
- clientName,
1948
- clientVersion,
1949
- wantedConformance: conformance
1950
- }
1948
+ function buildHelloRequest(username, password, clientName, clientVersion, conformance, tenantId, graph) {
1949
+ const helloReq = {
1950
+ username,
1951
+ password,
1952
+ clientName,
1953
+ clientVersion,
1954
+ wantedConformance: conformance,
1955
+ ...tenantId ? { tenantId } : {},
1956
+ ...graph ? { graph } : {}
1951
1957
  };
1958
+ return { hello: helloReq };
1952
1959
  }
1953
1960
  function buildExecuteRequest(sessionId, query2, params) {
1954
1961
  const protoParams = [];
@@ -2141,7 +2148,8 @@ var init_grpc_transport = __esm({
2141
2148
  rootCerts = Buffer.from(cfg.tlsCACert);
2142
2149
  }
2143
2150
  credentials2 = grpc.credentials.createSsl(rootCerts, null, null, {
2144
- checkServerIdentity: () => void 0
2151
+ checkServerIdentity: () => void 0,
2152
+ rejectUnauthorized: false
2145
2153
  });
2146
2154
  } else {
2147
2155
  const sslOptions = await buildGrpcSslOptions(cfg);
@@ -2159,6 +2167,11 @@ var init_grpc_transport = __esm({
2159
2167
  "grpc.keepalive_timeout_ms": 5e3,
2160
2168
  "grpc.keepalive_permit_without_calls": 1
2161
2169
  };
2170
+ if (cfg.insecureSkipVerify) {
2171
+ const authority = cfg.serverName ?? "localhost";
2172
+ options["grpc.ssl_target_name_override"] = authority;
2173
+ options["grpc.default_authority"] = authority;
2174
+ }
2162
2175
  transport._client = new protoDescriptor.geode.GeodeService(address, credentials2, options);
2163
2176
  return transport;
2164
2177
  } catch (e) {
@@ -2401,8 +2414,14 @@ var init_grpc_transport = __esm({
2401
2414
  this.resetStreamTimeout(stream, reject, () => {
2402
2415
  resolved = true;
2403
2416
  });
2404
- this.enqueueResponse({ execute: response });
2405
- if (this._pendingResponses.length >= this._backpressureThreshold) {
2417
+ const execResponse = response;
2418
+ this.enqueueResponse({ execute: execResponse });
2419
+ if (execResponse.payload === "page" && execResponse.page?.final || execResponse.payload === "error" || execResponse.payload === "heartbeat") {
2420
+ this.clearStreamTimeout();
2421
+ this._activeStream = null;
2422
+ this._streamComplete = true;
2423
+ }
2424
+ if (this._activeStream === stream && this._pendingResponses.length >= this._backpressureThreshold) {
2406
2425
  this._streamPaused = true;
2407
2426
  stream.pause();
2408
2427
  }
@@ -2413,8 +2432,10 @@ var init_grpc_transport = __esm({
2413
2432
  });
2414
2433
  stream.on("end", () => {
2415
2434
  this.clearStreamTimeout();
2416
- this._activeStream = null;
2417
- this._streamComplete = true;
2435
+ if (this._activeStream === stream) {
2436
+ this._activeStream = null;
2437
+ this._streamComplete = true;
2438
+ }
2418
2439
  if (!resolved) {
2419
2440
  resolved = true;
2420
2441
  resolve2();
@@ -2422,17 +2443,21 @@ var init_grpc_transport = __esm({
2422
2443
  });
2423
2444
  stream.on("error", (error) => {
2424
2445
  this.clearStreamTimeout();
2425
- this._activeStream = null;
2426
- this._streamComplete = true;
2446
+ if (this._activeStream === stream) {
2447
+ this._activeStream = null;
2448
+ this._streamComplete = true;
2449
+ }
2427
2450
  const transportError = new TransportError({
2428
2451
  operation: "execute",
2429
2452
  address: this._address,
2430
2453
  cause: new Error(`gRPC error ${error.code}: ${error.message}`)
2431
2454
  });
2432
- const pendingReads = this._pendingProtoReads;
2433
- this._pendingProtoReads = [];
2434
- for (const p of pendingReads) {
2435
- p.reject(transportError);
2455
+ if (this._activeStream === null || this._streamComplete) {
2456
+ const pendingReads = this._pendingProtoReads;
2457
+ this._pendingProtoReads = [];
2458
+ for (const p of pendingReads) {
2459
+ p.reject(transportError);
2460
+ }
2436
2461
  }
2437
2462
  if (!resolved) {
2438
2463
  resolved = true;
@@ -2461,8 +2486,10 @@ var init_grpc_transport = __esm({
2461
2486
  if (this._streamTimeoutMs <= 0) return;
2462
2487
  this._streamTimeoutTimer = setTimeout(() => {
2463
2488
  this._streamTimeoutTimer = null;
2464
- this._activeStream = null;
2465
- this._streamComplete = true;
2489
+ if (this._activeStream === stream) {
2490
+ this._activeStream = null;
2491
+ this._streamComplete = true;
2492
+ }
2466
2493
  stream.cancel();
2467
2494
  const timeoutError = new TransportError({
2468
2495
  operation: "execute",
@@ -2471,10 +2498,12 @@ var init_grpc_transport = __esm({
2471
2498
  `gRPC stream timed out: no data received within ${this._streamTimeoutMs}ms`
2472
2499
  )
2473
2500
  });
2474
- const pendingReads = this._pendingProtoReads;
2475
- this._pendingProtoReads = [];
2476
- for (const p of pendingReads) {
2477
- p.reject(timeoutError);
2501
+ if (this._activeStream === null || this._streamComplete) {
2502
+ const pendingReads = this._pendingProtoReads;
2503
+ this._pendingProtoReads = [];
2504
+ for (const p of pendingReads) {
2505
+ p.reject(timeoutError);
2506
+ }
2478
2507
  }
2479
2508
  markResolved();
2480
2509
  reject(timeoutError);
@@ -2589,6 +2618,7 @@ var init_transport = __esm({
2589
2618
  _maxMessageSize;
2590
2619
  _maxBufferBytes;
2591
2620
  _pendingProtoReads = [];
2621
+ _pendingResponses = [];
2592
2622
  constructor(address, maxMessageSize = DEFAULT_MAX_MESSAGE_SIZE, maxBufferBytes = DEFAULT_MAX_BUFFER_BYTES) {
2593
2623
  super(address);
2594
2624
  this._maxMessageSize = maxMessageSize;
@@ -2650,7 +2680,7 @@ var init_transport = __esm({
2650
2680
  {
2651
2681
  host,
2652
2682
  port,
2653
- serverName: cfg.serverName ?? host,
2683
+ serverName: cfg.serverName ?? (cfg.insecureSkipVerify ? "localhost" : host),
2654
2684
  crypto: cryptoOps,
2655
2685
  config
2656
2686
  },
@@ -2770,6 +2800,8 @@ var init_transport = __esm({
2770
2800
  const pending = this._pendingProtoReads.shift();
2771
2801
  if (pending) {
2772
2802
  pending.resolve(msg);
2803
+ } else {
2804
+ this._pendingResponses.push(msg);
2773
2805
  }
2774
2806
  } catch (err) {
2775
2807
  const pending = this._pendingProtoReads.shift();
@@ -2813,8 +2845,11 @@ var init_transport = __esm({
2813
2845
  try {
2814
2846
  const stream = this._stream;
2815
2847
  const writer = stream.writable.getWriter();
2816
- await writer.write(new Uint8Array(data));
2817
- writer.releaseLock();
2848
+ try {
2849
+ await writer.write(new Uint8Array(data));
2850
+ } finally {
2851
+ writer.releaseLock();
2852
+ }
2818
2853
  } catch (e) {
2819
2854
  throw new TransportError({
2820
2855
  operation: "sendProto",
@@ -2831,6 +2866,10 @@ var init_transport = __esm({
2831
2866
  if (signal?.aborted) {
2832
2867
  throw new TransportError({ operation: "receiveProto", cause: new Error("Aborted") });
2833
2868
  }
2869
+ const queued = this._pendingResponses.shift();
2870
+ if (queued) {
2871
+ return queued;
2872
+ }
2834
2873
  return new Promise((resolve2, reject) => {
2835
2874
  let onAbort = null;
2836
2875
  const pendingRead = {
@@ -2867,6 +2906,7 @@ var init_transport = __esm({
2867
2906
  pending.reject(ErrClosed());
2868
2907
  }
2869
2908
  this._pendingProtoReads = [];
2909
+ this._pendingResponses = [];
2870
2910
  this._chunks = [];
2871
2911
  this._totalLength = 0;
2872
2912
  if (this._client) {
@@ -4227,6 +4267,10 @@ var Transaction = class {
4227
4267
  }
4228
4268
  /**
4229
4269
  * Create a savepoint.
4270
+ *
4271
+ * Savepoints are only supported over the QUIC transport. Over gRPC this
4272
+ * rejects with a {@link DriverError} (statusClass `58000`) directing callers
4273
+ * to use `quic://`.
4230
4274
  */
4231
4275
  async savepoint(name, signal) {
4232
4276
  this.checkDone();
@@ -4235,6 +4279,10 @@ var Transaction = class {
4235
4279
  }
4236
4280
  /**
4237
4281
  * Rollback to a savepoint.
4282
+ *
4283
+ * Savepoints are only supported over the QUIC transport. Over gRPC this
4284
+ * rejects with a {@link DriverError} (statusClass `58000`) directing callers
4285
+ * to use `quic://`.
4238
4286
  */
4239
4287
  async rollbackTo(name, signal) {
4240
4288
  this.checkDone();
@@ -4655,7 +4703,10 @@ var Connection = class _Connection {
4655
4703
  this._config.password ?? "",
4656
4704
  this._config.helloName,
4657
4705
  this._config.helloVersion,
4658
- this._config.conformance
4706
+ this._config.conformance,
4707
+ void 0,
4708
+ // tenantId
4709
+ this._config.graph
4659
4710
  );
4660
4711
  await this._sendWithTimeout(msg);
4661
4712
  const response = await this._receiveWithTimeout();
@@ -4723,9 +4774,8 @@ var Connection = class _Connection {
4723
4774
  let isFinal = false;
4724
4775
  let isOrdered = false;
4725
4776
  let orderKeys = [];
4726
- const inlineResponse = await this._tryReceiveInline(signal);
4727
- if (inlineResponse?.execute) {
4728
- const inlineExec = inlineResponse.execute;
4777
+ const inlineExec = await this._readInlineExecute(signal);
4778
+ if (inlineExec) {
4729
4779
  if (isErrorResponse(inlineExec)) {
4730
4780
  this._state = this._inTransaction ? "in_transaction" : "idle";
4731
4781
  throw protoErrorToDriverError(inlineExec, inlineExec.status?.statusClass);
@@ -4744,9 +4794,12 @@ var Connection = class _Connection {
4744
4794
  validatePageSize(pageSize);
4745
4795
  const pullMsg = buildPullRequest(this._requestId, pageSize, this._sessionId);
4746
4796
  await this._sendWithTimeout(pullMsg, signal);
4747
- const pullResponse = await this._receiveWithTimeout(signal);
4748
- const pullExec = pullResponse.pull?.response ?? pullResponse.execute;
4749
- if (pullExec) {
4797
+ while (true) {
4798
+ const pullResponse = await this._receiveWithTimeout(signal);
4799
+ const pullExec = pullResponse.pull?.response ?? pullResponse.execute;
4800
+ if (!pullExec) {
4801
+ break;
4802
+ }
4750
4803
  if (isErrorResponse(pullExec)) {
4751
4804
  this._state = this._inTransaction ? "in_transaction" : "idle";
4752
4805
  throw protoErrorToDriverError(pullExec, pullExec.status?.statusClass);
@@ -4757,6 +4810,10 @@ var Connection = class _Connection {
4757
4810
  isFinal = page.final;
4758
4811
  isOrdered = page.ordered;
4759
4812
  orderKeys = page.orderKeys;
4813
+ break;
4814
+ }
4815
+ if (pullExec.heartbeat) {
4816
+ break;
4760
4817
  }
4761
4818
  }
4762
4819
  }
@@ -4810,15 +4867,12 @@ var Connection = class _Connection {
4810
4867
  }
4811
4868
  if (isSchemaResponse(execResp)) {
4812
4869
  this._columns = execResp.schema.columns;
4813
- const inlineResponse = await this._tryReceiveInline(signal);
4814
- if (inlineResponse?.execute) {
4815
- if (isErrorResponse(inlineResponse.execute)) {
4816
- throw protoErrorToDriverError(
4817
- inlineResponse.execute,
4818
- inlineResponse.execute.status?.statusClass
4819
- );
4870
+ const inlineExec = await this._readInlineExecute(signal);
4871
+ if (inlineExec) {
4872
+ if (isErrorResponse(inlineExec)) {
4873
+ throw protoErrorToDriverError(inlineExec, inlineExec.status?.statusClass);
4820
4874
  }
4821
- if (isDataPageResponse(inlineResponse.execute) && !inlineResponse.execute.page.final) {
4875
+ if (isDataPageResponse(inlineExec) && !inlineExec.page.final) {
4822
4876
  await this._drainRemainingPages(signal);
4823
4877
  }
4824
4878
  }
@@ -4833,22 +4887,26 @@ var Connection = class _Connection {
4833
4887
  this._requestId++;
4834
4888
  const pullMsg = buildPullRequest(this._requestId, pageSize, this._sessionId);
4835
4889
  await this._sendWithTimeout(pullMsg, signal);
4836
- const response = await this._receiveWithTimeout(signal);
4837
- const execResp = response.pull?.response ?? response.execute;
4838
- if (!execResp) {
4839
- return { rows: [], final: true };
4840
- }
4841
- if (isErrorResponse(execResp)) {
4842
- throw protoErrorToDriverError(execResp, execResp.status?.statusClass);
4843
- }
4844
- if (isDataPageResponse(execResp)) {
4845
- const page = execResp.page;
4846
- return {
4847
- rows: dataPageToRows(page, this._columns),
4848
- final: page.final
4849
- };
4890
+ while (true) {
4891
+ const response = await this._receiveWithTimeout(signal);
4892
+ const execResp = response.pull?.response ?? response.execute;
4893
+ if (!execResp) {
4894
+ return { rows: [], final: true };
4895
+ }
4896
+ if (isErrorResponse(execResp)) {
4897
+ throw protoErrorToDriverError(execResp, execResp.status?.statusClass);
4898
+ }
4899
+ if (isDataPageResponse(execResp)) {
4900
+ const page = execResp.page;
4901
+ return {
4902
+ rows: dataPageToRows(page, this._columns),
4903
+ final: page.final
4904
+ };
4905
+ }
4906
+ if (execResp.heartbeat) {
4907
+ return { rows: [], final: true };
4908
+ }
4850
4909
  }
4851
- return { rows: [], final: true };
4852
4910
  }
4853
4911
  /** Try to receive an inline response with short timeout. */
4854
4912
  async _tryReceiveInline(signal) {
@@ -4868,6 +4926,22 @@ var Connection = class _Connection {
4868
4926
  cleanup();
4869
4927
  }
4870
4928
  }
4929
+ /** Read inline execute responses until a page, error, heartbeat, or timeout arrives. */
4930
+ async _readInlineExecute(signal) {
4931
+ while (true) {
4932
+ const inlineResponse = await this._tryReceiveInline(signal);
4933
+ const inlineExec = inlineResponse?.execute;
4934
+ if (!inlineExec) {
4935
+ return null;
4936
+ }
4937
+ if (isErrorResponse(inlineExec) || isDataPageResponse(inlineExec)) {
4938
+ return inlineExec;
4939
+ }
4940
+ if (inlineExec.heartbeat) {
4941
+ return null;
4942
+ }
4943
+ }
4944
+ }
4871
4945
  /** Drain remaining data pages until final=true to prevent query corruption (QUAL-T7). */
4872
4946
  async _drainRemainingPages(signal) {
4873
4947
  let done = false;
@@ -4886,7 +4960,7 @@ var Connection = class _Connection {
4886
4960
  }
4887
4961
  if (isDataPageResponse(pullExec)) {
4888
4962
  done = pullExec.page.final;
4889
- } else {
4963
+ } else if (pullExec.heartbeat) {
4890
4964
  done = true;
4891
4965
  }
4892
4966
  }
@@ -5080,6 +5154,9 @@ var Connection = class _Connection {
5080
5154
  const { signal: timeoutSignal, cleanup } = this._withRequestTimeout(signal);
5081
5155
  try {
5082
5156
  await this._transport.sendProto(msg, timeoutSignal);
5157
+ } catch (e) {
5158
+ await this._closeOnTransportError(e);
5159
+ throw e;
5083
5160
  } finally {
5084
5161
  cleanup();
5085
5162
  }
@@ -5089,6 +5166,9 @@ var Connection = class _Connection {
5089
5166
  const { signal: timeoutSignal, cleanup } = this._withRequestTimeout(signal);
5090
5167
  try {
5091
5168
  return await this._transport.receiveProto(timeoutSignal);
5169
+ } catch (e) {
5170
+ await this._closeOnTransportError(e);
5171
+ throw e;
5092
5172
  } finally {
5093
5173
  cleanup();
5094
5174
  }
@@ -5097,6 +5177,24 @@ var Connection = class _Connection {
5097
5177
  _withRequestTimeout(signal) {
5098
5178
  return withAbortTimeout(signal, this._config.requestTimeout);
5099
5179
  }
5180
+ async _closeOnTransportError(err) {
5181
+ if (!(err instanceof TransportError) || err.cause?.message === "Aborted") {
5182
+ return;
5183
+ }
5184
+ if (this._state === "closed") {
5185
+ return;
5186
+ }
5187
+ this._state = "closed";
5188
+ this._inTransaction = false;
5189
+ if (this._activeResult) {
5190
+ this._activeResult._close();
5191
+ this._activeResult = null;
5192
+ }
5193
+ try {
5194
+ await this._transport.close();
5195
+ } catch {
5196
+ }
5197
+ }
5100
5198
  };
5101
5199
 
5102
5200
  // src/pool.ts
@@ -5165,6 +5263,7 @@ var RateLimiter = class {
5165
5263
  var ConnectionPool = class _ConnectionPool {
5166
5264
  _config;
5167
5265
  _connections = [];
5266
+ _pendingConnections = 0;
5168
5267
  _waitQueue = [];
5169
5268
  _closed = false;
5170
5269
  _maintenanceInterval;
@@ -5317,6 +5416,12 @@ var ConnectionPool = class _ConnectionPool {
5317
5416
  }
5318
5417
  } catch {
5319
5418
  await this.removeConnection(pooledConn);
5419
+ await this.fulfillWaiters();
5420
+ return;
5421
+ }
5422
+ if (conn.isClosed) {
5423
+ await this.removeConnection(pooledConn);
5424
+ await this.fulfillWaiters();
5320
5425
  return;
5321
5426
  }
5322
5427
  pooledConn.inUse = false;
@@ -5324,6 +5429,7 @@ var ConnectionPool = class _ConnectionPool {
5324
5429
  const waiter = this._waitQueue.shift();
5325
5430
  if (waiter) {
5326
5431
  pooledConn.inUse = true;
5432
+ pooledConn.lastUsedAt = Date.now();
5327
5433
  waiter.resolve(conn);
5328
5434
  }
5329
5435
  }
@@ -5397,18 +5503,19 @@ var ConnectionPool = class _ConnectionPool {
5397
5503
  * Add a new connection to the pool with rate limiting and exponential backoff.
5398
5504
  */
5399
5505
  async addConnection() {
5400
- if (this._connections.length >= this._maxConnections) {
5506
+ if (this._connections.length + this._pendingConnections >= this._maxConnections) {
5401
5507
  return;
5402
5508
  }
5403
- if (!this._rateLimiter.isAllowed()) {
5404
- throw new TransportError({
5405
- operation: "connect",
5406
- cause: new Error("Connection rate limit exceeded")
5407
- });
5408
- }
5409
- await this._rateLimiter.waitForBackoff();
5410
- this._rateLimiter.recordAttempt();
5509
+ this._pendingConnections++;
5411
5510
  try {
5511
+ if (!this._rateLimiter.isAllowed()) {
5512
+ throw new TransportError({
5513
+ operation: "connect",
5514
+ cause: new Error("Connection rate limit exceeded")
5515
+ });
5516
+ }
5517
+ await this._rateLimiter.waitForBackoff();
5518
+ this._rateLimiter.recordAttempt();
5412
5519
  const conn = await Connection.connect(this._config);
5413
5520
  this._rateLimiter.recordSuccess();
5414
5521
  this._connections.push({
@@ -5420,6 +5527,8 @@ var ConnectionPool = class _ConnectionPool {
5420
5527
  } catch (e) {
5421
5528
  this._rateLimiter.recordFailure();
5422
5529
  throw e;
5530
+ } finally {
5531
+ this._pendingConnections--;
5423
5532
  }
5424
5533
  }
5425
5534
  /**
@@ -5435,6 +5544,26 @@ var ConnectionPool = class _ConnectionPool {
5435
5544
  } catch {
5436
5545
  }
5437
5546
  }
5547
+ async fulfillWaiters() {
5548
+ while (this._waitQueue.length > 0) {
5549
+ const available = this._connections.find((c) => !c.inUse && !c.connection.isClosed);
5550
+ if (available) {
5551
+ available.inUse = true;
5552
+ available.lastUsedAt = Date.now();
5553
+ const waiter = this._waitQueue.shift();
5554
+ waiter?.resolve(available.connection);
5555
+ continue;
5556
+ }
5557
+ if (this._connections.length + this._pendingConnections >= this._maxConnections) {
5558
+ return;
5559
+ }
5560
+ try {
5561
+ await this.addConnection();
5562
+ } catch {
5563
+ return;
5564
+ }
5565
+ }
5566
+ }
5438
5567
  /**
5439
5568
  * Perform pool maintenance.
5440
5569
  */
@@ -5458,7 +5587,7 @@ var ConnectionPool = class _ConnectionPool {
5458
5587
  });
5459
5588
  }
5460
5589
  const available = this._connections.filter((c) => !c.connection.isClosed).length;
5461
- const toCreate = this._minConnections - available;
5590
+ const toCreate = this._minConnections - (available + this._pendingConnections);
5462
5591
  for (let i = 0; i < toCreate; i++) {
5463
5592
  this.addConnection().catch(() => {
5464
5593
  });
@@ -5947,6 +6076,53 @@ async function createClientWithConfig(config, options) {
5947
6076
  init_config();
5948
6077
  await init_types();
5949
6078
  init_errors();
6079
+
6080
+ // src/retry.ts
6081
+ init_errors();
6082
+ var DEFAULT_MAX_ATTEMPTS = 3;
6083
+ var DEFAULT_INITIAL_BACKOFF_MS = 1e3;
6084
+ var DEFAULT_MAX_BACKOFF_MS = 3e4;
6085
+ var DEFAULT_MULTIPLIER = 2;
6086
+ function defaultRetryPolicy() {
6087
+ return {
6088
+ maxAttempts: DEFAULT_MAX_ATTEMPTS,
6089
+ initialBackoffMs: DEFAULT_INITIAL_BACKOFF_MS,
6090
+ maxBackoffMs: DEFAULT_MAX_BACKOFF_MS,
6091
+ multiplier: DEFAULT_MULTIPLIER
6092
+ };
6093
+ }
6094
+ function backoffMs(policy, attempt) {
6095
+ const a = attempt < 1 ? 1 : attempt;
6096
+ const d = policy.initialBackoffMs * Math.pow(policy.multiplier, a - 1);
6097
+ return d > policy.maxBackoffMs ? policy.maxBackoffMs : d;
6098
+ }
6099
+ function sleep(ms) {
6100
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
6101
+ }
6102
+ async function withRetry(fn, policy = defaultRetryPolicy()) {
6103
+ const maxAttempts = policy.maxAttempts < 1 ? 1 : policy.maxAttempts;
6104
+ let lastErr;
6105
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
6106
+ try {
6107
+ return await fn();
6108
+ } catch (e) {
6109
+ lastErr = e;
6110
+ if (!isRetryableError(e)) {
6111
+ throw e;
6112
+ }
6113
+ if (attempt === maxAttempts) {
6114
+ break;
6115
+ }
6116
+ const delay = backoffMs(policy, attempt);
6117
+ if (delay > 0) {
6118
+ await sleep(delay);
6119
+ }
6120
+ }
6121
+ }
6122
+ throw lastErr;
6123
+ }
6124
+
6125
+ // src/index.ts
5950
6126
  await init_transport();
5951
6127
  await init_grpc_transport();
5952
6128
  init_validate();
@@ -6689,6 +6865,6 @@ await init_batch();
6689
6865
  init_auth();
6690
6866
  await init_proto();
6691
6867
 
6692
- export { AuthClient, BaseTransport, ConfigError, Connection, ConnectionPool, DEFAULT_CONFORMANCE, DEFAULT_GRPC_PORT, DEFAULT_HELLO_NAME, DEFAULT_HELLO_VERSION, DEFAULT_PAGE_SIZE, DEFAULT_PORT, DriverError, ERR_BAD_CONN_MESSAGE, ERR_CLOSED_MESSAGE, ERR_NO_TX_MESSAGE, ERR_QUERY_IN_PROGRESS_MESSAGE, ERR_ROWS_CLOSED_MESSAGE, ERR_TX_DONE_MESSAGE, ERR_TX_IN_PROGRESS_MESSAGE, EdgePatternBuilder, ErrBadConn, ErrClosed, ErrNoTx, ErrQueryInProgress, ErrRowsClosed, ErrTxDone, ErrTxInProgress, GQLValue, GeodeClient, GrpcTransport, MAX_PAGE_SIZE, MAX_QUERY_LENGTH, MockTransport, NodePatternBuilder, PatternBuilder, PredicateBuilder, PreparedStatement, QueryBuilder, QueryResult, QueryResultIterator, QuicTransport, QuicTransport as QuicheTransport, SUPPORTED_SCHEMES, SecurityError, StateError, StatusClass, Transaction, TransportError, batch, batchAll, batchFirst, batchMap, batchParallel, buildBeginRequest, buildCommitRequest, buildExecuteRequest, buildHelloRequest, buildPingRequest, buildPullRequest, buildRollbackRequest, buildRollbackToRequest, buildSavepointRequest, buildTLSConfig, cloneConfig, createAuthClient, createClient, createClientWithConfig, createTransport, decodeLengthPrefix, decodeQuicServerMessage, defaultConfig, edge, encodeQuicClientMessage, encodeWithLengthPrefix, ensureProtoInitialized, explain, extractParameters, formatPlan, formatProfile, fromJSON, getAddress, getProtoPath, initProtoSync, isDriverError, isGeodeError, isRetryableError, isSentinelError, jsToProtoValue, node, parseDSN, parseGQLType, parseRow, pattern, predicate, prepare, profile, protoValueToJS, query, redactConfig, redactDSN, rowToObject, rowToRecord, sanitizeForLog, validateConfig, validateHostname, validatePageSize, validateParamName, validateParamValue, validatePort, validateQuery, validateSavepointName, withTransaction };
6868
+ export { AuthClient, BaseTransport, ConfigError, Connection, ConnectionPool, DEFAULT_CONFORMANCE, DEFAULT_GRPC_PORT, DEFAULT_HELLO_NAME, DEFAULT_HELLO_VERSION, DEFAULT_PAGE_SIZE, DEFAULT_PORT, DriverError, ERR_BAD_CONN_MESSAGE, ERR_CLOSED_MESSAGE, ERR_NO_TX_MESSAGE, ERR_QUERY_IN_PROGRESS_MESSAGE, ERR_ROWS_CLOSED_MESSAGE, ERR_TX_DONE_MESSAGE, ERR_TX_IN_PROGRESS_MESSAGE, EdgePatternBuilder, ErrBadConn, ErrClosed, ErrNoTx, ErrQueryInProgress, ErrRowsClosed, ErrTxDone, ErrTxInProgress, GQLValue, GeodeClient, GrpcTransport, MAX_PAGE_SIZE, MAX_QUERY_LENGTH, MockTransport, NodePatternBuilder, PatternBuilder, PredicateBuilder, PreparedStatement, QueryBuilder, QueryResult, QueryResultIterator, QuicTransport, QuicTransport as QuicheTransport, SUPPORTED_SCHEMES, SecurityError, StateError, StatusClass, Transaction, TransportError, batch, batchAll, batchFirst, batchMap, batchParallel, buildBeginRequest, buildCommitRequest, buildExecuteRequest, buildHelloRequest, buildPingRequest, buildPullRequest, buildRollbackRequest, buildRollbackToRequest, buildSavepointRequest, buildTLSConfig, cloneConfig, createAuthClient, createClient, createClientWithConfig, createTransport, decodeLengthPrefix, decodeQuicServerMessage, defaultConfig, defaultRetryPolicy, edge, encodeQuicClientMessage, encodeWithLengthPrefix, ensureProtoInitialized, explain, extractParameters, formatPlan, formatProfile, fromJSON, getAddress, getProtoPath, initProtoSync, isDriverError, isGeodeError, isRetryableError, isSentinelError, jsToProtoValue, node, parseDSN, parseGQLType, parseRow, pattern, predicate, prepare, profile, protoValueToJS, query, redactConfig, redactDSN, rowToObject, rowToRecord, sanitizeForLog, validateConfig, validateHostname, validatePageSize, validateParamName, validateParamValue, validatePort, validateQuery, validateSavepointName, withRetry, withTransaction };
6693
6869
  //# sourceMappingURL=index.js.map
6694
6870
  //# sourceMappingURL=index.js.map