@ferricstore/ferricstore 0.11.9 → 0.11.10

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.cjs CHANGED
@@ -1556,6 +1556,7 @@ var neverAutoBatchCommandPrefixes = /* @__PURE__ */ new Set([
1556
1556
  "BLPOP",
1557
1557
  "BRPOP",
1558
1558
  "BRPOPLPUSH",
1559
+ "BZMPOP",
1559
1560
  "BZPOPMAX",
1560
1561
  "BZPOPMIN",
1561
1562
  "CLIENT",
@@ -1667,6 +1668,9 @@ var connectionBlockingCommands = /* @__PURE__ */ new Set([
1667
1668
  "BLPOP",
1668
1669
  "BRPOP",
1669
1670
  "BRPOPLPUSH",
1671
+ "BZMPOP",
1672
+ "BZPOPMAX",
1673
+ "BZPOPMIN",
1670
1674
  "XREAD",
1671
1675
  "XREADGROUP"
1672
1676
  ]);
@@ -2535,8 +2539,10 @@ function serverBlockMetadata(args) {
2535
2539
  serverBlockMs = blockDurationMs(args[3], 1e3);
2536
2540
  } else if (command === "BLMOVE" && args.length >= 6) {
2537
2541
  serverBlockMs = blockDurationMs(args[args.length - 1], 1e3);
2538
- } else if (command === "BLMPOP" && args.length >= 2) {
2542
+ } else if ((command === "BLMPOP" || command === "BZMPOP") && args.length >= 2) {
2539
2543
  serverBlockMs = blockDurationMs(args[1], 1e3);
2544
+ } else if ((command === "BZPOPMAX" || command === "BZPOPMIN") && args.length >= 3) {
2545
+ serverBlockMs = blockDurationMs(args[args.length - 1], 1e3);
2540
2546
  } else if (command === "XREAD" || command === "XREADGROUP") {
2541
2547
  serverBlockMs = optionBlockDurationMs(args, ["BLOCK"], "STREAMS");
2542
2548
  } else if (command === "WAIT" && args.length === 3) {
@@ -7596,6 +7602,24 @@ async function executeIndividually(host, commands, laneId, options) {
7596
7602
  }, commands, options);
7597
7603
  }
7598
7604
 
7605
+ // src/server-response-timeout.ts
7606
+ function serverResponseTimeoutMs(requestTimeoutMs, serverBlockMs) {
7607
+ if (serverBlockMs == null) return requestTimeoutMs;
7608
+ if (serverBlockMs === 0) return void 0;
7609
+ return saturatingAdd(requestTimeoutMs, serverBlockMs);
7610
+ }
7611
+ function combinedServerBlockMs(values) {
7612
+ let total;
7613
+ for (const value of values) {
7614
+ if (value === 0) return 0;
7615
+ if (value != null) total = saturatingAdd(total ?? 0, value);
7616
+ }
7617
+ return total;
7618
+ }
7619
+ function saturatingAdd(left, right) {
7620
+ return Math.min(Number.MAX_SAFE_INTEGER, left + right);
7621
+ }
7622
+
7599
7623
  // src/native-pending-timeout.ts
7600
7624
  function timeoutNativePendingRequest(operations, requestId, timeoutMs) {
7601
7625
  const pending = operations.getPending(requestId);
@@ -7624,10 +7648,7 @@ function timeoutNativePendingRequest(operations, requestId, timeoutMs) {
7624
7648
  pending.reject(new RequestTimeoutError(timeoutMs, "possibly_sent"));
7625
7649
  }
7626
7650
  function nativeResponseTimeoutMs(command, requestTimeoutMs) {
7627
- const blockMs = command.serverBlockMs;
7628
- if (blockMs == null) return requestTimeoutMs;
7629
- if (blockMs === 0) return void 0;
7630
- return Math.min(Number.MAX_SAFE_INTEGER, requestTimeoutMs + blockMs);
7651
+ return serverResponseTimeoutMs(requestTimeoutMs, command.serverBlockMs);
7631
7652
  }
7632
7653
 
7633
7654
  // src/native-chunk-assembler.ts
@@ -8655,12 +8676,14 @@ var NativeAdapter = class _NativeAdapter {
8655
8676
  };
8656
8677
 
8657
8678
  // src/http-command-policy.ts
8679
+ var import_node_buffer33 = require("buffer");
8658
8680
  var nativeOnlyCommands = /* @__PURE__ */ new Set([
8659
8681
  "AUTH",
8660
8682
  "BACKPRESSURE",
8661
8683
  "CLIENT",
8662
8684
  "CLIENT.INFO",
8663
8685
  "CLIENT.SETNAME",
8686
+ "COMMAND_EXEC",
8664
8687
  "EVENT",
8665
8688
  "GOAWAY",
8666
8689
  "HELLO",
@@ -8676,48 +8699,67 @@ var nativeOnlyCommands = /* @__PURE__ */ new Set([
8676
8699
  "WINDOW_UPDATE"
8677
8700
  ]);
8678
8701
  var sessionOnlyCommands = /* @__PURE__ */ new Set([
8702
+ "ASKING",
8679
8703
  "AUTH",
8680
- "BLMOVE",
8681
- "BLMPOP",
8682
- "BLPOP",
8683
- "BRPOP",
8684
8704
  "CLIENT",
8685
8705
  "DISCARD",
8686
8706
  "EXEC",
8687
8707
  "HELLO",
8708
+ "MONITOR",
8688
8709
  "MULTI",
8689
8710
  "PSUBSCRIBE",
8711
+ "PSYNC",
8690
8712
  "PUNSUBSCRIBE",
8691
8713
  "QUIT",
8714
+ "READONLY",
8715
+ "READWRITE",
8716
+ "REPLCONF",
8717
+ "RESET",
8718
+ "SANDBOX",
8692
8719
  "SELECT",
8720
+ "SSUBSCRIBE",
8693
8721
  "SUBSCRIBE",
8722
+ "SUNSUBSCRIBE",
8723
+ "SYNC",
8694
8724
  "UNSUBSCRIBE",
8695
8725
  "UNWATCH",
8696
- "WATCH",
8697
- "XREAD",
8698
- "XREADGROUP"
8726
+ "WATCH"
8699
8727
  ]);
8700
8728
  function httpCommandDisposition(name) {
8701
8729
  const normalized = name.toUpperCase();
8702
8730
  return nativeOnlyCommands.has(normalized) || sessionOnlyCommands.has(normalized) ? "native_only" : "supported";
8703
8731
  }
8704
8732
  function assertHTTPCommandSupported(name) {
8705
- if (typeof name !== "string" || name === "") throw new TypeError("HTTP command must have a name");
8706
- if (sessionOnlyCommands.has(name.toUpperCase())) {
8707
- throw new Error(`${name.toUpperCase()} requires a persistent native TCP session`);
8733
+ const normalized = normalizedCommandName(name);
8734
+ if (normalized == null || normalized === "") throw new TypeError("HTTP command must have a name");
8735
+ if (sessionOnlyCommands.has(normalized)) {
8736
+ throw new InvalidCommandError(`${normalized} requires a persistent native TCP session`);
8708
8737
  }
8738
+ if (nativeOnlyCommands.has(normalized)) {
8739
+ throw new InvalidCommandError(`${normalized} is a native TCP transport control command`);
8740
+ }
8741
+ }
8742
+ function normalizedCommandName(value) {
8743
+ if (typeof value === "string") return value.toUpperCase();
8744
+ if (import_node_buffer33.Buffer.isBuffer(value) || value instanceof Uint8Array) {
8745
+ return import_node_buffer33.Buffer.from(value).toString("utf8").toUpperCase();
8746
+ }
8747
+ return void 0;
8709
8748
  }
8710
8749
 
8711
8750
  // src/http-envelope.ts
8712
- var import_node_buffer33 = require("buffer");
8751
+ var import_node_buffer34 = require("buffer");
8713
8752
  var encoding = "ferricstore-json-v1";
8714
8753
  var bytesMarker = "$ferricstore_bytes";
8715
8754
  var mapMarker = "$ferricstore_map";
8716
8755
  var maxDepth = 64;
8717
- function encodeHTTPCommands(commands) {
8718
- return import_node_buffer33.Buffer.from(JSON.stringify({
8756
+ var bytesMarkerBaseBytes = import_node_buffer34.Buffer.byteLength(bytesMarker) + 7;
8757
+ var mapMarkerBaseBytes = import_node_buffer34.Buffer.byteLength(mapMarker) + 7;
8758
+ function encodeHTTPCommands(commands, maxBytes = Number.MAX_SAFE_INTEGER) {
8759
+ const budget = { remaining: maxBytes };
8760
+ return import_node_buffer34.Buffer.from(JSON.stringify({
8719
8761
  encoding,
8720
- commands: commands.map((command) => encodeValue(command, 0))
8762
+ commands: commands.map((command) => encodeValue(command, 0, budget))
8721
8763
  }));
8722
8764
  }
8723
8765
  function decodeHTTPEnvelope(source) {
@@ -8730,30 +8772,55 @@ function decodeHTTPEnvelope(source) {
8730
8772
  if (!isRecord(parsed)) throw new TypeError("HTTP command response must be an object");
8731
8773
  return decodePlainRecord(parsed, 0);
8732
8774
  }
8733
- function encodeValue(value, depth) {
8775
+ function encodeValue(value, depth, budget) {
8734
8776
  if (depth > maxDepth) throw new TypeError("HTTP command value exceeds maximum depth");
8735
- if (value == null || typeof value === "string" || typeof value === "boolean") return value;
8736
- if (import_node_buffer33.Buffer.isBuffer(value) || value instanceof Uint8Array) {
8737
- return { [bytesMarker]: import_node_buffer33.Buffer.from(value).toString("base64") };
8777
+ if (value == null) {
8778
+ consumeBudget(budget, 1);
8779
+ return value;
8780
+ }
8781
+ if (typeof value === "string") {
8782
+ consumeBudget(budget, import_node_buffer34.Buffer.byteLength(value) + 2);
8783
+ return value;
8784
+ }
8785
+ if (typeof value === "boolean") {
8786
+ consumeBudget(budget, 1);
8787
+ return value;
8788
+ }
8789
+ if (import_node_buffer34.Buffer.isBuffer(value) || value instanceof Uint8Array) {
8790
+ consumeBudget(budget, bytesMarkerBaseBytes + 4 * Math.ceil(value.byteLength / 3));
8791
+ return { [bytesMarker]: import_node_buffer34.Buffer.from(value).toString("base64") };
8738
8792
  }
8739
8793
  if (typeof value === "number") {
8740
8794
  if (!Number.isFinite(value)) throw new TypeError("HTTP command numbers must be finite");
8795
+ consumeBudget(budget, 1);
8741
8796
  return value;
8742
8797
  }
8743
8798
  if (typeof value === "bigint") {
8744
- return value >= BigInt(Number.MIN_SAFE_INTEGER) && value <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(value) : value.toString();
8799
+ const encoded = value >= BigInt(Number.MIN_SAFE_INTEGER) && value <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(value) : value.toString();
8800
+ consumeBudget(budget, typeof encoded === "number" ? 1 : import_node_buffer34.Buffer.byteLength(encoded) + 2);
8801
+ return encoded;
8802
+ }
8803
+ if (Array.isArray(value)) {
8804
+ consumeBudget(budget, 2 + Math.max(0, value.length - 1));
8805
+ return denseArray(value, depth + 1, (item, itemDepth) => encodeValue(item, itemDepth, budget));
8745
8806
  }
8746
- if (Array.isArray(value)) return denseArray(value, depth + 1, encodeValue);
8747
8807
  if (value instanceof Map) {
8748
- return { [mapMarker]: [...value.entries()].map(([key, item]) => [
8749
- encodeValue(key, depth + 1),
8750
- encodeValue(item, depth + 1)
8751
- ]) };
8808
+ consumeBudget(budget, mapMarkerBaseBytes + value.size);
8809
+ const pairs = [];
8810
+ for (const [key, item] of value.entries()) {
8811
+ pairs.push([
8812
+ encodeValue(key, depth + 1, budget),
8813
+ encodeValue(item, depth + 1, budget)
8814
+ ]);
8815
+ }
8816
+ return { [mapMarker]: pairs };
8752
8817
  }
8753
8818
  if (isRecord(value)) {
8754
- return { [mapMarker]: Object.entries(value).map(([key, item]) => [
8755
- encodeValue(key, depth + 1),
8756
- encodeValue(item, depth + 1)
8819
+ const keys = Object.keys(value);
8820
+ consumeBudget(budget, mapMarkerBaseBytes + keys.length);
8821
+ return { [mapMarker]: keys.map((key) => [
8822
+ encodeValue(key, depth + 1, budget),
8823
+ encodeValue(value[key], depth + 1, budget)
8757
8824
  ]) };
8758
8825
  }
8759
8826
  throw new TypeError(`unsupported HTTP command value: ${typeof value}`);
@@ -8779,15 +8846,28 @@ function decodeBase64(value) {
8779
8846
  if (value.length % 4 !== 0 || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(value)) {
8780
8847
  throw new TypeError("invalid HTTP bytes marker");
8781
8848
  }
8782
- const decoded = import_node_buffer33.Buffer.from(value, "base64");
8849
+ const decoded = import_node_buffer34.Buffer.from(value, "base64");
8783
8850
  if (decoded.toString("base64") !== value) throw new TypeError("invalid HTTP bytes marker");
8784
8851
  return decoded;
8785
8852
  }
8786
8853
  function decodePlainRecord(value, depth) {
8787
8854
  const result = {};
8788
- for (const [key, item] of Object.entries(value)) result[key] = decodeValue2(item, depth);
8855
+ for (const [key, item] of Object.entries(value)) {
8856
+ Object.defineProperty(result, key, {
8857
+ configurable: true,
8858
+ enumerable: true,
8859
+ value: decodeValue2(item, depth),
8860
+ writable: true
8861
+ });
8862
+ }
8789
8863
  return result;
8790
8864
  }
8865
+ function consumeBudget(budget, amount) {
8866
+ if (amount > budget.remaining) {
8867
+ throw new HTTPTransportError("HTTP command request exceeds maxRequestBytes");
8868
+ }
8869
+ budget.remaining -= amount;
8870
+ }
8791
8871
  function denseArray(values, depth, transform) {
8792
8872
  const result = new Array(values.length);
8793
8873
  for (let index = 0; index < values.length; index += 1) {
@@ -8797,10 +8877,12 @@ function denseArray(values, depth, transform) {
8797
8877
  return result;
8798
8878
  }
8799
8879
  function isRecord(value) {
8800
- return typeof value === "object" && value != null && !Array.isArray(value) && !import_node_buffer33.Buffer.isBuffer(value);
8880
+ return typeof value === "object" && value != null && !Array.isArray(value) && !import_node_buffer34.Buffer.isBuffer(value);
8801
8881
  }
8802
8882
 
8803
8883
  // src/http-options.ts
8884
+ var import_node_buffer35 = require("buffer");
8885
+ var import_node_http = require("http");
8804
8886
  function normalizeHTTPOptions(value, options) {
8805
8887
  const url = new URL(value);
8806
8888
  if (url.protocol !== "http:" && url.protocol !== "https:") {
@@ -8826,10 +8908,10 @@ function normalizeHTTPOptions(value, options) {
8826
8908
  });
8827
8909
  }
8828
8910
  function normalizedHeaders(source) {
8829
- const headers = {};
8911
+ const headers = /* @__PURE__ */ Object.create(null);
8830
8912
  for (const [rawName, value] of Object.entries(source)) {
8831
8913
  const name = rawName.toLowerCase();
8832
- if (name === "" || !safeHeader(name) || !safeHeader(value)) {
8914
+ if (typeof value !== "string" || !validHeader(name, value)) {
8833
8915
  throw new TypeError(`invalid HTTP header: ${rawName}`);
8834
8916
  }
8835
8917
  headers[name] = value;
@@ -8841,7 +8923,9 @@ function authorizationHeader(url, options, custom) {
8841
8923
  const count = Number(custom != null) + Number(options.bearerToken != null) + Number(basic);
8842
8924
  if (count > 1) throw new TypeError("HTTP credentials are mutually exclusive");
8843
8925
  if (options.bearerToken != null) {
8844
- if (!safeHeader(options.bearerToken)) throw new TypeError("invalid bearer token");
8926
+ if (options.bearerToken === "" || !validHeader("authorization", `Bearer ${options.bearerToken}`)) {
8927
+ throw new TypeError("invalid bearer token");
8928
+ }
8845
8929
  return `Bearer ${options.bearerToken}`;
8846
8930
  }
8847
8931
  if (!basic) return custom;
@@ -8851,7 +8935,7 @@ function authorizationHeader(url, options, custom) {
8851
8935
  if (username === "" || username.includes(":") || !safeHeader(username) || !safeHeader(options.password)) {
8852
8936
  throw new TypeError("invalid Basic authentication credentials");
8853
8937
  }
8854
- return `Basic ${Buffer.from(`${username}:${options.password}`).toString("base64")}`;
8938
+ return `Basic ${import_node_buffer35.Buffer.from(`${username}:${options.password}`).toString("base64")}`;
8855
8939
  }
8856
8940
  function positiveInteger(value, fallback, name) {
8857
8941
  const result = value ?? fallback;
@@ -8871,36 +8955,167 @@ function booleanOption(value, fallback, name) {
8871
8955
  function safeHeader(value) {
8872
8956
  return !value.includes("\r") && !value.includes("\n");
8873
8957
  }
8958
+ function validHeader(name, value) {
8959
+ try {
8960
+ (0, import_node_http.validateHeaderName)(name);
8961
+ (0, import_node_http.validateHeaderValue)(name, value);
8962
+ return true;
8963
+ } catch {
8964
+ return false;
8965
+ }
8966
+ }
8874
8967
 
8875
8968
  // src/http-transport.ts
8876
- var import_node_http = __toESM(require("http"), 1);
8877
- var import_node_http2 = __toESM(require("http2"), 1);
8969
+ var import_node_http2 = __toESM(require("http"), 1);
8970
+ var import_node_http22 = __toESM(require("http2"), 1);
8878
8971
  var import_node_https = __toESM(require("https"), 1);
8879
- var import_node_buffer34 = require("buffer");
8972
+ var import_node_buffer36 = require("buffer");
8973
+
8974
+ // src/http2-slot-pool.ts
8975
+ var HTTP2SessionRetiredError = class extends Error {
8976
+ constructor(message, cause) {
8977
+ super(message, { cause });
8978
+ this.name = "HTTP2SessionRetiredError";
8979
+ }
8980
+ };
8981
+ var HTTP2SlotPool = class {
8982
+ active = 0;
8983
+ idleCallback;
8984
+ limit;
8985
+ retiredError;
8986
+ waiterHead;
8987
+ waiterTail;
8988
+ acquire(signal) {
8989
+ if (signal.aborted) return Promise.reject(signalAbortError(signal));
8990
+ if (this.retiredError != null) return Promise.reject(this.retiredError);
8991
+ if (this.limit != null && this.active < this.limit) {
8992
+ this.active += 1;
8993
+ return Promise.resolve(this.releaseOnce());
8994
+ }
8995
+ return new Promise((resolve, reject) => {
8996
+ const waiter = {
8997
+ abort: () => {
8998
+ if (waiter.settled) return;
8999
+ waiter.settled = true;
9000
+ this.removeWaiter(waiter);
9001
+ reject(signalAbortError(signal));
9002
+ },
9003
+ queued: true,
9004
+ reject,
9005
+ resolve,
9006
+ settled: false,
9007
+ signal
9008
+ };
9009
+ this.enqueueWaiter(waiter);
9010
+ signal.addEventListener("abort", waiter.abort, { once: true });
9011
+ });
9012
+ }
9013
+ updateLimit(limit) {
9014
+ if (this.retiredError != null) return;
9015
+ this.limit = limit;
9016
+ this.drain();
9017
+ }
9018
+ retire(error) {
9019
+ if (this.retiredError != null) return;
9020
+ this.retiredError = error;
9021
+ while (this.waiterHead != null) {
9022
+ const waiter = this.waiterHead;
9023
+ this.removeWaiter(waiter);
9024
+ if (waiter.settled) continue;
9025
+ waiter.settled = true;
9026
+ waiter.signal.removeEventListener("abort", waiter.abort);
9027
+ waiter.reject(error);
9028
+ }
9029
+ }
9030
+ whenIdle(callback) {
9031
+ if (this.active === 0) callback();
9032
+ else this.idleCallback = callback;
9033
+ }
9034
+ drain() {
9035
+ while (this.retiredError == null && this.limit != null && this.active < this.limit) {
9036
+ const waiter = this.waiterHead;
9037
+ if (waiter == null) return;
9038
+ this.removeWaiter(waiter);
9039
+ if (waiter.settled) continue;
9040
+ waiter.settled = true;
9041
+ waiter.signal.removeEventListener("abort", waiter.abort);
9042
+ this.active += 1;
9043
+ waiter.resolve(this.releaseOnce());
9044
+ }
9045
+ }
9046
+ enqueueWaiter(waiter) {
9047
+ waiter.previous = this.waiterTail;
9048
+ if (this.waiterTail == null) this.waiterHead = waiter;
9049
+ else this.waiterTail.next = waiter;
9050
+ this.waiterTail = waiter;
9051
+ }
9052
+ removeWaiter(waiter) {
9053
+ if (!waiter.queued) return;
9054
+ if (waiter.previous == null) this.waiterHead = waiter.next;
9055
+ else waiter.previous.next = waiter.next;
9056
+ if (waiter.next == null) this.waiterTail = waiter.previous;
9057
+ else waiter.next.previous = waiter.previous;
9058
+ waiter.next = void 0;
9059
+ waiter.previous = void 0;
9060
+ waiter.queued = false;
9061
+ }
9062
+ releaseOnce() {
9063
+ let released = false;
9064
+ return () => {
9065
+ if (released) return;
9066
+ released = true;
9067
+ this.active -= 1;
9068
+ this.drain();
9069
+ if (this.active === 0) {
9070
+ const callback = this.idleCallback;
9071
+ this.idleCallback = void 0;
9072
+ callback?.();
9073
+ }
9074
+ };
9075
+ }
9076
+ };
9077
+ function signalAbortError(signal) {
9078
+ return signal.reason instanceof Error ? signal.reason : new HTTPTransportError("HTTP request was aborted", { raw: signal.reason });
9079
+ }
9080
+
9081
+ // src/http-transport.ts
8880
9082
  var HTTPTransport = class {
8881
9083
  constructor(config) {
8882
9084
  this.config = config;
8883
- this.#httpAgent = new import_node_http.default.Agent({ keepAlive: true, maxSockets: config.maxConnections });
9085
+ this.#httpAgent = new import_node_http2.default.Agent({
9086
+ keepAlive: true,
9087
+ maxFreeSockets: config.maxConnections,
9088
+ maxSockets: config.maxConnections,
9089
+ maxTotalSockets: config.maxConnections
9090
+ });
8884
9091
  this.#httpsAgent = new import_node_https.default.Agent({
8885
9092
  ...config.tlsOptions,
8886
9093
  keepAlive: true,
8887
- maxSockets: config.maxConnections
9094
+ maxFreeSockets: config.maxConnections,
9095
+ maxSockets: config.maxConnections,
9096
+ maxTotalSockets: config.maxConnections
8888
9097
  });
8889
9098
  }
8890
9099
  config;
8891
9100
  #httpAgent;
8892
9101
  #httpsAgent;
9102
+ #allSessions = /* @__PURE__ */ new Set();
8893
9103
  #sessions = /* @__PURE__ */ new Map();
9104
+ #sessionSlots = /* @__PURE__ */ new WeakMap();
9105
+ #requests = /* @__PURE__ */ new Set();
8894
9106
  #closed = false;
8895
- async post(body) {
9107
+ async post(body, timeoutMs) {
8896
9108
  if (this.#closed) throw new HTTPTransportError("HTTP transport is closed");
8897
9109
  const controller = new AbortController();
8898
- const timer = setTimeout(() => controller.abort(), this.config.timeoutMs);
9110
+ this.#requests.add(controller);
9111
+ const timer = timeoutMs == null ? void 0 : setLongTimeout(() => controller.abort(requestTimeoutReason), timeoutMs);
9112
+ timer?.unref();
8899
9113
  try {
8900
9114
  return await this.request(this.config.commandUrl, "POST", body, 0, controller.signal);
8901
9115
  } catch (error) {
8902
9116
  if (controller.signal.aborted) {
8903
- throw new RequestTimeoutError(this.config.timeoutMs, "possibly_sent", {
9117
+ if (controller.signal.reason instanceof HTTPTransportError) throw controller.signal.reason;
9118
+ throw new RequestTimeoutError(timeoutMs ?? this.config.timeoutMs, "possibly_sent", {
8904
9119
  cause: error,
8905
9120
  raw: { retryable: true, safe_to_retry: false }
8906
9121
  });
@@ -8912,15 +9127,19 @@ var HTTPTransport = class {
8912
9127
  safeToRetry: false
8913
9128
  });
8914
9129
  } finally {
8915
- clearTimeout(timer);
9130
+ timer?.cancel();
9131
+ this.#requests.delete(controller);
8916
9132
  }
8917
9133
  }
8918
9134
  async close() {
8919
9135
  if (this.#closed) return;
8920
9136
  this.#closed = true;
9137
+ const error = new HTTPTransportError("HTTP transport is closed");
9138
+ for (const controller of this.#requests) controller.abort(error);
8921
9139
  this.#httpAgent.destroy();
8922
9140
  this.#httpsAgent.destroy();
8923
- for (const session of this.#sessions.values()) session.destroy();
9141
+ for (const session of this.#allSessions) session.destroy();
9142
+ this.#allSessions.clear();
8924
9143
  this.#sessions.clear();
8925
9144
  }
8926
9145
  async request(url, method, body, redirects, signal) {
@@ -8943,7 +9162,7 @@ var HTTPTransport = class {
8943
9162
  );
8944
9163
  }
8945
9164
  async http1Request(url, method, body, signal) {
8946
- const request = url.protocol === "https:" ? import_node_https.default.request : import_node_http.default.request;
9165
+ const request = url.protocol === "https:" ? import_node_https.default.request : import_node_http2.default.request;
8947
9166
  const agent = url.protocol === "https:" ? this.#httpsAgent : this.#httpAgent;
8948
9167
  const headers = this.requestHeaders(body);
8949
9168
  return await new Promise((resolve, reject) => {
@@ -8968,7 +9187,6 @@ var HTTPTransport = class {
8968
9187
  );
8969
9188
  }
8970
9189
  async http2Request(url, method, body, signal) {
8971
- const session = this.session(url);
8972
9190
  const headers = {
8973
9191
  ...this.requestHeaders(body),
8974
9192
  ":authority": url.host,
@@ -8976,10 +9194,43 @@ var HTTPTransport = class {
8976
9194
  ":path": `${url.pathname}${url.search}`,
8977
9195
  ":scheme": url.protocol.slice(0, -1)
8978
9196
  };
9197
+ if (signal.aborted) throw signalAbortError(signal);
9198
+ for (let attempt = 0; attempt < 2; attempt += 1) {
9199
+ const session = this.session(url);
9200
+ let release;
9201
+ try {
9202
+ release = await this.slotPool(session).acquire(signal);
9203
+ } catch (error) {
9204
+ if (attempt === 0 && error instanceof HTTP2SessionRetiredError && !signal.aborted) continue;
9205
+ throw error;
9206
+ }
9207
+ try {
9208
+ let stream;
9209
+ try {
9210
+ stream = session.request(headers);
9211
+ } catch (error) {
9212
+ if (attempt === 0 && retryableSessionOpenError(error) && !signal.aborted) {
9213
+ this.retireSession(url.origin, session, true, error);
9214
+ continue;
9215
+ }
9216
+ throw error;
9217
+ }
9218
+ try {
9219
+ return await this.collectHttp2(stream, body, signal);
9220
+ } catch (error) {
9221
+ if (attempt === 0 && refusedStreamError(error) && !signal.aborted) continue;
9222
+ throw error;
9223
+ }
9224
+ } finally {
9225
+ release();
9226
+ }
9227
+ }
9228
+ throw new HTTPTransportError("HTTP/2 session could not accept the request");
9229
+ }
9230
+ async collectHttp2(stream, body, signal) {
8979
9231
  return await new Promise((resolve, reject) => {
8980
- const stream = session.request(headers);
8981
9232
  let responseHeaders = {};
8982
- const abort = () => stream.close(import_node_http2.default.constants.NGHTTP2_CANCEL);
9233
+ const abort = () => stream.close(import_node_http22.default.constants.NGHTTP2_CANCEL);
8983
9234
  signal.addEventListener("abort", abort, { once: true });
8984
9235
  stream.once("response", (value) => responseHeaders = value);
8985
9236
  stream.once("error", reject);
@@ -8987,19 +9238,60 @@ var HTTPTransport = class {
8987
9238
  const status = Number(responseHeaders[":status"] ?? 0);
8988
9239
  resolve({ body: response.body, headers: normalizeHeaders(responseHeaders), status });
8989
9240
  }, reject).finally(() => signal.removeEventListener("abort", abort));
8990
- stream.end(body);
9241
+ if (signal.aborted) abort();
9242
+ else stream.end(body);
8991
9243
  });
8992
9244
  }
8993
9245
  session(url) {
8994
9246
  const origin = url.origin;
8995
9247
  const current = this.#sessions.get(origin);
8996
9248
  if (current != null && !current.closed && !current.destroyed) return current;
8997
- const session = import_node_http2.default.connect(origin, this.config.tlsOptions);
8998
- session.on("error", () => void 0);
8999
- session.once("close", () => this.#sessions.delete(origin));
9249
+ const session = import_node_http22.default.connect(origin, {
9250
+ ...this.config.tlsOptions,
9251
+ settings: { enablePush: false }
9252
+ });
9253
+ const slots = new HTTP2SlotPool();
9254
+ this.#allSessions.add(session);
9255
+ this.#sessionSlots.set(session, slots);
9256
+ session.on("remoteSettings", (settings) => {
9257
+ const remoteLimit = settings.maxConcurrentStreams;
9258
+ const limit = typeof remoteLimit === "number" && Number.isFinite(remoteLimit) ? Math.max(0, Math.floor(remoteLimit)) : this.config.maxConnections;
9259
+ slots.updateLimit(Math.min(this.config.maxConnections, limit));
9260
+ });
9261
+ session.on("error", (error) => this.retireSession(origin, session, true, error));
9262
+ session.once("goaway", () => {
9263
+ this.retireSession(
9264
+ origin,
9265
+ session,
9266
+ "when_idle",
9267
+ new HTTP2SessionRetiredError("HTTP/2 session received GOAWAY")
9268
+ );
9269
+ });
9270
+ session.once("close", () => {
9271
+ if (session.destroyed) this.#allSessions.delete(session);
9272
+ this.retireSession(origin, session);
9273
+ });
9000
9274
  this.#sessions.set(origin, session);
9001
9275
  return session;
9002
9276
  }
9277
+ retireSession(origin, session, destroy = false, cause) {
9278
+ if (this.#sessions.get(origin) === session) this.#sessions.delete(origin);
9279
+ const slots = this.#sessionSlots.get(session);
9280
+ slots?.retire(
9281
+ cause instanceof HTTP2SessionRetiredError ? cause : new HTTP2SessionRetiredError("HTTP/2 session is unavailable", cause)
9282
+ );
9283
+ if (destroy === true && !session.destroyed) session.destroy();
9284
+ else if (destroy === "when_idle") {
9285
+ slots?.whenIdle(() => {
9286
+ if (!session.destroyed) session.destroy();
9287
+ });
9288
+ }
9289
+ }
9290
+ slotPool(session) {
9291
+ const slots = this.#sessionSlots.get(session);
9292
+ if (slots == null) throw new HTTP2SessionRetiredError("HTTP/2 session is unavailable");
9293
+ return slots;
9294
+ }
9003
9295
  requestHeaders(body) {
9004
9296
  const headers = { ...this.config.headers };
9005
9297
  delete headers["content-length"];
@@ -9011,11 +9303,21 @@ var HTTPTransport = class {
9011
9303
  };
9012
9304
  }
9013
9305
  };
9306
+ var requestTimeoutReason = /* @__PURE__ */ Symbol("ferricstore-http-request-timeout");
9307
+ function retryableSessionOpenError(error) {
9308
+ if (typeof error !== "object" || error == null || !("code" in error)) return false;
9309
+ const code = error.code;
9310
+ return code === "ERR_HTTP2_GOAWAY_SESSION" || code === "ERR_HTTP2_INVALID_SESSION";
9311
+ }
9312
+ function refusedStreamError(error) {
9313
+ if (!(error instanceof Error)) return false;
9314
+ return error.code === "ERR_HTTP2_STREAM_ERROR" && error.message.includes("NGHTTP2_REFUSED_STREAM");
9315
+ }
9014
9316
  async function collectBody(source, status, headers, maximum) {
9015
9317
  const chunks = [];
9016
9318
  let size = 0;
9017
9319
  for await (const chunk of source) {
9018
- const bytes2 = import_node_buffer34.Buffer.from(chunk);
9320
+ const bytes2 = import_node_buffer36.Buffer.from(chunk);
9019
9321
  size += bytes2.byteLength;
9020
9322
  if (size > maximum) {
9021
9323
  const destroy = source.destroy;
@@ -9024,10 +9326,10 @@ async function collectBody(source, status, headers, maximum) {
9024
9326
  }
9025
9327
  chunks.push(bytes2);
9026
9328
  }
9027
- return { body: import_node_buffer34.Buffer.concat(chunks, size), headers, status };
9329
+ return { body: import_node_buffer36.Buffer.concat(chunks, size), headers, status };
9028
9330
  }
9029
9331
  function normalizeHeaders(headers) {
9030
- const result = {};
9332
+ const result = /* @__PURE__ */ Object.create(null);
9031
9333
  for (const [name, raw] of Object.entries(headers)) {
9032
9334
  const value = headerValue(raw);
9033
9335
  if (value != null) result[name.toLowerCase()] = value;
@@ -9079,11 +9381,16 @@ var HTTPAdapter = class _HTTPAdapter {
9079
9381
  throw new HTTPTransportError("HTTP command batch exceeds maxBatchItems");
9080
9382
  }
9081
9383
  for (const command of commands) assertHTTPCommandSupported(command[0]);
9082
- const body = encodeHTTPCommands(commands.map((command) => httpCommand(command, this.#config.maxRequestBytes)));
9384
+ const prepared = commands.map((command) => prepareHTTPCommand(command, this.#config.maxRequestBytes));
9385
+ const body = encodeHTTPCommands(prepared.map((command) => command.encoded), this.#config.maxRequestBytes);
9083
9386
  if (body.byteLength > this.#config.maxRequestBytes) {
9084
9387
  throw new HTTPTransportError("HTTP command request exceeds maxRequestBytes");
9085
9388
  }
9086
- const response = await this.#transport.post(body);
9389
+ const serverBlockMs = combinedServerBlockMs(prepared.map((command) => command.serverBlockMs));
9390
+ const response = await this.#transport.post(
9391
+ body,
9392
+ serverResponseTimeoutMs(this.#config.timeoutMs, serverBlockMs)
9393
+ );
9087
9394
  let envelope = {};
9088
9395
  try {
9089
9396
  if (response.body.byteLength > 0) envelope = decodeHTTPEnvelope(response.body);
@@ -9107,12 +9414,17 @@ var HTTPAdapter = class _HTTPAdapter {
9107
9414
  var commandNamesByOpcode = new Map(
9108
9415
  Object.entries(COMMAND_OPCODES).map(([name, opcode]) => [opcode, name])
9109
9416
  );
9110
- function httpCommand(command, maxRequestBytes) {
9417
+ function prepareHTTPCommand(command, maxRequestBytes) {
9111
9418
  const protocol = buildProtocolCommand(command, maxRequestBytes, false);
9112
- if (protocol.opcode === OPCODES.commandExec) return command;
9419
+ if (protocol.opcode === OPCODES.commandExec) {
9420
+ return { encoded: command, serverBlockMs: protocol.serverBlockMs };
9421
+ }
9113
9422
  const name = commandNamesByOpcode.get(protocol.opcode);
9114
9423
  if (name == null) throw new HTTPTransportError(`HTTP command has unknown opcode ${protocol.opcode}`);
9115
- return { command: name, opcode: protocol.opcode, payload: protocol.payload ?? {} };
9424
+ return {
9425
+ encoded: { command: name, opcode: protocol.opcode, payload: protocol.payload ?? {} },
9426
+ serverBlockMs: protocol.serverBlockMs
9427
+ };
9116
9428
  }
9117
9429
  function validatedResult(value) {
9118
9430
  if (!isRecord2(value)) throw new HTTPTransportError("HTTP response has an invalid result item");
@@ -9132,7 +9444,7 @@ function commandError(value) {
9132
9444
  function topLevelError(status, envelope, retryAfter) {
9133
9445
  const details = isRecord2(envelope.error) ? envelope.error : {};
9134
9446
  const message = typeof details.message === "string" ? details.message : `HTTP command request failed with status ${status}`;
9135
- const retryAfterMs2 = retryAfter == null || !/^\d+$/u.test(retryAfter) ? void 0 : Number(retryAfter) * 1e3;
9447
+ const retryAfterMs2 = retryAfterMilliseconds(retryAfter);
9136
9448
  return new HTTPTransportError(message, {
9137
9449
  raw: details,
9138
9450
  retryable: status === 408 || status === 425 || status === 429 || status >= 500,
@@ -9141,6 +9453,18 @@ function topLevelError(status, envelope, retryAfter) {
9141
9453
  statusCode: status
9142
9454
  });
9143
9455
  }
9456
+ function retryAfterMilliseconds(value) {
9457
+ if (value == null) return void 0;
9458
+ if (/^\d+$/u.test(value)) {
9459
+ const seconds = Number.parseInt(value, 10);
9460
+ const milliseconds2 = seconds * 1e3;
9461
+ return Number.isSafeInteger(milliseconds2) ? milliseconds2 : void 0;
9462
+ }
9463
+ const deadline = Date.parse(value);
9464
+ if (!Number.isFinite(deadline)) return void 0;
9465
+ const milliseconds = Math.max(0, deadline - Date.now());
9466
+ return Number.isSafeInteger(milliseconds) ? milliseconds : void 0;
9467
+ }
9144
9468
  function isRecord2(value) {
9145
9469
  return typeof value === "object" && value != null && !Array.isArray(value);
9146
9470
  }
@@ -9153,10 +9477,10 @@ function executeCommandArgs(executor, args) {
9153
9477
  }
9154
9478
 
9155
9479
  // src/reconnecting-executor.ts
9156
- var import_node_buffer36 = require("buffer");
9480
+ var import_node_buffer38 = require("buffer");
9157
9481
 
9158
9482
  // src/command-retry-policy.ts
9159
- var import_node_buffer35 = require("buffer");
9483
+ var import_node_buffer37 = require("buffer");
9160
9484
  function isCasMutation(args) {
9161
9485
  const offset = commandName2(args[0]) === "COMMAND_EXEC" ? 1 : 0;
9162
9486
  const name = commandName2(args[offset]);
@@ -9170,8 +9494,8 @@ function isCasMutation(args) {
9170
9494
  }
9171
9495
  function commandName2(value) {
9172
9496
  if (typeof value === "string") return value.toUpperCase();
9173
- if (import_node_buffer35.Buffer.isBuffer(value) || value instanceof Uint8Array) {
9174
- return import_node_buffer35.Buffer.from(value).toString("utf8").toUpperCase();
9497
+ if (import_node_buffer37.Buffer.isBuffer(value) || value instanceof Uint8Array) {
9498
+ return import_node_buffer37.Buffer.from(value).toString("utf8").toUpperCase();
9175
9499
  }
9176
9500
  return void 0;
9177
9501
  }
@@ -9383,15 +9707,15 @@ function normalizeNonNegativeInteger2(value, fallback) {
9383
9707
  }
9384
9708
 
9385
9709
  // src/topology.ts
9386
- var import_node_buffer39 = require("buffer");
9710
+ var import_node_buffer41 = require("buffer");
9387
9711
 
9388
9712
  // src/topology-routing.ts
9389
- var import_node_buffer38 = require("buffer");
9713
+ var import_node_buffer40 = require("buffer");
9390
9714
 
9391
9715
  // src/flow-partition-route-cache.ts
9392
- var import_node_buffer37 = require("buffer");
9716
+ var import_node_buffer39 = require("buffer");
9393
9717
  var import_node_crypto = require("crypto");
9394
- var AUTO_PREFIX = import_node_buffer37.Buffer.from("__flow_auto__:", "ascii");
9718
+ var AUTO_PREFIX = import_node_buffer39.Buffer.from("__flow_auto__:", "ascii");
9395
9719
  var MAX_CACHEABLE_PARTITION_BYTES = 4 * 1024;
9396
9720
  var MAX_CACHE_BYTES = 1 * 1024 * 1024;
9397
9721
  var MAX_CACHE_ENTRIES = 1024;
@@ -9401,10 +9725,10 @@ var cacheBytes = 0;
9401
9725
  var cacheHits = 0;
9402
9726
  var cacheMisses = 0;
9403
9727
  function flowLogicalPartitionRoutingKey(value) {
9404
- if (typeof value !== "string" && !import_node_buffer37.Buffer.isBuffer(value)) return void 0;
9728
+ if (typeof value !== "string" && !import_node_buffer39.Buffer.isBuffer(value)) return void 0;
9405
9729
  const autoBucket = flowAutoBucket(value);
9406
9730
  if (autoBucket != null) return `{fa:${autoBucket}}`;
9407
- const bytes2 = import_node_buffer37.Buffer.isBuffer(value) ? value : import_node_buffer37.Buffer.from(value);
9731
+ const bytes2 = import_node_buffer39.Buffer.isBuffer(value) ? value : import_node_buffer39.Buffer.from(value);
9408
9732
  if (bytes2.byteLength > MAX_CACHEABLE_PARTITION_BYTES) return hashRoute(bytes2);
9409
9733
  const cacheKey = bytes2.toString("base64");
9410
9734
  const cached = routeCache.get(cacheKey);
@@ -9478,7 +9802,7 @@ function routingKeyFromProtocolPayload(name, command) {
9478
9802
  "scope"
9479
9803
  ]) {
9480
9804
  const value = getField(command.payload, field3);
9481
- if (typeof value === "string" || import_node_buffer38.Buffer.isBuffer(value)) {
9805
+ if (typeof value === "string" || import_node_buffer40.Buffer.isBuffer(value)) {
9482
9806
  return value;
9483
9807
  }
9484
9808
  }
@@ -9526,7 +9850,7 @@ function flowRoutingData(name, args) {
9526
9850
  if (typeof partition === "string" && partition.toUpperCase() !== "AUTO" && partition.toUpperCase() !== "MIXED") {
9527
9851
  return flowRoutingResult(flowLogicalPartitionRoutingKey(partition));
9528
9852
  }
9529
- if (import_node_buffer38.Buffer.isBuffer(partition)) {
9853
+ if (import_node_buffer40.Buffer.isBuffer(partition)) {
9530
9854
  const text3 = partition.toString("utf8").toUpperCase();
9531
9855
  if (text3 !== "AUTO" && text3 !== "MIXED") {
9532
9856
  return flowRoutingResult(flowLogicalPartitionRoutingKey(partition));
@@ -9617,17 +9941,17 @@ function flowPartitionRoutingKeyFromCommand(command, claim) {
9617
9941
  return { handled: false };
9618
9942
  }
9619
9943
  function isRoutingKey(value) {
9620
- return typeof value === "string" || import_node_buffer38.Buffer.isBuffer(value);
9944
+ return typeof value === "string" || import_node_buffer40.Buffer.isBuffer(value);
9621
9945
  }
9622
9946
  function flowAutoIdRoutingKey(value) {
9623
- if (typeof value !== "string" && !import_node_buffer38.Buffer.isBuffer(value)) {
9947
+ if (typeof value !== "string" && !import_node_buffer40.Buffer.isBuffer(value)) {
9624
9948
  return void 0;
9625
9949
  }
9626
- const bucket = (import_node_buffer38.Buffer.isBuffer(value) ? crc32(value) : crc32Utf8(value)) & 255;
9950
+ const bucket = (import_node_buffer40.Buffer.isBuffer(value) ? crc32(value) : crc32Utf8(value)) & 255;
9627
9951
  return `{fa:${bucket}}`;
9628
9952
  }
9629
9953
  function flowClaimLogicalPartitionRoutingKey(value) {
9630
- if (typeof value !== "string" && !import_node_buffer38.Buffer.isBuffer(value)) return void 0;
9954
+ if (typeof value !== "string" && !import_node_buffer40.Buffer.isBuffer(value)) return void 0;
9631
9955
  const selector = commandPart(value);
9632
9956
  if (selector === "AUTO" || selector === "ANY") return void 0;
9633
9957
  if (selector === "GLOBAL") return "{f}";
@@ -9642,7 +9966,7 @@ function singleShardFlowClaimPartitionKey(values) {
9642
9966
  return keys.some((key) => key == null) ? void 0 : singleShardKey(keys);
9643
9967
  }
9644
9968
  function singleShardKey(keys) {
9645
- if (keys.length === 0 || keys.some((key) => typeof key !== "string" && !import_node_buffer38.Buffer.isBuffer(key))) {
9969
+ if (keys.length === 0 || keys.some((key) => typeof key !== "string" && !import_node_buffer40.Buffer.isBuffer(key))) {
9646
9970
  return void 0;
9647
9971
  }
9648
9972
  const usable = keys;
@@ -9675,7 +9999,7 @@ function routedKeyGroups(keys, routeKey) {
9675
9999
  const groups = /* @__PURE__ */ new Map();
9676
10000
  for (let index = 0; index < keys.length; index += 1) {
9677
10001
  const key = keys[index];
9678
- if (typeof key !== "string" && !import_node_buffer38.Buffer.isBuffer(key)) return void 0;
10002
+ if (typeof key !== "string" && !import_node_buffer40.Buffer.isBuffer(key)) return void 0;
9679
10003
  const route = routeKey(key);
9680
10004
  const groupKey = `${route.endpointKey}\0${route.laneId}`;
9681
10005
  const group = groups.get(groupKey);
@@ -10764,7 +11088,7 @@ var TopologyNativeAdapterPool = class _TopologyNativeAdapterPool {
10764
11088
  };
10765
11089
 
10766
11090
  // src/response-map-preservation.ts
10767
- var import_node_buffer40 = require("buffer");
11091
+ var import_node_buffer42 = require("buffer");
10768
11092
  function toStringKeyMapPreservingValues(value) {
10769
11093
  if (value == null) return void 0;
10770
11094
  const result = {};
@@ -10774,7 +11098,7 @@ function toStringKeyMapPreservingValues(value) {
10774
11098
  }
10775
11099
  return result;
10776
11100
  }
10777
- if (typeof value === "object" && !Array.isArray(value) && !import_node_buffer40.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) {
11101
+ if (typeof value === "object" && !Array.isArray(value) && !import_node_buffer42.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) {
10778
11102
  for (const [key, item] of Object.entries(value)) {
10779
11103
  setOwnValue(result, text(key), normalizeMapStructurePreservingBytes(item));
10780
11104
  }
@@ -10783,7 +11107,7 @@ function toStringKeyMapPreservingValues(value) {
10783
11107
  return void 0;
10784
11108
  }
10785
11109
  function normalizeMapStructurePreservingBytes(value) {
10786
- if (import_node_buffer40.Buffer.isBuffer(value) || value instanceof Uint8Array) return value;
11110
+ if (import_node_buffer42.Buffer.isBuffer(value) || value instanceof Uint8Array) return value;
10787
11111
  if (value instanceof Map) {
10788
11112
  const result = {};
10789
11113
  for (const [key, item] of value.entries()) {
@@ -10805,7 +11129,7 @@ function normalizeMapStructurePreservingBytes(value) {
10805
11129
  }
10806
11130
 
10807
11131
  // src/native-kv-responses.ts
10808
- var import_node_buffer41 = require("buffer");
11132
+ var import_node_buffer43 = require("buffer");
10809
11133
  function rateLimitResultFromResp(value) {
10810
11134
  if (!Array.isArray(value) || value.length !== 4) {
10811
11135
  throw new TypeError("RATELIMIT.ADD returned an unexpected response");
@@ -10862,13 +11186,13 @@ function fetchOrComputeResultFromResp(value, codec) {
10862
11186
  }
10863
11187
  function decodePayload(codec, value) {
10864
11188
  if (value == null) return null;
10865
- if (import_node_buffer41.Buffer.isBuffer(value)) return codec.decode(value);
10866
- if (value instanceof Uint8Array) return codec.decode(import_node_buffer41.Buffer.from(value));
10867
- if (typeof value === "string") return codec.decode(import_node_buffer41.Buffer.from(value));
11189
+ if (import_node_buffer43.Buffer.isBuffer(value)) return codec.decode(value);
11190
+ if (value instanceof Uint8Array) return codec.decode(import_node_buffer43.Buffer.from(value));
11191
+ if (typeof value === "string") return codec.decode(import_node_buffer43.Buffer.from(value));
10868
11192
  return normalizeRefMeta(value);
10869
11193
  }
10870
11194
  function requiredResponseString(value, context) {
10871
- if (typeof value !== "string" && !import_node_buffer41.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) {
11195
+ if (typeof value !== "string" && !import_node_buffer43.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) {
10872
11196
  throw new TypeError(`${context} returned an unexpected response`);
10873
11197
  }
10874
11198
  const result = text(value);
@@ -10885,7 +11209,7 @@ function requiredNonNegativeInteger(value, context) {
10885
11209
  return result;
10886
11210
  }
10887
11211
  function responseBytes(value, context) {
10888
- if (typeof value !== "string" && !import_node_buffer41.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) {
11212
+ if (typeof value !== "string" && !import_node_buffer43.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) {
10889
11213
  throw new TypeError(`${context} returned an unexpected response`);
10890
11214
  }
10891
11215
  return bytes(value);
@@ -11568,7 +11892,7 @@ function groupAutoPartitionItems(items) {
11568
11892
  }
11569
11893
 
11570
11894
  // src/client-values.ts
11571
- var import_node_buffer42 = require("buffer");
11895
+ var import_node_buffer44 = require("buffer");
11572
11896
  async function valueMGetEntries(client, refs, options = {}) {
11573
11897
  const refCount = refs.length;
11574
11898
  if (refCount === 0) {
@@ -11603,12 +11927,12 @@ async function valueMGetEntries(client, refs, options = {}) {
11603
11927
  const item = response[index];
11604
11928
  if (item == null) {
11605
11929
  entries[index] = { found: false };
11606
- } else if (import_node_buffer42.Buffer.isBuffer(item)) {
11930
+ } else if (import_node_buffer44.Buffer.isBuffer(item)) {
11607
11931
  entries[index] = { found: true, value: client.codec.decode(item) };
11608
11932
  } else if (item instanceof Uint8Array) {
11609
- entries[index] = { found: true, value: client.codec.decode(import_node_buffer42.Buffer.from(item)) };
11933
+ entries[index] = { found: true, value: client.codec.decode(import_node_buffer44.Buffer.from(item)) };
11610
11934
  } else if (typeof item === "string") {
11611
- entries[index] = { found: true, value: client.codec.decode(import_node_buffer42.Buffer.from(item)) };
11935
+ entries[index] = { found: true, value: client.codec.decode(import_node_buffer44.Buffer.from(item)) };
11612
11936
  } else {
11613
11937
  entries[index] = { found: true, value: item };
11614
11938
  }
@@ -11617,10 +11941,10 @@ async function valueMGetEntries(client, refs, options = {}) {
11617
11941
  }
11618
11942
 
11619
11943
  // src/auto-batch.ts
11620
- var import_node_buffer44 = require("buffer");
11944
+ var import_node_buffer46 = require("buffer");
11621
11945
 
11622
11946
  // src/auto-batch-ordering.ts
11623
- var import_node_buffer43 = require("buffer");
11947
+ var import_node_buffer45 = require("buffer");
11624
11948
  function autoBatchOrderingPlan(batch) {
11625
11949
  const accesses = /* @__PURE__ */ new Map();
11626
11950
  const fallbackDependencies = [];
@@ -11735,13 +12059,13 @@ function flowManyAutoBatchIds(command, name) {
11735
12059
  return fixedFlowItemIds(
11736
12060
  command,
11737
12061
  mixed ? 4 : 3,
11738
- (itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && isFencingToken(command[itemIndex + (mixed ? 2 : 1)]) && import_node_buffer43.Buffer.isBuffer(command[itemIndex + (mixed ? 3 : 2)])
12062
+ (itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && isFencingToken(command[itemIndex + (mixed ? 2 : 1)]) && import_node_buffer45.Buffer.isBuffer(command[itemIndex + (mixed ? 3 : 2)])
11739
12063
  );
11740
12064
  }
11741
12065
  return fixedFlowItemIds(
11742
12066
  command,
11743
12067
  mixed ? 4 : 3,
11744
- (itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && import_node_buffer43.Buffer.isBuffer(command[itemIndex + (mixed ? 2 : 1)]) && isFencingToken(command[itemIndex + (mixed ? 3 : 2)])
12068
+ (itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && import_node_buffer45.Buffer.isBuffer(command[itemIndex + (mixed ? 2 : 1)]) && isFencingToken(command[itemIndex + (mixed ? 3 : 2)])
11745
12069
  );
11746
12070
  }
11747
12071
  function createManyAutoBatchIds(command) {
@@ -11754,7 +12078,7 @@ function createManyAutoBatchIds(command) {
11754
12078
  const ids = fixedFlowItemIds(
11755
12079
  command,
11756
12080
  width,
11757
- (itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && import_node_buffer43.Buffer.isBuffer(command[itemIndex + width - 1]),
12081
+ (itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && import_node_buffer45.Buffer.isBuffer(command[itemIndex + width - 1]),
11758
12082
  markerIndex
11759
12083
  );
11760
12084
  if (ids != null) return ids;
@@ -11772,7 +12096,7 @@ function extendedCreateManyAutoBatchIds(command, markerIndex) {
11772
12096
  let cursor = markerIndex + 2;
11773
12097
  for (let itemIndex = 0; itemIndex < itemCount; itemIndex += 1) {
11774
12098
  const id = command[cursor];
11775
- if (!isAutoBatchResourceValue(id) || !isAutoBatchResourceValue(command[cursor + 1]) || !import_node_buffer43.Buffer.isBuffer(command[cursor + 2])) return void 0;
12099
+ if (!isAutoBatchResourceValue(id) || !isAutoBatchResourceValue(command[cursor + 1]) || !import_node_buffer45.Buffer.isBuffer(command[cursor + 2])) return void 0;
11776
12100
  ids.push(id);
11777
12101
  cursor += 3;
11778
12102
  const afterValues = skipExtendedNamedItems(command, cursor, true);
@@ -11791,7 +12115,7 @@ function skipExtendedNamedItems(command, countIndex, encodedValues) {
11791
12115
  for (let index = 0; index < count; index += 1) {
11792
12116
  const name = command[firstItem + index * 2];
11793
12117
  const value = command[firstItem + index * 2 + 1];
11794
- if (!isAutoBatchResourceValue(name) || (encodedValues ? !import_node_buffer43.Buffer.isBuffer(value) : !isAutoBatchResourceValue(value))) return void 0;
12118
+ if (!isAutoBatchResourceValue(name) || (encodedValues ? !import_node_buffer45.Buffer.isBuffer(value) : !isAutoBatchResourceValue(value))) return void 0;
11795
12119
  }
11796
12120
  return firstItem + count * 2;
11797
12121
  }
@@ -11806,7 +12130,7 @@ function runStepsManyAutoBatchIds(command) {
11806
12130
  ids.push(item);
11807
12131
  continue;
11808
12132
  }
11809
- if (typeof item !== "object" || item == null || Array.isArray(item) || import_node_buffer43.Buffer.isBuffer(item)) return void 0;
12133
+ if (typeof item !== "object" || item == null || Array.isArray(item) || import_node_buffer45.Buffer.isBuffer(item)) return void 0;
11810
12134
  const id = item.id;
11811
12135
  if (!isAutoBatchResourceValue(id)) return void 0;
11812
12136
  ids.push(id);
@@ -11847,7 +12171,7 @@ function flowValuePutOwner(command, start) {
11847
12171
  }
11848
12172
  var flowValuePutOptionTokens = /* @__PURE__ */ new Set(["NAME", "NOW", "OVERRIDE", "OWNER_FLOW_ID", "PARTITION", "TTL", "TTL_MS"]);
11849
12173
  function isAutoBatchResourceValue(value) {
11850
- return typeof value === "string" || import_node_buffer43.Buffer.isBuffer(value);
12174
+ return typeof value === "string" || import_node_buffer45.Buffer.isBuffer(value);
11851
12175
  }
11852
12176
  function isFencingToken(value) {
11853
12177
  return typeof value === "number" && Number.isSafeInteger(value) || typeof value === "bigint";
@@ -11856,7 +12180,7 @@ function nonNegativeItemCount(value) {
11856
12180
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : void 0;
11857
12181
  }
11858
12182
  function autoBatchResourceKey(namespace, value) {
11859
- return `${namespace}:${import_node_buffer43.Buffer.from(value).toString("base64")}`;
12183
+ return `${namespace}:${import_node_buffer45.Buffer.from(value).toString("base64")}`;
11860
12184
  }
11861
12185
  function autoBatchCommandName(command) {
11862
12186
  return commandView(command).name ?? null;
@@ -12265,13 +12589,13 @@ function claimFailure(error) {
12265
12589
  }
12266
12590
 
12267
12591
  // src/client-flow-support.ts
12268
- var import_node_buffer57 = require("buffer");
12592
+ var import_node_buffer59 = require("buffer");
12269
12593
 
12270
12594
  // src/flow-query-builder.ts
12271
- var import_node_buffer46 = require("buffer");
12595
+ var import_node_buffer48 = require("buffer");
12272
12596
 
12273
12597
  // src/flow-query-metadata.ts
12274
- var import_node_buffer45 = require("buffer");
12598
+ var import_node_buffer47 = require("buffer");
12275
12599
  var MAX_FLOW_QUERY_METADATA_KEY_BYTES = 64;
12276
12600
  function normalizeStateMeta(value, state) {
12277
12601
  if (value == null) return {};
@@ -12296,7 +12620,7 @@ function normalizeStateMeta(value, state) {
12296
12620
  function metadataEntries(value, context) {
12297
12621
  const entries = objectEntries(value ?? {}, context).map(([rawName, item]) => {
12298
12622
  const name = rawName.trim();
12299
- const size = import_node_buffer45.Buffer.byteLength(name, "utf8");
12623
+ const size = import_node_buffer47.Buffer.byteLength(name, "utf8");
12300
12624
  if (size === 0 || size > MAX_FLOW_QUERY_METADATA_KEY_BYTES || name.startsWith("__")) {
12301
12625
  throw new TypeError(`${context} key is invalid or reserved`);
12302
12626
  }
@@ -12320,7 +12644,7 @@ function objectEntries(value, context) {
12320
12644
  return keys.map((key) => [key, value[key]]);
12321
12645
  }
12322
12646
  function isPlainRecord(value) {
12323
- if (typeof value !== "object" || value == null || Array.isArray(value) || import_node_buffer45.Buffer.isBuffer(value)) {
12647
+ if (typeof value !== "object" || value == null || Array.isArray(value) || import_node_buffer47.Buffer.isBuffer(value)) {
12324
12648
  return false;
12325
12649
  }
12326
12650
  const prototype = Object.getPrototypeOf(value);
@@ -12390,7 +12714,7 @@ var FlowCollectionQuery = class {
12390
12714
  const states = /* @__PURE__ */ new Set();
12391
12715
  for (const [rawState, metadata] of objectEntries(values, "stateMeta")) {
12392
12716
  const state = requiredText(rawState, "stateMeta state").trim();
12393
- const stateBytes = import_node_buffer46.Buffer.byteLength(state, "utf8");
12717
+ const stateBytes = import_node_buffer48.Buffer.byteLength(state, "utf8");
12394
12718
  if (stateBytes === 0 || stateBytes > MAX_FLOW_QUERY_STATE_BYTES) {
12395
12719
  throw new TypeError(
12396
12720
  `stateMeta state names must be 1..${MAX_FLOW_QUERY_STATE_BYTES} bytes`
@@ -12569,7 +12893,7 @@ function requiredPartition(value) {
12569
12893
  "FLOW.QUERY convenience methods require a partition key"
12570
12894
  );
12571
12895
  }
12572
- const size = import_node_buffer46.Buffer.byteLength(value, "utf8");
12896
+ const size = import_node_buffer48.Buffer.byteLength(value, "utf8");
12573
12897
  if (size === 0 || size > MAX_FLOW_QUERY_PARTITION_BYTES) {
12574
12898
  throw new TypeError(
12575
12899
  `FLOW.QUERY partition key must be 1..${MAX_FLOW_QUERY_PARTITION_BYTES} bytes`
@@ -12617,23 +12941,23 @@ function requiredText(value, context) {
12617
12941
  return value;
12618
12942
  }
12619
12943
  function queryParameter(value, context) {
12620
- if (typeof value === "string" || typeof value === "boolean" || typeof value === "bigint" || typeof value === "number" || import_node_buffer46.Buffer.isBuffer(value)) {
12944
+ if (typeof value === "string" || typeof value === "boolean" || typeof value === "bigint" || typeof value === "number" || import_node_buffer48.Buffer.isBuffer(value)) {
12621
12945
  return value;
12622
12946
  }
12623
12947
  throw new TypeError(`${context} must be a scalar FLOW.QUERY parameter`);
12624
12948
  }
12625
12949
 
12626
12950
  // src/flow-query-response.ts
12627
- var import_node_buffer50 = require("buffer");
12951
+ var import_node_buffer52 = require("buffer");
12628
12952
 
12629
12953
  // src/flow-query-diagnostic-response.ts
12630
- var import_node_buffer48 = require("buffer");
12954
+ var import_node_buffer50 = require("buffer");
12631
12955
 
12632
12956
  // src/flow-query-response-validation.ts
12633
- var import_node_buffer47 = require("buffer");
12957
+ var import_node_buffer49 = require("buffer");
12634
12958
  function requiredMap2(value, context) {
12635
12959
  if (value instanceof Map) return value;
12636
- if (typeof value !== "object" || value == null || Array.isArray(value) || import_node_buffer47.Buffer.isBuffer(value) || value instanceof Uint8Array) {
12960
+ if (typeof value !== "object" || value == null || Array.isArray(value) || import_node_buffer49.Buffer.isBuffer(value) || value instanceof Uint8Array) {
12637
12961
  throw decodeError(`${context} must be a map`, value);
12638
12962
  }
12639
12963
  return value;
@@ -12690,7 +13014,7 @@ function normalizeMetadataValue(value, context, budget, ancestors, depth) {
12690
13014
  if (!value.isWellFormed()) throw decodeError(`${context} contains invalid text`, value);
12691
13015
  return value;
12692
13016
  }
12693
- if (import_node_buffer47.Buffer.isBuffer(value) || value instanceof Uint8Array) {
13017
+ if (import_node_buffer49.Buffer.isBuffer(value) || value instanceof Uint8Array) {
12694
13018
  const decoded = strictText2(value);
12695
13019
  if (decoded == null) throw decodeError(`${context} contains invalid UTF-8`, value);
12696
13020
  return decoded;
@@ -12769,7 +13093,7 @@ function optionalText2(mapping2, name, context) {
12769
13093
  }
12770
13094
  function requiredBoundedText2(mapping2, name, context, maximumBytes) {
12771
13095
  const value = requiredText2(mapping2, name, context);
12772
- if (import_node_buffer47.Buffer.byteLength(value, "utf8") > maximumBytes) {
13096
+ if (import_node_buffer49.Buffer.byteLength(value, "utf8") > maximumBytes) {
12773
13097
  throw decodeError(
12774
13098
  `${context} ${name} exceeds ${maximumBytes} bytes`,
12775
13099
  mapping2
@@ -12782,7 +13106,7 @@ function boundedText(value, context, maximumBytes) {
12782
13106
  if (decoded == null || decoded.length === 0) {
12783
13107
  throw decodeError(`${context} must be non-empty text`, value);
12784
13108
  }
12785
- if (import_node_buffer47.Buffer.byteLength(decoded, "utf8") > maximumBytes) {
13109
+ if (import_node_buffer49.Buffer.byteLength(decoded, "utf8") > maximumBytes) {
12786
13110
  throw decodeError(`${context} exceeds ${maximumBytes} bytes`, value);
12787
13111
  }
12788
13112
  return decoded;
@@ -12836,10 +13160,10 @@ function positiveBoundedInteger(value, maximum, context) {
12836
13160
  function hasKey(mapping2, name) {
12837
13161
  if (!(mapping2 instanceof Map)) return Object.hasOwn(mapping2, name);
12838
13162
  if (mapping2.has(name)) return true;
12839
- const binaryName = import_node_buffer47.Buffer.from(name);
13163
+ const binaryName = import_node_buffer49.Buffer.from(name);
12840
13164
  for (const key of mapping2.keys()) {
12841
- if (import_node_buffer47.Buffer.isBuffer(key) && key.equals(binaryName)) return true;
12842
- if (key instanceof Uint8Array && import_node_buffer47.Buffer.from(key).equals(binaryName))
13165
+ if (import_node_buffer49.Buffer.isBuffer(key) && key.equals(binaryName)) return true;
13166
+ if (key instanceof Uint8Array && import_node_buffer49.Buffer.from(key).equals(binaryName))
12843
13167
  return true;
12844
13168
  }
12845
13169
  return false;
@@ -12850,7 +13174,7 @@ function decodeError(message, raw) {
12850
13174
  function strictText2(value) {
12851
13175
  if (typeof value === "string")
12852
13176
  return value.isWellFormed() ? value : void 0;
12853
- if (import_node_buffer47.Buffer.isBuffer(value) || value instanceof Uint8Array) {
13177
+ if (import_node_buffer49.Buffer.isBuffer(value) || value instanceof Uint8Array) {
12854
13178
  try {
12855
13179
  return new TextDecoder("utf-8", { fatal: true }).decode(value);
12856
13180
  } catch {
@@ -12930,7 +13254,7 @@ function tryDecodeFlowQueryError(value, cause) {
12930
13254
  }
12931
13255
  function optionalDiagnosticText(mapping2, name) {
12932
13256
  const value = optionalText2(mapping2, name, "FLOW.QUERY diagnostic");
12933
- if (value != null && import_node_buffer48.Buffer.byteLength(value, "utf8") > DIAGNOSTIC_TEXT_BYTES) {
13257
+ if (value != null && import_node_buffer50.Buffer.byteLength(value, "utf8") > DIAGNOSTIC_TEXT_BYTES) {
12934
13258
  throw decodeError(
12935
13259
  `FLOW.QUERY diagnostic ${name} exceeds ${DIAGNOSTIC_TEXT_BYTES} bytes`,
12936
13260
  mapping2
@@ -12965,7 +13289,7 @@ function validateDiagnosticContextValue(value, depth, budget) {
12965
13289
  }
12966
13290
  const text3 = diagnosticContextText(value);
12967
13291
  if (text3 != null) {
12968
- if (import_node_buffer48.Buffer.byteLength(text3, "utf8") <= DIAGNOSTIC_TEXT_BYTES) return;
13292
+ if (import_node_buffer50.Buffer.byteLength(text3, "utf8") <= DIAGNOSTIC_TEXT_BYTES) return;
12969
13293
  throw decodeError("FLOW.QUERY diagnostic context contains oversized text", value);
12970
13294
  }
12971
13295
  if (depth <= 0) {
@@ -12991,7 +13315,7 @@ function validateDiagnosticContextValue(value, depth, budget) {
12991
13315
  }
12992
13316
  for (const [rawKey, item] of entries) {
12993
13317
  const key = diagnosticContextText(rawKey);
12994
- if (key == null || key.length === 0 || import_node_buffer48.Buffer.byteLength(key, "utf8") > DIAGNOSTIC_CONTEXT_KEY_BYTES) {
13318
+ if (key == null || key.length === 0 || import_node_buffer50.Buffer.byteLength(key, "utf8") > DIAGNOSTIC_CONTEXT_KEY_BYTES) {
12995
13319
  throw decodeError("FLOW.QUERY diagnostic context contains an invalid key", value);
12996
13320
  }
12997
13321
  validateDiagnosticContextValue(item, depth - 1, budget);
@@ -13008,7 +13332,7 @@ function consumeDiagnosticContextNode(value, budget) {
13008
13332
  }
13009
13333
  function diagnosticContextText(value) {
13010
13334
  if (typeof value === "string") return value.isWellFormed() ? value : void 0;
13011
- if (!import_node_buffer48.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) return void 0;
13335
+ if (!import_node_buffer50.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) return void 0;
13012
13336
  try {
13013
13337
  return new TextDecoder("utf-8", { fatal: true }).decode(value);
13014
13338
  } catch {
@@ -13034,7 +13358,7 @@ function decodePosition(value) {
13034
13358
  }
13035
13359
 
13036
13360
  // src/flow-query-index-contract.ts
13037
- var import_node_buffer49 = require("buffer");
13361
+ var import_node_buffer51 = require("buffer");
13038
13362
  var FLOW_QUERY_BUILD_PHASES = ["pending", "snapshot", "backfill", "done"];
13039
13363
  var FLOW_QUERY_VALIDATION_PHASES = [
13040
13364
  "pending",
@@ -13280,10 +13604,10 @@ function fieldKind(name) {
13280
13604
  return void 0;
13281
13605
  }
13282
13606
  function validUnquoted(value) {
13283
- return !value.startsWith("__") && UNQUOTED_METADATA.test(value) && import_node_buffer49.Buffer.byteLength(value, "ascii") <= 64;
13607
+ return !value.startsWith("__") && UNQUOTED_METADATA.test(value) && import_node_buffer51.Buffer.byteLength(value, "ascii") <= 64;
13284
13608
  }
13285
13609
  function validMetadata(value, rejectReserved) {
13286
- return value.length > 0 && import_node_buffer49.Buffer.byteLength(value, "utf8") <= 64 && (!rejectReserved || !value.startsWith("__"));
13610
+ return value.length > 0 && import_node_buffer51.Buffer.byteLength(value, "utf8") <= 64 && (!rejectReserved || !value.startsWith("__"));
13287
13611
  }
13288
13612
  function externalSelector(root, ...segments) {
13289
13613
  return segments.every(validUnquoted) ? [root, ...segments].join(".") : root + segments.map((segment) => `['${segment.replaceAll("'", "''")}']`).join("");
@@ -14190,7 +14514,7 @@ function decodePage(value) {
14190
14514
  const mapping2 = requiredMap2(value, "FLOW.QUERY page");
14191
14515
  const hasMore = requiredBoolean(mapping2, "has_more", "FLOW.QUERY page");
14192
14516
  const cursor = optionalText2(mapping2, "cursor", "FLOW.QUERY page");
14193
- if (cursor != null && (!cursor.startsWith("fqc1_") || import_node_buffer50.Buffer.byteLength(cursor) < 16 || import_node_buffer50.Buffer.byteLength(cursor) > 4096)) {
14517
+ if (cursor != null && (!cursor.startsWith("fqc1_") || import_node_buffer52.Buffer.byteLength(cursor) < 16 || import_node_buffer52.Buffer.byteLength(cursor) > 4096)) {
14194
14518
  throw decodeError("FLOW.QUERY page cursor is invalid", value);
14195
14519
  }
14196
14520
  if (hasMore !== (cursor != null)) {
@@ -14200,12 +14524,12 @@ function decodePage(value) {
14200
14524
  }
14201
14525
 
14202
14526
  // src/client-core.ts
14203
- var import_node_buffer55 = require("buffer");
14527
+ var import_node_buffer57 = require("buffer");
14204
14528
 
14205
14529
  // src/client-core-helpers.ts
14206
- var import_node_buffer51 = require("buffer");
14530
+ var import_node_buffer53 = require("buffer");
14207
14531
  function bgsaveResponse(response) {
14208
- if ((typeof response === "string" || import_node_buffer51.Buffer.isBuffer(response) || response instanceof Uint8Array) && text(response) === "Background saving started") {
14532
+ if ((typeof response === "string" || import_node_buffer53.Buffer.isBuffer(response) || response instanceof Uint8Array) && text(response) === "Background saving started") {
14209
14533
  return true;
14210
14534
  }
14211
14535
  return okResponse(response);
@@ -14219,7 +14543,7 @@ function fetchOrComputeCompletionToken(options) {
14219
14543
  "fetch-or-compute completion requires computeToken"
14220
14544
  );
14221
14545
  }
14222
- if (!import_node_buffer51.Buffer.isBuffer(options.computeToken)) {
14546
+ if (!import_node_buffer53.Buffer.isBuffer(options.computeToken)) {
14223
14547
  throw new TypeError("fetch-or-compute computeToken must be a Buffer");
14224
14548
  }
14225
14549
  return options.computeToken;
@@ -14242,10 +14566,10 @@ function unsupportedClientCaching() {
14242
14566
  }
14243
14567
 
14244
14568
  // src/client-base.ts
14245
- var import_node_buffer53 = require("buffer");
14569
+ var import_node_buffer55 = require("buffer");
14246
14570
 
14247
14571
  // src/client-executor.ts
14248
- var import_node_buffer52 = require("buffer");
14572
+ var import_node_buffer54 = require("buffer");
14249
14573
  var ErrorMappingExecutor = class {
14250
14574
  constructor(executor) {
14251
14575
  this.executor = executor;
@@ -14586,14 +14910,14 @@ var FerricStoreAdministrationClient = class extends FerricStoreClientBase {
14586
14910
  };
14587
14911
 
14588
14912
  // src/store-utilities.ts
14589
- var import_node_buffer54 = require("buffer");
14913
+ var import_node_buffer56 = require("buffer");
14590
14914
  function encode(codec, value) {
14591
14915
  return codec.encode(value);
14592
14916
  }
14593
14917
  function decode(codec, value) {
14594
14918
  if (value == null) return null;
14595
- if (import_node_buffer54.Buffer.isBuffer(value)) return codec.decode(value);
14596
- if (value instanceof Uint8Array) return codec.decode(import_node_buffer54.Buffer.from(value));
14919
+ if (import_node_buffer56.Buffer.isBuffer(value)) return codec.decode(value);
14920
+ if (value instanceof Uint8Array) return codec.decode(import_node_buffer56.Buffer.from(value));
14597
14921
  return value;
14598
14922
  }
14599
14923
  function number(value) {
@@ -17449,7 +17773,7 @@ function throwIfClosed(signal) {
17449
17773
  }
17450
17774
 
17451
17775
  // src/flow-policy.ts
17452
- var import_node_buffer56 = require("buffer");
17776
+ var import_node_buffer58 = require("buffer");
17453
17777
  var MAX_FLOW_POLICY_GENERATION = Number.MAX_SAFE_INTEGER;
17454
17778
  function assertFlowPolicyGeneration(value) {
17455
17779
  if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
@@ -17539,7 +17863,7 @@ function requiredRecord(value, context) {
17539
17863
  }
17540
17864
  return result;
17541
17865
  }
17542
- if (typeof value === "object" && value != null && !Array.isArray(value) && !import_node_buffer56.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) return value;
17866
+ if (typeof value === "object" && value != null && !Array.isArray(value) && !import_node_buffer58.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) return value;
17543
17867
  throw new TypeError(`${context} returned an unexpected response`);
17544
17868
  }
17545
17869
  function optionalRecord(value, context) {
@@ -17560,8 +17884,8 @@ function stringArray(value, context) {
17560
17884
  }
17561
17885
  function requiredText4(value, context) {
17562
17886
  if (typeof value === "string") return value;
17563
- if (import_node_buffer56.Buffer.isBuffer(value) || value instanceof Uint8Array) {
17564
- return import_node_buffer56.Buffer.from(value).toString("utf8");
17887
+ if (import_node_buffer58.Buffer.isBuffer(value) || value instanceof Uint8Array) {
17888
+ return import_node_buffer58.Buffer.from(value).toString("utf8");
17565
17889
  }
17566
17890
  throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
17567
17891
  }
@@ -17817,7 +18141,7 @@ var FerricStoreFlowSupportClient = class extends FerricStoreFlowQueryClient {
17817
18141
  };
17818
18142
 
17819
18143
  // src/flow-many-snapshot.ts
17820
- var import_node_buffer58 = require("buffer");
18144
+ var import_node_buffer60 = require("buffer");
17821
18145
  var encodedOptionFields = ["error", "payload", "reason", "result"];
17822
18146
  function snapshotCreateItem(item, codec) {
17823
18147
  const snapshot = {
@@ -17857,7 +18181,7 @@ function snapshotFlowManyOptions(options, codec) {
17857
18181
  }
17858
18182
  function snapshotClaimedItem(item) {
17859
18183
  const wire = item[CLAIMED_ITEM_WIRE];
17860
- const leaseToken = import_node_buffer58.Buffer.from(wire?.leaseToken ?? item.leaseToken);
18184
+ const leaseToken = import_node_buffer60.Buffer.from(wire?.leaseToken ?? item.leaseToken);
17861
18185
  const snapshot = {
17862
18186
  ...item,
17863
18187
  fencingToken: wire?.fencingToken ?? item.fencingToken,
@@ -17874,15 +18198,15 @@ function snapshotClaimedItem(item) {
17874
18198
  function snapshotFencedItem(item) {
17875
18199
  return Object.freeze({
17876
18200
  ...item,
17877
- ...item.leaseToken == null ? {} : { leaseToken: import_node_buffer58.Buffer.from(item.leaseToken) }
18201
+ ...item.leaseToken == null ? {} : { leaseToken: import_node_buffer60.Buffer.from(item.leaseToken) }
17878
18202
  });
17879
18203
  }
17880
18204
  function snapshotClaimedItemWire(wire, leaseToken) {
17881
18205
  return Object.freeze({
17882
18206
  fencingToken: wire.fencingToken,
17883
- id: import_node_buffer58.Buffer.from(wire.id),
18207
+ id: import_node_buffer60.Buffer.from(wire.id),
17884
18208
  leaseToken,
17885
- partitionKey: wire.partitionKey == null ? wire.partitionKey : import_node_buffer58.Buffer.from(wire.partitionKey)
18209
+ partitionKey: wire.partitionKey == null ? wire.partitionKey : import_node_buffer60.Buffer.from(wire.partitionKey)
17886
18210
  });
17887
18211
  }
17888
18212
  function snapshotArray(values) {
@@ -17893,7 +18217,7 @@ function snapshotArray(values) {
17893
18217
  return Object.freeze(snapshot);
17894
18218
  }
17895
18219
  function snapshotStateMeta(stateMeta) {
17896
- return snapshotRecord(stateMeta, (value) => import_node_buffer58.Buffer.isBuffer(value) ? import_node_buffer58.Buffer.from(value) : value);
18220
+ return snapshotRecord(stateMeta, (value) => import_node_buffer60.Buffer.isBuffer(value) ? import_node_buffer60.Buffer.from(value) : value);
17897
18221
  }
17898
18222
  function snapshotCommandRecord(values) {
17899
18223
  const seen = /* @__PURE__ */ new WeakMap();
@@ -17911,7 +18235,7 @@ function snapshotRecord(values, capture) {
17911
18235
  }
17912
18236
  function snapshotCommandArgument(value, seen) {
17913
18237
  if (typeof value !== "object" || value == null) return value;
17914
- if (import_node_buffer58.Buffer.isBuffer(value) || value instanceof Uint8Array) return import_node_buffer58.Buffer.from(value);
18238
+ if (import_node_buffer60.Buffer.isBuffer(value) || value instanceof Uint8Array) return import_node_buffer60.Buffer.from(value);
17915
18239
  const objectValue = value;
17916
18240
  const existing = seen.get(objectValue);
17917
18241
  if (existing != null) return existing;
@@ -18907,7 +19231,7 @@ function nativeOptionsForBootstrap(options, signal) {
18907
19231
  }
18908
19232
 
18909
19233
  // src/flow-query-projection.ts
18910
- var import_node_buffer59 = require("buffer");
19234
+ var import_node_buffer61 = require("buffer");
18911
19235
  var MAX_PROJECTION_FIELDS = 32;
18912
19236
  var MAX_DYNAMIC_NAME_BYTES = 64;
18913
19237
  var FIELD_BRAND = /* @__PURE__ */ Symbol("FerricStoreFlowProjectionField");
@@ -18977,7 +19301,7 @@ function projectFlowQuery(query, shape, ...fields) {
18977
19301
  }
18978
19302
  const base = stripOptionalTerminator(query);
18979
19303
  const result = `${base} RETURN ${shape.toUpperCase()} (${selectors.join(", ")})`;
18980
- if (import_node_buffer59.Buffer.byteLength(result, "utf8") > FLOW_QUERY_MAX_BYTES) {
19304
+ if (import_node_buffer61.Buffer.byteLength(result, "utf8") > FLOW_QUERY_MAX_BYTES) {
18981
19305
  throw new TypeError(`FLOW.QUERY query exceeds ${FLOW_QUERY_MAX_BYTES} bytes`);
18982
19306
  }
18983
19307
  return result;
@@ -19037,7 +19361,7 @@ function quoteName(value, allowPrivate) {
19037
19361
  throw new TypeError("Flow query projection metadata name must be text");
19038
19362
  }
19039
19363
  validateUnicodeScalarText2(value);
19040
- const size = import_node_buffer59.Buffer.byteLength(value, "utf8");
19364
+ const size = import_node_buffer61.Buffer.byteLength(value, "utf8");
19041
19365
  if (size === 0 || size > MAX_DYNAMIC_NAME_BYTES || !allowPrivate && value.startsWith("__")) {
19042
19366
  throw new TypeError(
19043
19367
  `Flow query projection metadata names must be 1..${MAX_DYNAMIC_NAME_BYTES} UTF-8 bytes`
@@ -21043,7 +21367,7 @@ var WorkflowWorker = class {
21043
21367
  };
21044
21368
 
21045
21369
  // src/version.ts
21046
- var FERRICSTORE_SDK_VERSION = "0.11.9";
21370
+ var FERRICSTORE_SDK_VERSION = "0.11.10";
21047
21371
  var FERRICSTORE_MINIMUM_SERVER_VERSION = "0.11.4";
21048
21372
  var FERRICSTORE_NATIVE_PROTOCOL_VERSION = 1;
21049
21373
  // Annotate the CommonJS export names for ESM import in node: