@ferricstore/ferricstore 0.11.9 → 0.11.11

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
@@ -1456,6 +1456,7 @@ var neverAutoBatchCommandPrefixes = /* @__PURE__ */ new Set([
1456
1456
  "BLPOP",
1457
1457
  "BRPOP",
1458
1458
  "BRPOPLPUSH",
1459
+ "BZMPOP",
1459
1460
  "BZPOPMAX",
1460
1461
  "BZPOPMIN",
1461
1462
  "CLIENT",
@@ -1567,6 +1568,9 @@ var connectionBlockingCommands = /* @__PURE__ */ new Set([
1567
1568
  "BLPOP",
1568
1569
  "BRPOP",
1569
1570
  "BRPOPLPUSH",
1571
+ "BZMPOP",
1572
+ "BZPOPMAX",
1573
+ "BZPOPMIN",
1570
1574
  "XREAD",
1571
1575
  "XREADGROUP"
1572
1576
  ]);
@@ -2435,8 +2439,10 @@ function serverBlockMetadata(args) {
2435
2439
  serverBlockMs = blockDurationMs(args[3], 1e3);
2436
2440
  } else if (command === "BLMOVE" && args.length >= 6) {
2437
2441
  serverBlockMs = blockDurationMs(args[args.length - 1], 1e3);
2438
- } else if (command === "BLMPOP" && args.length >= 2) {
2442
+ } else if ((command === "BLMPOP" || command === "BZMPOP") && args.length >= 2) {
2439
2443
  serverBlockMs = blockDurationMs(args[1], 1e3);
2444
+ } else if ((command === "BZPOPMAX" || command === "BZPOPMIN") && args.length >= 3) {
2445
+ serverBlockMs = blockDurationMs(args[args.length - 1], 1e3);
2440
2446
  } else if (command === "XREAD" || command === "XREADGROUP") {
2441
2447
  serverBlockMs = optionBlockDurationMs(args, ["BLOCK"], "STREAMS");
2442
2448
  } else if (command === "WAIT" && args.length === 3) {
@@ -7496,6 +7502,24 @@ async function executeIndividually(host, commands, laneId, options) {
7496
7502
  }, commands, options);
7497
7503
  }
7498
7504
 
7505
+ // src/server-response-timeout.ts
7506
+ function serverResponseTimeoutMs(requestTimeoutMs, serverBlockMs) {
7507
+ if (serverBlockMs == null) return requestTimeoutMs;
7508
+ if (serverBlockMs === 0) return void 0;
7509
+ return saturatingAdd(requestTimeoutMs, serverBlockMs);
7510
+ }
7511
+ function combinedServerBlockMs(values) {
7512
+ let total;
7513
+ for (const value of values) {
7514
+ if (value === 0) return 0;
7515
+ if (value != null) total = saturatingAdd(total ?? 0, value);
7516
+ }
7517
+ return total;
7518
+ }
7519
+ function saturatingAdd(left, right) {
7520
+ return Math.min(Number.MAX_SAFE_INTEGER, left + right);
7521
+ }
7522
+
7499
7523
  // src/native-pending-timeout.ts
7500
7524
  function timeoutNativePendingRequest(operations, requestId, timeoutMs) {
7501
7525
  const pending = operations.getPending(requestId);
@@ -7524,10 +7548,7 @@ function timeoutNativePendingRequest(operations, requestId, timeoutMs) {
7524
7548
  pending.reject(new RequestTimeoutError(timeoutMs, "possibly_sent"));
7525
7549
  }
7526
7550
  function nativeResponseTimeoutMs(command, requestTimeoutMs) {
7527
- const blockMs = command.serverBlockMs;
7528
- if (blockMs == null) return requestTimeoutMs;
7529
- if (blockMs === 0) return void 0;
7530
- return Math.min(Number.MAX_SAFE_INTEGER, requestTimeoutMs + blockMs);
7551
+ return serverResponseTimeoutMs(requestTimeoutMs, command.serverBlockMs);
7531
7552
  }
7532
7553
 
7533
7554
  // src/native-chunk-assembler.ts
@@ -8555,12 +8576,14 @@ var NativeAdapter = class _NativeAdapter {
8555
8576
  };
8556
8577
 
8557
8578
  // src/http-command-policy.ts
8579
+ import { Buffer as Buffer33 } from "buffer";
8558
8580
  var nativeOnlyCommands = /* @__PURE__ */ new Set([
8559
8581
  "AUTH",
8560
8582
  "BACKPRESSURE",
8561
8583
  "CLIENT",
8562
8584
  "CLIENT.INFO",
8563
8585
  "CLIENT.SETNAME",
8586
+ "COMMAND_EXEC",
8564
8587
  "EVENT",
8565
8588
  "GOAWAY",
8566
8589
  "HELLO",
@@ -8576,84 +8599,139 @@ var nativeOnlyCommands = /* @__PURE__ */ new Set([
8576
8599
  "WINDOW_UPDATE"
8577
8600
  ]);
8578
8601
  var sessionOnlyCommands = /* @__PURE__ */ new Set([
8602
+ "ASKING",
8579
8603
  "AUTH",
8580
- "BLMOVE",
8581
- "BLMPOP",
8582
- "BLPOP",
8583
- "BRPOP",
8584
8604
  "CLIENT",
8585
8605
  "DISCARD",
8586
8606
  "EXEC",
8607
+ "FETCH_OR_COMPUTE",
8608
+ "FETCH_OR_COMPUTE_ERROR",
8609
+ "FETCH_OR_COMPUTE_RESULT",
8587
8610
  "HELLO",
8611
+ "MONITOR",
8588
8612
  "MULTI",
8589
8613
  "PSUBSCRIBE",
8614
+ "PSYNC",
8590
8615
  "PUNSUBSCRIBE",
8591
8616
  "QUIT",
8617
+ "READONLY",
8618
+ "READWRITE",
8619
+ "REPLCONF",
8620
+ "RESET",
8621
+ "SANDBOX",
8592
8622
  "SELECT",
8623
+ "SSUBSCRIBE",
8593
8624
  "SUBSCRIBE",
8625
+ "SUNSUBSCRIBE",
8626
+ "SYNC",
8594
8627
  "UNSUBSCRIBE",
8595
8628
  "UNWATCH",
8596
- "WATCH",
8597
- "XREAD",
8598
- "XREADGROUP"
8629
+ "WATCH"
8599
8630
  ]);
8600
8631
  function httpCommandDisposition(name) {
8601
8632
  const normalized = name.toUpperCase();
8602
8633
  return nativeOnlyCommands.has(normalized) || sessionOnlyCommands.has(normalized) ? "native_only" : "supported";
8603
8634
  }
8604
8635
  function assertHTTPCommandSupported(name) {
8605
- if (typeof name !== "string" || name === "") throw new TypeError("HTTP command must have a name");
8606
- if (sessionOnlyCommands.has(name.toUpperCase())) {
8607
- throw new Error(`${name.toUpperCase()} requires a persistent native TCP session`);
8636
+ const normalized = normalizedCommandName(name);
8637
+ if (normalized == null || normalized === "") throw new TypeError("HTTP command must have a name");
8638
+ if (sessionOnlyCommands.has(normalized)) {
8639
+ throw new InvalidCommandError(`${normalized} requires a persistent native TCP session`);
8640
+ }
8641
+ if (nativeOnlyCommands.has(normalized)) {
8642
+ throw new InvalidCommandError(`${normalized} is a native TCP transport control command`);
8608
8643
  }
8609
8644
  }
8645
+ function normalizedCommandName(value) {
8646
+ if (typeof value === "string") return value.toUpperCase();
8647
+ if (Buffer33.isBuffer(value) || value instanceof Uint8Array) {
8648
+ return Buffer33.from(value).toString("utf8").toUpperCase();
8649
+ }
8650
+ return void 0;
8651
+ }
8610
8652
 
8611
8653
  // src/http-envelope.ts
8612
- import { Buffer as Buffer33 } from "buffer";
8654
+ import { Buffer as Buffer34 } from "buffer";
8613
8655
  var encoding = "ferricstore-json-v1";
8614
8656
  var bytesMarker = "$ferricstore_bytes";
8615
8657
  var mapMarker = "$ferricstore_map";
8616
8658
  var maxDepth = 64;
8617
- function encodeHTTPCommands(commands) {
8618
- return Buffer33.from(JSON.stringify({
8659
+ var integerJSON = /^-?(?:0|[1-9][0-9]*)$/u;
8660
+ var bytesMarkerBaseBytes = Buffer34.byteLength(bytesMarker) + 7;
8661
+ var mapMarkerBaseBytes = Buffer34.byteLength(mapMarker) + 7;
8662
+ function encodeHTTPCommands(commands, maxBytes = Number.MAX_SAFE_INTEGER) {
8663
+ const budget = { remaining: maxBytes };
8664
+ return Buffer34.from(JSON.stringify({
8619
8665
  encoding,
8620
- commands: commands.map((command) => encodeValue(command, 0))
8666
+ commands: commands.map((command) => encodeValue(command, 0, budget))
8621
8667
  }));
8622
8668
  }
8623
8669
  function decodeHTTPEnvelope(source) {
8624
8670
  let parsed;
8625
8671
  try {
8626
- parsed = JSON.parse(source.toString("utf8"));
8672
+ parsed = JSON.parse(source.toString("utf8"), preserveIntegerPrecision);
8627
8673
  } catch (error) {
8628
8674
  throw new TypeError("invalid HTTP command response JSON", { cause: error });
8629
8675
  }
8630
8676
  if (!isRecord(parsed)) throw new TypeError("HTTP command response must be an object");
8631
8677
  return decodePlainRecord(parsed, 0);
8632
8678
  }
8633
- function encodeValue(value, depth) {
8679
+ function preserveIntegerPrecision(_key, value, context) {
8680
+ if (typeof value !== "number" || Number.isSafeInteger(value) || !Number.isInteger(value)) {
8681
+ return value;
8682
+ }
8683
+ const literal = context?.source;
8684
+ return literal != null && integerJSON.test(literal) ? BigInt(literal) : value;
8685
+ }
8686
+ function encodeValue(value, depth, budget) {
8634
8687
  if (depth > maxDepth) throw new TypeError("HTTP command value exceeds maximum depth");
8635
- if (value == null || typeof value === "string" || typeof value === "boolean") return value;
8636
- if (Buffer33.isBuffer(value) || value instanceof Uint8Array) {
8637
- return { [bytesMarker]: Buffer33.from(value).toString("base64") };
8688
+ if (value == null) {
8689
+ consumeBudget(budget, 1);
8690
+ return value;
8691
+ }
8692
+ if (typeof value === "string") {
8693
+ consumeBudget(budget, Buffer34.byteLength(value) + 2);
8694
+ return value;
8695
+ }
8696
+ if (typeof value === "boolean") {
8697
+ consumeBudget(budget, 1);
8698
+ return value;
8699
+ }
8700
+ if (Buffer34.isBuffer(value) || value instanceof Uint8Array) {
8701
+ consumeBudget(budget, bytesMarkerBaseBytes + 4 * Math.ceil(value.byteLength / 3));
8702
+ return { [bytesMarker]: Buffer34.from(value).toString("base64") };
8638
8703
  }
8639
8704
  if (typeof value === "number") {
8640
8705
  if (!Number.isFinite(value)) throw new TypeError("HTTP command numbers must be finite");
8706
+ consumeBudget(budget, 1);
8641
8707
  return value;
8642
8708
  }
8643
8709
  if (typeof value === "bigint") {
8644
- return value >= BigInt(Number.MIN_SAFE_INTEGER) && value <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(value) : value.toString();
8710
+ const encoded = value >= BigInt(Number.MIN_SAFE_INTEGER) && value <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(value) : value.toString();
8711
+ consumeBudget(budget, typeof encoded === "number" ? 1 : Buffer34.byteLength(encoded) + 2);
8712
+ return encoded;
8713
+ }
8714
+ if (Array.isArray(value)) {
8715
+ consumeBudget(budget, 2 + Math.max(0, value.length - 1));
8716
+ return denseArray(value, depth + 1, (item, itemDepth) => encodeValue(item, itemDepth, budget));
8645
8717
  }
8646
- if (Array.isArray(value)) return denseArray(value, depth + 1, encodeValue);
8647
8718
  if (value instanceof Map) {
8648
- return { [mapMarker]: [...value.entries()].map(([key, item]) => [
8649
- encodeValue(key, depth + 1),
8650
- encodeValue(item, depth + 1)
8651
- ]) };
8719
+ consumeBudget(budget, mapMarkerBaseBytes + value.size);
8720
+ const pairs = [];
8721
+ for (const [key, item] of value.entries()) {
8722
+ pairs.push([
8723
+ encodeValue(key, depth + 1, budget),
8724
+ encodeValue(item, depth + 1, budget)
8725
+ ]);
8726
+ }
8727
+ return { [mapMarker]: pairs };
8652
8728
  }
8653
8729
  if (isRecord(value)) {
8654
- return { [mapMarker]: Object.entries(value).map(([key, item]) => [
8655
- encodeValue(key, depth + 1),
8656
- encodeValue(item, depth + 1)
8730
+ const keys = Object.keys(value);
8731
+ consumeBudget(budget, mapMarkerBaseBytes + keys.length);
8732
+ return { [mapMarker]: keys.map((key) => [
8733
+ encodeValue(key, depth + 1, budget),
8734
+ encodeValue(value[key], depth + 1, budget)
8657
8735
  ]) };
8658
8736
  }
8659
8737
  throw new TypeError(`unsupported HTTP command value: ${typeof value}`);
@@ -8679,15 +8757,28 @@ function decodeBase64(value) {
8679
8757
  if (value.length % 4 !== 0 || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(value)) {
8680
8758
  throw new TypeError("invalid HTTP bytes marker");
8681
8759
  }
8682
- const decoded = Buffer33.from(value, "base64");
8760
+ const decoded = Buffer34.from(value, "base64");
8683
8761
  if (decoded.toString("base64") !== value) throw new TypeError("invalid HTTP bytes marker");
8684
8762
  return decoded;
8685
8763
  }
8686
8764
  function decodePlainRecord(value, depth) {
8687
8765
  const result = {};
8688
- for (const [key, item] of Object.entries(value)) result[key] = decodeValue2(item, depth);
8766
+ for (const [key, item] of Object.entries(value)) {
8767
+ Object.defineProperty(result, key, {
8768
+ configurable: true,
8769
+ enumerable: true,
8770
+ value: decodeValue2(item, depth),
8771
+ writable: true
8772
+ });
8773
+ }
8689
8774
  return result;
8690
8775
  }
8776
+ function consumeBudget(budget, amount) {
8777
+ if (amount > budget.remaining) {
8778
+ throw new HTTPTransportError("HTTP command request exceeds maxRequestBytes");
8779
+ }
8780
+ budget.remaining -= amount;
8781
+ }
8691
8782
  function denseArray(values, depth, transform) {
8692
8783
  const result = new Array(values.length);
8693
8784
  for (let index = 0; index < values.length; index += 1) {
@@ -8697,10 +8788,12 @@ function denseArray(values, depth, transform) {
8697
8788
  return result;
8698
8789
  }
8699
8790
  function isRecord(value) {
8700
- return typeof value === "object" && value != null && !Array.isArray(value) && !Buffer33.isBuffer(value);
8791
+ return typeof value === "object" && value != null && !Array.isArray(value) && !Buffer34.isBuffer(value);
8701
8792
  }
8702
8793
 
8703
8794
  // src/http-options.ts
8795
+ import { Buffer as Buffer35 } from "buffer";
8796
+ import { validateHeaderName, validateHeaderValue } from "http";
8704
8797
  function normalizeHTTPOptions(value, options) {
8705
8798
  const url = new URL(value);
8706
8799
  if (url.protocol !== "http:" && url.protocol !== "https:") {
@@ -8726,10 +8819,10 @@ function normalizeHTTPOptions(value, options) {
8726
8819
  });
8727
8820
  }
8728
8821
  function normalizedHeaders(source) {
8729
- const headers = {};
8822
+ const headers = /* @__PURE__ */ Object.create(null);
8730
8823
  for (const [rawName, value] of Object.entries(source)) {
8731
8824
  const name = rawName.toLowerCase();
8732
- if (name === "" || !safeHeader(name) || !safeHeader(value)) {
8825
+ if (typeof value !== "string" || !validHeader(name, value)) {
8733
8826
  throw new TypeError(`invalid HTTP header: ${rawName}`);
8734
8827
  }
8735
8828
  headers[name] = value;
@@ -8741,7 +8834,9 @@ function authorizationHeader(url, options, custom) {
8741
8834
  const count = Number(custom != null) + Number(options.bearerToken != null) + Number(basic);
8742
8835
  if (count > 1) throw new TypeError("HTTP credentials are mutually exclusive");
8743
8836
  if (options.bearerToken != null) {
8744
- if (!safeHeader(options.bearerToken)) throw new TypeError("invalid bearer token");
8837
+ if (options.bearerToken === "" || !validHeader("authorization", `Bearer ${options.bearerToken}`)) {
8838
+ throw new TypeError("invalid bearer token");
8839
+ }
8745
8840
  return `Bearer ${options.bearerToken}`;
8746
8841
  }
8747
8842
  if (!basic) return custom;
@@ -8751,7 +8846,7 @@ function authorizationHeader(url, options, custom) {
8751
8846
  if (username === "" || username.includes(":") || !safeHeader(username) || !safeHeader(options.password)) {
8752
8847
  throw new TypeError("invalid Basic authentication credentials");
8753
8848
  }
8754
- return `Basic ${Buffer.from(`${username}:${options.password}`).toString("base64")}`;
8849
+ return `Basic ${Buffer35.from(`${username}:${options.password}`).toString("base64")}`;
8755
8850
  }
8756
8851
  function positiveInteger(value, fallback, name) {
8757
8852
  const result = value ?? fallback;
@@ -8771,36 +8866,167 @@ function booleanOption(value, fallback, name) {
8771
8866
  function safeHeader(value) {
8772
8867
  return !value.includes("\r") && !value.includes("\n");
8773
8868
  }
8869
+ function validHeader(name, value) {
8870
+ try {
8871
+ validateHeaderName(name);
8872
+ validateHeaderValue(name, value);
8873
+ return true;
8874
+ } catch {
8875
+ return false;
8876
+ }
8877
+ }
8774
8878
 
8775
8879
  // src/http-transport.ts
8776
8880
  import http from "http";
8777
8881
  import http2 from "http2";
8778
8882
  import https from "https";
8779
- import { Buffer as Buffer34 } from "buffer";
8883
+ import { Buffer as Buffer36 } from "buffer";
8884
+
8885
+ // src/http2-slot-pool.ts
8886
+ var HTTP2SessionRetiredError = class extends Error {
8887
+ constructor(message, cause) {
8888
+ super(message, { cause });
8889
+ this.name = "HTTP2SessionRetiredError";
8890
+ }
8891
+ };
8892
+ var HTTP2SlotPool = class {
8893
+ active = 0;
8894
+ idleCallback;
8895
+ limit;
8896
+ retiredError;
8897
+ waiterHead;
8898
+ waiterTail;
8899
+ acquire(signal) {
8900
+ if (signal.aborted) return Promise.reject(signalAbortError(signal));
8901
+ if (this.retiredError != null) return Promise.reject(this.retiredError);
8902
+ if (this.limit != null && this.active < this.limit) {
8903
+ this.active += 1;
8904
+ return Promise.resolve(this.releaseOnce());
8905
+ }
8906
+ return new Promise((resolve, reject) => {
8907
+ const waiter = {
8908
+ abort: () => {
8909
+ if (waiter.settled) return;
8910
+ waiter.settled = true;
8911
+ this.removeWaiter(waiter);
8912
+ reject(signalAbortError(signal));
8913
+ },
8914
+ queued: true,
8915
+ reject,
8916
+ resolve,
8917
+ settled: false,
8918
+ signal
8919
+ };
8920
+ this.enqueueWaiter(waiter);
8921
+ signal.addEventListener("abort", waiter.abort, { once: true });
8922
+ });
8923
+ }
8924
+ updateLimit(limit) {
8925
+ if (this.retiredError != null) return;
8926
+ this.limit = limit;
8927
+ this.drain();
8928
+ }
8929
+ retire(error) {
8930
+ if (this.retiredError != null) return;
8931
+ this.retiredError = error;
8932
+ while (this.waiterHead != null) {
8933
+ const waiter = this.waiterHead;
8934
+ this.removeWaiter(waiter);
8935
+ if (waiter.settled) continue;
8936
+ waiter.settled = true;
8937
+ waiter.signal.removeEventListener("abort", waiter.abort);
8938
+ waiter.reject(error);
8939
+ }
8940
+ }
8941
+ whenIdle(callback) {
8942
+ if (this.active === 0) callback();
8943
+ else this.idleCallback = callback;
8944
+ }
8945
+ drain() {
8946
+ while (this.retiredError == null && this.limit != null && this.active < this.limit) {
8947
+ const waiter = this.waiterHead;
8948
+ if (waiter == null) return;
8949
+ this.removeWaiter(waiter);
8950
+ if (waiter.settled) continue;
8951
+ waiter.settled = true;
8952
+ waiter.signal.removeEventListener("abort", waiter.abort);
8953
+ this.active += 1;
8954
+ waiter.resolve(this.releaseOnce());
8955
+ }
8956
+ }
8957
+ enqueueWaiter(waiter) {
8958
+ waiter.previous = this.waiterTail;
8959
+ if (this.waiterTail == null) this.waiterHead = waiter;
8960
+ else this.waiterTail.next = waiter;
8961
+ this.waiterTail = waiter;
8962
+ }
8963
+ removeWaiter(waiter) {
8964
+ if (!waiter.queued) return;
8965
+ if (waiter.previous == null) this.waiterHead = waiter.next;
8966
+ else waiter.previous.next = waiter.next;
8967
+ if (waiter.next == null) this.waiterTail = waiter.previous;
8968
+ else waiter.next.previous = waiter.previous;
8969
+ waiter.next = void 0;
8970
+ waiter.previous = void 0;
8971
+ waiter.queued = false;
8972
+ }
8973
+ releaseOnce() {
8974
+ let released = false;
8975
+ return () => {
8976
+ if (released) return;
8977
+ released = true;
8978
+ this.active -= 1;
8979
+ this.drain();
8980
+ if (this.active === 0) {
8981
+ const callback = this.idleCallback;
8982
+ this.idleCallback = void 0;
8983
+ callback?.();
8984
+ }
8985
+ };
8986
+ }
8987
+ };
8988
+ function signalAbortError(signal) {
8989
+ return signal.reason instanceof Error ? signal.reason : new HTTPTransportError("HTTP request was aborted", { raw: signal.reason });
8990
+ }
8991
+
8992
+ // src/http-transport.ts
8780
8993
  var HTTPTransport = class {
8781
8994
  constructor(config) {
8782
8995
  this.config = config;
8783
- this.#httpAgent = new http.Agent({ keepAlive: true, maxSockets: config.maxConnections });
8996
+ this.#httpAgent = new http.Agent({
8997
+ keepAlive: true,
8998
+ maxFreeSockets: config.maxConnections,
8999
+ maxSockets: config.maxConnections,
9000
+ maxTotalSockets: config.maxConnections
9001
+ });
8784
9002
  this.#httpsAgent = new https.Agent({
8785
9003
  ...config.tlsOptions,
8786
9004
  keepAlive: true,
8787
- maxSockets: config.maxConnections
9005
+ maxFreeSockets: config.maxConnections,
9006
+ maxSockets: config.maxConnections,
9007
+ maxTotalSockets: config.maxConnections
8788
9008
  });
8789
9009
  }
8790
9010
  config;
8791
9011
  #httpAgent;
8792
9012
  #httpsAgent;
9013
+ #allSessions = /* @__PURE__ */ new Set();
8793
9014
  #sessions = /* @__PURE__ */ new Map();
9015
+ #sessionSlots = /* @__PURE__ */ new WeakMap();
9016
+ #requests = /* @__PURE__ */ new Set();
8794
9017
  #closed = false;
8795
- async post(body) {
9018
+ async post(body, timeoutMs) {
8796
9019
  if (this.#closed) throw new HTTPTransportError("HTTP transport is closed");
8797
9020
  const controller = new AbortController();
8798
- const timer = setTimeout(() => controller.abort(), this.config.timeoutMs);
9021
+ this.#requests.add(controller);
9022
+ const timer = timeoutMs == null ? void 0 : setLongTimeout(() => controller.abort(requestTimeoutReason), timeoutMs);
9023
+ timer?.unref();
8799
9024
  try {
8800
9025
  return await this.request(this.config.commandUrl, "POST", body, 0, controller.signal);
8801
9026
  } catch (error) {
8802
9027
  if (controller.signal.aborted) {
8803
- throw new RequestTimeoutError(this.config.timeoutMs, "possibly_sent", {
9028
+ if (controller.signal.reason instanceof HTTPTransportError) throw controller.signal.reason;
9029
+ throw new RequestTimeoutError(timeoutMs ?? this.config.timeoutMs, "possibly_sent", {
8804
9030
  cause: error,
8805
9031
  raw: { retryable: true, safe_to_retry: false }
8806
9032
  });
@@ -8812,15 +9038,19 @@ var HTTPTransport = class {
8812
9038
  safeToRetry: false
8813
9039
  });
8814
9040
  } finally {
8815
- clearTimeout(timer);
9041
+ timer?.cancel();
9042
+ this.#requests.delete(controller);
8816
9043
  }
8817
9044
  }
8818
9045
  async close() {
8819
9046
  if (this.#closed) return;
8820
9047
  this.#closed = true;
9048
+ const error = new HTTPTransportError("HTTP transport is closed");
9049
+ for (const controller of this.#requests) controller.abort(error);
8821
9050
  this.#httpAgent.destroy();
8822
9051
  this.#httpsAgent.destroy();
8823
- for (const session of this.#sessions.values()) session.destroy();
9052
+ for (const session of this.#allSessions) session.destroy();
9053
+ this.#allSessions.clear();
8824
9054
  this.#sessions.clear();
8825
9055
  }
8826
9056
  async request(url, method, body, redirects, signal) {
@@ -8868,7 +9098,6 @@ var HTTPTransport = class {
8868
9098
  );
8869
9099
  }
8870
9100
  async http2Request(url, method, body, signal) {
8871
- const session = this.session(url);
8872
9101
  const headers = {
8873
9102
  ...this.requestHeaders(body),
8874
9103
  ":authority": url.host,
@@ -8876,8 +9105,41 @@ var HTTPTransport = class {
8876
9105
  ":path": `${url.pathname}${url.search}`,
8877
9106
  ":scheme": url.protocol.slice(0, -1)
8878
9107
  };
9108
+ if (signal.aborted) throw signalAbortError(signal);
9109
+ for (let attempt = 0; attempt < 2; attempt += 1) {
9110
+ const session = this.session(url);
9111
+ let release;
9112
+ try {
9113
+ release = await this.slotPool(session).acquire(signal);
9114
+ } catch (error) {
9115
+ if (attempt === 0 && error instanceof HTTP2SessionRetiredError && !signal.aborted) continue;
9116
+ throw error;
9117
+ }
9118
+ try {
9119
+ let stream;
9120
+ try {
9121
+ stream = session.request(headers);
9122
+ } catch (error) {
9123
+ if (attempt === 0 && retryableSessionOpenError(error) && !signal.aborted) {
9124
+ this.retireSession(url.origin, session, true, error);
9125
+ continue;
9126
+ }
9127
+ throw error;
9128
+ }
9129
+ try {
9130
+ return await this.collectHttp2(stream, body, signal);
9131
+ } catch (error) {
9132
+ if (attempt === 0 && refusedStreamError(error) && !signal.aborted) continue;
9133
+ throw error;
9134
+ }
9135
+ } finally {
9136
+ release();
9137
+ }
9138
+ }
9139
+ throw new HTTPTransportError("HTTP/2 session could not accept the request");
9140
+ }
9141
+ async collectHttp2(stream, body, signal) {
8879
9142
  return await new Promise((resolve, reject) => {
8880
- const stream = session.request(headers);
8881
9143
  let responseHeaders = {};
8882
9144
  const abort = () => stream.close(http2.constants.NGHTTP2_CANCEL);
8883
9145
  signal.addEventListener("abort", abort, { once: true });
@@ -8887,19 +9149,60 @@ var HTTPTransport = class {
8887
9149
  const status = Number(responseHeaders[":status"] ?? 0);
8888
9150
  resolve({ body: response.body, headers: normalizeHeaders(responseHeaders), status });
8889
9151
  }, reject).finally(() => signal.removeEventListener("abort", abort));
8890
- stream.end(body);
9152
+ if (signal.aborted) abort();
9153
+ else stream.end(body);
8891
9154
  });
8892
9155
  }
8893
9156
  session(url) {
8894
9157
  const origin = url.origin;
8895
9158
  const current = this.#sessions.get(origin);
8896
9159
  if (current != null && !current.closed && !current.destroyed) return current;
8897
- const session = http2.connect(origin, this.config.tlsOptions);
8898
- session.on("error", () => void 0);
8899
- session.once("close", () => this.#sessions.delete(origin));
9160
+ const session = http2.connect(origin, {
9161
+ ...this.config.tlsOptions,
9162
+ settings: { enablePush: false }
9163
+ });
9164
+ const slots = new HTTP2SlotPool();
9165
+ this.#allSessions.add(session);
9166
+ this.#sessionSlots.set(session, slots);
9167
+ session.on("remoteSettings", (settings) => {
9168
+ const remoteLimit = settings.maxConcurrentStreams;
9169
+ const limit = typeof remoteLimit === "number" && Number.isFinite(remoteLimit) ? Math.max(0, Math.floor(remoteLimit)) : this.config.maxConnections;
9170
+ slots.updateLimit(Math.min(this.config.maxConnections, limit));
9171
+ });
9172
+ session.on("error", (error) => this.retireSession(origin, session, true, error));
9173
+ session.once("goaway", () => {
9174
+ this.retireSession(
9175
+ origin,
9176
+ session,
9177
+ "when_idle",
9178
+ new HTTP2SessionRetiredError("HTTP/2 session received GOAWAY")
9179
+ );
9180
+ });
9181
+ session.once("close", () => {
9182
+ if (session.destroyed) this.#allSessions.delete(session);
9183
+ this.retireSession(origin, session);
9184
+ });
8900
9185
  this.#sessions.set(origin, session);
8901
9186
  return session;
8902
9187
  }
9188
+ retireSession(origin, session, destroy = false, cause) {
9189
+ if (this.#sessions.get(origin) === session) this.#sessions.delete(origin);
9190
+ const slots = this.#sessionSlots.get(session);
9191
+ slots?.retire(
9192
+ cause instanceof HTTP2SessionRetiredError ? cause : new HTTP2SessionRetiredError("HTTP/2 session is unavailable", cause)
9193
+ );
9194
+ if (destroy === true && !session.destroyed) session.destroy();
9195
+ else if (destroy === "when_idle") {
9196
+ slots?.whenIdle(() => {
9197
+ if (!session.destroyed) session.destroy();
9198
+ });
9199
+ }
9200
+ }
9201
+ slotPool(session) {
9202
+ const slots = this.#sessionSlots.get(session);
9203
+ if (slots == null) throw new HTTP2SessionRetiredError("HTTP/2 session is unavailable");
9204
+ return slots;
9205
+ }
8903
9206
  requestHeaders(body) {
8904
9207
  const headers = { ...this.config.headers };
8905
9208
  delete headers["content-length"];
@@ -8911,11 +9214,21 @@ var HTTPTransport = class {
8911
9214
  };
8912
9215
  }
8913
9216
  };
9217
+ var requestTimeoutReason = /* @__PURE__ */ Symbol("ferricstore-http-request-timeout");
9218
+ function retryableSessionOpenError(error) {
9219
+ if (typeof error !== "object" || error == null || !("code" in error)) return false;
9220
+ const code = error.code;
9221
+ return code === "ERR_HTTP2_GOAWAY_SESSION" || code === "ERR_HTTP2_INVALID_SESSION";
9222
+ }
9223
+ function refusedStreamError(error) {
9224
+ if (!(error instanceof Error)) return false;
9225
+ return error.code === "ERR_HTTP2_STREAM_ERROR" && error.message.includes("NGHTTP2_REFUSED_STREAM");
9226
+ }
8914
9227
  async function collectBody(source, status, headers, maximum) {
8915
9228
  const chunks = [];
8916
9229
  let size = 0;
8917
9230
  for await (const chunk of source) {
8918
- const bytes2 = Buffer34.from(chunk);
9231
+ const bytes2 = Buffer36.from(chunk);
8919
9232
  size += bytes2.byteLength;
8920
9233
  if (size > maximum) {
8921
9234
  const destroy = source.destroy;
@@ -8924,10 +9237,10 @@ async function collectBody(source, status, headers, maximum) {
8924
9237
  }
8925
9238
  chunks.push(bytes2);
8926
9239
  }
8927
- return { body: Buffer34.concat(chunks, size), headers, status };
9240
+ return { body: Buffer36.concat(chunks, size), headers, status };
8928
9241
  }
8929
9242
  function normalizeHeaders(headers) {
8930
- const result = {};
9243
+ const result = /* @__PURE__ */ Object.create(null);
8931
9244
  for (const [name, raw] of Object.entries(headers)) {
8932
9245
  const value = headerValue(raw);
8933
9246
  if (value != null) result[name.toLowerCase()] = value;
@@ -8979,11 +9292,16 @@ var HTTPAdapter = class _HTTPAdapter {
8979
9292
  throw new HTTPTransportError("HTTP command batch exceeds maxBatchItems");
8980
9293
  }
8981
9294
  for (const command of commands) assertHTTPCommandSupported(command[0]);
8982
- const body = encodeHTTPCommands(commands.map((command) => httpCommand(command, this.#config.maxRequestBytes)));
9295
+ const prepared = commands.map((command) => prepareHTTPCommand(command, this.#config.maxRequestBytes));
9296
+ const body = encodeHTTPCommands(prepared.map((command) => command.encoded), this.#config.maxRequestBytes);
8983
9297
  if (body.byteLength > this.#config.maxRequestBytes) {
8984
9298
  throw new HTTPTransportError("HTTP command request exceeds maxRequestBytes");
8985
9299
  }
8986
- const response = await this.#transport.post(body);
9300
+ const serverBlockMs = combinedServerBlockMs(prepared.map((command) => command.serverBlockMs));
9301
+ const response = await this.#transport.post(
9302
+ body,
9303
+ serverResponseTimeoutMs(this.#config.timeoutMs, serverBlockMs)
9304
+ );
8987
9305
  let envelope = {};
8988
9306
  try {
8989
9307
  if (response.body.byteLength > 0) envelope = decodeHTTPEnvelope(response.body);
@@ -9007,12 +9325,17 @@ var HTTPAdapter = class _HTTPAdapter {
9007
9325
  var commandNamesByOpcode = new Map(
9008
9326
  Object.entries(COMMAND_OPCODES).map(([name, opcode]) => [opcode, name])
9009
9327
  );
9010
- function httpCommand(command, maxRequestBytes) {
9328
+ function prepareHTTPCommand(command, maxRequestBytes) {
9011
9329
  const protocol = buildProtocolCommand(command, maxRequestBytes, false);
9012
- if (protocol.opcode === OPCODES.commandExec) return command;
9330
+ if (protocol.opcode === OPCODES.commandExec) {
9331
+ return { encoded: command, serverBlockMs: protocol.serverBlockMs };
9332
+ }
9013
9333
  const name = commandNamesByOpcode.get(protocol.opcode);
9014
9334
  if (name == null) throw new HTTPTransportError(`HTTP command has unknown opcode ${protocol.opcode}`);
9015
- return { command: name, opcode: protocol.opcode, payload: protocol.payload ?? {} };
9335
+ return {
9336
+ encoded: { command: name, opcode: protocol.opcode, payload: protocol.payload ?? {} },
9337
+ serverBlockMs: protocol.serverBlockMs
9338
+ };
9016
9339
  }
9017
9340
  function validatedResult(value) {
9018
9341
  if (!isRecord2(value)) throw new HTTPTransportError("HTTP response has an invalid result item");
@@ -9032,7 +9355,7 @@ function commandError(value) {
9032
9355
  function topLevelError(status, envelope, retryAfter) {
9033
9356
  const details = isRecord2(envelope.error) ? envelope.error : {};
9034
9357
  const message = typeof details.message === "string" ? details.message : `HTTP command request failed with status ${status}`;
9035
- const retryAfterMs2 = retryAfter == null || !/^\d+$/u.test(retryAfter) ? void 0 : Number(retryAfter) * 1e3;
9358
+ const retryAfterMs2 = retryAfterMilliseconds(retryAfter);
9036
9359
  return new HTTPTransportError(message, {
9037
9360
  raw: details,
9038
9361
  retryable: status === 408 || status === 425 || status === 429 || status >= 500,
@@ -9041,6 +9364,18 @@ function topLevelError(status, envelope, retryAfter) {
9041
9364
  statusCode: status
9042
9365
  });
9043
9366
  }
9367
+ function retryAfterMilliseconds(value) {
9368
+ if (value == null) return void 0;
9369
+ if (/^\d+$/u.test(value)) {
9370
+ const seconds = Number.parseInt(value, 10);
9371
+ const milliseconds2 = seconds * 1e3;
9372
+ return Number.isSafeInteger(milliseconds2) ? milliseconds2 : void 0;
9373
+ }
9374
+ const deadline = Date.parse(value);
9375
+ if (!Number.isFinite(deadline)) return void 0;
9376
+ const milliseconds = Math.max(0, deadline - Date.now());
9377
+ return Number.isSafeInteger(milliseconds) ? milliseconds : void 0;
9378
+ }
9044
9379
  function isRecord2(value) {
9045
9380
  return typeof value === "object" && value != null && !Array.isArray(value);
9046
9381
  }
@@ -9056,7 +9391,7 @@ function executeCommandArgs(executor, args) {
9056
9391
  import "buffer";
9057
9392
 
9058
9393
  // src/command-retry-policy.ts
9059
- import { Buffer as Buffer35 } from "buffer";
9394
+ import { Buffer as Buffer37 } from "buffer";
9060
9395
  function isCasMutation(args) {
9061
9396
  const offset = commandName2(args[0]) === "COMMAND_EXEC" ? 1 : 0;
9062
9397
  const name = commandName2(args[offset]);
@@ -9070,8 +9405,8 @@ function isCasMutation(args) {
9070
9405
  }
9071
9406
  function commandName2(value) {
9072
9407
  if (typeof value === "string") return value.toUpperCase();
9073
- if (Buffer35.isBuffer(value) || value instanceof Uint8Array) {
9074
- return Buffer35.from(value).toString("utf8").toUpperCase();
9408
+ if (Buffer37.isBuffer(value) || value instanceof Uint8Array) {
9409
+ return Buffer37.from(value).toString("utf8").toUpperCase();
9075
9410
  }
9076
9411
  return void 0;
9077
9412
  }
@@ -9286,12 +9621,12 @@ function normalizeNonNegativeInteger2(value, fallback) {
9286
9621
  import "buffer";
9287
9622
 
9288
9623
  // src/topology-routing.ts
9289
- import { Buffer as Buffer38 } from "buffer";
9624
+ import { Buffer as Buffer40 } from "buffer";
9290
9625
 
9291
9626
  // src/flow-partition-route-cache.ts
9292
- import { Buffer as Buffer37 } from "buffer";
9627
+ import { Buffer as Buffer39 } from "buffer";
9293
9628
  import { createHash } from "crypto";
9294
- var AUTO_PREFIX = Buffer37.from("__flow_auto__:", "ascii");
9629
+ var AUTO_PREFIX = Buffer39.from("__flow_auto__:", "ascii");
9295
9630
  var MAX_CACHEABLE_PARTITION_BYTES = 4 * 1024;
9296
9631
  var MAX_CACHE_BYTES = 1 * 1024 * 1024;
9297
9632
  var MAX_CACHE_ENTRIES = 1024;
@@ -9301,10 +9636,10 @@ var cacheBytes = 0;
9301
9636
  var cacheHits = 0;
9302
9637
  var cacheMisses = 0;
9303
9638
  function flowLogicalPartitionRoutingKey(value) {
9304
- if (typeof value !== "string" && !Buffer37.isBuffer(value)) return void 0;
9639
+ if (typeof value !== "string" && !Buffer39.isBuffer(value)) return void 0;
9305
9640
  const autoBucket = flowAutoBucket(value);
9306
9641
  if (autoBucket != null) return `{fa:${autoBucket}}`;
9307
- const bytes2 = Buffer37.isBuffer(value) ? value : Buffer37.from(value);
9642
+ const bytes2 = Buffer39.isBuffer(value) ? value : Buffer39.from(value);
9308
9643
  if (bytes2.byteLength > MAX_CACHEABLE_PARTITION_BYTES) return hashRoute(bytes2);
9309
9644
  const cacheKey = bytes2.toString("base64");
9310
9645
  const cached = routeCache.get(cacheKey);
@@ -9378,7 +9713,7 @@ function routingKeyFromProtocolPayload(name, command) {
9378
9713
  "scope"
9379
9714
  ]) {
9380
9715
  const value = getField(command.payload, field3);
9381
- if (typeof value === "string" || Buffer38.isBuffer(value)) {
9716
+ if (typeof value === "string" || Buffer40.isBuffer(value)) {
9382
9717
  return value;
9383
9718
  }
9384
9719
  }
@@ -9426,7 +9761,7 @@ function flowRoutingData(name, args) {
9426
9761
  if (typeof partition === "string" && partition.toUpperCase() !== "AUTO" && partition.toUpperCase() !== "MIXED") {
9427
9762
  return flowRoutingResult(flowLogicalPartitionRoutingKey(partition));
9428
9763
  }
9429
- if (Buffer38.isBuffer(partition)) {
9764
+ if (Buffer40.isBuffer(partition)) {
9430
9765
  const text3 = partition.toString("utf8").toUpperCase();
9431
9766
  if (text3 !== "AUTO" && text3 !== "MIXED") {
9432
9767
  return flowRoutingResult(flowLogicalPartitionRoutingKey(partition));
@@ -9517,17 +9852,17 @@ function flowPartitionRoutingKeyFromCommand(command, claim) {
9517
9852
  return { handled: false };
9518
9853
  }
9519
9854
  function isRoutingKey(value) {
9520
- return typeof value === "string" || Buffer38.isBuffer(value);
9855
+ return typeof value === "string" || Buffer40.isBuffer(value);
9521
9856
  }
9522
9857
  function flowAutoIdRoutingKey(value) {
9523
- if (typeof value !== "string" && !Buffer38.isBuffer(value)) {
9858
+ if (typeof value !== "string" && !Buffer40.isBuffer(value)) {
9524
9859
  return void 0;
9525
9860
  }
9526
- const bucket = (Buffer38.isBuffer(value) ? crc32(value) : crc32Utf8(value)) & 255;
9861
+ const bucket = (Buffer40.isBuffer(value) ? crc32(value) : crc32Utf8(value)) & 255;
9527
9862
  return `{fa:${bucket}}`;
9528
9863
  }
9529
9864
  function flowClaimLogicalPartitionRoutingKey(value) {
9530
- if (typeof value !== "string" && !Buffer38.isBuffer(value)) return void 0;
9865
+ if (typeof value !== "string" && !Buffer40.isBuffer(value)) return void 0;
9531
9866
  const selector = commandPart(value);
9532
9867
  if (selector === "AUTO" || selector === "ANY") return void 0;
9533
9868
  if (selector === "GLOBAL") return "{f}";
@@ -9542,7 +9877,7 @@ function singleShardFlowClaimPartitionKey(values) {
9542
9877
  return keys.some((key) => key == null) ? void 0 : singleShardKey(keys);
9543
9878
  }
9544
9879
  function singleShardKey(keys) {
9545
- if (keys.length === 0 || keys.some((key) => typeof key !== "string" && !Buffer38.isBuffer(key))) {
9880
+ if (keys.length === 0 || keys.some((key) => typeof key !== "string" && !Buffer40.isBuffer(key))) {
9546
9881
  return void 0;
9547
9882
  }
9548
9883
  const usable = keys;
@@ -9575,7 +9910,7 @@ function routedKeyGroups(keys, routeKey) {
9575
9910
  const groups = /* @__PURE__ */ new Map();
9576
9911
  for (let index = 0; index < keys.length; index += 1) {
9577
9912
  const key = keys[index];
9578
- if (typeof key !== "string" && !Buffer38.isBuffer(key)) return void 0;
9913
+ if (typeof key !== "string" && !Buffer40.isBuffer(key)) return void 0;
9579
9914
  const route = routeKey(key);
9580
9915
  const groupKey = `${route.endpointKey}\0${route.laneId}`;
9581
9916
  const group = groups.get(groupKey);
@@ -10664,7 +10999,7 @@ var TopologyNativeAdapterPool = class _TopologyNativeAdapterPool {
10664
10999
  };
10665
11000
 
10666
11001
  // src/response-map-preservation.ts
10667
- import { Buffer as Buffer40 } from "buffer";
11002
+ import { Buffer as Buffer42 } from "buffer";
10668
11003
  function toStringKeyMapPreservingValues(value) {
10669
11004
  if (value == null) return void 0;
10670
11005
  const result = {};
@@ -10674,7 +11009,7 @@ function toStringKeyMapPreservingValues(value) {
10674
11009
  }
10675
11010
  return result;
10676
11011
  }
10677
- if (typeof value === "object" && !Array.isArray(value) && !Buffer40.isBuffer(value) && !(value instanceof Uint8Array)) {
11012
+ if (typeof value === "object" && !Array.isArray(value) && !Buffer42.isBuffer(value) && !(value instanceof Uint8Array)) {
10678
11013
  for (const [key, item] of Object.entries(value)) {
10679
11014
  setOwnValue(result, text(key), normalizeMapStructurePreservingBytes(item));
10680
11015
  }
@@ -10683,7 +11018,7 @@ function toStringKeyMapPreservingValues(value) {
10683
11018
  return void 0;
10684
11019
  }
10685
11020
  function normalizeMapStructurePreservingBytes(value) {
10686
- if (Buffer40.isBuffer(value) || value instanceof Uint8Array) return value;
11021
+ if (Buffer42.isBuffer(value) || value instanceof Uint8Array) return value;
10687
11022
  if (value instanceof Map) {
10688
11023
  const result = {};
10689
11024
  for (const [key, item] of value.entries()) {
@@ -10705,7 +11040,7 @@ function normalizeMapStructurePreservingBytes(value) {
10705
11040
  }
10706
11041
 
10707
11042
  // src/native-kv-responses.ts
10708
- import { Buffer as Buffer41 } from "buffer";
11043
+ import { Buffer as Buffer43 } from "buffer";
10709
11044
  function rateLimitResultFromResp(value) {
10710
11045
  if (!Array.isArray(value) || value.length !== 4) {
10711
11046
  throw new TypeError("RATELIMIT.ADD returned an unexpected response");
@@ -10762,13 +11097,13 @@ function fetchOrComputeResultFromResp(value, codec) {
10762
11097
  }
10763
11098
  function decodePayload(codec, value) {
10764
11099
  if (value == null) return null;
10765
- if (Buffer41.isBuffer(value)) return codec.decode(value);
10766
- if (value instanceof Uint8Array) return codec.decode(Buffer41.from(value));
10767
- if (typeof value === "string") return codec.decode(Buffer41.from(value));
11100
+ if (Buffer43.isBuffer(value)) return codec.decode(value);
11101
+ if (value instanceof Uint8Array) return codec.decode(Buffer43.from(value));
11102
+ if (typeof value === "string") return codec.decode(Buffer43.from(value));
10768
11103
  return normalizeRefMeta(value);
10769
11104
  }
10770
11105
  function requiredResponseString(value, context) {
10771
- if (typeof value !== "string" && !Buffer41.isBuffer(value) && !(value instanceof Uint8Array)) {
11106
+ if (typeof value !== "string" && !Buffer43.isBuffer(value) && !(value instanceof Uint8Array)) {
10772
11107
  throw new TypeError(`${context} returned an unexpected response`);
10773
11108
  }
10774
11109
  const result = text(value);
@@ -10785,7 +11120,7 @@ function requiredNonNegativeInteger(value, context) {
10785
11120
  return result;
10786
11121
  }
10787
11122
  function responseBytes(value, context) {
10788
- if (typeof value !== "string" && !Buffer41.isBuffer(value) && !(value instanceof Uint8Array)) {
11123
+ if (typeof value !== "string" && !Buffer43.isBuffer(value) && !(value instanceof Uint8Array)) {
10789
11124
  throw new TypeError(`${context} returned an unexpected response`);
10790
11125
  }
10791
11126
  return bytes(value);
@@ -11468,7 +11803,7 @@ function groupAutoPartitionItems(items) {
11468
11803
  }
11469
11804
 
11470
11805
  // src/client-values.ts
11471
- import { Buffer as Buffer42 } from "buffer";
11806
+ import { Buffer as Buffer44 } from "buffer";
11472
11807
  async function valueMGetEntries(client, refs, options = {}) {
11473
11808
  const refCount = refs.length;
11474
11809
  if (refCount === 0) {
@@ -11503,12 +11838,12 @@ async function valueMGetEntries(client, refs, options = {}) {
11503
11838
  const item = response[index];
11504
11839
  if (item == null) {
11505
11840
  entries[index] = { found: false };
11506
- } else if (Buffer42.isBuffer(item)) {
11841
+ } else if (Buffer44.isBuffer(item)) {
11507
11842
  entries[index] = { found: true, value: client.codec.decode(item) };
11508
11843
  } else if (item instanceof Uint8Array) {
11509
- entries[index] = { found: true, value: client.codec.decode(Buffer42.from(item)) };
11844
+ entries[index] = { found: true, value: client.codec.decode(Buffer44.from(item)) };
11510
11845
  } else if (typeof item === "string") {
11511
- entries[index] = { found: true, value: client.codec.decode(Buffer42.from(item)) };
11846
+ entries[index] = { found: true, value: client.codec.decode(Buffer44.from(item)) };
11512
11847
  } else {
11513
11848
  entries[index] = { found: true, value: item };
11514
11849
  }
@@ -11520,7 +11855,7 @@ async function valueMGetEntries(client, refs, options = {}) {
11520
11855
  import "buffer";
11521
11856
 
11522
11857
  // src/auto-batch-ordering.ts
11523
- import { Buffer as Buffer43 } from "buffer";
11858
+ import { Buffer as Buffer45 } from "buffer";
11524
11859
  function autoBatchOrderingPlan(batch) {
11525
11860
  const accesses = /* @__PURE__ */ new Map();
11526
11861
  const fallbackDependencies = [];
@@ -11635,13 +11970,13 @@ function flowManyAutoBatchIds(command, name) {
11635
11970
  return fixedFlowItemIds(
11636
11971
  command,
11637
11972
  mixed ? 4 : 3,
11638
- (itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && isFencingToken(command[itemIndex + (mixed ? 2 : 1)]) && Buffer43.isBuffer(command[itemIndex + (mixed ? 3 : 2)])
11973
+ (itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && isFencingToken(command[itemIndex + (mixed ? 2 : 1)]) && Buffer45.isBuffer(command[itemIndex + (mixed ? 3 : 2)])
11639
11974
  );
11640
11975
  }
11641
11976
  return fixedFlowItemIds(
11642
11977
  command,
11643
11978
  mixed ? 4 : 3,
11644
- (itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && Buffer43.isBuffer(command[itemIndex + (mixed ? 2 : 1)]) && isFencingToken(command[itemIndex + (mixed ? 3 : 2)])
11979
+ (itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && Buffer45.isBuffer(command[itemIndex + (mixed ? 2 : 1)]) && isFencingToken(command[itemIndex + (mixed ? 3 : 2)])
11645
11980
  );
11646
11981
  }
11647
11982
  function createManyAutoBatchIds(command) {
@@ -11654,7 +11989,7 @@ function createManyAutoBatchIds(command) {
11654
11989
  const ids = fixedFlowItemIds(
11655
11990
  command,
11656
11991
  width,
11657
- (itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && Buffer43.isBuffer(command[itemIndex + width - 1]),
11992
+ (itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && Buffer45.isBuffer(command[itemIndex + width - 1]),
11658
11993
  markerIndex
11659
11994
  );
11660
11995
  if (ids != null) return ids;
@@ -11672,7 +12007,7 @@ function extendedCreateManyAutoBatchIds(command, markerIndex) {
11672
12007
  let cursor = markerIndex + 2;
11673
12008
  for (let itemIndex = 0; itemIndex < itemCount; itemIndex += 1) {
11674
12009
  const id = command[cursor];
11675
- if (!isAutoBatchResourceValue(id) || !isAutoBatchResourceValue(command[cursor + 1]) || !Buffer43.isBuffer(command[cursor + 2])) return void 0;
12010
+ if (!isAutoBatchResourceValue(id) || !isAutoBatchResourceValue(command[cursor + 1]) || !Buffer45.isBuffer(command[cursor + 2])) return void 0;
11676
12011
  ids.push(id);
11677
12012
  cursor += 3;
11678
12013
  const afterValues = skipExtendedNamedItems(command, cursor, true);
@@ -11691,7 +12026,7 @@ function skipExtendedNamedItems(command, countIndex, encodedValues) {
11691
12026
  for (let index = 0; index < count; index += 1) {
11692
12027
  const name = command[firstItem + index * 2];
11693
12028
  const value = command[firstItem + index * 2 + 1];
11694
- if (!isAutoBatchResourceValue(name) || (encodedValues ? !Buffer43.isBuffer(value) : !isAutoBatchResourceValue(value))) return void 0;
12029
+ if (!isAutoBatchResourceValue(name) || (encodedValues ? !Buffer45.isBuffer(value) : !isAutoBatchResourceValue(value))) return void 0;
11695
12030
  }
11696
12031
  return firstItem + count * 2;
11697
12032
  }
@@ -11706,7 +12041,7 @@ function runStepsManyAutoBatchIds(command) {
11706
12041
  ids.push(item);
11707
12042
  continue;
11708
12043
  }
11709
- if (typeof item !== "object" || item == null || Array.isArray(item) || Buffer43.isBuffer(item)) return void 0;
12044
+ if (typeof item !== "object" || item == null || Array.isArray(item) || Buffer45.isBuffer(item)) return void 0;
11710
12045
  const id = item.id;
11711
12046
  if (!isAutoBatchResourceValue(id)) return void 0;
11712
12047
  ids.push(id);
@@ -11747,7 +12082,7 @@ function flowValuePutOwner(command, start) {
11747
12082
  }
11748
12083
  var flowValuePutOptionTokens = /* @__PURE__ */ new Set(["NAME", "NOW", "OVERRIDE", "OWNER_FLOW_ID", "PARTITION", "TTL", "TTL_MS"]);
11749
12084
  function isAutoBatchResourceValue(value) {
11750
- return typeof value === "string" || Buffer43.isBuffer(value);
12085
+ return typeof value === "string" || Buffer45.isBuffer(value);
11751
12086
  }
11752
12087
  function isFencingToken(value) {
11753
12088
  return typeof value === "number" && Number.isSafeInteger(value) || typeof value === "bigint";
@@ -11756,7 +12091,7 @@ function nonNegativeItemCount(value) {
11756
12091
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : void 0;
11757
12092
  }
11758
12093
  function autoBatchResourceKey(namespace, value) {
11759
- return `${namespace}:${Buffer43.from(value).toString("base64")}`;
12094
+ return `${namespace}:${Buffer45.from(value).toString("base64")}`;
11760
12095
  }
11761
12096
  function autoBatchCommandName(command) {
11762
12097
  return commandView(command).name ?? null;
@@ -12168,10 +12503,10 @@ function claimFailure(error) {
12168
12503
  import "buffer";
12169
12504
 
12170
12505
  // src/flow-query-builder.ts
12171
- import { Buffer as Buffer46 } from "buffer";
12506
+ import { Buffer as Buffer48 } from "buffer";
12172
12507
 
12173
12508
  // src/flow-query-metadata.ts
12174
- import { Buffer as Buffer45 } from "buffer";
12509
+ import { Buffer as Buffer47 } from "buffer";
12175
12510
  var MAX_FLOW_QUERY_METADATA_KEY_BYTES = 64;
12176
12511
  function normalizeStateMeta(value, state) {
12177
12512
  if (value == null) return {};
@@ -12196,7 +12531,7 @@ function normalizeStateMeta(value, state) {
12196
12531
  function metadataEntries(value, context) {
12197
12532
  const entries = objectEntries(value ?? {}, context).map(([rawName, item]) => {
12198
12533
  const name = rawName.trim();
12199
- const size = Buffer45.byteLength(name, "utf8");
12534
+ const size = Buffer47.byteLength(name, "utf8");
12200
12535
  if (size === 0 || size > MAX_FLOW_QUERY_METADATA_KEY_BYTES || name.startsWith("__")) {
12201
12536
  throw new TypeError(`${context} key is invalid or reserved`);
12202
12537
  }
@@ -12220,7 +12555,7 @@ function objectEntries(value, context) {
12220
12555
  return keys.map((key) => [key, value[key]]);
12221
12556
  }
12222
12557
  function isPlainRecord(value) {
12223
- if (typeof value !== "object" || value == null || Array.isArray(value) || Buffer45.isBuffer(value)) {
12558
+ if (typeof value !== "object" || value == null || Array.isArray(value) || Buffer47.isBuffer(value)) {
12224
12559
  return false;
12225
12560
  }
12226
12561
  const prototype = Object.getPrototypeOf(value);
@@ -12290,7 +12625,7 @@ var FlowCollectionQuery = class {
12290
12625
  const states = /* @__PURE__ */ new Set();
12291
12626
  for (const [rawState, metadata] of objectEntries(values, "stateMeta")) {
12292
12627
  const state = requiredText(rawState, "stateMeta state").trim();
12293
- const stateBytes = Buffer46.byteLength(state, "utf8");
12628
+ const stateBytes = Buffer48.byteLength(state, "utf8");
12294
12629
  if (stateBytes === 0 || stateBytes > MAX_FLOW_QUERY_STATE_BYTES) {
12295
12630
  throw new TypeError(
12296
12631
  `stateMeta state names must be 1..${MAX_FLOW_QUERY_STATE_BYTES} bytes`
@@ -12469,7 +12804,7 @@ function requiredPartition(value) {
12469
12804
  "FLOW.QUERY convenience methods require a partition key"
12470
12805
  );
12471
12806
  }
12472
- const size = Buffer46.byteLength(value, "utf8");
12807
+ const size = Buffer48.byteLength(value, "utf8");
12473
12808
  if (size === 0 || size > MAX_FLOW_QUERY_PARTITION_BYTES) {
12474
12809
  throw new TypeError(
12475
12810
  `FLOW.QUERY partition key must be 1..${MAX_FLOW_QUERY_PARTITION_BYTES} bytes`
@@ -12517,23 +12852,23 @@ function requiredText(value, context) {
12517
12852
  return value;
12518
12853
  }
12519
12854
  function queryParameter(value, context) {
12520
- if (typeof value === "string" || typeof value === "boolean" || typeof value === "bigint" || typeof value === "number" || Buffer46.isBuffer(value)) {
12855
+ if (typeof value === "string" || typeof value === "boolean" || typeof value === "bigint" || typeof value === "number" || Buffer48.isBuffer(value)) {
12521
12856
  return value;
12522
12857
  }
12523
12858
  throw new TypeError(`${context} must be a scalar FLOW.QUERY parameter`);
12524
12859
  }
12525
12860
 
12526
12861
  // src/flow-query-response.ts
12527
- import { Buffer as Buffer50 } from "buffer";
12862
+ import { Buffer as Buffer52 } from "buffer";
12528
12863
 
12529
12864
  // src/flow-query-diagnostic-response.ts
12530
- import { Buffer as Buffer48 } from "buffer";
12865
+ import { Buffer as Buffer50 } from "buffer";
12531
12866
 
12532
12867
  // src/flow-query-response-validation.ts
12533
- import { Buffer as Buffer47 } from "buffer";
12868
+ import { Buffer as Buffer49 } from "buffer";
12534
12869
  function requiredMap2(value, context) {
12535
12870
  if (value instanceof Map) return value;
12536
- if (typeof value !== "object" || value == null || Array.isArray(value) || Buffer47.isBuffer(value) || value instanceof Uint8Array) {
12871
+ if (typeof value !== "object" || value == null || Array.isArray(value) || Buffer49.isBuffer(value) || value instanceof Uint8Array) {
12537
12872
  throw decodeError(`${context} must be a map`, value);
12538
12873
  }
12539
12874
  return value;
@@ -12590,7 +12925,7 @@ function normalizeMetadataValue(value, context, budget, ancestors, depth) {
12590
12925
  if (!value.isWellFormed()) throw decodeError(`${context} contains invalid text`, value);
12591
12926
  return value;
12592
12927
  }
12593
- if (Buffer47.isBuffer(value) || value instanceof Uint8Array) {
12928
+ if (Buffer49.isBuffer(value) || value instanceof Uint8Array) {
12594
12929
  const decoded = strictText2(value);
12595
12930
  if (decoded == null) throw decodeError(`${context} contains invalid UTF-8`, value);
12596
12931
  return decoded;
@@ -12669,7 +13004,7 @@ function optionalText2(mapping2, name, context) {
12669
13004
  }
12670
13005
  function requiredBoundedText2(mapping2, name, context, maximumBytes) {
12671
13006
  const value = requiredText2(mapping2, name, context);
12672
- if (Buffer47.byteLength(value, "utf8") > maximumBytes) {
13007
+ if (Buffer49.byteLength(value, "utf8") > maximumBytes) {
12673
13008
  throw decodeError(
12674
13009
  `${context} ${name} exceeds ${maximumBytes} bytes`,
12675
13010
  mapping2
@@ -12682,7 +13017,7 @@ function boundedText(value, context, maximumBytes) {
12682
13017
  if (decoded == null || decoded.length === 0) {
12683
13018
  throw decodeError(`${context} must be non-empty text`, value);
12684
13019
  }
12685
- if (Buffer47.byteLength(decoded, "utf8") > maximumBytes) {
13020
+ if (Buffer49.byteLength(decoded, "utf8") > maximumBytes) {
12686
13021
  throw decodeError(`${context} exceeds ${maximumBytes} bytes`, value);
12687
13022
  }
12688
13023
  return decoded;
@@ -12736,10 +13071,10 @@ function positiveBoundedInteger(value, maximum, context) {
12736
13071
  function hasKey(mapping2, name) {
12737
13072
  if (!(mapping2 instanceof Map)) return Object.hasOwn(mapping2, name);
12738
13073
  if (mapping2.has(name)) return true;
12739
- const binaryName = Buffer47.from(name);
13074
+ const binaryName = Buffer49.from(name);
12740
13075
  for (const key of mapping2.keys()) {
12741
- if (Buffer47.isBuffer(key) && key.equals(binaryName)) return true;
12742
- if (key instanceof Uint8Array && Buffer47.from(key).equals(binaryName))
13076
+ if (Buffer49.isBuffer(key) && key.equals(binaryName)) return true;
13077
+ if (key instanceof Uint8Array && Buffer49.from(key).equals(binaryName))
12743
13078
  return true;
12744
13079
  }
12745
13080
  return false;
@@ -12750,7 +13085,7 @@ function decodeError(message, raw) {
12750
13085
  function strictText2(value) {
12751
13086
  if (typeof value === "string")
12752
13087
  return value.isWellFormed() ? value : void 0;
12753
- if (Buffer47.isBuffer(value) || value instanceof Uint8Array) {
13088
+ if (Buffer49.isBuffer(value) || value instanceof Uint8Array) {
12754
13089
  try {
12755
13090
  return new TextDecoder("utf-8", { fatal: true }).decode(value);
12756
13091
  } catch {
@@ -12830,7 +13165,7 @@ function tryDecodeFlowQueryError(value, cause) {
12830
13165
  }
12831
13166
  function optionalDiagnosticText(mapping2, name) {
12832
13167
  const value = optionalText2(mapping2, name, "FLOW.QUERY diagnostic");
12833
- if (value != null && Buffer48.byteLength(value, "utf8") > DIAGNOSTIC_TEXT_BYTES) {
13168
+ if (value != null && Buffer50.byteLength(value, "utf8") > DIAGNOSTIC_TEXT_BYTES) {
12834
13169
  throw decodeError(
12835
13170
  `FLOW.QUERY diagnostic ${name} exceeds ${DIAGNOSTIC_TEXT_BYTES} bytes`,
12836
13171
  mapping2
@@ -12865,7 +13200,7 @@ function validateDiagnosticContextValue(value, depth, budget) {
12865
13200
  }
12866
13201
  const text3 = diagnosticContextText(value);
12867
13202
  if (text3 != null) {
12868
- if (Buffer48.byteLength(text3, "utf8") <= DIAGNOSTIC_TEXT_BYTES) return;
13203
+ if (Buffer50.byteLength(text3, "utf8") <= DIAGNOSTIC_TEXT_BYTES) return;
12869
13204
  throw decodeError("FLOW.QUERY diagnostic context contains oversized text", value);
12870
13205
  }
12871
13206
  if (depth <= 0) {
@@ -12891,7 +13226,7 @@ function validateDiagnosticContextValue(value, depth, budget) {
12891
13226
  }
12892
13227
  for (const [rawKey, item] of entries) {
12893
13228
  const key = diagnosticContextText(rawKey);
12894
- if (key == null || key.length === 0 || Buffer48.byteLength(key, "utf8") > DIAGNOSTIC_CONTEXT_KEY_BYTES) {
13229
+ if (key == null || key.length === 0 || Buffer50.byteLength(key, "utf8") > DIAGNOSTIC_CONTEXT_KEY_BYTES) {
12895
13230
  throw decodeError("FLOW.QUERY diagnostic context contains an invalid key", value);
12896
13231
  }
12897
13232
  validateDiagnosticContextValue(item, depth - 1, budget);
@@ -12908,7 +13243,7 @@ function consumeDiagnosticContextNode(value, budget) {
12908
13243
  }
12909
13244
  function diagnosticContextText(value) {
12910
13245
  if (typeof value === "string") return value.isWellFormed() ? value : void 0;
12911
- if (!Buffer48.isBuffer(value) && !(value instanceof Uint8Array)) return void 0;
13246
+ if (!Buffer50.isBuffer(value) && !(value instanceof Uint8Array)) return void 0;
12912
13247
  try {
12913
13248
  return new TextDecoder("utf-8", { fatal: true }).decode(value);
12914
13249
  } catch {
@@ -12934,7 +13269,7 @@ function decodePosition(value) {
12934
13269
  }
12935
13270
 
12936
13271
  // src/flow-query-index-contract.ts
12937
- import { Buffer as Buffer49 } from "buffer";
13272
+ import { Buffer as Buffer51 } from "buffer";
12938
13273
  var FLOW_QUERY_BUILD_PHASES = ["pending", "snapshot", "backfill", "done"];
12939
13274
  var FLOW_QUERY_VALIDATION_PHASES = [
12940
13275
  "pending",
@@ -13180,10 +13515,10 @@ function fieldKind(name) {
13180
13515
  return void 0;
13181
13516
  }
13182
13517
  function validUnquoted(value) {
13183
- return !value.startsWith("__") && UNQUOTED_METADATA.test(value) && Buffer49.byteLength(value, "ascii") <= 64;
13518
+ return !value.startsWith("__") && UNQUOTED_METADATA.test(value) && Buffer51.byteLength(value, "ascii") <= 64;
13184
13519
  }
13185
13520
  function validMetadata(value, rejectReserved) {
13186
- return value.length > 0 && Buffer49.byteLength(value, "utf8") <= 64 && (!rejectReserved || !value.startsWith("__"));
13521
+ return value.length > 0 && Buffer51.byteLength(value, "utf8") <= 64 && (!rejectReserved || !value.startsWith("__"));
13187
13522
  }
13188
13523
  function externalSelector(root, ...segments) {
13189
13524
  return segments.every(validUnquoted) ? [root, ...segments].join(".") : root + segments.map((segment) => `['${segment.replaceAll("'", "''")}']`).join("");
@@ -14090,7 +14425,7 @@ function decodePage(value) {
14090
14425
  const mapping2 = requiredMap2(value, "FLOW.QUERY page");
14091
14426
  const hasMore = requiredBoolean(mapping2, "has_more", "FLOW.QUERY page");
14092
14427
  const cursor = optionalText2(mapping2, "cursor", "FLOW.QUERY page");
14093
- if (cursor != null && (!cursor.startsWith("fqc1_") || Buffer50.byteLength(cursor) < 16 || Buffer50.byteLength(cursor) > 4096)) {
14428
+ if (cursor != null && (!cursor.startsWith("fqc1_") || Buffer52.byteLength(cursor) < 16 || Buffer52.byteLength(cursor) > 4096)) {
14094
14429
  throw decodeError("FLOW.QUERY page cursor is invalid", value);
14095
14430
  }
14096
14431
  if (hasMore !== (cursor != null)) {
@@ -14103,9 +14438,9 @@ function decodePage(value) {
14103
14438
  import "buffer";
14104
14439
 
14105
14440
  // src/client-core-helpers.ts
14106
- import { Buffer as Buffer51 } from "buffer";
14441
+ import { Buffer as Buffer53 } from "buffer";
14107
14442
  function bgsaveResponse(response) {
14108
- if ((typeof response === "string" || Buffer51.isBuffer(response) || response instanceof Uint8Array) && text(response) === "Background saving started") {
14443
+ if ((typeof response === "string" || Buffer53.isBuffer(response) || response instanceof Uint8Array) && text(response) === "Background saving started") {
14109
14444
  return true;
14110
14445
  }
14111
14446
  return okResponse(response);
@@ -14119,7 +14454,7 @@ function fetchOrComputeCompletionToken(options) {
14119
14454
  "fetch-or-compute completion requires computeToken"
14120
14455
  );
14121
14456
  }
14122
- if (!Buffer51.isBuffer(options.computeToken)) {
14457
+ if (!Buffer53.isBuffer(options.computeToken)) {
14123
14458
  throw new TypeError("fetch-or-compute computeToken must be a Buffer");
14124
14459
  }
14125
14460
  return options.computeToken;
@@ -14486,14 +14821,14 @@ var FerricStoreAdministrationClient = class extends FerricStoreClientBase {
14486
14821
  };
14487
14822
 
14488
14823
  // src/store-utilities.ts
14489
- import { Buffer as Buffer54 } from "buffer";
14824
+ import { Buffer as Buffer56 } from "buffer";
14490
14825
  function encode(codec, value) {
14491
14826
  return codec.encode(value);
14492
14827
  }
14493
14828
  function decode(codec, value) {
14494
14829
  if (value == null) return null;
14495
- if (Buffer54.isBuffer(value)) return codec.decode(value);
14496
- if (value instanceof Uint8Array) return codec.decode(Buffer54.from(value));
14830
+ if (Buffer56.isBuffer(value)) return codec.decode(value);
14831
+ if (value instanceof Uint8Array) return codec.decode(Buffer56.from(value));
14497
14832
  return value;
14498
14833
  }
14499
14834
  function number(value) {
@@ -17349,7 +17684,7 @@ function throwIfClosed(signal) {
17349
17684
  }
17350
17685
 
17351
17686
  // src/flow-policy.ts
17352
- import { Buffer as Buffer56 } from "buffer";
17687
+ import { Buffer as Buffer58 } from "buffer";
17353
17688
  var MAX_FLOW_POLICY_GENERATION = Number.MAX_SAFE_INTEGER;
17354
17689
  function assertFlowPolicyGeneration(value) {
17355
17690
  if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
@@ -17439,7 +17774,7 @@ function requiredRecord(value, context) {
17439
17774
  }
17440
17775
  return result;
17441
17776
  }
17442
- if (typeof value === "object" && value != null && !Array.isArray(value) && !Buffer56.isBuffer(value) && !(value instanceof Uint8Array)) return value;
17777
+ if (typeof value === "object" && value != null && !Array.isArray(value) && !Buffer58.isBuffer(value) && !(value instanceof Uint8Array)) return value;
17443
17778
  throw new TypeError(`${context} returned an unexpected response`);
17444
17779
  }
17445
17780
  function optionalRecord(value, context) {
@@ -17460,8 +17795,8 @@ function stringArray(value, context) {
17460
17795
  }
17461
17796
  function requiredText4(value, context) {
17462
17797
  if (typeof value === "string") return value;
17463
- if (Buffer56.isBuffer(value) || value instanceof Uint8Array) {
17464
- return Buffer56.from(value).toString("utf8");
17798
+ if (Buffer58.isBuffer(value) || value instanceof Uint8Array) {
17799
+ return Buffer58.from(value).toString("utf8");
17465
17800
  }
17466
17801
  throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
17467
17802
  }
@@ -17717,7 +18052,7 @@ var FerricStoreFlowSupportClient = class extends FerricStoreFlowQueryClient {
17717
18052
  };
17718
18053
 
17719
18054
  // src/flow-many-snapshot.ts
17720
- import { Buffer as Buffer58 } from "buffer";
18055
+ import { Buffer as Buffer60 } from "buffer";
17721
18056
  var encodedOptionFields = ["error", "payload", "reason", "result"];
17722
18057
  function snapshotCreateItem(item, codec) {
17723
18058
  const snapshot = {
@@ -17757,7 +18092,7 @@ function snapshotFlowManyOptions(options, codec) {
17757
18092
  }
17758
18093
  function snapshotClaimedItem(item) {
17759
18094
  const wire = item[CLAIMED_ITEM_WIRE];
17760
- const leaseToken = Buffer58.from(wire?.leaseToken ?? item.leaseToken);
18095
+ const leaseToken = Buffer60.from(wire?.leaseToken ?? item.leaseToken);
17761
18096
  const snapshot = {
17762
18097
  ...item,
17763
18098
  fencingToken: wire?.fencingToken ?? item.fencingToken,
@@ -17774,15 +18109,15 @@ function snapshotClaimedItem(item) {
17774
18109
  function snapshotFencedItem(item) {
17775
18110
  return Object.freeze({
17776
18111
  ...item,
17777
- ...item.leaseToken == null ? {} : { leaseToken: Buffer58.from(item.leaseToken) }
18112
+ ...item.leaseToken == null ? {} : { leaseToken: Buffer60.from(item.leaseToken) }
17778
18113
  });
17779
18114
  }
17780
18115
  function snapshotClaimedItemWire(wire, leaseToken) {
17781
18116
  return Object.freeze({
17782
18117
  fencingToken: wire.fencingToken,
17783
- id: Buffer58.from(wire.id),
18118
+ id: Buffer60.from(wire.id),
17784
18119
  leaseToken,
17785
- partitionKey: wire.partitionKey == null ? wire.partitionKey : Buffer58.from(wire.partitionKey)
18120
+ partitionKey: wire.partitionKey == null ? wire.partitionKey : Buffer60.from(wire.partitionKey)
17786
18121
  });
17787
18122
  }
17788
18123
  function snapshotArray(values) {
@@ -17793,7 +18128,7 @@ function snapshotArray(values) {
17793
18128
  return Object.freeze(snapshot);
17794
18129
  }
17795
18130
  function snapshotStateMeta(stateMeta) {
17796
- return snapshotRecord(stateMeta, (value) => Buffer58.isBuffer(value) ? Buffer58.from(value) : value);
18131
+ return snapshotRecord(stateMeta, (value) => Buffer60.isBuffer(value) ? Buffer60.from(value) : value);
17797
18132
  }
17798
18133
  function snapshotCommandRecord(values) {
17799
18134
  const seen = /* @__PURE__ */ new WeakMap();
@@ -17811,7 +18146,7 @@ function snapshotRecord(values, capture) {
17811
18146
  }
17812
18147
  function snapshotCommandArgument(value, seen) {
17813
18148
  if (typeof value !== "object" || value == null) return value;
17814
- if (Buffer58.isBuffer(value) || value instanceof Uint8Array) return Buffer58.from(value);
18149
+ if (Buffer60.isBuffer(value) || value instanceof Uint8Array) return Buffer60.from(value);
17815
18150
  const objectValue = value;
17816
18151
  const existing = seen.get(objectValue);
17817
18152
  if (existing != null) return existing;
@@ -18807,7 +19142,7 @@ function nativeOptionsForBootstrap(options, signal) {
18807
19142
  }
18808
19143
 
18809
19144
  // src/flow-query-projection.ts
18810
- import { Buffer as Buffer59 } from "buffer";
19145
+ import { Buffer as Buffer61 } from "buffer";
18811
19146
  var MAX_PROJECTION_FIELDS = 32;
18812
19147
  var MAX_DYNAMIC_NAME_BYTES = 64;
18813
19148
  var FIELD_BRAND = /* @__PURE__ */ Symbol("FerricStoreFlowProjectionField");
@@ -18877,7 +19212,7 @@ function projectFlowQuery(query, shape, ...fields) {
18877
19212
  }
18878
19213
  const base = stripOptionalTerminator(query);
18879
19214
  const result = `${base} RETURN ${shape.toUpperCase()} (${selectors.join(", ")})`;
18880
- if (Buffer59.byteLength(result, "utf8") > FLOW_QUERY_MAX_BYTES) {
19215
+ if (Buffer61.byteLength(result, "utf8") > FLOW_QUERY_MAX_BYTES) {
18881
19216
  throw new TypeError(`FLOW.QUERY query exceeds ${FLOW_QUERY_MAX_BYTES} bytes`);
18882
19217
  }
18883
19218
  return result;
@@ -18937,7 +19272,7 @@ function quoteName(value, allowPrivate) {
18937
19272
  throw new TypeError("Flow query projection metadata name must be text");
18938
19273
  }
18939
19274
  validateUnicodeScalarText2(value);
18940
- const size = Buffer59.byteLength(value, "utf8");
19275
+ const size = Buffer61.byteLength(value, "utf8");
18941
19276
  if (size === 0 || size > MAX_DYNAMIC_NAME_BYTES || !allowPrivate && value.startsWith("__")) {
18942
19277
  throw new TypeError(
18943
19278
  `Flow query projection metadata names must be 1..${MAX_DYNAMIC_NAME_BYTES} UTF-8 bytes`
@@ -20943,7 +21278,7 @@ var WorkflowWorker = class {
20943
21278
  };
20944
21279
 
20945
21280
  // src/version.ts
20946
- var FERRICSTORE_SDK_VERSION = "0.11.9";
21281
+ var FERRICSTORE_SDK_VERSION = "0.11.11";
20947
21282
  var FERRICSTORE_MINIMUM_SERVER_VERSION = "0.11.4";
20948
21283
  var FERRICSTORE_NATIVE_PROTOCOL_VERSION = 1;
20949
21284
  export {