@ferricstore/ferricstore 0.11.8 → 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.
Files changed (261) hide show
  1. package/README.md +43 -3
  2. package/dist/index.cjs +1001 -157
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +42 -2
  5. package/dist/index.d.ts +42 -2
  6. package/dist/index.js +991 -150
  7. package/dist/index.js.map +1 -1
  8. package/docs/api/assets/hierarchy.js +1 -1
  9. package/docs/api/assets/highlight.css +1 -1
  10. package/docs/api/assets/main.js +1 -1
  11. package/docs/api/assets/navigation.js +1 -1
  12. package/docs/api/assets/search.js +1 -1
  13. package/docs/api/assets/style.css +18 -3
  14. package/docs/api/classes/BitmapStore.html +192 -3
  15. package/docs/api/classes/BloomFilterStore.html +197 -3
  16. package/docs/api/classes/ClaimHydrationError.html +202 -7
  17. package/docs/api/classes/ConnectionClosedError.html +193 -8
  18. package/docs/api/classes/CountMinSketchStore.html +171 -3
  19. package/docs/api/classes/CuckooFilterStore.html +196 -3
  20. package/docs/api/classes/FerricStoreClient.html +2888 -7
  21. package/docs/api/classes/FerricStoreError.html +197 -7
  22. package/docs/api/classes/FlowAlreadyExistsError.html +185 -7
  23. package/docs/api/classes/FlowBatchError.html +204 -8
  24. package/docs/api/classes/FlowNotFoundError.html +185 -7
  25. package/docs/api/classes/FlowQueryError.html +204 -7
  26. package/docs/api/classes/FlowWrongStateError.html +185 -7
  27. package/docs/api/classes/GeoStore.html +188 -3
  28. package/docs/api/classes/HTTPAdapter.html +144 -0
  29. package/docs/api/classes/HTTPTransportError.html +222 -0
  30. package/docs/api/classes/HashStore.html +493 -3
  31. package/docs/api/classes/HyperLogLogStore.html +148 -3
  32. package/docs/api/classes/InvalidCommandError.html +185 -7
  33. package/docs/api/classes/JsonCodec.html +104 -3
  34. package/docs/api/classes/KeyValueStore.html +794 -3
  35. package/docs/api/classes/LeaseRenewalError.html +157 -8
  36. package/docs/api/classes/ListStore.html +451 -3
  37. package/docs/api/classes/LockHeldError.html +185 -7
  38. package/docs/api/classes/LockNotOwnedError.html +185 -7
  39. package/docs/api/classes/NativeAdapter.html +135 -3
  40. package/docs/api/classes/OverloadedError.html +190 -7
  41. package/docs/api/classes/Queue.html +141 -4
  42. package/docs/api/classes/QueueClient.html +97 -4
  43. package/docs/api/classes/QueueCompletionError.html +163 -8
  44. package/docs/api/classes/QueueWorker.html +153 -4
  45. package/docs/api/classes/RawCodec.html +96 -3
  46. package/docs/api/classes/ReconnectingExecutor.html +180 -5
  47. package/docs/api/classes/RequestTimeoutError.html +199 -8
  48. package/docs/api/classes/RerouteError.html +188 -8
  49. package/docs/api/classes/RoutingTopology.html +125 -3
  50. package/docs/api/classes/SetStore.html +363 -3
  51. package/docs/api/classes/SortedSetStore.html +369 -3
  52. package/docs/api/classes/StaleLeaseError.html +185 -7
  53. package/docs/api/classes/StalePolicyGenerationError.html +188 -8
  54. package/docs/api/classes/StreamStore.html +259 -3
  55. package/docs/api/classes/TDigestStore.html +348 -3
  56. package/docs/api/classes/TopKStore.html +229 -3
  57. package/docs/api/classes/TopologyNativeAdapterPool.html +180 -5
  58. package/docs/api/classes/Workflow.html +266 -4
  59. package/docs/api/classes/WorkflowClient.html +97 -4
  60. package/docs/api/classes/WorkflowContext.html +293 -5
  61. package/docs/api/classes/WorkflowFlowCommands.html +251 -3
  62. package/docs/api/classes/WorkflowWorker.html +108 -4
  63. package/docs/api/functions/classifyServerError.html +44 -1
  64. package/docs/api/functions/complete.html +41 -1
  65. package/docs/api/functions/fail.html +41 -1
  66. package/docs/api/functions/httpCommandDisposition.html +41 -0
  67. package/docs/api/functions/isOutcome.html +41 -1
  68. package/docs/api/functions/isReconnectableClosedConnectionError.html +41 -1
  69. package/docs/api/functions/mapException.html +41 -1
  70. package/docs/api/functions/projectFlowQuery.html +43 -1
  71. package/docs/api/functions/retry.html +41 -1
  72. package/docs/api/functions/transition.html +42 -1
  73. package/docs/api/hierarchy.html +112 -1
  74. package/docs/api/index.html +78 -5
  75. package/docs/api/interfaces/AdminListOptions.html +70 -2
  76. package/docs/api/interfaces/ApprovalListOptions.html +74 -2
  77. package/docs/api/interfaces/ApprovalRequestOptions.html +99 -2
  78. package/docs/api/interfaces/AttributeQueryOptions.html +69 -2
  79. package/docs/api/interfaces/AutoBatchOptions.html +72 -3
  80. package/docs/api/interfaces/BackpressurePolicy.html +69 -2
  81. package/docs/api/interfaces/BudgetCommitOptions.html +59 -2
  82. package/docs/api/interfaces/BudgetReserveOptions.html +69 -2
  83. package/docs/api/interfaces/CancelOptions.html +135 -2
  84. package/docs/api/interfaces/ChildSpec.html +79 -2
  85. package/docs/api/interfaces/CircuitOpenOptions.html +64 -2
  86. package/docs/api/interfaces/ClaimDueOptions.html +146 -3
  87. package/docs/api/interfaces/ClaimHydrationItem.html +59 -2
  88. package/docs/api/interfaces/ClaimedItem.html +100 -3
  89. package/docs/api/interfaces/Codec.html +84 -2
  90. package/docs/api/interfaces/CommandExecutor.html +145 -4
  91. package/docs/api/interfaces/CompleteJobsAndClaimJobsResult.html +84 -7
  92. package/docs/api/interfaces/CompleteManyOptions.html +114 -2
  93. package/docs/api/interfaces/CompleteOptions.html +143 -2
  94. package/docs/api/interfaces/CompleteOutcome.html +117 -2
  95. package/docs/api/interfaces/CountMinMergeOptions.html +54 -2
  96. package/docs/api/interfaces/CreateItem.html +84 -2
  97. package/docs/api/interfaces/CreateManyOptions.html +173 -6
  98. package/docs/api/interfaces/CreateOptions.html +143 -4
  99. package/docs/api/interfaces/EffectCompensateOptions.html +89 -2
  100. package/docs/api/interfaces/EffectConfirmOptions.html +89 -2
  101. package/docs/api/interfaces/EffectFailOptions.html +94 -2
  102. package/docs/api/interfaces/EffectReserveOptions.html +84 -2
  103. package/docs/api/interfaces/EffectStatusOptions.html +77 -2
  104. package/docs/api/interfaces/ExecutePipelineOptions.html +68 -4
  105. package/docs/api/interfaces/ExtendLeaseOptions.html +79 -2
  106. package/docs/api/interfaces/FailOptions.html +143 -2
  107. package/docs/api/interfaces/FailOutcome.html +117 -2
  108. package/docs/api/interfaces/FencedItem.html +69 -2
  109. package/docs/api/interfaces/FerricStoreClientFromUrlOptions.html +105 -4
  110. package/docs/api/interfaces/FerricStoreClientOptions.html +84 -4
  111. package/docs/api/interfaces/FetchOrComputeComputeResult.html +83 -4
  112. package/docs/api/interfaces/FetchOrComputeHitResult.html +78 -2
  113. package/docs/api/interfaces/FlowBatchCompletedItem.html +59 -2
  114. package/docs/api/interfaces/FlowEventProjectionField.html +64 -2
  115. package/docs/api/interfaces/FlowExplainCapabilities.html +69 -2
  116. package/docs/api/interfaces/FlowExplainResult.html +124 -2
  117. package/docs/api/interfaces/FlowMaxActiveFailure.html +59 -2
  118. package/docs/api/interfaces/FlowPolicyBackoffSnapshot.html +69 -2
  119. package/docs/api/interfaces/FlowPolicyOptions.html +107 -6
  120. package/docs/api/interfaces/FlowPolicyRetentionSnapshot.html +59 -2
  121. package/docs/api/interfaces/FlowPolicyRetrySnapshot.html +64 -2
  122. package/docs/api/interfaces/FlowPolicySnapshot.html +121 -5
  123. package/docs/api/interfaces/FlowPolicyStateSnapshot.html +74 -2
  124. package/docs/api/interfaces/FlowQueryCountResult.html +89 -2
  125. package/docs/api/interfaces/FlowQueryErrorPosition.html +64 -2
  126. package/docs/api/interfaces/FlowQueryIndex.html +134 -2
  127. package/docs/api/interfaces/FlowQueryIndexBuild.html +106 -2
  128. package/docs/api/interfaces/FlowQueryIndexCoverage.html +69 -2
  129. package/docs/api/interfaces/FlowQueryIndexField.html +69 -2
  130. package/docs/api/interfaces/FlowQueryIndexFormat.html +79 -2
  131. package/docs/api/interfaces/FlowQueryIndexProgress.html +86 -2
  132. package/docs/api/interfaces/FlowQueryIndexRegistry.html +59 -2
  133. package/docs/api/interfaces/FlowQueryIndexRetirement.html +94 -2
  134. package/docs/api/interfaces/FlowQueryIndexServices.html +74 -2
  135. package/docs/api/interfaces/FlowQueryIndexStatistics.html +99 -2
  136. package/docs/api/interfaces/FlowQueryIndexStatus.html +84 -2
  137. package/docs/api/interfaces/FlowQueryIndexValidation.html +121 -2
  138. package/docs/api/interfaces/FlowQueryPage.html +59 -2
  139. package/docs/api/interfaces/FlowQueryQuality.html +69 -2
  140. package/docs/api/interfaces/FlowQueryRecordsResult.html +94 -2
  141. package/docs/api/interfaces/FlowQueryUsage.html +104 -2
  142. package/docs/api/interfaces/FlowRecord.html +173 -2
  143. package/docs/api/interfaces/FlowRunProjectionField.html +64 -2
  144. package/docs/api/interfaces/FlowStatePolicy.html +59 -2
  145. package/docs/api/interfaces/FlowStatsOptions.html +74 -2
  146. package/docs/api/interfaces/GeoMember.html +64 -2
  147. package/docs/api/interfaces/GovernanceLedgerOptions.html +74 -2
  148. package/docs/api/interfaces/HTTPAdapterOptions.html +124 -0
  149. package/docs/api/interfaces/HistoryOptions.html +124 -2
  150. package/docs/api/interfaces/InvocationCreateOptions.html +71 -2
  151. package/docs/api/interfaces/KeyInfo.html +79 -2
  152. package/docs/api/interfaces/LeaseMutationOptions.html +136 -2
  153. package/docs/api/interfaces/LimitAmountOptions.html +64 -2
  154. package/docs/api/interfaces/LimitLeaseOptions.html +74 -2
  155. package/docs/api/interfaces/LimitListOptions.html +78 -2
  156. package/docs/api/interfaces/LimitReleaseOptions.html +64 -2
  157. package/docs/api/interfaces/MutateOptions.html +110 -2
  158. package/docs/api/interfaces/NamedValueMutation.html +93 -2
  159. package/docs/api/interfaces/NativeAdapterOptions.html +175 -12
  160. package/docs/api/interfaces/NativeClientOptions.html +249 -16
  161. package/docs/api/interfaces/NativeProtocolEvent.html +69 -2
  162. package/docs/api/interfaces/ProtocolCommand.html +69 -2
  163. package/docs/api/interfaces/QueueOptions.html +64 -2
  164. package/docs/api/interfaces/QueueWorkerResult.html +69 -2
  165. package/docs/api/interfaces/RangeLimit.html +59 -2
  166. package/docs/api/interfaces/RateLimitResult.html +74 -2
  167. package/docs/api/interfaces/ReadOptions.html +107 -3
  168. package/docs/api/interfaces/ReclaimOptions.html +140 -3
  169. package/docs/api/interfaces/ReconnectOptions.html +75 -5
  170. package/docs/api/interfaces/RequestContext.html +64 -2
  171. package/docs/api/interfaces/RequestContextOptions.html +60 -2
  172. package/docs/api/interfaces/RetryOptions.html +143 -2
  173. package/docs/api/interfaces/RetryOutcome.html +117 -2
  174. package/docs/api/interfaces/RetryPolicy.html +79 -2
  175. package/docs/api/interfaces/RoutingEndpoint.html +69 -2
  176. package/docs/api/interfaces/RoutingRoute.html +79 -2
  177. package/docs/api/interfaces/RunStepsItem.html +59 -2
  178. package/docs/api/interfaces/RunStepsManyOptions.html +99 -2
  179. package/docs/api/interfaces/ScanOptions.html +66 -3
  180. package/docs/api/interfaces/ScheduleFireDueOptions.html +74 -2
  181. package/docs/api/interfaces/ScheduleFireOptions.html +59 -2
  182. package/docs/api/interfaces/ScheduleListOptions.html +89 -2
  183. package/docs/api/interfaces/ScheduleOptions.html +131 -3
  184. package/docs/api/interfaces/SearchOptions.html +122 -3
  185. package/docs/api/interfaces/StartAndClaimOptions.html +136 -3
  186. package/docs/api/interfaces/StateOptions.html +94 -2
  187. package/docs/api/interfaces/StateRegistration.html +104 -2
  188. package/docs/api/interfaces/StepContinueOptions.html +159 -3
  189. package/docs/api/interfaces/StoreCommandClient.html +89 -3
  190. package/docs/api/interfaces/TDigestCreateOptions.html +60 -2
  191. package/docs/api/interfaces/TDigestMergeOptions.html +66 -2
  192. package/docs/api/interfaces/TopologyNativeAdapterOptions.html +228 -15
  193. package/docs/api/interfaces/TransitionOptions.html +153 -2
  194. package/docs/api/interfaces/TransitionOutcome.html +122 -2
  195. package/docs/api/interfaces/ValueConfig.html +59 -2
  196. package/docs/api/interfaces/WorkerConfig.html +230 -15
  197. package/docs/api/interfaces/WorkflowOptions.html +69 -2
  198. package/docs/api/interfaces/WorkflowWorkerResult.html +69 -2
  199. package/docs/api/interfaces/XReadStream.html +59 -2
  200. package/docs/api/interfaces/ZAddMember.html +59 -2
  201. package/docs/api/modules.html +51 -1
  202. package/docs/api/types/BackoffKind.html +32 -1
  203. package/docs/api/types/CollectionScanOptions.html +34 -2
  204. package/docs/api/types/Command.html +32 -1
  205. package/docs/api/types/CommandArgument.html +32 -1
  206. package/docs/api/types/ConnectionRequestDisposition.html +36 -2
  207. package/docs/api/types/EndpointPolicy.html +34 -2
  208. package/docs/api/types/ExceptionPolicy.html +32 -1
  209. package/docs/api/types/ExpiryCondition.html +32 -1
  210. package/docs/api/types/FencingToken.html +34 -2
  211. package/docs/api/types/FetchOrComputeFencedResult.html +32 -1
  212. package/docs/api/types/FetchOrComputeResult.html +36 -1
  213. package/docs/api/types/FlowAdminRecord.html +32 -1
  214. package/docs/api/types/FlowPolicyBackoffKind.html +32 -1
  215. package/docs/api/types/FlowProjectionField.html +32 -1
  216. package/docs/api/types/FlowProjectionShape.html +32 -1
  217. package/docs/api/types/FlowQueryIndexServiceState.html +32 -1
  218. package/docs/api/types/FlowQueryInteger.html +32 -1
  219. package/docs/api/types/FlowQueryParameter.html +32 -1
  220. package/docs/api/types/FlowQueryParameters.html +32 -1
  221. package/docs/api/types/FlowQueryRecord.html +32 -1
  222. package/docs/api/types/FlowQueryResult.html +32 -1
  223. package/docs/api/types/FlowStateMode.html +32 -1
  224. package/docs/api/types/FlowStatePolicyLike.html +32 -1
  225. package/docs/api/types/GeoAddOptions.html +34 -2
  226. package/docs/api/types/GetExOptions.html +34 -2
  227. package/docs/api/types/HTTPCommandDisposition.html +32 -0
  228. package/docs/api/types/HashScanResult.html +38 -2
  229. package/docs/api/types/IntegerReply.html +34 -2
  230. package/docs/api/types/ManagementPairs.html +32 -1
  231. package/docs/api/types/MaxActiveMs.html +32 -1
  232. package/docs/api/types/Outcome.html +32 -1
  233. package/docs/api/types/QueueBatchHandler.html +44 -1
  234. package/docs/api/types/QueueHandler.html +44 -1
  235. package/docs/api/types/QueueJob.html +32 -1
  236. package/docs/api/types/RequestDisposition.html +32 -1
  237. package/docs/api/types/ScheduleCatchupPolicy.html +34 -2
  238. package/docs/api/types/ScheduleFireDueResult.html +55 -3
  239. package/docs/api/types/ScheduleFireResult.html +34 -2
  240. package/docs/api/types/ScheduleKind.html +32 -1
  241. package/docs/api/types/ScheduleOverlapPolicy.html +32 -1
  242. package/docs/api/types/ScheduleRecord.html +95 -12
  243. package/docs/api/types/ScheduleState.html +32 -1
  244. package/docs/api/types/SearchStateMeta.html +32 -1
  245. package/docs/api/types/SetOptions.html +34 -2
  246. package/docs/api/types/SetScanResult.html +38 -2
  247. package/docs/api/types/SortedSetScanResult.html +38 -2
  248. package/docs/api/types/StateMeta.html +32 -1
  249. package/docs/api/types/StateMetaValue.html +32 -1
  250. package/docs/api/types/TopKReserveOptions.html +32 -1
  251. package/docs/api/types/WorkerProfile.html +32 -1
  252. package/docs/api/types/WorkerRefillStrategy.html +32 -1
  253. package/docs/api/types/WorkflowHandler.html +44 -1
  254. package/docs/api/types/ZAddOptions.html +34 -2
  255. package/docs/api/variables/COMMAND_OPCODES.html +297 -1
  256. package/docs/api/variables/FERRICSTORE_MINIMUM_SERVER_VERSION.html +34 -2
  257. package/docs/api/variables/FERRICSTORE_NATIVE_PROTOCOL_VERSION.html +34 -2
  258. package/docs/api/variables/FERRICSTORE_SDK_VERSION.html +34 -2
  259. package/docs/api/variables/FlowProjection.html +32 -1
  260. package/docs/api/variables/MAX_FLOW_POLICY_GENERATION.html +32 -1
  261. package/package.json +8 -8
package/dist/index.cjs CHANGED
@@ -49,6 +49,8 @@ __export(index_exports, {
49
49
  FlowQueryError: () => FlowQueryError,
50
50
  FlowWrongStateError: () => FlowWrongStateError,
51
51
  GeoStore: () => GeoStore,
52
+ HTTPAdapter: () => HTTPAdapter,
53
+ HTTPTransportError: () => HTTPTransportError,
52
54
  HashStore: () => HashStore,
53
55
  HyperLogLogStore: () => HyperLogLogStore,
54
56
  InvalidCommandError: () => InvalidCommandError,
@@ -86,6 +88,7 @@ __export(index_exports, {
86
88
  classifyServerError: () => classifyServerError,
87
89
  complete: () => complete,
88
90
  fail: () => fail2,
91
+ httpCommandDisposition: () => httpCommandDisposition,
89
92
  isOutcome: () => isOutcome,
90
93
  isReconnectableClosedConnectionError: () => isReconnectableClosedConnectionError,
91
94
  mapException: () => mapException,
@@ -125,6 +128,14 @@ var FerricStoreError = class extends Error {
125
128
  this.retryAfterMs = options.retryAfterMs ?? structuredIntegerField(options.raw, "retry_after_ms");
126
129
  }
127
130
  };
131
+ var HTTPTransportError = class extends FerricStoreError {
132
+ code = "http_transport";
133
+ statusCode;
134
+ constructor(message, options = {}) {
135
+ super(message, options);
136
+ this.statusCode = options.statusCode;
137
+ }
138
+ };
128
139
  var ConnectionClosedError = class extends FerricStoreError {
129
140
  code = "connection_closed";
130
141
  requestDisposition;
@@ -1545,6 +1556,7 @@ var neverAutoBatchCommandPrefixes = /* @__PURE__ */ new Set([
1545
1556
  "BLPOP",
1546
1557
  "BRPOP",
1547
1558
  "BRPOPLPUSH",
1559
+ "BZMPOP",
1548
1560
  "BZPOPMAX",
1549
1561
  "BZPOPMIN",
1550
1562
  "CLIENT",
@@ -1656,6 +1668,9 @@ var connectionBlockingCommands = /* @__PURE__ */ new Set([
1656
1668
  "BLPOP",
1657
1669
  "BRPOP",
1658
1670
  "BRPOPLPUSH",
1671
+ "BZMPOP",
1672
+ "BZPOPMAX",
1673
+ "BZPOPMIN",
1659
1674
  "XREAD",
1660
1675
  "XREADGROUP"
1661
1676
  ]);
@@ -2524,8 +2539,10 @@ function serverBlockMetadata(args) {
2524
2539
  serverBlockMs = blockDurationMs(args[3], 1e3);
2525
2540
  } else if (command === "BLMOVE" && args.length >= 6) {
2526
2541
  serverBlockMs = blockDurationMs(args[args.length - 1], 1e3);
2527
- } else if (command === "BLMPOP" && args.length >= 2) {
2542
+ } else if ((command === "BLMPOP" || command === "BZMPOP") && args.length >= 2) {
2528
2543
  serverBlockMs = blockDurationMs(args[1], 1e3);
2544
+ } else if ((command === "BZPOPMAX" || command === "BZPOPMIN") && args.length >= 3) {
2545
+ serverBlockMs = blockDurationMs(args[args.length - 1], 1e3);
2529
2546
  } else if (command === "XREAD" || command === "XREADGROUP") {
2530
2547
  serverBlockMs = optionBlockDurationMs(args, ["BLOCK"], "STREAMS");
2531
2548
  } else if (command === "WAIT" && args.length === 3) {
@@ -7585,6 +7602,24 @@ async function executeIndividually(host, commands, laneId, options) {
7585
7602
  }, commands, options);
7586
7603
  }
7587
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
+
7588
7623
  // src/native-pending-timeout.ts
7589
7624
  function timeoutNativePendingRequest(operations, requestId, timeoutMs) {
7590
7625
  const pending = operations.getPending(requestId);
@@ -7613,10 +7648,7 @@ function timeoutNativePendingRequest(operations, requestId, timeoutMs) {
7613
7648
  pending.reject(new RequestTimeoutError(timeoutMs, "possibly_sent"));
7614
7649
  }
7615
7650
  function nativeResponseTimeoutMs(command, requestTimeoutMs) {
7616
- const blockMs = command.serverBlockMs;
7617
- if (blockMs == null) return requestTimeoutMs;
7618
- if (blockMs === 0) return void 0;
7619
- return Math.min(Number.MAX_SAFE_INTEGER, requestTimeoutMs + blockMs);
7651
+ return serverResponseTimeoutMs(requestTimeoutMs, command.serverBlockMs);
7620
7652
  }
7621
7653
 
7622
7654
  // src/native-chunk-assembler.ts
@@ -8643,6 +8675,800 @@ var NativeAdapter = class _NativeAdapter {
8643
8675
  }
8644
8676
  };
8645
8677
 
8678
+ // src/http-command-policy.ts
8679
+ var import_node_buffer33 = require("buffer");
8680
+ var nativeOnlyCommands = /* @__PURE__ */ new Set([
8681
+ "AUTH",
8682
+ "BACKPRESSURE",
8683
+ "CLIENT",
8684
+ "CLIENT.INFO",
8685
+ "CLIENT.SETNAME",
8686
+ "COMMAND_EXEC",
8687
+ "EVENT",
8688
+ "GOAWAY",
8689
+ "HELLO",
8690
+ "OPTIONS",
8691
+ "PIPELINE",
8692
+ "QUIT",
8693
+ "ROUTE",
8694
+ "ROUTE_BATCH",
8695
+ "SHARDS",
8696
+ "STARTUP",
8697
+ "SUBSCRIBE_EVENTS",
8698
+ "UNSUBSCRIBE_EVENTS",
8699
+ "WINDOW_UPDATE"
8700
+ ]);
8701
+ var sessionOnlyCommands = /* @__PURE__ */ new Set([
8702
+ "ASKING",
8703
+ "AUTH",
8704
+ "CLIENT",
8705
+ "DISCARD",
8706
+ "EXEC",
8707
+ "HELLO",
8708
+ "MONITOR",
8709
+ "MULTI",
8710
+ "PSUBSCRIBE",
8711
+ "PSYNC",
8712
+ "PUNSUBSCRIBE",
8713
+ "QUIT",
8714
+ "READONLY",
8715
+ "READWRITE",
8716
+ "REPLCONF",
8717
+ "RESET",
8718
+ "SANDBOX",
8719
+ "SELECT",
8720
+ "SSUBSCRIBE",
8721
+ "SUBSCRIBE",
8722
+ "SUNSUBSCRIBE",
8723
+ "SYNC",
8724
+ "UNSUBSCRIBE",
8725
+ "UNWATCH",
8726
+ "WATCH"
8727
+ ]);
8728
+ function httpCommandDisposition(name) {
8729
+ const normalized = name.toUpperCase();
8730
+ return nativeOnlyCommands.has(normalized) || sessionOnlyCommands.has(normalized) ? "native_only" : "supported";
8731
+ }
8732
+ function assertHTTPCommandSupported(name) {
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`);
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;
8748
+ }
8749
+
8750
+ // src/http-envelope.ts
8751
+ var import_node_buffer34 = require("buffer");
8752
+ var encoding = "ferricstore-json-v1";
8753
+ var bytesMarker = "$ferricstore_bytes";
8754
+ var mapMarker = "$ferricstore_map";
8755
+ var maxDepth = 64;
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({
8761
+ encoding,
8762
+ commands: commands.map((command) => encodeValue(command, 0, budget))
8763
+ }));
8764
+ }
8765
+ function decodeHTTPEnvelope(source) {
8766
+ let parsed;
8767
+ try {
8768
+ parsed = JSON.parse(source.toString("utf8"));
8769
+ } catch (error) {
8770
+ throw new TypeError("invalid HTTP command response JSON", { cause: error });
8771
+ }
8772
+ if (!isRecord(parsed)) throw new TypeError("HTTP command response must be an object");
8773
+ return decodePlainRecord(parsed, 0);
8774
+ }
8775
+ function encodeValue(value, depth, budget) {
8776
+ if (depth > maxDepth) throw new TypeError("HTTP command value exceeds maximum depth");
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") };
8792
+ }
8793
+ if (typeof value === "number") {
8794
+ if (!Number.isFinite(value)) throw new TypeError("HTTP command numbers must be finite");
8795
+ consumeBudget(budget, 1);
8796
+ return value;
8797
+ }
8798
+ if (typeof value === "bigint") {
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));
8806
+ }
8807
+ if (value instanceof Map) {
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 };
8817
+ }
8818
+ if (isRecord(value)) {
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)
8824
+ ]) };
8825
+ }
8826
+ throw new TypeError(`unsupported HTTP command value: ${typeof value}`);
8827
+ }
8828
+ function decodeValue2(value, depth) {
8829
+ if (depth > maxDepth) throw new TypeError("HTTP response value exceeds maximum depth");
8830
+ if (Array.isArray(value)) return denseArray(value, depth + 1, decodeValue2);
8831
+ if (!isRecord(value)) return value;
8832
+ if (Object.keys(value).length === 1 && typeof value[bytesMarker] === "string") {
8833
+ return decodeBase64(value[bytesMarker]);
8834
+ }
8835
+ if (Object.keys(value).length === 1 && Array.isArray(value[mapMarker])) {
8836
+ const result = /* @__PURE__ */ new Map();
8837
+ for (const pair of value[mapMarker]) {
8838
+ if (!Array.isArray(pair) || pair.length !== 2) throw new TypeError("invalid HTTP map marker");
8839
+ result.set(decodeValue2(pair[0], depth + 1), decodeValue2(pair[1], depth + 1));
8840
+ }
8841
+ return result;
8842
+ }
8843
+ return decodePlainRecord(value, depth + 1);
8844
+ }
8845
+ function decodeBase64(value) {
8846
+ if (value.length % 4 !== 0 || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(value)) {
8847
+ throw new TypeError("invalid HTTP bytes marker");
8848
+ }
8849
+ const decoded = import_node_buffer34.Buffer.from(value, "base64");
8850
+ if (decoded.toString("base64") !== value) throw new TypeError("invalid HTTP bytes marker");
8851
+ return decoded;
8852
+ }
8853
+ function decodePlainRecord(value, depth) {
8854
+ const result = {};
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
+ }
8863
+ return result;
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
+ }
8871
+ function denseArray(values, depth, transform) {
8872
+ const result = new Array(values.length);
8873
+ for (let index = 0; index < values.length; index += 1) {
8874
+ if (!Object.hasOwn(values, index)) throw new TypeError("HTTP command arrays must be dense");
8875
+ result[index] = transform(values[index], depth);
8876
+ }
8877
+ return result;
8878
+ }
8879
+ function isRecord(value) {
8880
+ return typeof value === "object" && value != null && !Array.isArray(value) && !import_node_buffer34.Buffer.isBuffer(value);
8881
+ }
8882
+
8883
+ // src/http-options.ts
8884
+ var import_node_buffer35 = require("buffer");
8885
+ var import_node_http = require("http");
8886
+ function normalizeHTTPOptions(value, options) {
8887
+ const url = new URL(value);
8888
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
8889
+ throw new TypeError(`unsupported HTTP URL scheme: ${url.protocol}`);
8890
+ }
8891
+ if (url.username !== "" || url.password !== "") throw new TypeError("HTTP URL userinfo is not allowed");
8892
+ if (url.search !== "" || url.hash !== "") throw new TypeError("HTTP base URL cannot contain query or fragment");
8893
+ const headers = normalizedHeaders(options.headers ?? {});
8894
+ const authorization = authorizationHeader(url, options, headers.authorization);
8895
+ if (authorization != null) headers.authorization = authorization;
8896
+ url.pathname = `${url.pathname.replace(/\/$/u, "")}/v1/commands`;
8897
+ return Object.freeze({
8898
+ commandUrl: url,
8899
+ headers: Object.freeze(headers),
8900
+ http2: booleanOption(options.http2, false, "http2"),
8901
+ maxBatchItems: positiveInteger(options.maxBatchItems, 1e3, "maxBatchItems"),
8902
+ maxConnections: positiveInteger(options.maxConnections, 100, "maxConnections"),
8903
+ maxRedirects: nonNegativeInteger(options.maxRedirects, 20, "maxRedirects"),
8904
+ maxRequestBytes: positiveInteger(options.maxRequestBytes, 1024 * 1024, "maxRequestBytes"),
8905
+ maxResponseBytes: positiveInteger(options.maxResponseBytes, 16 * 1024 * 1024, "maxResponseBytes"),
8906
+ timeoutMs: positiveInteger(options.timeoutMs, 3e4, "timeoutMs"),
8907
+ tlsOptions: Object.freeze({ ...options.tlsOptions ?? {} })
8908
+ });
8909
+ }
8910
+ function normalizedHeaders(source) {
8911
+ const headers = /* @__PURE__ */ Object.create(null);
8912
+ for (const [rawName, value] of Object.entries(source)) {
8913
+ const name = rawName.toLowerCase();
8914
+ if (typeof value !== "string" || !validHeader(name, value)) {
8915
+ throw new TypeError(`invalid HTTP header: ${rawName}`);
8916
+ }
8917
+ headers[name] = value;
8918
+ }
8919
+ return headers;
8920
+ }
8921
+ function authorizationHeader(url, options, custom) {
8922
+ const basic = options.username != null || options.password != null;
8923
+ const count = Number(custom != null) + Number(options.bearerToken != null) + Number(basic);
8924
+ if (count > 1) throw new TypeError("HTTP credentials are mutually exclusive");
8925
+ if (options.bearerToken != null) {
8926
+ if (options.bearerToken === "" || !validHeader("authorization", `Bearer ${options.bearerToken}`)) {
8927
+ throw new TypeError("invalid bearer token");
8928
+ }
8929
+ return `Bearer ${options.bearerToken}`;
8930
+ }
8931
+ if (!basic) return custom;
8932
+ if (url.protocol !== "https:") throw new TypeError("Basic authentication requires HTTPS");
8933
+ if (typeof options.password !== "string") throw new TypeError("Basic authentication requires a password");
8934
+ const username = options.username ?? "default";
8935
+ if (username === "" || username.includes(":") || !safeHeader(username) || !safeHeader(options.password)) {
8936
+ throw new TypeError("invalid Basic authentication credentials");
8937
+ }
8938
+ return `Basic ${import_node_buffer35.Buffer.from(`${username}:${options.password}`).toString("base64")}`;
8939
+ }
8940
+ function positiveInteger(value, fallback, name) {
8941
+ const result = value ?? fallback;
8942
+ if (!Number.isSafeInteger(result) || result <= 0) throw new TypeError(`${name} must be a positive integer`);
8943
+ return result;
8944
+ }
8945
+ function nonNegativeInteger(value, fallback, name) {
8946
+ const result = value ?? fallback;
8947
+ if (!Number.isSafeInteger(result) || result < 0) throw new TypeError(`${name} must be a non-negative integer`);
8948
+ return result;
8949
+ }
8950
+ function booleanOption(value, fallback, name) {
8951
+ const result = value ?? fallback;
8952
+ if (typeof result !== "boolean") throw new TypeError(`${name} must be a boolean`);
8953
+ return result;
8954
+ }
8955
+ function safeHeader(value) {
8956
+ return !value.includes("\r") && !value.includes("\n");
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
+ }
8967
+
8968
+ // src/http-transport.ts
8969
+ var import_node_http2 = __toESM(require("http"), 1);
8970
+ var import_node_http22 = __toESM(require("http2"), 1);
8971
+ var import_node_https = __toESM(require("https"), 1);
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
9082
+ var HTTPTransport = class {
9083
+ constructor(config) {
9084
+ this.config = config;
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
+ });
9091
+ this.#httpsAgent = new import_node_https.default.Agent({
9092
+ ...config.tlsOptions,
9093
+ keepAlive: true,
9094
+ maxFreeSockets: config.maxConnections,
9095
+ maxSockets: config.maxConnections,
9096
+ maxTotalSockets: config.maxConnections
9097
+ });
9098
+ }
9099
+ config;
9100
+ #httpAgent;
9101
+ #httpsAgent;
9102
+ #allSessions = /* @__PURE__ */ new Set();
9103
+ #sessions = /* @__PURE__ */ new Map();
9104
+ #sessionSlots = /* @__PURE__ */ new WeakMap();
9105
+ #requests = /* @__PURE__ */ new Set();
9106
+ #closed = false;
9107
+ async post(body, timeoutMs) {
9108
+ if (this.#closed) throw new HTTPTransportError("HTTP transport is closed");
9109
+ const controller = new AbortController();
9110
+ this.#requests.add(controller);
9111
+ const timer = timeoutMs == null ? void 0 : setLongTimeout(() => controller.abort(requestTimeoutReason), timeoutMs);
9112
+ timer?.unref();
9113
+ try {
9114
+ return await this.request(this.config.commandUrl, "POST", body, 0, controller.signal);
9115
+ } catch (error) {
9116
+ if (controller.signal.aborted) {
9117
+ if (controller.signal.reason instanceof HTTPTransportError) throw controller.signal.reason;
9118
+ throw new RequestTimeoutError(timeoutMs ?? this.config.timeoutMs, "possibly_sent", {
9119
+ cause: error,
9120
+ raw: { retryable: true, safe_to_retry: false }
9121
+ });
9122
+ }
9123
+ if (error instanceof HTTPTransportError || error instanceof RequestTimeoutError) throw error;
9124
+ throw new HTTPTransportError("HTTP command request failed", {
9125
+ cause: error,
9126
+ retryable: true,
9127
+ safeToRetry: false
9128
+ });
9129
+ } finally {
9130
+ timer?.cancel();
9131
+ this.#requests.delete(controller);
9132
+ }
9133
+ }
9134
+ async close() {
9135
+ if (this.#closed) return;
9136
+ this.#closed = true;
9137
+ const error = new HTTPTransportError("HTTP transport is closed");
9138
+ for (const controller of this.#requests) controller.abort(error);
9139
+ this.#httpAgent.destroy();
9140
+ this.#httpsAgent.destroy();
9141
+ for (const session of this.#allSessions) session.destroy();
9142
+ this.#allSessions.clear();
9143
+ this.#sessions.clear();
9144
+ }
9145
+ async request(url, method, body, redirects, signal) {
9146
+ const response = this.config.http2 ? await this.http2Request(url, method, body, signal) : await this.http1Request(url, method, body, signal);
9147
+ if (![301, 302, 303, 307, 308].includes(response.status)) return response;
9148
+ if (redirects >= this.config.maxRedirects) throw new HTTPTransportError("too many HTTP redirects");
9149
+ const location = response.headers.location;
9150
+ if (location == null || location === "") throw new HTTPTransportError("HTTP redirect has no location");
9151
+ const target = new URL(location, url);
9152
+ if (target.protocol !== "http:" && target.protocol !== "https:") {
9153
+ throw new HTTPTransportError("HTTP redirect has an unsupported scheme");
9154
+ }
9155
+ const switchToGet = [301, 302, 303].includes(response.status);
9156
+ return await this.request(
9157
+ target,
9158
+ switchToGet ? "GET" : method,
9159
+ switchToGet ? void 0 : body,
9160
+ redirects + 1,
9161
+ signal
9162
+ );
9163
+ }
9164
+ async http1Request(url, method, body, signal) {
9165
+ const request = url.protocol === "https:" ? import_node_https.default.request : import_node_http2.default.request;
9166
+ const agent = url.protocol === "https:" ? this.#httpsAgent : this.#httpAgent;
9167
+ const headers = this.requestHeaders(body);
9168
+ return await new Promise((resolve, reject) => {
9169
+ const outgoing = request(url, { agent, headers, method, signal }, (response) => {
9170
+ void this.collectHttp1(response).then(resolve, reject);
9171
+ });
9172
+ outgoing.once("error", reject);
9173
+ outgoing.end(body);
9174
+ });
9175
+ }
9176
+ async collectHttp1(response) {
9177
+ const declared = headerValue(response.headers["content-length"]);
9178
+ if (declared != null && Number(declared) > this.config.maxResponseBytes) {
9179
+ response.destroy();
9180
+ throw new HTTPTransportError("HTTP response exceeds maxResponseBytes");
9181
+ }
9182
+ return await collectBody(
9183
+ response,
9184
+ response.statusCode ?? 0,
9185
+ normalizeHeaders(response.headers),
9186
+ this.config.maxResponseBytes
9187
+ );
9188
+ }
9189
+ async http2Request(url, method, body, signal) {
9190
+ const headers = {
9191
+ ...this.requestHeaders(body),
9192
+ ":authority": url.host,
9193
+ ":method": method,
9194
+ ":path": `${url.pathname}${url.search}`,
9195
+ ":scheme": url.protocol.slice(0, -1)
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) {
9231
+ return await new Promise((resolve, reject) => {
9232
+ let responseHeaders = {};
9233
+ const abort = () => stream.close(import_node_http22.default.constants.NGHTTP2_CANCEL);
9234
+ signal.addEventListener("abort", abort, { once: true });
9235
+ stream.once("response", (value) => responseHeaders = value);
9236
+ stream.once("error", reject);
9237
+ void collectBody(stream, 0, {}, this.config.maxResponseBytes).then((response) => {
9238
+ const status = Number(responseHeaders[":status"] ?? 0);
9239
+ resolve({ body: response.body, headers: normalizeHeaders(responseHeaders), status });
9240
+ }, reject).finally(() => signal.removeEventListener("abort", abort));
9241
+ if (signal.aborted) abort();
9242
+ else stream.end(body);
9243
+ });
9244
+ }
9245
+ session(url) {
9246
+ const origin = url.origin;
9247
+ const current = this.#sessions.get(origin);
9248
+ if (current != null && !current.closed && !current.destroyed) return current;
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
+ });
9274
+ this.#sessions.set(origin, session);
9275
+ return session;
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
+ }
9295
+ requestHeaders(body) {
9296
+ const headers = { ...this.config.headers };
9297
+ delete headers["content-length"];
9298
+ delete headers["content-type"];
9299
+ return {
9300
+ ...headers,
9301
+ accept: "application/json",
9302
+ ...body == null ? {} : { "content-length": body.byteLength, "content-type": "application/json" }
9303
+ };
9304
+ }
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
+ }
9316
+ async function collectBody(source, status, headers, maximum) {
9317
+ const chunks = [];
9318
+ let size = 0;
9319
+ for await (const chunk of source) {
9320
+ const bytes2 = import_node_buffer36.Buffer.from(chunk);
9321
+ size += bytes2.byteLength;
9322
+ if (size > maximum) {
9323
+ const destroy = source.destroy;
9324
+ if (destroy != null) destroy.call(source);
9325
+ throw new HTTPTransportError("HTTP response exceeds maxResponseBytes");
9326
+ }
9327
+ chunks.push(bytes2);
9328
+ }
9329
+ return { body: import_node_buffer36.Buffer.concat(chunks, size), headers, status };
9330
+ }
9331
+ function normalizeHeaders(headers) {
9332
+ const result = /* @__PURE__ */ Object.create(null);
9333
+ for (const [name, raw] of Object.entries(headers)) {
9334
+ const value = headerValue(raw);
9335
+ if (value != null) result[name.toLowerCase()] = value;
9336
+ }
9337
+ return result;
9338
+ }
9339
+ function headerValue(value) {
9340
+ if (Array.isArray(value)) return value.join(", ");
9341
+ return value == null ? void 0 : String(value);
9342
+ }
9343
+
9344
+ // src/http-adapter.ts
9345
+ var HTTPAdapter = class _HTTPAdapter {
9346
+ #config;
9347
+ #transport;
9348
+ static async fromUrl(url, options = {}) {
9349
+ return new _HTTPAdapter(normalizeHTTPOptions(url, options));
9350
+ }
9351
+ constructor(config) {
9352
+ this.#config = config;
9353
+ this.#transport = new HTTPTransport(config);
9354
+ }
9355
+ async executeCommand(...args) {
9356
+ return await this.executeCommandArgs(args);
9357
+ }
9358
+ async executeCommandArgs(args) {
9359
+ const [result] = await this.executeBatch([args]);
9360
+ if (result == null) throw new HTTPTransportError("HTTP response omitted a command result");
9361
+ if (result.status === "error") throw commandError(result.error);
9362
+ return result.value;
9363
+ }
9364
+ async executePipeline(commands, options = {}) {
9365
+ const results = await this.executeBatch(commands);
9366
+ const values = results.map((result) => result.status === "ok" ? result.value : commandError(result.error));
9367
+ if (options.throwOnItemError !== false) {
9368
+ const failure = values.find((value) => value instanceof Error);
9369
+ if (failure instanceof Error) throw failure;
9370
+ }
9371
+ return values;
9372
+ }
9373
+ async executeFusedPipeline(commands, options = {}) {
9374
+ return await this.executePipeline(commands, options);
9375
+ }
9376
+ async close() {
9377
+ await this.#transport.close();
9378
+ }
9379
+ async executeBatch(commands) {
9380
+ if (commands.length > this.#config.maxBatchItems) {
9381
+ throw new HTTPTransportError("HTTP command batch exceeds maxBatchItems");
9382
+ }
9383
+ for (const command of commands) assertHTTPCommandSupported(command[0]);
9384
+ const prepared = commands.map((command) => prepareHTTPCommand(command, this.#config.maxRequestBytes));
9385
+ const body = encodeHTTPCommands(prepared.map((command) => command.encoded), this.#config.maxRequestBytes);
9386
+ if (body.byteLength > this.#config.maxRequestBytes) {
9387
+ throw new HTTPTransportError("HTTP command request exceeds maxRequestBytes");
9388
+ }
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
+ );
9394
+ let envelope = {};
9395
+ try {
9396
+ if (response.body.byteLength > 0) envelope = decodeHTTPEnvelope(response.body);
9397
+ } catch (error) {
9398
+ if (response.status >= 200 && response.status < 300) throw error;
9399
+ }
9400
+ if (response.status < 200 || response.status >= 300) throw topLevelError(
9401
+ response.status,
9402
+ envelope,
9403
+ response.headers["retry-after"]
9404
+ );
9405
+ if (envelope.encoding !== "ferricstore-json-v1") {
9406
+ throw new HTTPTransportError("HTTP response has an unsupported encoding");
9407
+ }
9408
+ if (!Array.isArray(envelope.results) || envelope.results.length !== commands.length) {
9409
+ throw new HTTPTransportError("HTTP response result count does not match the command batch");
9410
+ }
9411
+ return envelope.results.map((result) => validatedResult(result));
9412
+ }
9413
+ };
9414
+ var commandNamesByOpcode = new Map(
9415
+ Object.entries(COMMAND_OPCODES).map(([name, opcode]) => [opcode, name])
9416
+ );
9417
+ function prepareHTTPCommand(command, maxRequestBytes) {
9418
+ const protocol = buildProtocolCommand(command, maxRequestBytes, false);
9419
+ if (protocol.opcode === OPCODES.commandExec) {
9420
+ return { encoded: command, serverBlockMs: protocol.serverBlockMs };
9421
+ }
9422
+ const name = commandNamesByOpcode.get(protocol.opcode);
9423
+ if (name == null) throw new HTTPTransportError(`HTTP command has unknown opcode ${protocol.opcode}`);
9424
+ return {
9425
+ encoded: { command: name, opcode: protocol.opcode, payload: protocol.payload ?? {} },
9426
+ serverBlockMs: protocol.serverBlockMs
9427
+ };
9428
+ }
9429
+ function validatedResult(value) {
9430
+ if (!isRecord2(value)) throw new HTTPTransportError("HTTP response has an invalid result item");
9431
+ if (value.status === "ok" && Object.hasOwn(value, "value")) {
9432
+ return { status: "ok", value: value.value };
9433
+ }
9434
+ if (value.status === "error" && isRecord2(value.error)) {
9435
+ return { error: value.error, status: "error" };
9436
+ }
9437
+ throw new HTTPTransportError("HTTP response has an invalid result item");
9438
+ }
9439
+ function commandError(value) {
9440
+ const message = isRecord2(value) && typeof value.message === "string" ? value.message : "FerricStore command failed";
9441
+ const code = isRecord2(value) && typeof value.code === "string" ? value.code : void 0;
9442
+ return classifyServerError(message, value, void 0, code);
9443
+ }
9444
+ function topLevelError(status, envelope, retryAfter) {
9445
+ const details = isRecord2(envelope.error) ? envelope.error : {};
9446
+ const message = typeof details.message === "string" ? details.message : `HTTP command request failed with status ${status}`;
9447
+ const retryAfterMs2 = retryAfterMilliseconds(retryAfter);
9448
+ return new HTTPTransportError(message, {
9449
+ raw: details,
9450
+ retryable: status === 408 || status === 425 || status === 429 || status >= 500,
9451
+ retryAfterMs: retryAfterMs2,
9452
+ safeToRetry: false,
9453
+ statusCode: status
9454
+ });
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
+ }
9468
+ function isRecord2(value) {
9469
+ return typeof value === "object" && value != null && !Array.isArray(value);
9470
+ }
9471
+
8646
9472
  // src/adapters.ts
8647
9473
  function executeCommandArgs(executor, args) {
8648
9474
  if (executor.executeCommandArgs != null) return executor.executeCommandArgs(args);
@@ -8651,10 +9477,10 @@ function executeCommandArgs(executor, args) {
8651
9477
  }
8652
9478
 
8653
9479
  // src/reconnecting-executor.ts
8654
- var import_node_buffer34 = require("buffer");
9480
+ var import_node_buffer38 = require("buffer");
8655
9481
 
8656
9482
  // src/command-retry-policy.ts
8657
- var import_node_buffer33 = require("buffer");
9483
+ var import_node_buffer37 = require("buffer");
8658
9484
  function isCasMutation(args) {
8659
9485
  const offset = commandName2(args[0]) === "COMMAND_EXEC" ? 1 : 0;
8660
9486
  const name = commandName2(args[offset]);
@@ -8668,8 +9494,8 @@ function isCasMutation(args) {
8668
9494
  }
8669
9495
  function commandName2(value) {
8670
9496
  if (typeof value === "string") return value.toUpperCase();
8671
- if (import_node_buffer33.Buffer.isBuffer(value) || value instanceof Uint8Array) {
8672
- return import_node_buffer33.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();
8673
9499
  }
8674
9500
  return void 0;
8675
9501
  }
@@ -8881,15 +9707,15 @@ function normalizeNonNegativeInteger2(value, fallback) {
8881
9707
  }
8882
9708
 
8883
9709
  // src/topology.ts
8884
- var import_node_buffer37 = require("buffer");
9710
+ var import_node_buffer41 = require("buffer");
8885
9711
 
8886
9712
  // src/topology-routing.ts
8887
- var import_node_buffer36 = require("buffer");
9713
+ var import_node_buffer40 = require("buffer");
8888
9714
 
8889
9715
  // src/flow-partition-route-cache.ts
8890
- var import_node_buffer35 = require("buffer");
9716
+ var import_node_buffer39 = require("buffer");
8891
9717
  var import_node_crypto = require("crypto");
8892
- var AUTO_PREFIX = import_node_buffer35.Buffer.from("__flow_auto__:", "ascii");
9718
+ var AUTO_PREFIX = import_node_buffer39.Buffer.from("__flow_auto__:", "ascii");
8893
9719
  var MAX_CACHEABLE_PARTITION_BYTES = 4 * 1024;
8894
9720
  var MAX_CACHE_BYTES = 1 * 1024 * 1024;
8895
9721
  var MAX_CACHE_ENTRIES = 1024;
@@ -8899,10 +9725,10 @@ var cacheBytes = 0;
8899
9725
  var cacheHits = 0;
8900
9726
  var cacheMisses = 0;
8901
9727
  function flowLogicalPartitionRoutingKey(value) {
8902
- if (typeof value !== "string" && !import_node_buffer35.Buffer.isBuffer(value)) return void 0;
9728
+ if (typeof value !== "string" && !import_node_buffer39.Buffer.isBuffer(value)) return void 0;
8903
9729
  const autoBucket = flowAutoBucket(value);
8904
9730
  if (autoBucket != null) return `{fa:${autoBucket}}`;
8905
- const bytes2 = import_node_buffer35.Buffer.isBuffer(value) ? value : import_node_buffer35.Buffer.from(value);
9731
+ const bytes2 = import_node_buffer39.Buffer.isBuffer(value) ? value : import_node_buffer39.Buffer.from(value);
8906
9732
  if (bytes2.byteLength > MAX_CACHEABLE_PARTITION_BYTES) return hashRoute(bytes2);
8907
9733
  const cacheKey = bytes2.toString("base64");
8908
9734
  const cached = routeCache.get(cacheKey);
@@ -8976,7 +9802,7 @@ function routingKeyFromProtocolPayload(name, command) {
8976
9802
  "scope"
8977
9803
  ]) {
8978
9804
  const value = getField(command.payload, field3);
8979
- if (typeof value === "string" || import_node_buffer36.Buffer.isBuffer(value)) {
9805
+ if (typeof value === "string" || import_node_buffer40.Buffer.isBuffer(value)) {
8980
9806
  return value;
8981
9807
  }
8982
9808
  }
@@ -9024,7 +9850,7 @@ function flowRoutingData(name, args) {
9024
9850
  if (typeof partition === "string" && partition.toUpperCase() !== "AUTO" && partition.toUpperCase() !== "MIXED") {
9025
9851
  return flowRoutingResult(flowLogicalPartitionRoutingKey(partition));
9026
9852
  }
9027
- if (import_node_buffer36.Buffer.isBuffer(partition)) {
9853
+ if (import_node_buffer40.Buffer.isBuffer(partition)) {
9028
9854
  const text3 = partition.toString("utf8").toUpperCase();
9029
9855
  if (text3 !== "AUTO" && text3 !== "MIXED") {
9030
9856
  return flowRoutingResult(flowLogicalPartitionRoutingKey(partition));
@@ -9115,17 +9941,17 @@ function flowPartitionRoutingKeyFromCommand(command, claim) {
9115
9941
  return { handled: false };
9116
9942
  }
9117
9943
  function isRoutingKey(value) {
9118
- return typeof value === "string" || import_node_buffer36.Buffer.isBuffer(value);
9944
+ return typeof value === "string" || import_node_buffer40.Buffer.isBuffer(value);
9119
9945
  }
9120
9946
  function flowAutoIdRoutingKey(value) {
9121
- if (typeof value !== "string" && !import_node_buffer36.Buffer.isBuffer(value)) {
9947
+ if (typeof value !== "string" && !import_node_buffer40.Buffer.isBuffer(value)) {
9122
9948
  return void 0;
9123
9949
  }
9124
- const bucket = (import_node_buffer36.Buffer.isBuffer(value) ? crc32(value) : crc32Utf8(value)) & 255;
9950
+ const bucket = (import_node_buffer40.Buffer.isBuffer(value) ? crc32(value) : crc32Utf8(value)) & 255;
9125
9951
  return `{fa:${bucket}}`;
9126
9952
  }
9127
9953
  function flowClaimLogicalPartitionRoutingKey(value) {
9128
- if (typeof value !== "string" && !import_node_buffer36.Buffer.isBuffer(value)) return void 0;
9954
+ if (typeof value !== "string" && !import_node_buffer40.Buffer.isBuffer(value)) return void 0;
9129
9955
  const selector = commandPart(value);
9130
9956
  if (selector === "AUTO" || selector === "ANY") return void 0;
9131
9957
  if (selector === "GLOBAL") return "{f}";
@@ -9140,7 +9966,7 @@ function singleShardFlowClaimPartitionKey(values) {
9140
9966
  return keys.some((key) => key == null) ? void 0 : singleShardKey(keys);
9141
9967
  }
9142
9968
  function singleShardKey(keys) {
9143
- if (keys.length === 0 || keys.some((key) => typeof key !== "string" && !import_node_buffer36.Buffer.isBuffer(key))) {
9969
+ if (keys.length === 0 || keys.some((key) => typeof key !== "string" && !import_node_buffer40.Buffer.isBuffer(key))) {
9144
9970
  return void 0;
9145
9971
  }
9146
9972
  const usable = keys;
@@ -9173,7 +9999,7 @@ function routedKeyGroups(keys, routeKey) {
9173
9999
  const groups = /* @__PURE__ */ new Map();
9174
10000
  for (let index = 0; index < keys.length; index += 1) {
9175
10001
  const key = keys[index];
9176
- if (typeof key !== "string" && !import_node_buffer36.Buffer.isBuffer(key)) return void 0;
10002
+ if (typeof key !== "string" && !import_node_buffer40.Buffer.isBuffer(key)) return void 0;
9177
10003
  const route = routeKey(key);
9178
10004
  const groupKey = `${route.endpointKey}\0${route.laneId}`;
9179
10005
  const group = groups.get(groupKey);
@@ -10262,7 +11088,7 @@ var TopologyNativeAdapterPool = class _TopologyNativeAdapterPool {
10262
11088
  };
10263
11089
 
10264
11090
  // src/response-map-preservation.ts
10265
- var import_node_buffer38 = require("buffer");
11091
+ var import_node_buffer42 = require("buffer");
10266
11092
  function toStringKeyMapPreservingValues(value) {
10267
11093
  if (value == null) return void 0;
10268
11094
  const result = {};
@@ -10272,7 +11098,7 @@ function toStringKeyMapPreservingValues(value) {
10272
11098
  }
10273
11099
  return result;
10274
11100
  }
10275
- if (typeof value === "object" && !Array.isArray(value) && !import_node_buffer38.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) {
11101
+ if (typeof value === "object" && !Array.isArray(value) && !import_node_buffer42.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) {
10276
11102
  for (const [key, item] of Object.entries(value)) {
10277
11103
  setOwnValue(result, text(key), normalizeMapStructurePreservingBytes(item));
10278
11104
  }
@@ -10281,7 +11107,7 @@ function toStringKeyMapPreservingValues(value) {
10281
11107
  return void 0;
10282
11108
  }
10283
11109
  function normalizeMapStructurePreservingBytes(value) {
10284
- if (import_node_buffer38.Buffer.isBuffer(value) || value instanceof Uint8Array) return value;
11110
+ if (import_node_buffer42.Buffer.isBuffer(value) || value instanceof Uint8Array) return value;
10285
11111
  if (value instanceof Map) {
10286
11112
  const result = {};
10287
11113
  for (const [key, item] of value.entries()) {
@@ -10303,7 +11129,7 @@ function normalizeMapStructurePreservingBytes(value) {
10303
11129
  }
10304
11130
 
10305
11131
  // src/native-kv-responses.ts
10306
- var import_node_buffer39 = require("buffer");
11132
+ var import_node_buffer43 = require("buffer");
10307
11133
  function rateLimitResultFromResp(value) {
10308
11134
  if (!Array.isArray(value) || value.length !== 4) {
10309
11135
  throw new TypeError("RATELIMIT.ADD returned an unexpected response");
@@ -10360,13 +11186,13 @@ function fetchOrComputeResultFromResp(value, codec) {
10360
11186
  }
10361
11187
  function decodePayload(codec, value) {
10362
11188
  if (value == null) return null;
10363
- if (import_node_buffer39.Buffer.isBuffer(value)) return codec.decode(value);
10364
- if (value instanceof Uint8Array) return codec.decode(import_node_buffer39.Buffer.from(value));
10365
- if (typeof value === "string") return codec.decode(import_node_buffer39.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));
10366
11192
  return normalizeRefMeta(value);
10367
11193
  }
10368
11194
  function requiredResponseString(value, context) {
10369
- if (typeof value !== "string" && !import_node_buffer39.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) {
11195
+ if (typeof value !== "string" && !import_node_buffer43.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) {
10370
11196
  throw new TypeError(`${context} returned an unexpected response`);
10371
11197
  }
10372
11198
  const result = text(value);
@@ -10383,7 +11209,7 @@ function requiredNonNegativeInteger(value, context) {
10383
11209
  return result;
10384
11210
  }
10385
11211
  function responseBytes(value, context) {
10386
- if (typeof value !== "string" && !import_node_buffer39.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) {
11212
+ if (typeof value !== "string" && !import_node_buffer43.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) {
10387
11213
  throw new TypeError(`${context} returned an unexpected response`);
10388
11214
  }
10389
11215
  return bytes(value);
@@ -11066,7 +11892,7 @@ function groupAutoPartitionItems(items) {
11066
11892
  }
11067
11893
 
11068
11894
  // src/client-values.ts
11069
- var import_node_buffer40 = require("buffer");
11895
+ var import_node_buffer44 = require("buffer");
11070
11896
  async function valueMGetEntries(client, refs, options = {}) {
11071
11897
  const refCount = refs.length;
11072
11898
  if (refCount === 0) {
@@ -11101,12 +11927,12 @@ async function valueMGetEntries(client, refs, options = {}) {
11101
11927
  const item = response[index];
11102
11928
  if (item == null) {
11103
11929
  entries[index] = { found: false };
11104
- } else if (import_node_buffer40.Buffer.isBuffer(item)) {
11930
+ } else if (import_node_buffer44.Buffer.isBuffer(item)) {
11105
11931
  entries[index] = { found: true, value: client.codec.decode(item) };
11106
11932
  } else if (item instanceof Uint8Array) {
11107
- entries[index] = { found: true, value: client.codec.decode(import_node_buffer40.Buffer.from(item)) };
11933
+ entries[index] = { found: true, value: client.codec.decode(import_node_buffer44.Buffer.from(item)) };
11108
11934
  } else if (typeof item === "string") {
11109
- entries[index] = { found: true, value: client.codec.decode(import_node_buffer40.Buffer.from(item)) };
11935
+ entries[index] = { found: true, value: client.codec.decode(import_node_buffer44.Buffer.from(item)) };
11110
11936
  } else {
11111
11937
  entries[index] = { found: true, value: item };
11112
11938
  }
@@ -11115,10 +11941,10 @@ async function valueMGetEntries(client, refs, options = {}) {
11115
11941
  }
11116
11942
 
11117
11943
  // src/auto-batch.ts
11118
- var import_node_buffer42 = require("buffer");
11944
+ var import_node_buffer46 = require("buffer");
11119
11945
 
11120
11946
  // src/auto-batch-ordering.ts
11121
- var import_node_buffer41 = require("buffer");
11947
+ var import_node_buffer45 = require("buffer");
11122
11948
  function autoBatchOrderingPlan(batch) {
11123
11949
  const accesses = /* @__PURE__ */ new Map();
11124
11950
  const fallbackDependencies = [];
@@ -11233,13 +12059,13 @@ function flowManyAutoBatchIds(command, name) {
11233
12059
  return fixedFlowItemIds(
11234
12060
  command,
11235
12061
  mixed ? 4 : 3,
11236
- (itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && isFencingToken(command[itemIndex + (mixed ? 2 : 1)]) && import_node_buffer41.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)])
11237
12063
  );
11238
12064
  }
11239
12065
  return fixedFlowItemIds(
11240
12066
  command,
11241
12067
  mixed ? 4 : 3,
11242
- (itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && import_node_buffer41.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)])
11243
12069
  );
11244
12070
  }
11245
12071
  function createManyAutoBatchIds(command) {
@@ -11252,7 +12078,7 @@ function createManyAutoBatchIds(command) {
11252
12078
  const ids = fixedFlowItemIds(
11253
12079
  command,
11254
12080
  width,
11255
- (itemIndex) => isAutoBatchResourceValue(command[itemIndex]) && (!mixed || isAutoBatchResourceValue(command[itemIndex + 1])) && import_node_buffer41.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]),
11256
12082
  markerIndex
11257
12083
  );
11258
12084
  if (ids != null) return ids;
@@ -11270,7 +12096,7 @@ function extendedCreateManyAutoBatchIds(command, markerIndex) {
11270
12096
  let cursor = markerIndex + 2;
11271
12097
  for (let itemIndex = 0; itemIndex < itemCount; itemIndex += 1) {
11272
12098
  const id = command[cursor];
11273
- if (!isAutoBatchResourceValue(id) || !isAutoBatchResourceValue(command[cursor + 1]) || !import_node_buffer41.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;
11274
12100
  ids.push(id);
11275
12101
  cursor += 3;
11276
12102
  const afterValues = skipExtendedNamedItems(command, cursor, true);
@@ -11289,7 +12115,7 @@ function skipExtendedNamedItems(command, countIndex, encodedValues) {
11289
12115
  for (let index = 0; index < count; index += 1) {
11290
12116
  const name = command[firstItem + index * 2];
11291
12117
  const value = command[firstItem + index * 2 + 1];
11292
- if (!isAutoBatchResourceValue(name) || (encodedValues ? !import_node_buffer41.Buffer.isBuffer(value) : !isAutoBatchResourceValue(value))) return void 0;
12118
+ if (!isAutoBatchResourceValue(name) || (encodedValues ? !import_node_buffer45.Buffer.isBuffer(value) : !isAutoBatchResourceValue(value))) return void 0;
11293
12119
  }
11294
12120
  return firstItem + count * 2;
11295
12121
  }
@@ -11304,7 +12130,7 @@ function runStepsManyAutoBatchIds(command) {
11304
12130
  ids.push(item);
11305
12131
  continue;
11306
12132
  }
11307
- if (typeof item !== "object" || item == null || Array.isArray(item) || import_node_buffer41.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;
11308
12134
  const id = item.id;
11309
12135
  if (!isAutoBatchResourceValue(id)) return void 0;
11310
12136
  ids.push(id);
@@ -11345,7 +12171,7 @@ function flowValuePutOwner(command, start) {
11345
12171
  }
11346
12172
  var flowValuePutOptionTokens = /* @__PURE__ */ new Set(["NAME", "NOW", "OVERRIDE", "OWNER_FLOW_ID", "PARTITION", "TTL", "TTL_MS"]);
11347
12173
  function isAutoBatchResourceValue(value) {
11348
- return typeof value === "string" || import_node_buffer41.Buffer.isBuffer(value);
12174
+ return typeof value === "string" || import_node_buffer45.Buffer.isBuffer(value);
11349
12175
  }
11350
12176
  function isFencingToken(value) {
11351
12177
  return typeof value === "number" && Number.isSafeInteger(value) || typeof value === "bigint";
@@ -11354,7 +12180,7 @@ function nonNegativeItemCount(value) {
11354
12180
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : void 0;
11355
12181
  }
11356
12182
  function autoBatchResourceKey(namespace, value) {
11357
- return `${namespace}:${import_node_buffer41.Buffer.from(value).toString("base64")}`;
12183
+ return `${namespace}:${import_node_buffer45.Buffer.from(value).toString("base64")}`;
11358
12184
  }
11359
12185
  function autoBatchCommandName(command) {
11360
12186
  return commandView(command).name ?? null;
@@ -11763,13 +12589,13 @@ function claimFailure(error) {
11763
12589
  }
11764
12590
 
11765
12591
  // src/client-flow-support.ts
11766
- var import_node_buffer55 = require("buffer");
12592
+ var import_node_buffer59 = require("buffer");
11767
12593
 
11768
12594
  // src/flow-query-builder.ts
11769
- var import_node_buffer44 = require("buffer");
12595
+ var import_node_buffer48 = require("buffer");
11770
12596
 
11771
12597
  // src/flow-query-metadata.ts
11772
- var import_node_buffer43 = require("buffer");
12598
+ var import_node_buffer47 = require("buffer");
11773
12599
  var MAX_FLOW_QUERY_METADATA_KEY_BYTES = 64;
11774
12600
  function normalizeStateMeta(value, state) {
11775
12601
  if (value == null) return {};
@@ -11794,7 +12620,7 @@ function normalizeStateMeta(value, state) {
11794
12620
  function metadataEntries(value, context) {
11795
12621
  const entries = objectEntries(value ?? {}, context).map(([rawName, item]) => {
11796
12622
  const name = rawName.trim();
11797
- const size = import_node_buffer43.Buffer.byteLength(name, "utf8");
12623
+ const size = import_node_buffer47.Buffer.byteLength(name, "utf8");
11798
12624
  if (size === 0 || size > MAX_FLOW_QUERY_METADATA_KEY_BYTES || name.startsWith("__")) {
11799
12625
  throw new TypeError(`${context} key is invalid or reserved`);
11800
12626
  }
@@ -11818,7 +12644,7 @@ function objectEntries(value, context) {
11818
12644
  return keys.map((key) => [key, value[key]]);
11819
12645
  }
11820
12646
  function isPlainRecord(value) {
11821
- if (typeof value !== "object" || value == null || Array.isArray(value) || import_node_buffer43.Buffer.isBuffer(value)) {
12647
+ if (typeof value !== "object" || value == null || Array.isArray(value) || import_node_buffer47.Buffer.isBuffer(value)) {
11822
12648
  return false;
11823
12649
  }
11824
12650
  const prototype = Object.getPrototypeOf(value);
@@ -11888,7 +12714,7 @@ var FlowCollectionQuery = class {
11888
12714
  const states = /* @__PURE__ */ new Set();
11889
12715
  for (const [rawState, metadata] of objectEntries(values, "stateMeta")) {
11890
12716
  const state = requiredText(rawState, "stateMeta state").trim();
11891
- const stateBytes = import_node_buffer44.Buffer.byteLength(state, "utf8");
12717
+ const stateBytes = import_node_buffer48.Buffer.byteLength(state, "utf8");
11892
12718
  if (stateBytes === 0 || stateBytes > MAX_FLOW_QUERY_STATE_BYTES) {
11893
12719
  throw new TypeError(
11894
12720
  `stateMeta state names must be 1..${MAX_FLOW_QUERY_STATE_BYTES} bytes`
@@ -12067,7 +12893,7 @@ function requiredPartition(value) {
12067
12893
  "FLOW.QUERY convenience methods require a partition key"
12068
12894
  );
12069
12895
  }
12070
- const size = import_node_buffer44.Buffer.byteLength(value, "utf8");
12896
+ const size = import_node_buffer48.Buffer.byteLength(value, "utf8");
12071
12897
  if (size === 0 || size > MAX_FLOW_QUERY_PARTITION_BYTES) {
12072
12898
  throw new TypeError(
12073
12899
  `FLOW.QUERY partition key must be 1..${MAX_FLOW_QUERY_PARTITION_BYTES} bytes`
@@ -12115,23 +12941,23 @@ function requiredText(value, context) {
12115
12941
  return value;
12116
12942
  }
12117
12943
  function queryParameter(value, context) {
12118
- if (typeof value === "string" || typeof value === "boolean" || typeof value === "bigint" || typeof value === "number" || import_node_buffer44.Buffer.isBuffer(value)) {
12944
+ if (typeof value === "string" || typeof value === "boolean" || typeof value === "bigint" || typeof value === "number" || import_node_buffer48.Buffer.isBuffer(value)) {
12119
12945
  return value;
12120
12946
  }
12121
12947
  throw new TypeError(`${context} must be a scalar FLOW.QUERY parameter`);
12122
12948
  }
12123
12949
 
12124
12950
  // src/flow-query-response.ts
12125
- var import_node_buffer48 = require("buffer");
12951
+ var import_node_buffer52 = require("buffer");
12126
12952
 
12127
12953
  // src/flow-query-diagnostic-response.ts
12128
- var import_node_buffer46 = require("buffer");
12954
+ var import_node_buffer50 = require("buffer");
12129
12955
 
12130
12956
  // src/flow-query-response-validation.ts
12131
- var import_node_buffer45 = require("buffer");
12957
+ var import_node_buffer49 = require("buffer");
12132
12958
  function requiredMap2(value, context) {
12133
12959
  if (value instanceof Map) return value;
12134
- if (typeof value !== "object" || value == null || Array.isArray(value) || import_node_buffer45.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) {
12135
12961
  throw decodeError(`${context} must be a map`, value);
12136
12962
  }
12137
12963
  return value;
@@ -12188,7 +13014,7 @@ function normalizeMetadataValue(value, context, budget, ancestors, depth) {
12188
13014
  if (!value.isWellFormed()) throw decodeError(`${context} contains invalid text`, value);
12189
13015
  return value;
12190
13016
  }
12191
- if (import_node_buffer45.Buffer.isBuffer(value) || value instanceof Uint8Array) {
13017
+ if (import_node_buffer49.Buffer.isBuffer(value) || value instanceof Uint8Array) {
12192
13018
  const decoded = strictText2(value);
12193
13019
  if (decoded == null) throw decodeError(`${context} contains invalid UTF-8`, value);
12194
13020
  return decoded;
@@ -12267,7 +13093,7 @@ function optionalText2(mapping2, name, context) {
12267
13093
  }
12268
13094
  function requiredBoundedText2(mapping2, name, context, maximumBytes) {
12269
13095
  const value = requiredText2(mapping2, name, context);
12270
- if (import_node_buffer45.Buffer.byteLength(value, "utf8") > maximumBytes) {
13096
+ if (import_node_buffer49.Buffer.byteLength(value, "utf8") > maximumBytes) {
12271
13097
  throw decodeError(
12272
13098
  `${context} ${name} exceeds ${maximumBytes} bytes`,
12273
13099
  mapping2
@@ -12280,7 +13106,7 @@ function boundedText(value, context, maximumBytes) {
12280
13106
  if (decoded == null || decoded.length === 0) {
12281
13107
  throw decodeError(`${context} must be non-empty text`, value);
12282
13108
  }
12283
- if (import_node_buffer45.Buffer.byteLength(decoded, "utf8") > maximumBytes) {
13109
+ if (import_node_buffer49.Buffer.byteLength(decoded, "utf8") > maximumBytes) {
12284
13110
  throw decodeError(`${context} exceeds ${maximumBytes} bytes`, value);
12285
13111
  }
12286
13112
  return decoded;
@@ -12292,7 +13118,7 @@ function requiredBoolean(mapping2, name, context) {
12292
13118
  }
12293
13119
  return value;
12294
13120
  }
12295
- function nonNegativeInteger(value, context) {
13121
+ function nonNegativeInteger2(value, context) {
12296
13122
  if (typeof value === "bigint") {
12297
13123
  if (value >= 0n && value <= BigInt(Number.MAX_SAFE_INTEGER))
12298
13124
  return Number(value);
@@ -12301,8 +13127,8 @@ function nonNegativeInteger(value, context) {
12301
13127
  }
12302
13128
  throw decodeError(`${context} must be a non-negative safe integer`, value);
12303
13129
  }
12304
- function positiveInteger(value, context) {
12305
- const parsed = nonNegativeInteger(value, context);
13130
+ function positiveInteger2(value, context) {
13131
+ const parsed = nonNegativeInteger2(value, context);
12306
13132
  if (parsed === 0) throw decodeError(`${context} must be positive`, value);
12307
13133
  return parsed;
12308
13134
  }
@@ -12334,10 +13160,10 @@ function positiveBoundedInteger(value, maximum, context) {
12334
13160
  function hasKey(mapping2, name) {
12335
13161
  if (!(mapping2 instanceof Map)) return Object.hasOwn(mapping2, name);
12336
13162
  if (mapping2.has(name)) return true;
12337
- const binaryName = import_node_buffer45.Buffer.from(name);
13163
+ const binaryName = import_node_buffer49.Buffer.from(name);
12338
13164
  for (const key of mapping2.keys()) {
12339
- if (import_node_buffer45.Buffer.isBuffer(key) && key.equals(binaryName)) return true;
12340
- if (key instanceof Uint8Array && import_node_buffer45.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))
12341
13167
  return true;
12342
13168
  }
12343
13169
  return false;
@@ -12348,7 +13174,7 @@ function decodeError(message, raw) {
12348
13174
  function strictText2(value) {
12349
13175
  if (typeof value === "string")
12350
13176
  return value.isWellFormed() ? value : void 0;
12351
- if (import_node_buffer45.Buffer.isBuffer(value) || value instanceof Uint8Array) {
13177
+ if (import_node_buffer49.Buffer.isBuffer(value) || value instanceof Uint8Array) {
12352
13178
  try {
12353
13179
  return new TextDecoder("utf-8", { fatal: true }).decode(value);
12354
13180
  } catch {
@@ -12412,7 +13238,7 @@ function tryDecodeFlowQueryError(value, cause) {
12412
13238
  hint: optionalDiagnosticText(mapping2, "hint"),
12413
13239
  retryable: requiredBoolean(mapping2, "retryable", "FLOW.QUERY diagnostic"),
12414
13240
  safeToRetry: requiredBoolean(mapping2, "safe_to_retry", "FLOW.QUERY diagnostic"),
12415
- retryAfterMs: nonNegativeInteger(
13241
+ retryAfterMs: nonNegativeInteger2(
12416
13242
  field(mapping2, "retry_after_ms"),
12417
13243
  "FLOW.QUERY diagnostic retry_after_ms"
12418
13244
  ),
@@ -12428,7 +13254,7 @@ function tryDecodeFlowQueryError(value, cause) {
12428
13254
  }
12429
13255
  function optionalDiagnosticText(mapping2, name) {
12430
13256
  const value = optionalText2(mapping2, name, "FLOW.QUERY diagnostic");
12431
- if (value != null && import_node_buffer46.Buffer.byteLength(value, "utf8") > DIAGNOSTIC_TEXT_BYTES) {
13257
+ if (value != null && import_node_buffer50.Buffer.byteLength(value, "utf8") > DIAGNOSTIC_TEXT_BYTES) {
12432
13258
  throw decodeError(
12433
13259
  `FLOW.QUERY diagnostic ${name} exceeds ${DIAGNOSTIC_TEXT_BYTES} bytes`,
12434
13260
  mapping2
@@ -12463,7 +13289,7 @@ function validateDiagnosticContextValue(value, depth, budget) {
12463
13289
  }
12464
13290
  const text3 = diagnosticContextText(value);
12465
13291
  if (text3 != null) {
12466
- if (import_node_buffer46.Buffer.byteLength(text3, "utf8") <= DIAGNOSTIC_TEXT_BYTES) return;
13292
+ if (import_node_buffer50.Buffer.byteLength(text3, "utf8") <= DIAGNOSTIC_TEXT_BYTES) return;
12467
13293
  throw decodeError("FLOW.QUERY diagnostic context contains oversized text", value);
12468
13294
  }
12469
13295
  if (depth <= 0) {
@@ -12489,7 +13315,7 @@ function validateDiagnosticContextValue(value, depth, budget) {
12489
13315
  }
12490
13316
  for (const [rawKey, item] of entries) {
12491
13317
  const key = diagnosticContextText(rawKey);
12492
- if (key == null || key.length === 0 || import_node_buffer46.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) {
12493
13319
  throw decodeError("FLOW.QUERY diagnostic context contains an invalid key", value);
12494
13320
  }
12495
13321
  validateDiagnosticContextValue(item, depth - 1, budget);
@@ -12506,7 +13332,7 @@ function consumeDiagnosticContextNode(value, budget) {
12506
13332
  }
12507
13333
  function diagnosticContextText(value) {
12508
13334
  if (typeof value === "string") return value.isWellFormed() ? value : void 0;
12509
- if (!import_node_buffer46.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) return void 0;
13335
+ if (!import_node_buffer50.Buffer.isBuffer(value) && !(value instanceof Uint8Array)) return void 0;
12510
13336
  try {
12511
13337
  return new TextDecoder("utf-8", { fatal: true }).decode(value);
12512
13338
  } catch {
@@ -12522,9 +13348,9 @@ function decodePosition(value) {
12522
13348
  if (value == null) return void 0;
12523
13349
  const mapping2 = requiredMap2(value, "FLOW.QUERY diagnostic position");
12524
13350
  return Object.freeze({
12525
- byte: positiveInteger(field(mapping2, "byte"), "FLOW.QUERY diagnostic position byte"),
12526
- line: positiveInteger(field(mapping2, "line"), "FLOW.QUERY diagnostic position line"),
12527
- column: positiveInteger(
13351
+ byte: positiveInteger2(field(mapping2, "byte"), "FLOW.QUERY diagnostic position byte"),
13352
+ line: positiveInteger2(field(mapping2, "line"), "FLOW.QUERY diagnostic position line"),
13353
+ column: positiveInteger2(
12528
13354
  field(mapping2, "column"),
12529
13355
  "FLOW.QUERY diagnostic position column"
12530
13356
  )
@@ -12532,7 +13358,7 @@ function decodePosition(value) {
12532
13358
  }
12533
13359
 
12534
13360
  // src/flow-query-index-contract.ts
12535
- var import_node_buffer47 = require("buffer");
13361
+ var import_node_buffer51 = require("buffer");
12536
13362
  var FLOW_QUERY_BUILD_PHASES = ["pending", "snapshot", "backfill", "done"];
12537
13363
  var FLOW_QUERY_VALIDATION_PHASES = [
12538
13364
  "pending",
@@ -12778,10 +13604,10 @@ function fieldKind(name) {
12778
13604
  return void 0;
12779
13605
  }
12780
13606
  function validUnquoted(value) {
12781
- return !value.startsWith("__") && UNQUOTED_METADATA.test(value) && import_node_buffer47.Buffer.byteLength(value, "ascii") <= 64;
13607
+ return !value.startsWith("__") && UNQUOTED_METADATA.test(value) && import_node_buffer51.Buffer.byteLength(value, "ascii") <= 64;
12782
13608
  }
12783
13609
  function validMetadata(value, rejectReserved) {
12784
- return value.length > 0 && import_node_buffer47.Buffer.byteLength(value, "utf8") <= 64 && (!rejectReserved || !value.startsWith("__"));
13610
+ return value.length > 0 && import_node_buffer51.Buffer.byteLength(value, "utf8") <= 64 && (!rejectReserved || !value.startsWith("__"));
12785
13611
  }
12786
13612
  function externalSelector(root, ...segments) {
12787
13613
  return segments.every(validUnquoted) ? [root, ...segments].join(".") : root + segments.map((segment) => `['${segment.replaceAll("'", "''")}']`).join("");
@@ -13291,7 +14117,7 @@ function decodeCountPrefixes(value, fieldCount) {
13291
14117
  if (!Object.hasOwn(value, index)) {
13292
14118
  throw decodeError(`${context} must be dense`, value);
13293
14119
  }
13294
- const prefix = positiveInteger(value[index], `${context} entry`);
14120
+ const prefix = positiveInteger2(value[index], `${context} entry`);
13295
14121
  if (prefix > fieldCount || prefix <= previous) {
13296
14122
  throw decodeError(`${context} are invalid`, value);
13297
14123
  }
@@ -13673,7 +14499,7 @@ function decodeUsage(value) {
13673
14499
  const mapping2 = requiredMap2(value, "FLOW.QUERY usage");
13674
14500
  const usage = /* @__PURE__ */ Object.create(null);
13675
14501
  for (const [wireName, property] of USAGE_FIELDS2) {
13676
- usage[property] = nonNegativeInteger(
14502
+ usage[property] = nonNegativeInteger2(
13677
14503
  field(mapping2, wireName),
13678
14504
  `FLOW.QUERY usage ${wireName}`
13679
14505
  );
@@ -13688,7 +14514,7 @@ function decodePage(value) {
13688
14514
  const mapping2 = requiredMap2(value, "FLOW.QUERY page");
13689
14515
  const hasMore = requiredBoolean(mapping2, "has_more", "FLOW.QUERY page");
13690
14516
  const cursor = optionalText2(mapping2, "cursor", "FLOW.QUERY page");
13691
- if (cursor != null && (!cursor.startsWith("fqc1_") || import_node_buffer48.Buffer.byteLength(cursor) < 16 || import_node_buffer48.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)) {
13692
14518
  throw decodeError("FLOW.QUERY page cursor is invalid", value);
13693
14519
  }
13694
14520
  if (hasMore !== (cursor != null)) {
@@ -13698,12 +14524,12 @@ function decodePage(value) {
13698
14524
  }
13699
14525
 
13700
14526
  // src/client-core.ts
13701
- var import_node_buffer53 = require("buffer");
14527
+ var import_node_buffer57 = require("buffer");
13702
14528
 
13703
14529
  // src/client-core-helpers.ts
13704
- var import_node_buffer49 = require("buffer");
14530
+ var import_node_buffer53 = require("buffer");
13705
14531
  function bgsaveResponse(response) {
13706
- if ((typeof response === "string" || import_node_buffer49.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") {
13707
14533
  return true;
13708
14534
  }
13709
14535
  return okResponse(response);
@@ -13717,7 +14543,7 @@ function fetchOrComputeCompletionToken(options) {
13717
14543
  "fetch-or-compute completion requires computeToken"
13718
14544
  );
13719
14545
  }
13720
- if (!import_node_buffer49.Buffer.isBuffer(options.computeToken)) {
14546
+ if (!import_node_buffer53.Buffer.isBuffer(options.computeToken)) {
13721
14547
  throw new TypeError("fetch-or-compute computeToken must be a Buffer");
13722
14548
  }
13723
14549
  return options.computeToken;
@@ -13740,10 +14566,10 @@ function unsupportedClientCaching() {
13740
14566
  }
13741
14567
 
13742
14568
  // src/client-base.ts
13743
- var import_node_buffer51 = require("buffer");
14569
+ var import_node_buffer55 = require("buffer");
13744
14570
 
13745
14571
  // src/client-executor.ts
13746
- var import_node_buffer50 = require("buffer");
14572
+ var import_node_buffer54 = require("buffer");
13747
14573
  var ErrorMappingExecutor = class {
13748
14574
  constructor(executor) {
13749
14575
  this.executor = executor;
@@ -13808,7 +14634,14 @@ function snapshotClientOptions(options) {
13808
14634
  ...own2,
13809
14635
  ...typeof own2.autoBatch === "object" && own2.autoBatch != null ? { autoBatch: Object.freeze({ ...own2.autoBatch }) } : {},
13810
14636
  ...own2.backpressure == null ? {} : { backpressure: Object.freeze({ ...own2.backpressure }) },
13811
- ...typeof own2.reconnect === "object" && own2.reconnect != null ? { reconnect: Object.freeze({ ...own2.reconnect }) } : {}
14637
+ ...typeof own2.reconnect === "object" && own2.reconnect != null ? { reconnect: Object.freeze({ ...own2.reconnect }) } : {},
14638
+ ...own2.httpOptions == null ? {} : {
14639
+ httpOptions: Object.freeze({
14640
+ ...own2.httpOptions,
14641
+ ...own2.httpOptions.headers == null ? {} : { headers: Object.freeze({ ...own2.httpOptions.headers }) },
14642
+ ...own2.httpOptions.tlsOptions == null ? {} : { tlsOptions: Object.freeze({ ...own2.httpOptions.tlsOptions }) }
14643
+ })
14644
+ }
13812
14645
  };
13813
14646
  return Object.freeze(snapshot);
13814
14647
  }
@@ -14077,14 +14910,14 @@ var FerricStoreAdministrationClient = class extends FerricStoreClientBase {
14077
14910
  };
14078
14911
 
14079
14912
  // src/store-utilities.ts
14080
- var import_node_buffer52 = require("buffer");
14913
+ var import_node_buffer56 = require("buffer");
14081
14914
  function encode(codec, value) {
14082
14915
  return codec.encode(value);
14083
14916
  }
14084
14917
  function decode(codec, value) {
14085
14918
  if (value == null) return null;
14086
- if (import_node_buffer52.Buffer.isBuffer(value)) return codec.decode(value);
14087
- if (value instanceof Uint8Array) return codec.decode(import_node_buffer52.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));
14088
14921
  return value;
14089
14922
  }
14090
14923
  function number(value) {
@@ -14105,7 +14938,7 @@ function array(value, expectedItems, command) {
14105
14938
  }
14106
14939
  return value;
14107
14940
  }
14108
- function denseArray(value, command) {
14941
+ function denseArray2(value, command) {
14109
14942
  return assertDenseArray(array(value), command);
14110
14943
  }
14111
14944
  function denseArrayResponse(value, expectedItems, command) {
@@ -14393,7 +15226,7 @@ var BloomFilterStore = class {
14393
15226
  return integerReply(await this.client.command("BF.CARD", key));
14394
15227
  }
14395
15228
  async info(key) {
14396
- return denseArray(await this.client.command("BF.INFO", key), "BF.INFO");
15229
+ return denseArray2(await this.client.command("BF.INFO", key), "BF.INFO");
14397
15230
  }
14398
15231
  };
14399
15232
  var CuckooFilterStore = class {
@@ -14432,7 +15265,7 @@ var CuckooFilterStore = class {
14432
15265
  return integerReply(await this.client.command("CF.COUNT", key, encode(this.client.codec, element)));
14433
15266
  }
14434
15267
  async info(key) {
14435
- return denseArray(await this.client.command("CF.INFO", key), "CF.INFO");
15268
+ return denseArray2(await this.client.command("CF.INFO", key), "CF.INFO");
14436
15269
  }
14437
15270
  };
14438
15271
  var CountMinSketchStore = class {
@@ -14477,7 +15310,7 @@ var CountMinSketchStore = class {
14477
15310
  return okResponse(await commandArgs(this.client, args));
14478
15311
  }
14479
15312
  async info(key) {
14480
- return denseArray(await this.client.command("CMS.INFO", key), "CMS.INFO");
15313
+ return denseArray2(await this.client.command("CMS.INFO", key), "CMS.INFO");
14481
15314
  }
14482
15315
  };
14483
15316
  var TopKStore = class {
@@ -14560,7 +15393,7 @@ var TopKStore = class {
14560
15393
  );
14561
15394
  }
14562
15395
  async info(key) {
14563
- return denseArray(await this.client.command("TOPK.INFO", key), "TOPK.INFO");
15396
+ return denseArray2(await this.client.command("TOPK.INFO", key), "TOPK.INFO");
14564
15397
  }
14565
15398
  };
14566
15399
  var TDigestStore = class {
@@ -14651,7 +15484,7 @@ var TDigestStore = class {
14651
15484
  return string(await this.client.command("TDIGEST.MAX", key));
14652
15485
  }
14653
15486
  async info(key) {
14654
- return denseArray(await this.client.command("TDIGEST.INFO", key), "TDIGEST.INFO");
15487
+ return denseArray2(await this.client.command("TDIGEST.INFO", key), "TDIGEST.INFO");
14655
15488
  }
14656
15489
  async merge(destination, sources, options = {}) {
14657
15490
  requireNonEmpty(sources, "TDIGEST.MERGE", "source");
@@ -15043,7 +15876,7 @@ var KeyValueStore = class {
15043
15876
  return response == null ? null : string(response);
15044
15877
  }
15045
15878
  async objectHelp() {
15046
- return denseArray(await this.client.command("OBJECT", "HELP"), "OBJECT HELP");
15879
+ return denseArray2(await this.client.command("OBJECT", "HELP"), "OBJECT HELP");
15047
15880
  }
15048
15881
  async objectFreq(key) {
15049
15882
  return number(await this.client.command("OBJECT", "FREQ", key));
@@ -16051,14 +16884,14 @@ function validateScheduleCreate(id, options) {
16051
16884
  validateTiming(kind, options);
16052
16885
  const recurring = RECURRING_KINDS.has(kind);
16053
16886
  validateTarget(options.target, recurring);
16054
- nonNegativeInteger2(options.atMs, "at_ms");
16055
- nonNegativeInteger2(options.delayMs, "delay_ms");
16056
- nonNegativeInteger2(options.startAtMs, "start_at_ms");
16057
- positiveInteger2(options.everyMs, "every_ms");
16058
- positiveInteger2(options.overlapRetryMs, "overlap_retry_ms");
16059
- positiveInteger2(options.maxFires, "max_fires");
16060
- nonNegativeInteger2(options.endAtMs, "end_at_ms");
16061
- nonNegativeInteger2(options.nowMs, "now_ms");
16887
+ nonNegativeInteger3(options.atMs, "at_ms");
16888
+ nonNegativeInteger3(options.delayMs, "delay_ms");
16889
+ nonNegativeInteger3(options.startAtMs, "start_at_ms");
16890
+ positiveInteger3(options.everyMs, "every_ms");
16891
+ positiveInteger3(options.overlapRetryMs, "overlap_retry_ms");
16892
+ positiveInteger3(options.maxFires, "max_fires");
16893
+ nonNegativeInteger3(options.endAtMs, "end_at_ms");
16894
+ nonNegativeInteger3(options.nowMs, "now_ms");
16062
16895
  optionalBoolean(options.overwrite, "overwrite");
16063
16896
  if (kind === "delay") {
16064
16897
  if (options.delayMs == null) throw new TypeError("delay_ms is required for delay schedules");
@@ -16115,20 +16948,20 @@ function validateScheduleID(id) {
16115
16948
  }
16116
16949
  function validateScheduleFire(id, options) {
16117
16950
  validateScheduleID(id);
16118
- nonNegativeInteger2(options.fireAtMs, "fire_at_ms");
16119
- nonNegativeInteger2(options.nowMs, "now_ms");
16951
+ nonNegativeInteger3(options.fireAtMs, "fire_at_ms");
16952
+ nonNegativeInteger3(options.nowMs, "now_ms");
16120
16953
  }
16121
16954
  function validateScheduleStatus(id, nowMs2) {
16122
16955
  validateScheduleID(id);
16123
- nonNegativeInteger2(nowMs2, "now_ms");
16956
+ nonNegativeInteger3(nowMs2, "now_ms");
16124
16957
  }
16125
16958
  function validateScheduleFireDue(options) {
16126
16959
  if (!mapping(options)) throw new TypeError("schedule fire-due options must be a mapping");
16127
- nonNegativeInteger2(options.nowMs, "now_ms");
16960
+ nonNegativeInteger3(options.nowMs, "now_ms");
16128
16961
  optionalText3(options.worker, "worker");
16129
- positiveInteger2(options.leaseMs, "lease_ms");
16130
- nonNegativeInteger2(options.blockMs, "block_ms");
16131
- positiveInteger2(options.limit, "limit");
16962
+ positiveInteger3(options.leaseMs, "lease_ms");
16963
+ nonNegativeInteger3(options.blockMs, "block_ms");
16964
+ positiveInteger3(options.limit, "limit");
16132
16965
  const leaseMs = options.leaseMs ?? 3e4;
16133
16966
  if (options.nowMs != null && options.nowMs > MAX_EXACT_INTEGER - leaseMs) {
16134
16967
  throw new TypeError("now_ms plus lease_ms exceeds the exact integer range");
@@ -16144,12 +16977,12 @@ function validateScheduleList(options) {
16144
16977
  }
16145
16978
  optionalText3(options.timezone, "timezone");
16146
16979
  optionalText3(options.targetType, "target_type");
16147
- nonNegativeInteger2(options.fromMs, "from_ms");
16148
- nonNegativeInteger2(options.toMs, "to_ms");
16980
+ nonNegativeInteger3(options.fromMs, "from_ms");
16981
+ nonNegativeInteger3(options.toMs, "to_ms");
16149
16982
  if (options.fromMs != null && options.toMs != null && options.fromMs > options.toMs) {
16150
16983
  throw new TypeError("from_ms must not exceed to_ms");
16151
16984
  }
16152
- positiveInteger2(options.count, "count");
16985
+ positiveInteger3(options.count, "count");
16153
16986
  optionalBoolean(options.rev, "rev");
16154
16987
  }
16155
16988
  function effectiveKind(options) {
@@ -16207,7 +17040,7 @@ function validateTarget(value, recurring) {
16207
17040
  if (typeof idPrefix === "string" && idPrefix.startsWith(INTERNAL_SCHEDULE_ID_PREFIX)) {
16208
17041
  throw new TypeError("target id_prefix is reserved for internal use");
16209
17042
  }
16210
- nonNegativeInteger2(own(target, "run_at_ms"), "target run_at_ms");
17043
+ nonNegativeInteger3(own(target, "run_at_ms"), "target run_at_ms");
16211
17044
  const priority = own(target, "priority");
16212
17045
  if (priority != null && (typeof priority !== "number" || !Number.isSafeInteger(priority) || priority < 0 || priority > 2)) {
16213
17046
  throw new TypeError("target priority must be an integer between 0 and 2");
@@ -16229,12 +17062,12 @@ function requiredText3(value, name) {
16229
17062
  function optionalText3(value, name) {
16230
17063
  if (value != null) requiredText3(value, name);
16231
17064
  }
16232
- function nonNegativeInteger2(value, name) {
17065
+ function nonNegativeInteger3(value, name) {
16233
17066
  if (value != null && (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0)) {
16234
17067
  throw new TypeError(`${name} must be a non-negative exact integer`);
16235
17068
  }
16236
17069
  }
16237
- function positiveInteger2(value, name) {
17070
+ function positiveInteger3(value, name) {
16238
17071
  if (value != null && (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0)) {
16239
17072
  throw new TypeError(`${name} must be a positive exact integer`);
16240
17073
  }
@@ -16940,7 +17773,7 @@ function throwIfClosed(signal) {
16940
17773
  }
16941
17774
 
16942
17775
  // src/flow-policy.ts
16943
- var import_node_buffer54 = require("buffer");
17776
+ var import_node_buffer58 = require("buffer");
16944
17777
  var MAX_FLOW_POLICY_GENERATION = Number.MAX_SAFE_INTEGER;
16945
17778
  function assertFlowPolicyGeneration(value) {
16946
17779
  if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
@@ -16958,7 +17791,7 @@ function flowPolicySnapshotFromResp(value) {
16958
17791
  const states = optionalStates(field(policy, "states"));
16959
17792
  return {
16960
17793
  type: requiredText4(field(policy, "type"), "type"),
16961
- generation: nonNegativeInteger3(field(policy, "generation"), "generation"),
17794
+ generation: nonNegativeInteger4(field(policy, "generation"), "generation"),
16962
17795
  ...state == null ? {} : { state },
16963
17796
  ...version == null ? {} : { version },
16964
17797
  ...mode == null ? {} : { mode },
@@ -16976,12 +17809,12 @@ function retrySnapshot(value, context) {
16976
17809
  const retry2 = requiredRecord(value, `FLOW policy ${context}`);
16977
17810
  const backoff = requiredRecord(field(retry2, "backoff"), `FLOW policy ${context}.backoff`);
16978
17811
  return {
16979
- maxRetries: nonNegativeInteger3(field(retry2, "max_retries"), `${context}.max_retries`),
17812
+ maxRetries: nonNegativeInteger4(field(retry2, "max_retries"), `${context}.max_retries`),
16980
17813
  backoff: {
16981
17814
  kind: backoffKind(field(backoff, "kind"), `${context}.backoff.kind`),
16982
- baseMs: nonNegativeInteger3(field(backoff, "base_ms"), `${context}.backoff.base_ms`),
16983
- maxMs: nonNegativeInteger3(field(backoff, "max_ms"), `${context}.backoff.max_ms`),
16984
- jitterPct: nonNegativeInteger3(field(backoff, "jitter_pct"), `${context}.backoff.jitter_pct`)
17815
+ baseMs: nonNegativeInteger4(field(backoff, "base_ms"), `${context}.backoff.base_ms`),
17816
+ maxMs: nonNegativeInteger4(field(backoff, "max_ms"), `${context}.backoff.max_ms`),
17817
+ jitterPct: nonNegativeInteger4(field(backoff, "jitter_pct"), `${context}.backoff.jitter_pct`)
16985
17818
  },
16986
17819
  exhaustedTo: requiredText4(field(retry2, "exhausted_to"), `${context}.exhausted_to`)
16987
17820
  };
@@ -16989,8 +17822,8 @@ function retrySnapshot(value, context) {
16989
17822
  function retentionSnapshot(value, context) {
16990
17823
  const retention = requiredRecord(value, `FLOW policy ${context}`);
16991
17824
  return {
16992
- ttlMs: nonNegativeInteger3(field(retention, "ttl_ms"), `${context}.ttl_ms`),
16993
- historyMaxEvents: nonNegativeInteger3(
17825
+ ttlMs: nonNegativeInteger4(field(retention, "ttl_ms"), `${context}.ttl_ms`),
17826
+ historyMaxEvents: nonNegativeInteger4(
16994
17827
  field(retention, "history_max_events"),
16995
17828
  `${context}.history_max_events`
16996
17829
  )
@@ -17030,7 +17863,7 @@ function requiredRecord(value, context) {
17030
17863
  }
17031
17864
  return result;
17032
17865
  }
17033
- if (typeof value === "object" && value != null && !Array.isArray(value) && !import_node_buffer54.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;
17034
17867
  throw new TypeError(`${context} returned an unexpected response`);
17035
17868
  }
17036
17869
  function optionalRecord(value, context) {
@@ -17051,15 +17884,15 @@ function stringArray(value, context) {
17051
17884
  }
17052
17885
  function requiredText4(value, context) {
17053
17886
  if (typeof value === "string") return value;
17054
- if (import_node_buffer54.Buffer.isBuffer(value) || value instanceof Uint8Array) {
17055
- return import_node_buffer54.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");
17056
17889
  }
17057
17890
  throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
17058
17891
  }
17059
17892
  function optionalText4(value, context) {
17060
17893
  return value == null ? void 0 : requiredText4(value, context);
17061
17894
  }
17062
- function nonNegativeInteger3(value, context) {
17895
+ function nonNegativeInteger4(value, context) {
17063
17896
  let parsed;
17064
17897
  try {
17065
17898
  parsed = integer(value);
@@ -17071,14 +17904,14 @@ function nonNegativeInteger3(value, context) {
17071
17904
  }
17072
17905
  function optionalPositiveInteger(value, context) {
17073
17906
  if (value == null) return void 0;
17074
- const parsed = nonNegativeInteger3(value, context);
17907
+ const parsed = nonNegativeInteger4(value, context);
17075
17908
  if (parsed === 0) throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
17076
17909
  return parsed;
17077
17910
  }
17078
17911
  function optionalVersion(value) {
17079
17912
  if (value == null) return void 0;
17080
17913
  if (typeof value === "number" || typeof value === "bigint") {
17081
- return nonNegativeInteger3(value, "version");
17914
+ return nonNegativeInteger4(value, "version");
17082
17915
  }
17083
17916
  return requiredText4(value, "version");
17084
17917
  }
@@ -17308,7 +18141,7 @@ var FerricStoreFlowSupportClient = class extends FerricStoreFlowQueryClient {
17308
18141
  };
17309
18142
 
17310
18143
  // src/flow-many-snapshot.ts
17311
- var import_node_buffer56 = require("buffer");
18144
+ var import_node_buffer60 = require("buffer");
17312
18145
  var encodedOptionFields = ["error", "payload", "reason", "result"];
17313
18146
  function snapshotCreateItem(item, codec) {
17314
18147
  const snapshot = {
@@ -17348,7 +18181,7 @@ function snapshotFlowManyOptions(options, codec) {
17348
18181
  }
17349
18182
  function snapshotClaimedItem(item) {
17350
18183
  const wire = item[CLAIMED_ITEM_WIRE];
17351
- const leaseToken = import_node_buffer56.Buffer.from(wire?.leaseToken ?? item.leaseToken);
18184
+ const leaseToken = import_node_buffer60.Buffer.from(wire?.leaseToken ?? item.leaseToken);
17352
18185
  const snapshot = {
17353
18186
  ...item,
17354
18187
  fencingToken: wire?.fencingToken ?? item.fencingToken,
@@ -17365,15 +18198,15 @@ function snapshotClaimedItem(item) {
17365
18198
  function snapshotFencedItem(item) {
17366
18199
  return Object.freeze({
17367
18200
  ...item,
17368
- ...item.leaseToken == null ? {} : { leaseToken: import_node_buffer56.Buffer.from(item.leaseToken) }
18201
+ ...item.leaseToken == null ? {} : { leaseToken: import_node_buffer60.Buffer.from(item.leaseToken) }
17369
18202
  });
17370
18203
  }
17371
18204
  function snapshotClaimedItemWire(wire, leaseToken) {
17372
18205
  return Object.freeze({
17373
18206
  fencingToken: wire.fencingToken,
17374
- id: import_node_buffer56.Buffer.from(wire.id),
18207
+ id: import_node_buffer60.Buffer.from(wire.id),
17375
18208
  leaseToken,
17376
- partitionKey: wire.partitionKey == null ? wire.partitionKey : import_node_buffer56.Buffer.from(wire.partitionKey)
18209
+ partitionKey: wire.partitionKey == null ? wire.partitionKey : import_node_buffer60.Buffer.from(wire.partitionKey)
17377
18210
  });
17378
18211
  }
17379
18212
  function snapshotArray(values) {
@@ -17384,7 +18217,7 @@ function snapshotArray(values) {
17384
18217
  return Object.freeze(snapshot);
17385
18218
  }
17386
18219
  function snapshotStateMeta(stateMeta) {
17387
- return snapshotRecord(stateMeta, (value) => import_node_buffer56.Buffer.isBuffer(value) ? import_node_buffer56.Buffer.from(value) : value);
18220
+ return snapshotRecord(stateMeta, (value) => import_node_buffer60.Buffer.isBuffer(value) ? import_node_buffer60.Buffer.from(value) : value);
17388
18221
  }
17389
18222
  function snapshotCommandRecord(values) {
17390
18223
  const seen = /* @__PURE__ */ new WeakMap();
@@ -17402,7 +18235,7 @@ function snapshotRecord(values, capture) {
17402
18235
  }
17403
18236
  function snapshotCommandArgument(value, seen) {
17404
18237
  if (typeof value !== "object" || value == null) return value;
17405
- if (import_node_buffer56.Buffer.isBuffer(value) || value instanceof Uint8Array) return import_node_buffer56.Buffer.from(value);
18238
+ if (import_node_buffer60.Buffer.isBuffer(value) || value instanceof Uint8Array) return import_node_buffer60.Buffer.from(value);
17406
18239
  const objectValue = value;
17407
18240
  const existing = seen.get(objectValue);
17408
18241
  if (existing != null) return existing;
@@ -18167,6 +19000,14 @@ var FerricStoreProducerClient = class extends FerricStoreClaimClient {
18167
19000
  var FerricStoreClient = class _FerricStoreClient extends FerricStoreProducerClient {
18168
19001
  static async fromUrl(url, options = {}) {
18169
19002
  const clientOptions = snapshotClientOptions(options);
19003
+ const scheme = new URL(url).protocol;
19004
+ if (scheme === "http:" || scheme === "https:") {
19005
+ if (clientOptions.nativeOptions != null) {
19006
+ throw new TypeError("nativeOptions are not valid for an HTTP FerricStore URL");
19007
+ }
19008
+ const executor2 = await HTTPAdapter.fromUrl(url, clientOptions.httpOptions);
19009
+ return new _FerricStoreClient(executor2, clientOptions);
19010
+ }
18170
19011
  const nativeOptions = snapshotNativeClientOptions(clientOptions.nativeOptions ?? {});
18171
19012
  const reconnectOptions = clientOptions.reconnect ?? nativeOptions.autoReconnect ?? true;
18172
19013
  const seeds = nativeOptions.seeds ?? [];
@@ -18390,7 +19231,7 @@ function nativeOptionsForBootstrap(options, signal) {
18390
19231
  }
18391
19232
 
18392
19233
  // src/flow-query-projection.ts
18393
- var import_node_buffer57 = require("buffer");
19234
+ var import_node_buffer61 = require("buffer");
18394
19235
  var MAX_PROJECTION_FIELDS = 32;
18395
19236
  var MAX_DYNAMIC_NAME_BYTES = 64;
18396
19237
  var FIELD_BRAND = /* @__PURE__ */ Symbol("FerricStoreFlowProjectionField");
@@ -18460,7 +19301,7 @@ function projectFlowQuery(query, shape, ...fields) {
18460
19301
  }
18461
19302
  const base = stripOptionalTerminator(query);
18462
19303
  const result = `${base} RETURN ${shape.toUpperCase()} (${selectors.join(", ")})`;
18463
- if (import_node_buffer57.Buffer.byteLength(result, "utf8") > FLOW_QUERY_MAX_BYTES) {
19304
+ if (import_node_buffer61.Buffer.byteLength(result, "utf8") > FLOW_QUERY_MAX_BYTES) {
18464
19305
  throw new TypeError(`FLOW.QUERY query exceeds ${FLOW_QUERY_MAX_BYTES} bytes`);
18465
19306
  }
18466
19307
  return result;
@@ -18520,7 +19361,7 @@ function quoteName(value, allowPrivate) {
18520
19361
  throw new TypeError("Flow query projection metadata name must be text");
18521
19362
  }
18522
19363
  validateUnicodeScalarText2(value);
18523
- const size = import_node_buffer57.Buffer.byteLength(value, "utf8");
19364
+ const size = import_node_buffer61.Buffer.byteLength(value, "utf8");
18524
19365
  if (size === 0 || size > MAX_DYNAMIC_NAME_BYTES || !allowPrivate && value.startsWith("__")) {
18525
19366
  throw new TypeError(
18526
19367
  `Flow query projection metadata names must be 1..${MAX_DYNAMIC_NAME_BYTES} UTF-8 bytes`
@@ -18622,7 +19463,7 @@ var LeaseRenewalGuard = class {
18622
19463
  if (options.leaseRenewal === false) {
18623
19464
  return;
18624
19465
  }
18625
- const intervalMs = positiveInteger3(options.leaseRenewIntervalMs, Math.max(1, Math.trunc(leaseMs / 2)));
19466
+ const intervalMs = positiveInteger4(options.leaseRenewIntervalMs, Math.max(1, Math.trunc(leaseMs / 2)));
18626
19467
  this.timer = setLongInterval(() => this.renew(), intervalMs);
18627
19468
  this.timer.unref();
18628
19469
  }
@@ -18694,7 +19535,7 @@ function snapshotLeasedJob(job) {
18694
19535
  return snapshot;
18695
19536
  }
18696
19537
  function workerConcurrency(options) {
18697
- return positiveInteger3(options.concurrency ?? options.workers, 1);
19538
+ return positiveInteger4(options.concurrency ?? options.workers, 1);
18698
19539
  }
18699
19540
  function workerRefillStrategy(options) {
18700
19541
  return options.refillStrategy === "wave" ? "wave" : "continuous";
@@ -18737,18 +19578,18 @@ function workerErrorPayload(error, options, codec) {
18737
19578
  }
18738
19579
  function workerBatchSize(options, flowManyBatchLimit = DEFAULT_FLOW_MANY_BATCH_LIMIT2) {
18739
19580
  return Math.min(
18740
- positiveInteger3(options.batchSize, 10),
18741
- positiveInteger3(flowManyBatchLimit, DEFAULT_FLOW_MANY_BATCH_LIMIT2)
19581
+ positiveInteger4(options.batchSize, 10),
19582
+ positiveInteger4(flowManyBatchLimit, DEFAULT_FLOW_MANY_BATCH_LIMIT2)
18742
19583
  );
18743
19584
  }
18744
19585
  function workerClaimLimit(options, flowManyBatchLimit = DEFAULT_FLOW_MANY_BATCH_LIMIT2) {
18745
19586
  return Math.min(workerBatchSize(options, flowManyBatchLimit), workerConcurrency(options));
18746
19587
  }
18747
19588
  function workerDrainBatches(options) {
18748
- return positiveInteger3(options.claimDrainBatches, 1);
19589
+ return positiveInteger4(options.claimDrainBatches, 1);
18749
19590
  }
18750
19591
  function workerLeaseMs(options, fallback = 3e4) {
18751
- return positiveInteger3(options.leaseMs, positiveInteger3(fallback, 3e4));
19592
+ return positiveInteger4(options.leaseMs, positiveInteger4(fallback, 3e4));
18752
19593
  }
18753
19594
  function workerIdleSleepMs(options) {
18754
19595
  return nonNegativeDuration(options.idleSleepMs, 250);
@@ -18760,7 +19601,7 @@ function workerClaimBlockMs(options, useBlocking) {
18760
19601
  if (options.signal == null || !Number.isFinite(options.blockMs) || options.blockMs < 0) {
18761
19602
  return options.blockMs;
18762
19603
  }
18763
- const abortPollMs = positiveInteger3(options.abortPollMs, 1e3);
19604
+ const abortPollMs = positiveInteger4(options.abortPollMs, 1e3);
18764
19605
  return options.blockMs === 0 ? abortPollMs : Math.min(Math.trunc(options.blockMs), abortPollMs);
18765
19606
  }
18766
19607
  function workerMaxIdleSleepMs(options, idleSleepMs = workerIdleSleepMs(options)) {
@@ -18771,14 +19612,14 @@ function nextWorkerIdleSleepMs(currentIdleSleepMs, maxIdleSleepMs) {
18771
19612
  return Math.min(maxIdleSleepMs, Math.max(1, currentIdleSleepMs * 2));
18772
19613
  }
18773
19614
  async function runContinuousWorkerPool(options) {
18774
- const concurrency = positiveInteger3(options.concurrency, 1);
18775
- const maxClaimSize = positiveInteger3(options.maxClaimSize, concurrency);
19615
+ const concurrency = positiveInteger4(options.concurrency, 1);
19616
+ const maxClaimSize = positiveInteger4(options.maxClaimSize, concurrency);
18776
19617
  const initialIdleSleepMs = nonNegativeDuration(options.idleSleepMs, 250);
18777
19618
  const maxIdleSleepMs = Math.max(
18778
19619
  initialIdleSleepMs,
18779
19620
  nonNegativeDuration(options.maxIdleSleepMs, 5e3)
18780
19621
  );
18781
- const refillDelayMs = nonNegativeInteger4(options.refillDelayMs, 0);
19622
+ const refillDelayMs = nonNegativeInteger5(options.refillDelayMs, 0);
18782
19623
  const active = /* @__PURE__ */ new Set();
18783
19624
  const pending = [];
18784
19625
  let pendingIndex = 0;
@@ -18894,10 +19735,10 @@ function normalizeWorkflowWorkerConfig(options) {
18894
19735
  ...captured
18895
19736
  });
18896
19737
  }
18897
- function positiveInteger3(value, fallback) {
19738
+ function positiveInteger4(value, fallback) {
18898
19739
  return value == null || !Number.isFinite(value) ? fallback : Math.max(1, Math.trunc(value));
18899
19740
  }
18900
- function nonNegativeInteger4(value, fallback) {
19741
+ function nonNegativeInteger5(value, fallback) {
18901
19742
  return value == null || !Number.isFinite(value) ? fallback : Math.max(0, Math.trunc(value));
18902
19743
  }
18903
19744
  function nonNegativeDuration(value, fallback) {
@@ -20526,7 +21367,7 @@ var WorkflowWorker = class {
20526
21367
  };
20527
21368
 
20528
21369
  // src/version.ts
20529
- var FERRICSTORE_SDK_VERSION = "0.11.8";
21370
+ var FERRICSTORE_SDK_VERSION = "0.11.10";
20530
21371
  var FERRICSTORE_MINIMUM_SERVER_VERSION = "0.11.4";
20531
21372
  var FERRICSTORE_NATIVE_PROTOCOL_VERSION = 1;
20532
21373
  // Annotate the CommonJS export names for ESM import in node:
@@ -20550,6 +21391,8 @@ var FERRICSTORE_NATIVE_PROTOCOL_VERSION = 1;
20550
21391
  FlowQueryError,
20551
21392
  FlowWrongStateError,
20552
21393
  GeoStore,
21394
+ HTTPAdapter,
21395
+ HTTPTransportError,
20553
21396
  HashStore,
20554
21397
  HyperLogLogStore,
20555
21398
  InvalidCommandError,
@@ -20587,6 +21430,7 @@ var FERRICSTORE_NATIVE_PROTOCOL_VERSION = 1;
20587
21430
  classifyServerError,
20588
21431
  complete,
20589
21432
  fail,
21433
+ httpCommandDisposition,
20590
21434
  isOutcome,
20591
21435
  isReconnectableClosedConnectionError,
20592
21436
  mapException,