@ferricstore/ferricstore 0.5.2 → 0.11.5

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 (111) hide show
  1. package/README.md +45 -5
  2. package/dist/index.cjs +996 -314
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +90 -26
  5. package/dist/index.d.ts +90 -26
  6. package/dist/index.js +996 -314
  7. package/dist/index.js.map +1 -1
  8. package/docs/api/assets/hierarchy.js +1 -1
  9. package/docs/api/assets/navigation.js +1 -1
  10. package/docs/api/assets/search.js +1 -1
  11. package/docs/api/classes/ConnectionClosedError.html +1 -1
  12. package/docs/api/classes/FerricStoreClient.html +3 -3
  13. package/docs/api/classes/FerricStoreError.html +1 -1
  14. package/docs/api/classes/FlowAlreadyExistsError.html +1 -1
  15. package/docs/api/classes/FlowBatchError.html +1 -1
  16. package/docs/api/classes/FlowNotFoundError.html +1 -1
  17. package/docs/api/classes/FlowQueryError.html +1 -1
  18. package/docs/api/classes/FlowWrongStateError.html +1 -1
  19. package/docs/api/classes/InvalidCommandError.html +1 -1
  20. package/docs/api/classes/LeaseRenewalError.html +1 -1
  21. package/docs/api/classes/LockHeldError.html +1 -1
  22. package/docs/api/classes/LockNotOwnedError.html +1 -1
  23. package/docs/api/classes/OverloadedError.html +1 -1
  24. package/docs/api/classes/QueueCompletionError.html +1 -1
  25. package/docs/api/classes/RequestTimeoutError.html +1 -1
  26. package/docs/api/classes/RerouteError.html +1 -1
  27. package/docs/api/classes/StaleLeaseError.html +1 -1
  28. package/docs/api/classes/StalePolicyGenerationError.html +1 -1
  29. package/docs/api/hierarchy.html +1 -1
  30. package/docs/api/index.html +35 -5
  31. package/docs/api/interfaces/AdminListOptions.html +2 -2
  32. package/docs/api/interfaces/ApprovalListOptions.html +2 -2
  33. package/docs/api/interfaces/ApprovalRequestOptions.html +2 -2
  34. package/docs/api/interfaces/AttributeQueryOptions.html +2 -2
  35. package/docs/api/interfaces/AutoBatchOptions.html +2 -2
  36. package/docs/api/interfaces/BudgetCommitOptions.html +2 -2
  37. package/docs/api/interfaces/BudgetReserveOptions.html +2 -2
  38. package/docs/api/interfaces/CancelOptions.html +2 -2
  39. package/docs/api/interfaces/CircuitOpenOptions.html +2 -2
  40. package/docs/api/interfaces/ClaimDueOptions.html +3 -3
  41. package/docs/api/interfaces/ClaimHydrationItem.html +2 -2
  42. package/docs/api/interfaces/CompleteJobsAndClaimJobsResult.html +6 -6
  43. package/docs/api/interfaces/CompleteManyOptions.html +2 -2
  44. package/docs/api/interfaces/CompleteOptions.html +2 -2
  45. package/docs/api/interfaces/CompleteOutcome.html +1 -1
  46. package/docs/api/interfaces/CreateManyOptions.html +5 -5
  47. package/docs/api/interfaces/CreateOptions.html +3 -3
  48. package/docs/api/interfaces/EffectCompensateOptions.html +2 -2
  49. package/docs/api/interfaces/EffectConfirmOptions.html +2 -2
  50. package/docs/api/interfaces/EffectFailOptions.html +2 -2
  51. package/docs/api/interfaces/EffectReserveOptions.html +2 -2
  52. package/docs/api/interfaces/EffectStatusOptions.html +2 -2
  53. package/docs/api/interfaces/ExtendLeaseOptions.html +2 -2
  54. package/docs/api/interfaces/FailOptions.html +2 -2
  55. package/docs/api/interfaces/FailOutcome.html +1 -1
  56. package/docs/api/interfaces/FerricStoreClientFromUrlOptions.html +4 -4
  57. package/docs/api/interfaces/FerricStoreClientOptions.html +4 -4
  58. package/docs/api/interfaces/FlowBatchCompletedItem.html +2 -2
  59. package/docs/api/interfaces/FlowPolicyOptions.html +5 -5
  60. package/docs/api/interfaces/FlowQueryCountResult.html +1 -1
  61. package/docs/api/interfaces/FlowQueryIndexBuild.html +1 -1
  62. package/docs/api/interfaces/FlowQueryIndexProgress.html +1 -1
  63. package/docs/api/interfaces/FlowQueryIndexValidation.html +1 -1
  64. package/docs/api/interfaces/FlowQueryRecordsResult.html +1 -1
  65. package/docs/api/interfaces/FlowStatePolicy.html +2 -2
  66. package/docs/api/interfaces/FlowStatsOptions.html +2 -2
  67. package/docs/api/interfaces/GovernanceLedgerOptions.html +2 -2
  68. package/docs/api/interfaces/HistoryOptions.html +2 -2
  69. package/docs/api/interfaces/InvocationCreateOptions.html +2 -2
  70. package/docs/api/interfaces/LeaseMutationOptions.html +2 -2
  71. package/docs/api/interfaces/LimitAmountOptions.html +2 -2
  72. package/docs/api/interfaces/LimitLeaseOptions.html +2 -2
  73. package/docs/api/interfaces/LimitListOptions.html +2 -2
  74. package/docs/api/interfaces/LimitReleaseOptions.html +2 -2
  75. package/docs/api/interfaces/MutateOptions.html +2 -2
  76. package/docs/api/interfaces/NamedValueMutation.html +1 -1
  77. package/docs/api/interfaces/ReadOptions.html +3 -3
  78. package/docs/api/interfaces/ReclaimOptions.html +2 -2
  79. package/docs/api/interfaces/RequestContext.html +2 -2
  80. package/docs/api/interfaces/RequestContextOptions.html +2 -2
  81. package/docs/api/interfaces/RetryOptions.html +2 -2
  82. package/docs/api/interfaces/RetryOutcome.html +1 -1
  83. package/docs/api/interfaces/RunStepsItem.html +2 -2
  84. package/docs/api/interfaces/RunStepsManyOptions.html +2 -2
  85. package/docs/api/interfaces/ScheduleFireDueOptions.html +3 -2
  86. package/docs/api/interfaces/ScheduleFireOptions.html +3 -0
  87. package/docs/api/interfaces/ScheduleListOptions.html +2 -2
  88. package/docs/api/interfaces/ScheduleOptions.html +4 -2
  89. package/docs/api/interfaces/SearchOptions.html +3 -3
  90. package/docs/api/interfaces/StartAndClaimOptions.html +3 -3
  91. package/docs/api/interfaces/StepContinueOptions.html +3 -3
  92. package/docs/api/interfaces/TDigestCreateOptions.html +1 -1
  93. package/docs/api/interfaces/TDigestMergeOptions.html +1 -1
  94. package/docs/api/interfaces/TransitionOptions.html +2 -2
  95. package/docs/api/interfaces/TransitionOutcome.html +1 -1
  96. package/docs/api/modules.html +1 -1
  97. package/docs/api/types/ConnectionRequestDisposition.html +1 -1
  98. package/docs/api/types/FlowStateMode.html +1 -1
  99. package/docs/api/types/FlowStatePolicyLike.html +1 -1
  100. package/docs/api/types/ManagementPairs.html +1 -1
  101. package/docs/api/types/ScheduleCatchupPolicy.html +2 -0
  102. package/docs/api/types/ScheduleFireDueResult.html +3 -0
  103. package/docs/api/types/ScheduleFireResult.html +2 -0
  104. package/docs/api/types/ScheduleKind.html +1 -0
  105. package/docs/api/types/ScheduleOverlapPolicy.html +1 -0
  106. package/docs/api/types/ScheduleRecord.html +12 -0
  107. package/docs/api/types/ScheduleState.html +1 -0
  108. package/docs/api/types/SearchStateMeta.html +1 -1
  109. package/docs/api/variables/FERRICSTORE_MINIMUM_SERVER_VERSION.html +1 -1
  110. package/docs/api/variables/FERRICSTORE_SDK_VERSION.html +1 -1
  111. package/package.json +2 -2
package/dist/index.cjs CHANGED
@@ -3187,6 +3187,7 @@ var FLOW_ADMIN_FIELDS = {
3187
3187
  AT_MS: "at_ms",
3188
3188
  BLOCK: "block_ms",
3189
3189
  BLOCK_MS: "block_ms",
3190
+ CATCHUP_POLICY: "catchup_policy",
3190
3191
  CONSISTENT_PROJECTION: "consistent_projection",
3191
3192
  CORRELATION_ID: "correlation_id",
3192
3193
  COUNT: "count",
@@ -4631,7 +4632,7 @@ function compactKeyPipelinePayload(opcode, args, mode, maxBodyBytes) {
4631
4632
  }
4632
4633
  return { flags: FLAG_CUSTOM_PAYLOAD, opcode, payload: out };
4633
4634
  }
4634
- function compactPipelinePayload(commands, maxBodyBytes) {
4635
+ function compactPipelinePayload(commands, maxBodyBytes, allowStreamXAdd = true, allowPubSubPublish = true) {
4635
4636
  if (commands.length === 0) {
4636
4637
  assertCompactPayloadFits(6, maxBodyBytes);
4637
4638
  const out = import_node_buffer14.Buffer.allocUnsafe(6);
@@ -4643,8 +4644,115 @@ function compactPipelinePayload(commands, maxBodyBytes) {
4643
4644
  }
4644
4645
  if (commandNameIs(commands[0]?.[0], "SET")) return compactSetPipelinePayload(commands, maxBodyBytes);
4645
4646
  if (commandNameIs(commands[0]?.[0], "GET")) return compactGetPipelinePayload(commands, maxBodyBytes);
4647
+ if (commandNameIs(commands[0]?.[0], "XADD")) {
4648
+ return allowStreamXAdd ? compactStreamXAddPipelinePayload(commands, maxBodyBytes) : void 0;
4649
+ }
4650
+ if (commandNameIs(commands[0]?.[0], "PUBLISH")) {
4651
+ return allowPubSubPublish ? compactPubSubPublishPipelinePayload(commands, maxBodyBytes) : void 0;
4652
+ }
4646
4653
  return void 0;
4647
4654
  }
4655
+ function compactPubSubPublishPipelinePayload(commands, maxBodyBytes) {
4656
+ const minimum = 6 + commands.length * 8;
4657
+ if (!compactPayloadFits(minimum, maxBodyBytes)) {
4658
+ if (!compactPipelineEligible(commands, "PUBLISH", 3)) return void 0;
4659
+ assertCompactPayloadFits(minimum, maxBodyBytes);
4660
+ }
4661
+ const argumentByteLengths = new Uint32Array(commands.length * 2);
4662
+ const argumentValues = new Array(commands.length * 2);
4663
+ let total = 6;
4664
+ for (let index = 0; index < commands.length; index += 1) {
4665
+ const command = commands[index];
4666
+ if (!Object.hasOwn(commands, index) || !Array.isArray(command)) {
4667
+ throw new TypeError("pipeline commands must be a dense array of command arrays");
4668
+ }
4669
+ if (command.length !== 3 || !Object.hasOwn(command, 0) || !Object.hasOwn(command, 1) || !Object.hasOwn(command, 2)) {
4670
+ if (command.length === 3) throw new TypeError("pipeline command arguments must be dense");
4671
+ return void 0;
4672
+ }
4673
+ if (!commandNameIs(command[0], "PUBLISH")) return void 0;
4674
+ const channel = command[1];
4675
+ const message = command[2];
4676
+ if (!isCompactBinaryScalar(channel) || !isCompactBinaryScalar(message)) return void 0;
4677
+ const channelByteLength = compactBinaryByteLength(channel);
4678
+ const messageByteLength = compactBinaryByteLength(message);
4679
+ argumentValues[index * 2] = channel;
4680
+ argumentValues[index * 2 + 1] = message;
4681
+ argumentByteLengths[index * 2] = channelByteLength;
4682
+ argumentByteLengths[index * 2 + 1] = messageByteLength;
4683
+ total += 8 + channelByteLength + messageByteLength;
4684
+ }
4685
+ assertCompactPayloadFits(total, maxBodyBytes);
4686
+ const out = import_node_buffer14.Buffer.allocUnsafe(total);
4687
+ let offset = writeCompactPipelineHeader(out, 128 | 35, commands.length);
4688
+ for (let index = 0; index < commands.length; index += 1) {
4689
+ offset = writeBinaryValue(
4690
+ out,
4691
+ offset,
4692
+ argumentValues[index * 2],
4693
+ argumentByteLengths[index * 2] ?? 0
4694
+ );
4695
+ offset = writeBinaryValue(
4696
+ out,
4697
+ offset,
4698
+ argumentValues[index * 2 + 1],
4699
+ argumentByteLengths[index * 2 + 1] ?? 0
4700
+ );
4701
+ }
4702
+ return out;
4703
+ }
4704
+ function compactStreamXAddPipelinePayload(commands, maxBodyBytes) {
4705
+ let argumentCount = 0;
4706
+ let minimum = 6;
4707
+ for (const command of commands) {
4708
+ if (!Array.isArray(command)) {
4709
+ throw new TypeError("pipeline commands must be a dense array of command arrays");
4710
+ }
4711
+ if (command.length < 5 || (command.length - 3) % 2 !== 0) return void 0;
4712
+ for (let argumentIndex = 0; argumentIndex < command.length; argumentIndex += 1) {
4713
+ if (!Object.hasOwn(command, argumentIndex)) {
4714
+ throw new TypeError("pipeline command arguments must be dense");
4715
+ }
4716
+ }
4717
+ if (!commandTokenIs(command[0], "XADD") || !commandTokenIs(command[2], "*")) return void 0;
4718
+ if ((command.length - 3) / 2 > 65535) return void 0;
4719
+ for (let argumentIndex = 1; argumentIndex < command.length; argumentIndex += 1) {
4720
+ if (argumentIndex !== 2 && !isCompactBinaryScalar(command[argumentIndex])) return void 0;
4721
+ }
4722
+ argumentCount += command.length - 2;
4723
+ minimum += 2 + (command.length - 2) * 4;
4724
+ }
4725
+ assertCompactPayloadFits(minimum, maxBodyBytes);
4726
+ const byteLengths = new Uint32Array(argumentCount);
4727
+ let lengthIndex = 0;
4728
+ let total = 6;
4729
+ for (const command of commands) {
4730
+ total += 2;
4731
+ for (let argumentIndex = 1; argumentIndex < command.length; argumentIndex += 1) {
4732
+ if (argumentIndex === 2) continue;
4733
+ const value = command[argumentIndex];
4734
+ const byteLength = compactBinaryByteLength(value);
4735
+ byteLengths[lengthIndex] = byteLength;
4736
+ lengthIndex += 1;
4737
+ total += 4 + byteLength;
4738
+ }
4739
+ }
4740
+ assertCompactPayloadFits(total, maxBodyBytes);
4741
+ const out = import_node_buffer14.Buffer.allocUnsafe(total);
4742
+ let offset = writeCompactPipelineHeader(out, 128 | 34, commands.length);
4743
+ lengthIndex = 0;
4744
+ for (const command of commands) {
4745
+ offset = writeBinaryValue(out, offset, command[1], byteLengths[lengthIndex] ?? 0);
4746
+ lengthIndex += 1;
4747
+ out.writeUInt16BE((command.length - 3) / 2, offset);
4748
+ offset += 2;
4749
+ for (let argumentIndex = 3; argumentIndex < command.length; argumentIndex += 1) {
4750
+ offset = writeBinaryValue(out, offset, command[argumentIndex], byteLengths[lengthIndex] ?? 0);
4751
+ lengthIndex += 1;
4752
+ }
4753
+ }
4754
+ return out;
4755
+ }
4648
4756
  function compactSetPipelinePayload(commands, maxBodyBytes) {
4649
4757
  let total = 6;
4650
4758
  const minimum = total + commands.length * 8;
@@ -5226,10 +5334,19 @@ function decodeValueAt(data, offset, limits, budget, depth) {
5226
5334
  const count = data.readUInt32BE(offset);
5227
5335
  requireValueContainer(count, depth, limits, budget);
5228
5336
  offset += 4;
5229
- const values = [];
5337
+ const values = new Array(count);
5338
+ if (count === 3) {
5339
+ const first = decodeValueAt(data, offset, limits, budget, depth + 1);
5340
+ const second = decodeValueAt(data, first.offset, limits, budget, depth + 1);
5341
+ const third = decodeValueAt(data, second.offset, limits, budget, depth + 1);
5342
+ values[0] = first.value;
5343
+ values[1] = second.value;
5344
+ values[2] = third.value;
5345
+ return { value: values, offset: third.offset };
5346
+ }
5230
5347
  for (let index = 0; index < count; index += 1) {
5231
5348
  const read = decodeValueAt(data, offset, limits, budget, depth + 1);
5232
- values.push(read.value);
5349
+ values[index] = read.value;
5233
5350
  offset = read.offset;
5234
5351
  }
5235
5352
  return { value: values, offset };
@@ -5546,6 +5663,8 @@ function nativeNegotiation(value) {
5546
5663
  compactResponseOpcodes: parseCompactResponseOpcodes(
5547
5664
  field(responseCodecs, "compact_response_opcodes")
5548
5665
  ),
5666
+ compactPubSubPublish: strictUnsigned16(field(field(field(capabilities, "pipeline"), "modes"), "pubsub_publish")) === 35,
5667
+ compactStreamXAdd: strictUnsigned16(field(field(field(capabilities, "pipeline"), "modes"), "stream_xadd_auto")) === 34,
5549
5668
  flowQuery: parseFlowQueryNegotiation(capabilities, schemas),
5550
5669
  ...maxResponseBytes == null ? {} : { maxResponseBytes }
5551
5670
  };
@@ -5620,15 +5739,15 @@ function requiredMap(value, context) {
5620
5739
  }
5621
5740
  throw incompatibleServer(`${context} is missing or invalid`);
5622
5741
  }
5623
- function requiredBoundedText(mapping, name) {
5624
- const value = strictText(field(mapping, name));
5742
+ function requiredBoundedText(mapping2, name) {
5743
+ const value = strictText(field(mapping2, name));
5625
5744
  if (value == null || value.length === 0 || import_node_buffer20.Buffer.byteLength(value) > 256) {
5626
5745
  throw incompatibleServer(`HELLO flow_query ${name} must be bounded non-empty text`);
5627
5746
  }
5628
5747
  return value;
5629
5748
  }
5630
- function boundedTextSet(mapping, name, maximum) {
5631
- const raw = field(mapping, name);
5749
+ function boundedTextSet(mapping2, name, maximum) {
5750
+ const raw = field(mapping2, name);
5632
5751
  if (!Array.isArray(raw) || raw.length < 1 || raw.length > maximum) {
5633
5752
  throw incompatibleServer(`HELLO ${name} must contain 1..${maximum} entries`);
5634
5753
  }
@@ -6838,8 +6957,13 @@ function buildProtocolCommand(args, maxBodyBytes = Number.MAX_SAFE_INTEGER, allo
6838
6957
  }
6839
6958
  return commandExec(args);
6840
6959
  }
6841
- function tryPipelineCommand(commands, maxBodyBytes = Number.MAX_SAFE_INTEGER) {
6842
- const compact = compactPipelinePayload(commands, maxBodyBytes);
6960
+ function tryPipelineCommand(commands, maxBodyBytes = Number.MAX_SAFE_INTEGER, allowStreamXAdd = true, allowPubSubPublish = true) {
6961
+ const compact = compactPipelinePayload(
6962
+ commands,
6963
+ maxBodyBytes,
6964
+ allowStreamXAdd,
6965
+ allowPubSubPublish
6966
+ );
6843
6967
  if (compact != null) {
6844
6968
  return {
6845
6969
  compactResponseItems: commands.length,
@@ -6951,15 +7075,15 @@ function snapshotOwnStringArray(values, name) {
6951
7075
 
6952
7076
  // src/client-native-options.ts
6953
7077
  function snapshotNativeClientOptions(options) {
6954
- const own = { ...options };
7078
+ const own2 = { ...options };
6955
7079
  const snapshot = {
6956
- ...own,
6957
- ...typeof own.autoReconnect === "object" && own.autoReconnect != null ? { autoReconnect: Object.freeze({ ...own.autoReconnect }) } : {},
6958
- ...own.endpointPolicy == null ? {} : { endpointPolicy: snapshotEndpointPolicy(own.endpointPolicy) },
6959
- ...own.events == null ? {} : { events: snapshotOwnStringArray(own.events, "events") },
6960
- ...own.seeds == null ? {} : { seeds: snapshotOwnStringArray(own.seeds, "seeds") },
6961
- ...own.tlsOptions == null ? {} : { tlsOptions: snapshotTlsOptions(own.tlsOptions) },
6962
- ...own.trustedHosts == null ? {} : { trustedHosts: snapshotOwnStringArray(own.trustedHosts, "trustedHosts") }
7080
+ ...own2,
7081
+ ...typeof own2.autoReconnect === "object" && own2.autoReconnect != null ? { autoReconnect: Object.freeze({ ...own2.autoReconnect }) } : {},
7082
+ ...own2.endpointPolicy == null ? {} : { endpointPolicy: snapshotEndpointPolicy(own2.endpointPolicy) },
7083
+ ...own2.events == null ? {} : { events: snapshotOwnStringArray(own2.events, "events") },
7084
+ ...own2.seeds == null ? {} : { seeds: snapshotOwnStringArray(own2.seeds, "seeds") },
7085
+ ...own2.tlsOptions == null ? {} : { tlsOptions: snapshotTlsOptions(own2.tlsOptions) },
7086
+ ...own2.trustedHosts == null ? {} : { trustedHosts: snapshotOwnStringArray(own2.trustedHosts, "trustedHosts") }
6963
7087
  };
6964
7088
  return Object.freeze(snapshot);
6965
7089
  }
@@ -7000,12 +7124,12 @@ function topologyNativeOptions(options) {
7000
7124
  }
7001
7125
  function snapshotEndpointPolicy(policy) {
7002
7126
  if (typeof policy !== "object") return policy;
7003
- const own = { ...policy };
7004
- if (!Object.hasOwn(own, "allowHosts") || !Array.isArray(own.allowHosts)) {
7127
+ const own2 = { ...policy };
7128
+ if (!Object.hasOwn(own2, "allowHosts") || !Array.isArray(own2.allowHosts)) {
7005
7129
  throw new TypeError("endpointPolicy.allowHosts must be an own array of strings");
7006
7130
  }
7007
7131
  return Object.freeze({
7008
- allowHosts: snapshotOwnStringArray(own.allowHosts, "endpointPolicy.allowHosts")
7132
+ allowHosts: snapshotOwnStringArray(own2.allowHosts, "endpointPolicy.allowHosts")
7009
7133
  });
7010
7134
  }
7011
7135
  function snapshotTlsOptions(options) {
@@ -7340,13 +7464,18 @@ function surfaceIndividualCommandErrors(results, rejected, hasRejected, options)
7340
7464
  }
7341
7465
 
7342
7466
  // src/native-pipeline-execution.ts
7343
- async function executeNativeFusedPipeline(host, commands, laneId, options, maxPipelineCommands, maxRequestFrameBytes) {
7467
+ async function executeNativeFusedPipeline(host, commands, laneId, options, maxPipelineCommands, maxRequestFrameBytes, compactStreamXAdd = true, compactPubSubPublish = true) {
7344
7468
  commands = snapshotPipelineCommands(commands);
7345
7469
  options = snapshotPipelineOptions(options) ?? options;
7346
7470
  if (commands.length === 0) return [];
7347
7471
  if (maxPipelineCommands === 0 || commands.length > maxPipelineCommands) return void 0;
7348
7472
  try {
7349
- const pipeline = tryPipelineCommand(commands, maxRequestFrameBytes);
7473
+ const pipeline = tryPipelineCommand(
7474
+ commands,
7475
+ maxRequestFrameBytes,
7476
+ compactStreamXAdd,
7477
+ compactPubSubPublish
7478
+ );
7350
7479
  if (pipeline == null) return void 0;
7351
7480
  const response = await host.executeProtocolCommand(pipeline, laneId);
7352
7481
  return unwrapPipelineResponse(response, options, commands.length);
@@ -7355,7 +7484,7 @@ async function executeNativeFusedPipeline(host, commands, laneId, options, maxPi
7355
7484
  throw error;
7356
7485
  }
7357
7486
  }
7358
- async function executeNativePipeline(host, commands, laneId, options, maxPipelineCommands, maxRequestFrameBytes) {
7487
+ async function executeNativePipeline(host, commands, laneId, options, maxPipelineCommands, maxRequestFrameBytes, compactStreamXAdd = true, compactPubSubPublish = true) {
7359
7488
  commands = snapshotPipelineCommands(commands);
7360
7489
  options = snapshotPipelineOptions(options) ?? options;
7361
7490
  if (commands.length === 0) return [];
@@ -7363,7 +7492,15 @@ async function executeNativePipeline(host, commands, laneId, options, maxPipelin
7363
7492
  return await executeIndividually(host, commands, laneId, pipelineFallbackOptions(commands, options));
7364
7493
  }
7365
7494
  if (commands.length <= maxPipelineCommands) {
7366
- return await executeChunk(host, commands, laneId, options, maxRequestFrameBytes);
7495
+ return await executeChunk(
7496
+ host,
7497
+ commands,
7498
+ laneId,
7499
+ options,
7500
+ maxRequestFrameBytes,
7501
+ compactStreamXAdd,
7502
+ compactPubSubPublish
7503
+ );
7367
7504
  }
7368
7505
  const collectingOptions = pipelineErrorCollectingOptions(options);
7369
7506
  const results = new Array(commands.length);
@@ -7375,7 +7512,9 @@ async function executeNativePipeline(host, commands, laneId, options, maxPipelin
7375
7512
  chunk,
7376
7513
  laneId,
7377
7514
  pipelineSliceOptions(collectingOptions, start, start + chunk.length),
7378
- maxRequestFrameBytes
7515
+ maxRequestFrameBytes,
7516
+ compactStreamXAdd,
7517
+ compactPubSubPublish
7379
7518
  );
7380
7519
  for (let index = 0; index < chunkResults.length; index += 1) results[start + index] = chunkResults[index];
7381
7520
  rejected = collectPipelineRejections(chunkResults, start, rejected);
@@ -7383,9 +7522,14 @@ async function executeNativePipeline(host, commands, laneId, options, maxPipelin
7383
7522
  if (rejected != null) attachPipelineItemRejectionFlags(results, rejected);
7384
7523
  return surfaceFirstPipelineItemError(results, options);
7385
7524
  }
7386
- async function executeChunk(host, commands, laneId, options, maxRequestFrameBytes) {
7525
+ async function executeChunk(host, commands, laneId, options, maxRequestFrameBytes, compactStreamXAdd, compactPubSubPublish) {
7387
7526
  try {
7388
- const pipeline = tryPipelineCommand(commands, maxRequestFrameBytes);
7527
+ const pipeline = tryPipelineCommand(
7528
+ commands,
7529
+ maxRequestFrameBytes,
7530
+ compactStreamXAdd,
7531
+ compactPubSubPublish
7532
+ );
7389
7533
  if (pipeline != null) {
7390
7534
  const response = await host.executeProtocolCommand(pipeline, laneId);
7391
7535
  return unwrapPipelineResponse(response, options, commands.length);
@@ -7403,14 +7547,18 @@ async function executeChunk(host, commands, laneId, options, maxRequestFrameByte
7403
7547
  commands.slice(0, middle),
7404
7548
  laneId,
7405
7549
  pipelineSliceOptions(collectingOptions, 0, middle),
7406
- maxRequestFrameBytes
7550
+ maxRequestFrameBytes,
7551
+ compactStreamXAdd,
7552
+ compactPubSubPublish
7407
7553
  );
7408
7554
  const second = await executeChunk(
7409
7555
  host,
7410
7556
  commands.slice(middle),
7411
7557
  laneId,
7412
7558
  pipelineSliceOptions(collectingOptions, middle, commands.length),
7413
- maxRequestFrameBytes
7559
+ maxRequestFrameBytes,
7560
+ compactStreamXAdd,
7561
+ compactPubSubPublish
7414
7562
  );
7415
7563
  return surfaceFirstPipelineItemError(mergePipelineResults(first, second), options);
7416
7564
  }
@@ -8044,6 +8192,8 @@ var NativeConnectionCapabilities = class {
8044
8192
  }
8045
8193
  configuredRequestFrameBytes;
8046
8194
  compactResponseOpcodes = EMPTY_COMPACT_RESPONSE_OPCODES;
8195
+ compactPubSubPublish = false;
8196
+ compactStreamXAdd = false;
8047
8197
  flowQuery;
8048
8198
  requestFrameBytes;
8049
8199
  negotiatedRequestFrameBytes;
@@ -8051,6 +8201,8 @@ var NativeConnectionCapabilities = class {
8051
8201
  const limits = startupLimits(value);
8052
8202
  const negotiation = nativeNegotiation(value);
8053
8203
  this.compactResponseOpcodes = negotiation.compactResponseOpcodes;
8204
+ this.compactPubSubPublish = negotiation.compactPubSubPublish;
8205
+ this.compactStreamXAdd = negotiation.compactStreamXAdd;
8054
8206
  this.flowQuery = negotiation.flowQuery;
8055
8207
  if (limits.frameBytes != null) {
8056
8208
  this.negotiatedRequestFrameBytes = Math.min(
@@ -8276,7 +8428,9 @@ var NativeAdapter = class _NativeAdapter {
8276
8428
  laneId,
8277
8429
  options,
8278
8430
  this.maxPipelineCommands,
8279
- this.capabilities.requestFrameBytes
8431
+ this.capabilities.requestFrameBytes,
8432
+ this.capabilities.compactStreamXAdd,
8433
+ this.capabilities.compactPubSubPublish
8280
8434
  );
8281
8435
  }
8282
8436
  /** @internal Execute an ordered pipeline on a topology-selected lane. */
@@ -8287,7 +8441,9 @@ var NativeAdapter = class _NativeAdapter {
8287
8441
  laneId,
8288
8442
  options,
8289
8443
  this.maxPipelineCommands,
8290
- this.capabilities.requestFrameBytes
8444
+ this.capabilities.requestFrameBytes,
8445
+ this.capabilities.compactStreamXAdd,
8446
+ this.capabilities.compactPubSubPublish
8291
8447
  );
8292
8448
  }
8293
8449
  async close() {
@@ -12085,36 +12241,36 @@ function isPlainObject6(value) {
12085
12241
  const prototype = Object.getPrototypeOf(value);
12086
12242
  return prototype === Object.prototype || prototype === null;
12087
12243
  }
12088
- function requireContract(mapping, name, expected, context) {
12089
- const actual = requiredText2(mapping, name, context);
12244
+ function requireContract(mapping2, name, expected, context) {
12245
+ const actual = requiredText2(mapping2, name, context);
12090
12246
  if (actual !== expected) {
12091
12247
  throw decodeError(
12092
12248
  `${context} has unsupported contract ${JSON.stringify(actual)}`,
12093
- mapping
12249
+ mapping2
12094
12250
  );
12095
12251
  }
12096
12252
  }
12097
- function requiredText2(mapping, name, context) {
12098
- const value = strictText2(field(mapping, name));
12253
+ function requiredText2(mapping2, name, context) {
12254
+ const value = strictText2(field(mapping2, name));
12099
12255
  if (value == null || value.length === 0) {
12100
- throw decodeError(`${context} ${name} must be non-empty text`, mapping);
12256
+ throw decodeError(`${context} ${name} must be non-empty text`, mapping2);
12101
12257
  }
12102
12258
  return value;
12103
12259
  }
12104
- function optionalText2(mapping, name, context) {
12105
- const raw = field(mapping, name);
12260
+ function optionalText2(mapping2, name, context) {
12261
+ const raw = field(mapping2, name);
12106
12262
  if (raw == null) return void 0;
12107
12263
  const value = strictText2(raw);
12108
12264
  if (value == null)
12109
- throw decodeError(`${context} ${name} must be text`, mapping);
12265
+ throw decodeError(`${context} ${name} must be text`, mapping2);
12110
12266
  return value;
12111
12267
  }
12112
- function requiredBoundedText2(mapping, name, context, maximumBytes) {
12113
- const value = requiredText2(mapping, name, context);
12268
+ function requiredBoundedText2(mapping2, name, context, maximumBytes) {
12269
+ const value = requiredText2(mapping2, name, context);
12114
12270
  if (import_node_buffer45.Buffer.byteLength(value, "utf8") > maximumBytes) {
12115
12271
  throw decodeError(
12116
12272
  `${context} ${name} exceeds ${maximumBytes} bytes`,
12117
- mapping
12273
+ mapping2
12118
12274
  );
12119
12275
  }
12120
12276
  return value;
@@ -12129,10 +12285,10 @@ function boundedText(value, context, maximumBytes) {
12129
12285
  }
12130
12286
  return decoded;
12131
12287
  }
12132
- function requiredBoolean(mapping, name, context) {
12133
- const value = field(mapping, name);
12288
+ function requiredBoolean(mapping2, name, context) {
12289
+ const value = field(mapping2, name);
12134
12290
  if (typeof value !== "boolean") {
12135
- throw decodeError(`${context} ${name} must be boolean`, mapping);
12291
+ throw decodeError(`${context} ${name} must be boolean`, mapping2);
12136
12292
  }
12137
12293
  return value;
12138
12294
  }
@@ -12175,11 +12331,11 @@ function positiveBoundedInteger(value, maximum, context) {
12175
12331
  if (parsed === 0) throw decodeError(`${context} must be positive`, value);
12176
12332
  return parsed;
12177
12333
  }
12178
- function hasKey(mapping, name) {
12179
- if (!(mapping instanceof Map)) return Object.hasOwn(mapping, name);
12180
- if (mapping.has(name)) return true;
12334
+ function hasKey(mapping2, name) {
12335
+ if (!(mapping2 instanceof Map)) return Object.hasOwn(mapping2, name);
12336
+ if (mapping2.has(name)) return true;
12181
12337
  const binaryName = import_node_buffer45.Buffer.from(name);
12182
- for (const key of mapping.keys()) {
12338
+ for (const key of mapping2.keys()) {
12183
12339
  if (import_node_buffer45.Buffer.isBuffer(key) && key.equals(binaryName)) return true;
12184
12340
  if (key instanceof Uint8Array && import_node_buffer45.Buffer.from(key).equals(binaryName))
12185
12341
  return true;
@@ -12236,28 +12392,28 @@ var DIAGNOSTIC_CONTEXT_DEPTH = 6;
12236
12392
  var DIAGNOSTIC_CONTEXT_NODES = 512;
12237
12393
  function tryDecodeFlowQueryError(value, cause) {
12238
12394
  try {
12239
- const mapping = requiredMap2(value, "FLOW.QUERY diagnostic");
12240
- const context = decodeDiagnosticContext(field(mapping, "context"));
12241
- const position = decodePosition(field(mapping, "position"));
12395
+ const mapping2 = requiredMap2(value, "FLOW.QUERY diagnostic");
12396
+ const context = decodeDiagnosticContext(field(mapping2, "context"));
12397
+ const position = decodePosition(field(mapping2, "position"));
12242
12398
  return new FlowQueryError({
12243
12399
  code: requiredBoundedText2(
12244
- mapping,
12400
+ mapping2,
12245
12401
  "code",
12246
12402
  "FLOW.QUERY diagnostic",
12247
12403
  DIAGNOSTIC_TEXT_BYTES
12248
12404
  ),
12249
12405
  message: requiredBoundedText2(
12250
- mapping,
12406
+ mapping2,
12251
12407
  "message",
12252
12408
  "FLOW.QUERY diagnostic",
12253
12409
  DIAGNOSTIC_TEXT_BYTES
12254
12410
  ),
12255
- detail: optionalDiagnosticText(mapping, "detail"),
12256
- hint: optionalDiagnosticText(mapping, "hint"),
12257
- retryable: requiredBoolean(mapping, "retryable", "FLOW.QUERY diagnostic"),
12258
- safeToRetry: requiredBoolean(mapping, "safe_to_retry", "FLOW.QUERY diagnostic"),
12411
+ detail: optionalDiagnosticText(mapping2, "detail"),
12412
+ hint: optionalDiagnosticText(mapping2, "hint"),
12413
+ retryable: requiredBoolean(mapping2, "retryable", "FLOW.QUERY diagnostic"),
12414
+ safeToRetry: requiredBoolean(mapping2, "safe_to_retry", "FLOW.QUERY diagnostic"),
12259
12415
  retryAfterMs: nonNegativeInteger(
12260
- field(mapping, "retry_after_ms"),
12416
+ field(mapping2, "retry_after_ms"),
12261
12417
  "FLOW.QUERY diagnostic retry_after_ms"
12262
12418
  ),
12263
12419
  position,
@@ -12270,29 +12426,29 @@ function tryDecodeFlowQueryError(value, cause) {
12270
12426
  throw error;
12271
12427
  }
12272
12428
  }
12273
- function optionalDiagnosticText(mapping, name) {
12274
- const value = optionalText2(mapping, name, "FLOW.QUERY diagnostic");
12429
+ function optionalDiagnosticText(mapping2, name) {
12430
+ const value = optionalText2(mapping2, name, "FLOW.QUERY diagnostic");
12275
12431
  if (value != null && import_node_buffer46.Buffer.byteLength(value, "utf8") > DIAGNOSTIC_TEXT_BYTES) {
12276
12432
  throw decodeError(
12277
12433
  `FLOW.QUERY diagnostic ${name} exceeds ${DIAGNOSTIC_TEXT_BYTES} bytes`,
12278
- mapping
12434
+ mapping2
12279
12435
  );
12280
12436
  }
12281
12437
  return value;
12282
12438
  }
12283
12439
  function decodeDiagnosticContext(value) {
12284
12440
  if (value == null) return void 0;
12285
- const mapping = requiredMap2(value, "FLOW.QUERY diagnostic context");
12286
- const size = mapping instanceof Map ? mapping.size : Object.keys(mapping).length;
12441
+ const mapping2 = requiredMap2(value, "FLOW.QUERY diagnostic context");
12442
+ const size = mapping2 instanceof Map ? mapping2.size : Object.keys(mapping2).length;
12287
12443
  if (size > DIAGNOSTIC_CONTEXT_ENTRIES) {
12288
12444
  throw decodeError("FLOW.QUERY diagnostic context contains too many entries", value);
12289
12445
  }
12290
12446
  validateDiagnosticContextValue(
12291
- mapping,
12447
+ mapping2,
12292
12448
  DIAGNOSTIC_CONTEXT_DEPTH,
12293
12449
  { remaining: DIAGNOSTIC_CONTEXT_NODES }
12294
12450
  );
12295
- return freezeMetadataMap(mapping, "FLOW.QUERY diagnostic context");
12451
+ return freezeMetadataMap(mapping2, "FLOW.QUERY diagnostic context");
12296
12452
  }
12297
12453
  function validateDiagnosticContextValue(value, depth, budget) {
12298
12454
  consumeDiagnosticContextNode(value, budget);
@@ -12364,12 +12520,12 @@ function isDiagnosticContextRecord(value) {
12364
12520
  }
12365
12521
  function decodePosition(value) {
12366
12522
  if (value == null) return void 0;
12367
- const mapping = requiredMap2(value, "FLOW.QUERY diagnostic position");
12523
+ const mapping2 = requiredMap2(value, "FLOW.QUERY diagnostic position");
12368
12524
  return Object.freeze({
12369
- byte: positiveInteger(field(mapping, "byte"), "FLOW.QUERY diagnostic position byte"),
12370
- line: positiveInteger(field(mapping, "line"), "FLOW.QUERY diagnostic position line"),
12525
+ byte: positiveInteger(field(mapping2, "byte"), "FLOW.QUERY diagnostic position byte"),
12526
+ line: positiveInteger(field(mapping2, "line"), "FLOW.QUERY diagnostic position line"),
12371
12527
  column: positiveInteger(
12372
- field(mapping, "column"),
12528
+ field(mapping2, "column"),
12373
12529
  "FLOW.QUERY diagnostic position column"
12374
12530
  )
12375
12531
  });
@@ -12669,25 +12825,25 @@ function decodeUniqueTextArray(value, context, maximum, maximumBytes) {
12669
12825
  }
12670
12826
  return Object.freeze(result);
12671
12827
  }
12672
- function requiredChoice(mapping, name, context, choices) {
12673
- const value = requiredBoundedText2(mapping, name, context, 64);
12828
+ function requiredChoice(mapping2, name, context, choices) {
12829
+ const value = requiredBoundedText2(mapping2, name, context, 64);
12674
12830
  if (!choices.includes(value)) {
12675
- throw decodeError(`${context} ${name} is unsupported`, mapping);
12831
+ throw decodeError(`${context} ${name} is unsupported`, mapping2);
12676
12832
  }
12677
12833
  return value;
12678
12834
  }
12679
- function optionalBoundedText(mapping, name, context, maximumBytes) {
12680
- const value = field(mapping, name);
12835
+ function optionalBoundedText(mapping2, name, context, maximumBytes) {
12836
+ const value = field(mapping2, name);
12681
12837
  if (value == null) return void 0;
12682
12838
  return boundedText(value, `${context} ${name}`, maximumBytes);
12683
12839
  }
12684
- function optionalIndexInteger(mapping, name, context) {
12685
- const value = field(mapping, name);
12840
+ function optionalIndexInteger(mapping2, name, context) {
12841
+ const value = field(mapping2, name);
12686
12842
  return value == null ? void 0 : unsignedIndexInteger(value, `${context} ${name}`);
12687
12843
  }
12688
- function indexCounter(mapping, name, section) {
12844
+ function indexCounter(mapping2, name, section) {
12689
12845
  return unsignedIndexInteger(
12690
- field(mapping, name),
12846
+ field(mapping2, name),
12691
12847
  `FLOW.QUERY.INDEXES index ${section} ${name}`
12692
12848
  );
12693
12849
  }
@@ -12704,13 +12860,13 @@ function indexInteger2(value) {
12704
12860
  // src/flow-query-index-lifecycle-response.ts
12705
12861
  function decodeIndexCoverage(value) {
12706
12862
  const context = "FLOW.QUERY.INDEXES index coverage";
12707
- const mapping = requiredMap2(value, context);
12863
+ const mapping2 = requiredMap2(value, context);
12708
12864
  const completeShards = unsignedIndexInteger(
12709
- field(mapping, "complete_shards"),
12865
+ field(mapping2, "complete_shards"),
12710
12866
  `${context} complete_shards`
12711
12867
  );
12712
12868
  const totalShards = positiveIndexInteger(
12713
- field(mapping, "total_shards"),
12869
+ field(mapping2, "total_shards"),
12714
12870
  `${context} total_shards`
12715
12871
  );
12716
12872
  if (indexInteger2(completeShards) > indexInteger2(totalShards)) {
@@ -12719,60 +12875,60 @@ function decodeIndexCoverage(value) {
12719
12875
  return Object.freeze({
12720
12876
  completeShards,
12721
12877
  totalShards,
12722
- validation: requiredChoice(mapping, "validation", context, [
12878
+ validation: requiredChoice(mapping2, "validation", context, [
12723
12879
  "pending",
12724
12880
  "passed",
12725
12881
  "failed"
12726
12882
  ]),
12727
- raw: freezeMap(mapping)
12883
+ raw: freezeMap(mapping2)
12728
12884
  });
12729
12885
  }
12730
12886
  function decodeIndexBuild(value) {
12731
- const mapping = requiredMap2(value, "FLOW.QUERY.INDEXES index build");
12887
+ const mapping2 = requiredMap2(value, "FLOW.QUERY.INDEXES index build");
12732
12888
  const progress = decodeIndexProgress(
12733
- mapping,
12889
+ mapping2,
12734
12890
  "build",
12735
12891
  FLOW_QUERY_BUILD_PHASES
12736
12892
  );
12737
12893
  return Object.freeze({
12738
12894
  ...progress,
12739
- scannedRecords: indexCounter(mapping, "scanned_records", "build"),
12740
- writtenEntries: indexCounter(mapping, "written_entries", "build"),
12741
- writtenBytes: indexCounter(mapping, "written_bytes", "build")
12895
+ scannedRecords: indexCounter(mapping2, "scanned_records", "build"),
12896
+ writtenEntries: indexCounter(mapping2, "written_entries", "build"),
12897
+ writtenBytes: indexCounter(mapping2, "written_bytes", "build")
12742
12898
  });
12743
12899
  }
12744
12900
  function decodeIndexValidation(value) {
12745
- const mapping = requiredMap2(value, "FLOW.QUERY.INDEXES index validation");
12746
- if (!hasKey(mapping, "failure_reason") || !hasKey(mapping, "validated_at_ms")) {
12901
+ const mapping2 = requiredMap2(value, "FLOW.QUERY.INDEXES index validation");
12902
+ if (!hasKey(mapping2, "failure_reason") || !hasKey(mapping2, "validated_at_ms")) {
12747
12903
  throw decodeError(
12748
12904
  "FLOW.QUERY.INDEXES index validation is missing nullable fields",
12749
12905
  value
12750
12906
  );
12751
12907
  }
12752
12908
  const progress = decodeIndexProgress(
12753
- mapping,
12909
+ mapping2,
12754
12910
  "validation",
12755
12911
  FLOW_QUERY_VALIDATION_PHASES
12756
12912
  );
12757
12913
  return Object.freeze({
12758
12914
  ...progress,
12759
12915
  status: requiredChoice(
12760
- mapping,
12916
+ mapping2,
12761
12917
  "status",
12762
12918
  "FLOW.QUERY.INDEXES index validation",
12763
12919
  ["pending", "passed", "failed"]
12764
12920
  ),
12765
- checkedRecords: indexCounter(mapping, "checked_records", "validation"),
12766
- checkedEntries: indexCounter(mapping, "checked_entries", "validation"),
12767
- mismatches: indexCounter(mapping, "mismatches", "validation"),
12921
+ checkedRecords: indexCounter(mapping2, "checked_records", "validation"),
12922
+ checkedEntries: indexCounter(mapping2, "checked_entries", "validation"),
12923
+ mismatches: indexCounter(mapping2, "mismatches", "validation"),
12768
12924
  failureReason: optionalBoundedText(
12769
- mapping,
12925
+ mapping2,
12770
12926
  "failure_reason",
12771
12927
  "FLOW.QUERY.INDEXES index validation",
12772
12928
  128
12773
12929
  ),
12774
12930
  validatedAtMs: optionalIndexInteger(
12775
- mapping,
12931
+ mapping2,
12776
12932
  "validated_at_ms",
12777
12933
  "FLOW.QUERY.INDEXES index validation"
12778
12934
  )
@@ -12780,77 +12936,77 @@ function decodeIndexValidation(value) {
12780
12936
  }
12781
12937
  function decodeIndexRetirement(value) {
12782
12938
  const context = "FLOW.QUERY.INDEXES index retirement";
12783
- const mapping = requiredMap2(value, context);
12784
- const status = requiredChoice(mapping, "status", context, [
12939
+ const mapping2 = requiredMap2(value, context);
12940
+ const status = requiredChoice(mapping2, "status", context, [
12785
12941
  "not_applicable",
12786
12942
  "pending",
12787
12943
  "complete"
12788
12944
  ]);
12789
12945
  if (status === "not_applicable") {
12790
- return Object.freeze({ status, raw: freezeMap(mapping) });
12946
+ return Object.freeze({ status, raw: freezeMap(mapping2) });
12791
12947
  }
12792
12948
  const completedShards = unsignedIndexInteger(
12793
- field(mapping, "completed_shards"),
12949
+ field(mapping2, "completed_shards"),
12794
12950
  `${context} completed_shards`
12795
12951
  );
12796
12952
  const totalShards = positiveIndexInteger(
12797
- field(mapping, "total_shards"),
12953
+ field(mapping2, "total_shards"),
12798
12954
  `${context} total_shards`
12799
12955
  );
12800
12956
  if (indexInteger2(completedShards) > indexInteger2(totalShards)) {
12801
12957
  throw decodeError(
12802
12958
  `${context} completed_shards exceeds total_shards`,
12803
- mapping
12959
+ mapping2
12804
12960
  );
12805
12961
  }
12806
12962
  return Object.freeze({
12807
12963
  status,
12808
12964
  phaseCounts: decodePhaseCounts(
12809
- field(mapping, "phase_counts"),
12965
+ field(mapping2, "phase_counts"),
12810
12966
  "retirement"
12811
12967
  ),
12812
12968
  currentPhases: decodeAllowedPhases(
12813
- field(mapping, "current_phases"),
12969
+ field(mapping2, "current_phases"),
12814
12970
  "retirement",
12815
12971
  FLOW_QUERY_RETIREMENT_PHASES
12816
12972
  ),
12817
12973
  completedShards,
12818
12974
  totalShards,
12819
- deletedEntries: indexCounter(mapping, "deleted_entries", "retirement"),
12820
- deletedBytes: indexCounter(mapping, "deleted_bytes", "retirement"),
12975
+ deletedEntries: indexCounter(mapping2, "deleted_entries", "retirement"),
12976
+ deletedBytes: indexCounter(mapping2, "deleted_bytes", "retirement"),
12821
12977
  rewrittenReverseRows: indexCounter(
12822
- mapping,
12978
+ mapping2,
12823
12979
  "rewritten_reverse_rows",
12824
12980
  "retirement"
12825
12981
  ),
12826
- raw: freezeMap(mapping)
12982
+ raw: freezeMap(mapping2)
12827
12983
  });
12828
12984
  }
12829
12985
  function decodeIndexStatistics(value) {
12830
12986
  const context = "FLOW.QUERY.INDEXES index statistics";
12831
- const mapping = requiredMap2(value, context);
12987
+ const mapping2 = requiredMap2(value, context);
12832
12988
  for (const name of [
12833
12989
  "oldest_collected_at_ms",
12834
12990
  "newest_collected_at_ms",
12835
12991
  "oldest_age_ms",
12836
12992
  "newest_age_ms"
12837
12993
  ]) {
12838
- if (!hasKey(mapping, name)) {
12994
+ if (!hasKey(mapping2, name)) {
12839
12995
  throw decodeError(
12840
12996
  `${context} is missing required nullable fields`,
12841
12997
  value
12842
12998
  );
12843
12999
  }
12844
13000
  }
12845
- const samples = indexCounter(mapping, "samples", "statistics");
12846
- const freshSamples = indexCounter(mapping, "fresh_samples", "statistics");
12847
- const staleSamples = indexCounter(mapping, "stale_samples", "statistics");
12848
- const futureSamples = indexCounter(mapping, "future_samples", "statistics");
13001
+ const samples = indexCounter(mapping2, "samples", "statistics");
13002
+ const freshSamples = indexCounter(mapping2, "fresh_samples", "statistics");
13003
+ const staleSamples = indexCounter(mapping2, "stale_samples", "statistics");
13004
+ const futureSamples = indexCounter(mapping2, "future_samples", "statistics");
12849
13005
  if (indexInteger2(freshSamples) + indexInteger2(staleSamples) !== indexInteger2(samples) || indexInteger2(futureSamples) > indexInteger2(staleSamples)) {
12850
13006
  throw decodeError(`${context} counters are inconsistent`, value);
12851
13007
  }
12852
13008
  return Object.freeze({
12853
- status: requiredChoice(mapping, "status", context, [
13009
+ status: requiredChoice(mapping2, "status", context, [
12854
13010
  "fresh",
12855
13011
  "stale",
12856
13012
  "future",
@@ -12863,53 +13019,53 @@ function decodeIndexStatistics(value) {
12863
13019
  staleSamples,
12864
13020
  futureSamples,
12865
13021
  oldestCollectedAtMs: optionalIndexInteger(
12866
- mapping,
13022
+ mapping2,
12867
13023
  "oldest_collected_at_ms",
12868
13024
  context
12869
13025
  ),
12870
13026
  newestCollectedAtMs: optionalIndexInteger(
12871
- mapping,
13027
+ mapping2,
12872
13028
  "newest_collected_at_ms",
12873
13029
  context
12874
13030
  ),
12875
- oldestAgeMs: optionalIndexInteger(mapping, "oldest_age_ms", context),
12876
- newestAgeMs: optionalIndexInteger(mapping, "newest_age_ms", context),
12877
- raw: freezeMap(mapping)
13031
+ oldestAgeMs: optionalIndexInteger(mapping2, "oldest_age_ms", context),
13032
+ newestAgeMs: optionalIndexInteger(mapping2, "newest_age_ms", context),
13033
+ raw: freezeMap(mapping2)
12878
13034
  });
12879
13035
  }
12880
- function decodeIndexProgress(mapping, section, allowedPhases) {
13036
+ function decodeIndexProgress(mapping2, section, allowedPhases) {
12881
13037
  const context = `FLOW.QUERY.INDEXES index ${section}`;
12882
13038
  const completedShards = unsignedIndexInteger(
12883
- field(mapping, "completed_shards"),
13039
+ field(mapping2, "completed_shards"),
12884
13040
  `${context} completed_shards`
12885
13041
  );
12886
13042
  const totalShards = positiveIndexInteger(
12887
- field(mapping, "total_shards"),
13043
+ field(mapping2, "total_shards"),
12888
13044
  `${context} total_shards`
12889
13045
  );
12890
13046
  if (indexInteger2(completedShards) > indexInteger2(totalShards)) {
12891
13047
  throw decodeError(
12892
13048
  `${context} completed_shards exceeds total_shards`,
12893
- mapping
13049
+ mapping2
12894
13050
  );
12895
13051
  }
12896
13052
  return Object.freeze({
12897
- scope: requiredChoice(mapping, "scope", context, ["catalog_build"]),
12898
- phaseCounts: decodePhaseCounts(field(mapping, "phase_counts"), section),
13053
+ scope: requiredChoice(mapping2, "scope", context, ["catalog_build"]),
13054
+ phaseCounts: decodePhaseCounts(field(mapping2, "phase_counts"), section),
12899
13055
  currentPhases: decodeAllowedPhases(
12900
- field(mapping, "current_phases"),
13056
+ field(mapping2, "current_phases"),
12901
13057
  section,
12902
13058
  allowedPhases
12903
13059
  ),
12904
13060
  completedShards,
12905
13061
  totalShards,
12906
- raw: freezeMap(mapping)
13062
+ raw: freezeMap(mapping2)
12907
13063
  });
12908
13064
  }
12909
13065
  function decodePhaseCounts(value, section) {
12910
13066
  const context = `FLOW.QUERY.INDEXES index ${section} phase_counts`;
12911
- const mapping = requiredMap2(value, context);
12912
- const entries = mapping instanceof Map ? [...mapping.entries()] : Object.entries(mapping);
13067
+ const mapping2 = requiredMap2(value, context);
13068
+ const entries = mapping2 instanceof Map ? [...mapping2.entries()] : Object.entries(mapping2);
12913
13069
  if (entries.length > 16) {
12914
13070
  throw decodeError(`${context} contains too many entries`, value);
12915
13071
  }
@@ -12942,19 +13098,19 @@ function decodeAllowedPhases(value, section, allowed) {
12942
13098
  // src/flow-query-index-response.ts
12943
13099
  var FLOW_QUERY_INDEXES_CONTRACT = "ferric.flow.query.indexes/v1";
12944
13100
  function decodeFlowQueryIndexStatus(value, expectedId) {
12945
- const mapping = requiredMap2(value, "FLOW.QUERY.INDEXES");
13101
+ const mapping2 = requiredMap2(value, "FLOW.QUERY.INDEXES");
12946
13102
  requireContract(
12947
- mapping,
13103
+ mapping2,
12948
13104
  "contract_version",
12949
13105
  FLOW_QUERY_INDEXES_CONTRACT,
12950
13106
  "FLOW.QUERY.INDEXES"
12951
13107
  );
12952
13108
  const registry = requiredMap2(
12953
- field(mapping, "registry"),
13109
+ field(mapping2, "registry"),
12954
13110
  "FLOW.QUERY.INDEXES registry"
12955
13111
  );
12956
- const services = decodeIndexServices(field(mapping, "services"));
12957
- const rawIndexes = field(mapping, "indexes");
13112
+ const services = decodeIndexServices(field(mapping2, "services"));
13113
+ const rawIndexes = field(mapping2, "indexes");
12958
13114
  if (!Array.isArray(rawIndexes) || rawIndexes.length > 32) {
12959
13115
  throw decodeError(
12960
13116
  "FLOW.QUERY.INDEXES indexes must contain at most 32 entries",
@@ -12974,11 +13130,11 @@ function decodeFlowQueryIndexStatus(value, expectedId) {
12974
13130
  const status = Object.freeze({
12975
13131
  contractVersion: FLOW_QUERY_INDEXES_CONTRACT,
12976
13132
  observedAtMs: unsignedIndexInteger(
12977
- field(mapping, "observed_at_ms"),
13133
+ field(mapping2, "observed_at_ms"),
12978
13134
  "FLOW.QUERY.INDEXES observed_at_ms"
12979
13135
  ),
12980
13136
  statisticsMaxAgeMs: unsignedIndexInteger(
12981
- field(mapping, "statistics_max_age_ms"),
13137
+ field(mapping2, "statistics_max_age_ms"),
12982
13138
  "FLOW.QUERY.INDEXES statistics_max_age_ms"
12983
13139
  ),
12984
13140
  registry: Object.freeze({
@@ -12993,30 +13149,30 @@ function decodeFlowQueryIndexStatus(value, expectedId) {
12993
13149
  }),
12994
13150
  services,
12995
13151
  indexes: Object.freeze(indexes),
12996
- raw: freezeMap(mapping)
13152
+ raw: freezeMap(mapping2)
12997
13153
  });
12998
13154
  validateFlowQueryIndexContract(status, expectedId);
12999
13155
  return status;
13000
13156
  }
13001
13157
  function decodeIndex(value, index) {
13002
- const mapping = requiredMap2(value, `FLOW.QUERY.INDEXES index ${index}`);
13003
- const fields = decodeIndexFields(field(mapping, "fields"));
13158
+ const mapping2 = requiredMap2(value, `FLOW.QUERY.INDEXES index ${index}`);
13159
+ const fields = decodeIndexFields(field(mapping2, "fields"));
13004
13160
  return Object.freeze({
13005
- id: requiredBoundedText2(mapping, "id", "FLOW.QUERY.INDEXES index", 64),
13161
+ id: requiredBoundedText2(mapping2, "id", "FLOW.QUERY.INDEXES index", 64),
13006
13162
  version: positiveIndexInteger(
13007
- field(mapping, "version"),
13163
+ field(mapping2, "version"),
13008
13164
  "FLOW.QUERY.INDEXES index version"
13009
13165
  ),
13010
13166
  buildId: requiredBoundedText2(
13011
- mapping,
13167
+ mapping2,
13012
13168
  "build_id",
13013
13169
  "FLOW.QUERY.INDEXES index",
13014
13170
  128
13015
13171
  ),
13016
- source: requiredChoice(mapping, "source", "FLOW.QUERY.INDEXES index", [
13172
+ source: requiredChoice(mapping2, "source", "FLOW.QUERY.INDEXES index", [
13017
13173
  "runs"
13018
13174
  ]),
13019
- state: requiredChoice(mapping, "state", "FLOW.QUERY.INDEXES index", [
13175
+ state: requiredChoice(mapping2, "state", "FLOW.QUERY.INDEXES index", [
13020
13176
  "building",
13021
13177
  "validating",
13022
13178
  "active",
@@ -13024,60 +13180,60 @@ function decodeIndex(value, index) {
13024
13180
  "failed"
13025
13181
  ]),
13026
13182
  queryable: requiredBoolean(
13027
- mapping,
13183
+ mapping2,
13028
13184
  "queryable",
13029
13185
  "FLOW.QUERY.INDEXES index"
13030
13186
  ),
13031
13187
  fields,
13032
13188
  workloads: decodeUniqueTextArray(
13033
- field(mapping, "workloads"),
13189
+ field(mapping2, "workloads"),
13034
13190
  "FLOW.QUERY.INDEXES index workloads",
13035
13191
  16,
13036
13192
  64
13037
13193
  ),
13038
13194
  countPrefixes: decodeCountPrefixes(
13039
- field(mapping, "count_prefixes"),
13195
+ field(mapping2, "count_prefixes"),
13040
13196
  fields.length
13041
13197
  ),
13042
- coveringFields: decodeCoveringFields(mapping),
13043
- format: decodeIndexFormat(mapping),
13044
- coverage: decodeIndexCoverage(field(mapping, "coverage")),
13045
- build: decodeIndexBuild(field(mapping, "build")),
13046
- validation: decodeIndexValidation(field(mapping, "validation")),
13047
- retirement: decodeIndexRetirement(field(mapping, "retirement")),
13048
- statistics: decodeIndexStatistics(field(mapping, "statistics")),
13049
- raw: freezeMap(mapping)
13198
+ coveringFields: decodeCoveringFields(mapping2),
13199
+ format: decodeIndexFormat(mapping2),
13200
+ coverage: decodeIndexCoverage(field(mapping2, "coverage")),
13201
+ build: decodeIndexBuild(field(mapping2, "build")),
13202
+ validation: decodeIndexValidation(field(mapping2, "validation")),
13203
+ retirement: decodeIndexRetirement(field(mapping2, "retirement")),
13204
+ statistics: decodeIndexStatistics(field(mapping2, "statistics")),
13205
+ raw: freezeMap(mapping2)
13050
13206
  });
13051
13207
  }
13052
13208
  function decodeIndexServices(value) {
13053
- const mapping = requiredMap2(value, "FLOW.QUERY.INDEXES services");
13209
+ const mapping2 = requiredMap2(value, "FLOW.QUERY.INDEXES services");
13054
13210
  const choices = ["ready", "unavailable"];
13055
13211
  return Object.freeze({
13056
13212
  registry: requiredChoice(
13057
- mapping,
13213
+ mapping2,
13058
13214
  "registry",
13059
13215
  "FLOW.QUERY.INDEXES services",
13060
13216
  choices
13061
13217
  ),
13062
13218
  lifecycleWorker: requiredChoice(
13063
- mapping,
13219
+ mapping2,
13064
13220
  "lifecycle_worker",
13065
13221
  "FLOW.QUERY.INDEXES services",
13066
13222
  choices
13067
13223
  ),
13068
13224
  statisticsStore: requiredChoice(
13069
- mapping,
13225
+ mapping2,
13070
13226
  "statistics_store",
13071
13227
  "FLOW.QUERY.INDEXES services",
13072
13228
  choices
13073
13229
  ),
13074
13230
  statisticsWorker: requiredChoice(
13075
- mapping,
13231
+ mapping2,
13076
13232
  "statistics_worker",
13077
13233
  "FLOW.QUERY.INDEXES services",
13078
13234
  choices
13079
13235
  ),
13080
- raw: freezeMap(mapping)
13236
+ raw: freezeMap(mapping2)
13081
13237
  });
13082
13238
  }
13083
13239
  function decodeIndexFields(value) {
@@ -13091,12 +13247,12 @@ function decodeIndexFields(value) {
13091
13247
  if (!Object.hasOwn(value, index)) {
13092
13248
  throw decodeError(`${context} must be dense`, value);
13093
13249
  }
13094
- const mapping = requiredMap2(
13250
+ const mapping2 = requiredMap2(
13095
13251
  value[index],
13096
13252
  `FLOW.QUERY.INDEXES index field ${index}`
13097
13253
  );
13098
13254
  const name = requiredBoundedText2(
13099
- mapping,
13255
+ mapping2,
13100
13256
  "name",
13101
13257
  "FLOW.QUERY.INDEXES index field",
13102
13258
  512
@@ -13108,18 +13264,18 @@ function decodeIndexFields(value) {
13108
13264
  fields[index] = Object.freeze({
13109
13265
  name,
13110
13266
  direction: requiredChoice(
13111
- mapping,
13267
+ mapping2,
13112
13268
  "direction",
13113
13269
  "FLOW.QUERY.INDEXES index field",
13114
13270
  ["asc", "desc"]
13115
13271
  ),
13116
13272
  encoding: requiredChoice(
13117
- mapping,
13273
+ mapping2,
13118
13274
  "encoding",
13119
13275
  "FLOW.QUERY.INDEXES index field",
13120
13276
  ["hashed", "ordered"]
13121
13277
  ),
13122
- raw: freezeMap(mapping)
13278
+ raw: freezeMap(mapping2)
13123
13279
  });
13124
13280
  }
13125
13281
  return Object.freeze(fields);
@@ -13144,8 +13300,8 @@ function decodeCountPrefixes(value, fieldCount) {
13144
13300
  }
13145
13301
  return Object.freeze(prefixes);
13146
13302
  }
13147
- function decodeCoveringFields(mapping) {
13148
- const raw = field(mapping, "covering_fields");
13303
+ function decodeCoveringFields(mapping2) {
13304
+ const raw = field(mapping2, "covering_fields");
13149
13305
  if (!Array.isArray(raw) || raw.length > 32) {
13150
13306
  throw decodeError(
13151
13307
  "FLOW.QUERY.INDEXES index covering_fields must contain at most 32 entries",
@@ -13177,9 +13333,9 @@ function decodeCoveringFields(mapping) {
13177
13333
  }
13178
13334
  return Object.freeze(fields);
13179
13335
  }
13180
- function decodeIndexFormat(mapping) {
13336
+ function decodeIndexFormat(mapping2) {
13181
13337
  const raw = requiredMap2(
13182
- field(mapping, "format"),
13338
+ field(mapping2, "format"),
13183
13339
  "FLOW.QUERY.INDEXES index format"
13184
13340
  );
13185
13341
  if (!hasKey(raw, "counter")) {
@@ -13248,7 +13404,7 @@ var QUALITY_VALUES2 = {
13248
13404
  pagination: ["none", "complete", "authenticated_seek", "live_seek"]
13249
13405
  };
13250
13406
  function decodeFlowQueryResult(value) {
13251
- const result = decodeFlowQueryResponse(value, (mapping) => freezeMap(mapping));
13407
+ const result = decodeFlowQueryResponse(value, (mapping2) => freezeMap(mapping2));
13252
13408
  if (result.kind === "records") {
13253
13409
  return Object.freeze({
13254
13410
  kind: "records",
@@ -13272,7 +13428,7 @@ function decodeFlowQueryResult(value) {
13272
13428
  function decodeFlowQueryRecords(value, decodeRecord) {
13273
13429
  const result = decodeFlowQueryResponse(
13274
13430
  value,
13275
- (mapping, index) => decodeRecord(mapping instanceof Map ? freezeMap(mapping) : mapping, index)
13431
+ (mapping2, index) => decodeRecord(mapping2 instanceof Map ? freezeMap(mapping2) : mapping2, index)
13276
13432
  );
13277
13433
  if (result.kind === "count") {
13278
13434
  throw new FerricStoreError("Flow record convenience query returned a count result", {
@@ -13282,18 +13438,18 @@ function decodeFlowQueryRecords(value, decodeRecord) {
13282
13438
  return result.records;
13283
13439
  }
13284
13440
  function decodeFlowQueryResponse(value, decodeRecord) {
13285
- const mapping = requiredMap2(value, "FLOW.QUERY result");
13286
- requireContract(mapping, "version", FLOW_QUERY_RESULT_CONTRACT, "FLOW.QUERY result");
13287
- const quality = decodeQuality(field(mapping, "quality"));
13288
- const usage = decodeUsage(field(mapping, "usage"));
13289
- const hasRecords = hasKey(mapping, "records");
13290
- const hasCount = hasKey(mapping, "result");
13441
+ const mapping2 = requiredMap2(value, "FLOW.QUERY result");
13442
+ requireContract(mapping2, "version", FLOW_QUERY_RESULT_CONTRACT, "FLOW.QUERY result");
13443
+ const quality = decodeQuality(field(mapping2, "quality"));
13444
+ const usage = decodeUsage(field(mapping2, "usage"));
13445
+ const hasRecords = hasKey(mapping2, "records");
13446
+ const hasCount = hasKey(mapping2, "result");
13291
13447
  if (hasRecords === hasCount) {
13292
13448
  throw decodeError("FLOW.QUERY result must contain exactly one records or count shape", value);
13293
13449
  }
13294
- const raw = freezeMap(mapping);
13450
+ const raw = freezeMap(mapping2);
13295
13451
  if (hasRecords) {
13296
- const rawRecords = field(mapping, "records");
13452
+ const rawRecords = field(mapping2, "records");
13297
13453
  if (!Array.isArray(rawRecords) || rawRecords.length > 100) {
13298
13454
  throw decodeError("FLOW.QUERY records must be an array of at most 100 maps", value);
13299
13455
  }
@@ -13313,16 +13469,16 @@ function decodeFlowQueryResponse(value, decodeRecord) {
13313
13469
  return {
13314
13470
  kind: "records",
13315
13471
  records,
13316
- page: decodePage(field(mapping, "page")),
13472
+ page: decodePage(field(mapping2, "page")),
13317
13473
  quality,
13318
13474
  usage,
13319
13475
  raw
13320
13476
  };
13321
13477
  }
13322
- if (hasKey(mapping, "page")) {
13478
+ if (hasKey(mapping2, "page")) {
13323
13479
  throw decodeError("FLOW.QUERY count result contains an unexpected page", value);
13324
13480
  }
13325
- const countResult = requiredMap2(field(mapping, "result"), "FLOW.QUERY count result");
13481
+ const countResult = requiredMap2(field(mapping2, "result"), "FLOW.QUERY count result");
13326
13482
  if (requiredText2(countResult, "kind", "FLOW.QUERY count result") !== "count") {
13327
13483
  throw decodeError("FLOW.QUERY count result kind must be count", value);
13328
13484
  }
@@ -13343,31 +13499,31 @@ function decodeFlowQueryResponse(value, decodeRecord) {
13343
13499
  };
13344
13500
  }
13345
13501
  function decodeFlowExplainResult(value) {
13346
- const mapping = requiredMap2(value, "FLOW.QUERY explain");
13347
- requireContract(mapping, "version", FLOW_EXPLAIN_CONTRACT, "FLOW.QUERY explain");
13348
- const queryFingerprint = requiredText2(mapping, "query_fingerprint", "FLOW.QUERY explain");
13502
+ const mapping2 = requiredMap2(value, "FLOW.QUERY explain");
13503
+ requireContract(mapping2, "version", FLOW_EXPLAIN_CONTRACT, "FLOW.QUERY explain");
13504
+ const queryFingerprint = requiredText2(mapping2, "query_fingerprint", "FLOW.QUERY explain");
13349
13505
  if (!/^[0-9a-f]{64}$/iu.test(queryFingerprint)) {
13350
13506
  throw decodeError("FLOW.QUERY explain query_fingerprint is invalid", value);
13351
13507
  }
13352
- const status = requiredText2(mapping, "status", "FLOW.QUERY explain");
13508
+ const status = requiredText2(mapping2, "status", "FLOW.QUERY explain");
13353
13509
  if (status !== "planned" && status !== "rejected" && status !== "executed") {
13354
13510
  throw decodeError(`FLOW.QUERY explain status ${JSON.stringify(status)} is unsupported`, value);
13355
13511
  }
13356
13512
  const plan = freezeMetadataMap(
13357
- requiredMap2(field(mapping, "plan"), "FLOW.QUERY explain plan"),
13513
+ requiredMap2(field(mapping2, "plan"), "FLOW.QUERY explain plan"),
13358
13514
  "FLOW.QUERY explain plan"
13359
13515
  );
13360
13516
  const estimate = freezeMetadataMap(
13361
- requiredMap2(field(mapping, "estimate"), "FLOW.QUERY explain estimate"),
13517
+ requiredMap2(field(mapping2, "estimate"), "FLOW.QUERY explain estimate"),
13362
13518
  "FLOW.QUERY explain estimate"
13363
13519
  );
13364
13520
  const bounds = freezeMetadataMap(
13365
- requiredMap2(field(mapping, "bounds"), "FLOW.QUERY explain bounds"),
13521
+ requiredMap2(field(mapping2, "bounds"), "FLOW.QUERY explain bounds"),
13366
13522
  "FLOW.QUERY explain bounds"
13367
13523
  );
13368
- const capabilities = decodeExplainCapabilities(mapping);
13524
+ const capabilities = decodeExplainCapabilities(mapping2);
13369
13525
  const extendedFields = ["stats", "quality", "pressure", "decision", "alternatives"];
13370
- const extendedPresence = extendedFields.map((name) => hasKey(mapping, name));
13526
+ const extendedPresence = extendedFields.map((name) => hasKey(mapping2, name));
13371
13527
  const specialized = capabilities != null && !extendedPresence.some(Boolean);
13372
13528
  let stats;
13373
13529
  let quality;
@@ -13378,30 +13534,30 @@ function decodeFlowExplainResult(value) {
13378
13534
  if (status !== "planned") {
13379
13535
  throw decodeError("FLOW.QUERY specialized explain must be planned", value);
13380
13536
  }
13381
- if (hasKey(mapping, "actual") || hasKey(mapping, "diagnostic")) {
13537
+ if (hasKey(mapping2, "actual") || hasKey(mapping2, "diagnostic")) {
13382
13538
  throw decodeError("FLOW.QUERY specialized explain has extended status fields", value);
13383
13539
  }
13384
13540
  alternatives = Object.freeze([]);
13385
13541
  } else {
13386
- if (!extendedPresence.every(Boolean) || !hasKey(mapping, "actual") || !hasKey(mapping, "diagnostic")) {
13542
+ if (!extendedPresence.every(Boolean) || !hasKey(mapping2, "actual") || !hasKey(mapping2, "diagnostic")) {
13387
13543
  throw decodeError("FLOW.QUERY explain is missing required v1 fields", value);
13388
13544
  }
13389
13545
  stats = freezeMetadataMap(
13390
- requiredMap2(field(mapping, "stats"), "FLOW.QUERY explain stats"),
13546
+ requiredMap2(field(mapping2, "stats"), "FLOW.QUERY explain stats"),
13391
13547
  "FLOW.QUERY explain stats"
13392
13548
  );
13393
- quality = decodeQuality(field(mapping, "quality"));
13549
+ quality = decodeQuality(field(mapping2, "quality"));
13394
13550
  pressure = freezeMetadataMap(
13395
- requiredMap2(field(mapping, "pressure"), "FLOW.QUERY explain pressure"),
13551
+ requiredMap2(field(mapping2, "pressure"), "FLOW.QUERY explain pressure"),
13396
13552
  "FLOW.QUERY explain pressure"
13397
13553
  );
13398
13554
  decision = freezeMetadataMap(
13399
- requiredMap2(field(mapping, "decision"), "FLOW.QUERY explain decision"),
13555
+ requiredMap2(field(mapping2, "decision"), "FLOW.QUERY explain decision"),
13400
13556
  "FLOW.QUERY explain decision"
13401
13557
  );
13402
- alternatives = decodeExplainAlternatives(field(mapping, "alternatives"));
13558
+ alternatives = decodeExplainAlternatives(field(mapping2, "alternatives"));
13403
13559
  }
13404
- const actualValue = field(mapping, "actual");
13560
+ const actualValue = field(mapping2, "actual");
13405
13561
  let actual;
13406
13562
  if (status === "executed") {
13407
13563
  if (actualValue == null) {
@@ -13411,7 +13567,7 @@ function decodeFlowExplainResult(value) {
13411
13567
  } else if (actualValue != null) {
13412
13568
  throw decodeError("FLOW.QUERY non-executed explain contains actual usage", value);
13413
13569
  }
13414
- const diagnosticValue = field(mapping, "diagnostic");
13570
+ const diagnosticValue = field(mapping2, "diagnostic");
13415
13571
  let diagnostic;
13416
13572
  if (status === "rejected") {
13417
13573
  diagnostic = tryDecodeFlowQueryError(diagnosticValue);
@@ -13436,13 +13592,13 @@ function decodeFlowExplainResult(value) {
13436
13592
  capabilities,
13437
13593
  actual,
13438
13594
  diagnostic,
13439
- raw: freezeMap(mapping)
13595
+ raw: freezeMap(mapping2)
13440
13596
  });
13441
13597
  }
13442
- function decodeExplainCapabilities(mapping) {
13443
- if (!hasKey(mapping, "capabilities")) return void 0;
13598
+ function decodeExplainCapabilities(mapping2) {
13599
+ if (!hasKey(mapping2, "capabilities")) return void 0;
13444
13600
  const value = requiredMap2(
13445
- field(mapping, "capabilities"),
13601
+ field(mapping2, "capabilities"),
13446
13602
  "FLOW.QUERY explain capabilities"
13447
13603
  );
13448
13604
  return Object.freeze({
@@ -13498,27 +13654,27 @@ function decodeExplainAlternatives(value) {
13498
13654
  return Object.freeze(alternatives);
13499
13655
  }
13500
13656
  function decodeQuality(value) {
13501
- const mapping = requiredMap2(value, "FLOW.QUERY quality");
13657
+ const mapping2 = requiredMap2(value, "FLOW.QUERY quality");
13502
13658
  return Object.freeze({
13503
- exactness: decodeQualityValue(mapping, "exactness", QUALITY_VALUES2.exactness),
13504
- freshness: decodeQualityValue(mapping, "freshness", QUALITY_VALUES2.freshness),
13505
- coverage: decodeQualityValue(mapping, "coverage", QUALITY_VALUES2.coverage),
13506
- pagination: decodeQualityValue(mapping, "pagination", QUALITY_VALUES2.pagination)
13659
+ exactness: decodeQualityValue(mapping2, "exactness", QUALITY_VALUES2.exactness),
13660
+ freshness: decodeQualityValue(mapping2, "freshness", QUALITY_VALUES2.freshness),
13661
+ coverage: decodeQualityValue(mapping2, "coverage", QUALITY_VALUES2.coverage),
13662
+ pagination: decodeQualityValue(mapping2, "pagination", QUALITY_VALUES2.pagination)
13507
13663
  });
13508
13664
  }
13509
- function decodeQualityValue(mapping, name, allowed) {
13510
- const value = requiredBoundedText2(mapping, name, "FLOW.QUERY quality", 64);
13665
+ function decodeQualityValue(mapping2, name, allowed) {
13666
+ const value = requiredBoundedText2(mapping2, name, "FLOW.QUERY quality", 64);
13511
13667
  if (!allowed.includes(value)) {
13512
- throw decodeError(`FLOW.QUERY quality ${name} is unsupported`, mapping);
13668
+ throw decodeError(`FLOW.QUERY quality ${name} is unsupported`, mapping2);
13513
13669
  }
13514
13670
  return value;
13515
13671
  }
13516
13672
  function decodeUsage(value) {
13517
- const mapping = requiredMap2(value, "FLOW.QUERY usage");
13673
+ const mapping2 = requiredMap2(value, "FLOW.QUERY usage");
13518
13674
  const usage = /* @__PURE__ */ Object.create(null);
13519
13675
  for (const [wireName, property] of USAGE_FIELDS2) {
13520
13676
  usage[property] = nonNegativeInteger(
13521
- field(mapping, wireName),
13677
+ field(mapping2, wireName),
13522
13678
  `FLOW.QUERY usage ${wireName}`
13523
13679
  );
13524
13680
  }
@@ -13529,9 +13685,9 @@ function decodeUsage(value) {
13529
13685
  return Object.freeze(decoded);
13530
13686
  }
13531
13687
  function decodePage(value) {
13532
- const mapping = requiredMap2(value, "FLOW.QUERY page");
13533
- const hasMore = requiredBoolean(mapping, "has_more", "FLOW.QUERY page");
13534
- const cursor = optionalText2(mapping, "cursor", "FLOW.QUERY page");
13688
+ const mapping2 = requiredMap2(value, "FLOW.QUERY page");
13689
+ const hasMore = requiredBoolean(mapping2, "has_more", "FLOW.QUERY page");
13690
+ const cursor = optionalText2(mapping2, "cursor", "FLOW.QUERY page");
13535
13691
  if (cursor != null && (!cursor.startsWith("fqc1_") || import_node_buffer48.Buffer.byteLength(cursor) < 16 || import_node_buffer48.Buffer.byteLength(cursor) > 4096)) {
13536
13692
  throw decodeError("FLOW.QUERY page cursor is invalid", value);
13537
13693
  }
@@ -13647,12 +13803,12 @@ var ErrorMappingExecutor = class {
13647
13803
 
13648
13804
  // src/client-config.ts
13649
13805
  function snapshotClientOptions(options) {
13650
- const own = { ...options };
13806
+ const own2 = { ...options };
13651
13807
  const snapshot = {
13652
- ...own,
13653
- ...typeof own.autoBatch === "object" && own.autoBatch != null ? { autoBatch: Object.freeze({ ...own.autoBatch }) } : {},
13654
- ...own.backpressure == null ? {} : { backpressure: Object.freeze({ ...own.backpressure }) },
13655
- ...typeof own.reconnect === "object" && own.reconnect != null ? { reconnect: Object.freeze({ ...own.reconnect }) } : {}
13808
+ ...own2,
13809
+ ...typeof own2.autoBatch === "object" && own2.autoBatch != null ? { autoBatch: Object.freeze({ ...own2.autoBatch }) } : {},
13810
+ ...own2.backpressure == null ? {} : { backpressure: Object.freeze({ ...own2.backpressure }) },
13811
+ ...typeof own2.reconnect === "object" && own2.reconnect != null ? { reconnect: Object.freeze({ ...own2.reconnect }) } : {}
13656
13812
  };
13657
13813
  return Object.freeze(snapshot);
13658
13814
  }
@@ -15841,33 +15997,511 @@ var FerricStoreClientCore = class extends FerricStoreAdministrationClient {
15841
15997
  }
15842
15998
  };
15843
15999
 
15844
- // src/client-management.ts
15845
- var FerricStoreManagementClient = class extends FerricStoreClientCore {
15846
- async stats(type, options = {}) {
15847
- const args = ["FLOW.STATS", type];
15848
- append(args, "STATE", options.state);
15849
- append(args, "COUNT", options.count);
15850
- append(args, "PARTITION", options.partitionKey);
15851
- appendAttributes(args, options.attributes);
15852
- appendBool(args, "CONSISTENT_PROJECTION", options.consistentProjection);
15853
- return adminRecordResponse(await this.commandArgs(args), "FLOW.STATS");
16000
+ // src/schedule-request.ts
16001
+ var MAX_EXACT_INTEGER = Number.MAX_SAFE_INTEGER;
16002
+ var SCHEDULE_KINDS = /* @__PURE__ */ new Set(["one_shot", "delay", "interval", "cron"]);
16003
+ var RECURRING_KINDS = /* @__PURE__ */ new Set(["interval", "cron"]);
16004
+ var OVERLAP_POLICIES = /* @__PURE__ */ new Set([
16005
+ "allow",
16006
+ "skip",
16007
+ "queue_after_previous",
16008
+ "fail_schedule"
16009
+ ]);
16010
+ var SCHEDULE_STATES = /* @__PURE__ */ new Set([
16011
+ "active",
16012
+ "paused",
16013
+ "running",
16014
+ "completed",
16015
+ "failed",
16016
+ "cancelled",
16017
+ "all"
16018
+ ]);
16019
+ var TARGET_FIELDS = /* @__PURE__ */ new Set([
16020
+ "correlation_id",
16021
+ "id",
16022
+ "id_prefix",
16023
+ "parent_flow_id",
16024
+ "partition_key",
16025
+ "payload",
16026
+ "payload_ref",
16027
+ "priority",
16028
+ "root_flow_id",
16029
+ "run_at_ms",
16030
+ "state",
16031
+ "type",
16032
+ "value_refs",
16033
+ "values"
16034
+ ]);
16035
+ var TARGET_TEXT_FIELDS = [
16036
+ "state",
16037
+ "id",
16038
+ "id_prefix",
16039
+ "partition_key",
16040
+ "correlation_id",
16041
+ "parent_flow_id",
16042
+ "root_flow_id",
16043
+ "payload_ref"
16044
+ ];
16045
+ var INTERNAL_SCHEDULE_TYPE = "__ferricstore_schedule";
16046
+ var INTERNAL_SCHEDULE_ID_PREFIX = "__ferricstore_schedule__:";
16047
+ function validateScheduleCreate(id, options) {
16048
+ requiredText3(id, "id");
16049
+ if (!mapping(options)) throw new TypeError("schedule options must be a mapping");
16050
+ const kind = effectiveKind(options);
16051
+ validateTiming(kind, options);
16052
+ const recurring = RECURRING_KINDS.has(kind);
16053
+ 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");
16062
+ optionalBoolean(options.overwrite, "overwrite");
16063
+ if (kind === "delay") {
16064
+ if (options.delayMs == null) throw new TypeError("delay_ms is required for delay schedules");
16065
+ if (options.nowMs != null && options.nowMs > MAX_EXACT_INTEGER - options.delayMs) {
16066
+ throw new TypeError("now_ms plus delay_ms exceeds the exact integer range");
16067
+ }
16068
+ }
16069
+ if (kind === "interval" && options.everyMs == null) {
16070
+ throw new TypeError("every_ms is required for interval schedules");
16071
+ }
16072
+ if (kind === "cron") {
16073
+ requiredText3(options.cron, "cron");
16074
+ optionalText3(options.timezone, "timezone");
16075
+ } else if (options.timezone != null) {
16076
+ throw new TypeError("timezone is only supported for cron schedules");
16077
+ }
16078
+ if (kind === "interval") {
16079
+ if (options.catchupPolicy != null && options.catchupPolicy !== "fire_once") {
16080
+ throw new TypeError("catchup_policy must be fire_once");
16081
+ }
16082
+ } else if (options.catchupPolicy != null) {
16083
+ throw new TypeError("catchup_policy is only supported for interval schedules");
16084
+ }
16085
+ if (recurring) {
16086
+ if (options.overlapPolicy != null && !OVERLAP_POLICIES.has(options.overlapPolicy)) {
16087
+ throw new TypeError(
16088
+ "overlap_policy must be allow, skip, queue_after_previous, or fail_schedule"
16089
+ );
16090
+ }
16091
+ if (options.overlapRetryMs != null && options.overlapPolicy !== "queue_after_previous") {
16092
+ throw new TypeError("overlap_retry_ms requires overlap_policy queue_after_previous");
16093
+ }
16094
+ const firstRun = knownFirstRun(kind, options);
16095
+ if (options.endAtMs != null && firstRun != null && options.endAtMs < firstRun) {
16096
+ throw new TypeError("end_at_ms must be at or after first run");
16097
+ }
16098
+ } else {
16099
+ if (options.overlapPolicy != null) {
16100
+ throw new TypeError("overlap_policy is only supported for recurring schedules");
16101
+ }
16102
+ if (options.overlapRetryMs != null) {
16103
+ throw new TypeError("overlap_retry_ms requires overlap_policy queue_after_previous");
16104
+ }
16105
+ if (options.maxFires != null) {
16106
+ throw new TypeError("max_fires is only supported for recurring schedules");
16107
+ }
16108
+ if (options.endAtMs != null) {
16109
+ throw new TypeError("end_at_ms is only supported for recurring schedules");
16110
+ }
15854
16111
  }
15855
- async countByState(type, state, options = {}) {
15856
- const stats = await this.stats(type, { ...options, state });
15857
- if (!("count" in stats)) throw new TypeError("FLOW.STATS response missing count");
15858
- return integer(stats.count);
16112
+ }
16113
+ function validateScheduleID(id) {
16114
+ requiredText3(id, "id");
16115
+ }
16116
+ function validateScheduleFire(id, options) {
16117
+ validateScheduleID(id);
16118
+ nonNegativeInteger2(options.fireAtMs, "fire_at_ms");
16119
+ nonNegativeInteger2(options.nowMs, "now_ms");
16120
+ }
16121
+ function validateScheduleStatus(id, nowMs2) {
16122
+ validateScheduleID(id);
16123
+ nonNegativeInteger2(nowMs2, "now_ms");
16124
+ }
16125
+ function validateScheduleFireDue(options) {
16126
+ if (!mapping(options)) throw new TypeError("schedule fire-due options must be a mapping");
16127
+ nonNegativeInteger2(options.nowMs, "now_ms");
16128
+ optionalText3(options.worker, "worker");
16129
+ positiveInteger2(options.leaseMs, "lease_ms");
16130
+ nonNegativeInteger2(options.blockMs, "block_ms");
16131
+ positiveInteger2(options.limit, "limit");
16132
+ const leaseMs = options.leaseMs ?? 3e4;
16133
+ if (options.nowMs != null && options.nowMs > MAX_EXACT_INTEGER - leaseMs) {
16134
+ throw new TypeError("now_ms plus lease_ms exceeds the exact integer range");
15859
16135
  }
15860
- async attributes(type, options = {}) {
15861
- const args = ["FLOW.ATTRIBUTES", type];
15862
- appendAttributeQueryOptions(args, options);
15863
- return adminRecordList(await this.commandArgs(args), "FLOW.ATTRIBUTES");
16136
+ }
16137
+ function validateScheduleList(options) {
16138
+ if (!mapping(options)) throw new TypeError("schedule list options must be a mapping");
16139
+ if (options.kind != null && !SCHEDULE_KINDS.has(options.kind)) {
16140
+ throw new TypeError("kind must be one_shot, delay, interval, or cron");
15864
16141
  }
15865
- async attributeValues(type, attribute, options = {}) {
15866
- const args = ["FLOW.ATTRIBUTE_VALUES", type, attribute];
15867
- appendAttributeQueryOptions(args, options);
15868
- return adminRecordList(await this.commandArgs(args), "FLOW.ATTRIBUTE_VALUES");
16142
+ if (options.state != null && !SCHEDULE_STATES.has(options.state)) {
16143
+ throw new TypeError("state is invalid");
16144
+ }
16145
+ optionalText3(options.timezone, "timezone");
16146
+ optionalText3(options.targetType, "target_type");
16147
+ nonNegativeInteger2(options.fromMs, "from_ms");
16148
+ nonNegativeInteger2(options.toMs, "to_ms");
16149
+ if (options.fromMs != null && options.toMs != null && options.fromMs > options.toMs) {
16150
+ throw new TypeError("from_ms must not exceed to_ms");
16151
+ }
16152
+ positiveInteger2(options.count, "count");
16153
+ optionalBoolean(options.rev, "rev");
16154
+ }
16155
+ function effectiveKind(options) {
16156
+ if (options.kind != null) {
16157
+ if (!SCHEDULE_KINDS.has(options.kind)) {
16158
+ throw new TypeError("kind must be one_shot, delay, interval, or cron");
16159
+ }
16160
+ return options.kind;
16161
+ }
16162
+ if (options.cron != null) return "cron";
16163
+ if (options.everyMs != null) return "interval";
16164
+ if (options.delayMs != null) return "delay";
16165
+ return "one_shot";
16166
+ }
16167
+ function validateTiming(kind, options) {
16168
+ if (options.atMs != null && options.startAtMs != null) {
16169
+ throw new TypeError("cannot set both at_ms and start_at_ms");
16170
+ }
16171
+ if (options.delayMs != null && kind !== "delay") {
16172
+ throw new TypeError("delay_ms is only supported for delay schedules");
16173
+ }
16174
+ if (options.everyMs != null && kind !== "interval") {
16175
+ throw new TypeError("every_ms is only supported for interval schedules");
16176
+ }
16177
+ if (options.cron != null && kind !== "cron") {
16178
+ throw new TypeError("cron is only supported for cron schedules");
16179
+ }
16180
+ if (kind === "delay" && (options.atMs != null || options.startAtMs != null)) {
16181
+ throw new TypeError("at_ms and start_at_ms are not supported for delay schedules");
16182
+ }
16183
+ }
16184
+ function validateTarget(value, recurring) {
16185
+ if (!mapping(value)) throw new TypeError("target must be a mapping with a non-empty type");
16186
+ const target = value;
16187
+ for (const key of Object.keys(target)) {
16188
+ if (!TARGET_FIELDS.has(key)) throw new TypeError(`target contains unknown field ${key}`);
16189
+ }
16190
+ const type = own(target, "type");
16191
+ requiredText3(type, "target type");
16192
+ if (type === INTERNAL_SCHEDULE_TYPE) {
16193
+ throw new TypeError("target type is reserved for internal use");
16194
+ }
16195
+ for (const key of TARGET_TEXT_FIELDS) optionalText3(own(target, key), `target ${key}`);
16196
+ const id = own(target, "id");
16197
+ const idPrefix = own(target, "id_prefix");
16198
+ if (id != null && idPrefix != null) {
16199
+ throw new TypeError("target cannot set both id and id_prefix");
16200
+ }
16201
+ if (recurring && id != null) {
16202
+ throw new TypeError("target id is not supported for recurring schedules; use id_prefix");
16203
+ }
16204
+ if (typeof id === "string" && id.startsWith(INTERNAL_SCHEDULE_ID_PREFIX)) {
16205
+ throw new TypeError("target id is reserved for internal use");
16206
+ }
16207
+ if (typeof idPrefix === "string" && idPrefix.startsWith(INTERNAL_SCHEDULE_ID_PREFIX)) {
16208
+ throw new TypeError("target id_prefix is reserved for internal use");
16209
+ }
16210
+ nonNegativeInteger2(own(target, "run_at_ms"), "target run_at_ms");
16211
+ const priority = own(target, "priority");
16212
+ if (priority != null && (typeof priority !== "number" || !Number.isSafeInteger(priority) || priority < 0 || priority > 2)) {
16213
+ throw new TypeError("target priority must be an integer between 0 and 2");
16214
+ }
16215
+ }
16216
+ function knownFirstRun(kind, options) {
16217
+ if (kind === "delay") {
16218
+ if (options.nowMs == null || options.delayMs == null) return void 0;
16219
+ return options.nowMs + options.delayMs;
16220
+ }
16221
+ if (kind === "cron") return options.startAtMs ?? options.atMs ?? options.nowMs;
16222
+ return options.atMs ?? options.startAtMs ?? options.nowMs;
16223
+ }
16224
+ function requiredText3(value, name) {
16225
+ if (typeof value !== "string" || value.length === 0) {
16226
+ throw new TypeError(`${name} must be a non-empty string`);
16227
+ }
16228
+ }
16229
+ function optionalText3(value, name) {
16230
+ if (value != null) requiredText3(value, name);
16231
+ }
16232
+ function nonNegativeInteger2(value, name) {
16233
+ if (value != null && (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0)) {
16234
+ throw new TypeError(`${name} must be a non-negative exact integer`);
16235
+ }
16236
+ }
16237
+ function positiveInteger2(value, name) {
16238
+ if (value != null && (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0)) {
16239
+ throw new TypeError(`${name} must be a positive exact integer`);
16240
+ }
16241
+ }
16242
+ function optionalBoolean(value, name) {
16243
+ if (value != null && typeof value !== "boolean") {
16244
+ throw new TypeError(`${name} must be a boolean`);
16245
+ }
16246
+ }
16247
+ function mapping(value) {
16248
+ return typeof value === "object" && value !== null && !Array.isArray(value);
16249
+ }
16250
+ function own(mapping2, key) {
16251
+ return Object.prototype.hasOwnProperty.call(mapping2, key) ? mapping2[key] : void 0;
16252
+ }
16253
+
16254
+ // src/schedule-response.ts
16255
+ var SCHEDULE_INTEGER_FIELDS = [
16256
+ "end_at_ms",
16257
+ "last_catchup_at_ms",
16258
+ "last_fire_at_ms",
16259
+ "last_overlap_at_ms",
16260
+ "last_skipped_at_ms",
16261
+ "max_fires",
16262
+ "next_run_at_ms",
16263
+ "overlap_queued_due_at_ms"
16264
+ ];
16265
+ var REQUIRED_SCHEDULE_INTEGER_FIELDS = [
16266
+ "attempts",
16267
+ "coalesced_count",
16268
+ "fire_count",
16269
+ "last_coalesced_count",
16270
+ "skipped_count"
16271
+ ];
16272
+ var OPTIONAL_SCHEDULE_TEXT_FIELDS = [
16273
+ "cron",
16274
+ "end_reason",
16275
+ "flow_id",
16276
+ "last_overlap_reason",
16277
+ "last_overlap_target_id",
16278
+ "last_planning_error",
16279
+ "last_target_id",
16280
+ "timezone"
16281
+ ];
16282
+ var SCHEDULE_KINDS2 = /* @__PURE__ */ new Set(["one_shot", "delay", "interval", "cron"]);
16283
+ var SCHEDULE_STATES2 = /* @__PURE__ */ new Set([
16284
+ "active",
16285
+ "paused",
16286
+ "running",
16287
+ "completed",
16288
+ "failed",
16289
+ "cancelled"
16290
+ ]);
16291
+ var SCHEDULE_OVERLAP_POLICIES = /* @__PURE__ */ new Set([
16292
+ "allow",
16293
+ "skip",
16294
+ "queue_after_previous",
16295
+ "fail_schedule"
16296
+ ]);
16297
+ function scheduleRecordResponse(value, context) {
16298
+ const record = adminRecordResponse(value, context);
16299
+ if (typeof record.id !== "string" || record.id.length === 0) {
16300
+ throw new TypeError(`${context} response missing id`);
16301
+ }
16302
+ if (typeof record.kind !== "string" || !SCHEDULE_KINDS2.has(record.kind)) {
16303
+ throw new TypeError(`${context} response missing or invalid kind`);
16304
+ }
16305
+ if (typeof record.state !== "string" || !SCHEDULE_STATES2.has(record.state)) {
16306
+ throw new TypeError(`${context} response missing or invalid state`);
16307
+ }
16308
+ if (typeof record.target !== "object" || record.target == null || Array.isArray(record.target)) {
16309
+ throw new TypeError(`${context} response missing or invalid target`);
16310
+ }
16311
+ const target = record.target;
16312
+ if (typeof target.type !== "string" || target.type.length === 0) {
16313
+ throw new TypeError(`${context} response missing or invalid target type`);
16314
+ }
16315
+ if (!("catchup_policy" in record) || record.kind === "interval" && record.catchup_policy !== "fire_once" || record.kind !== "interval" && record.catchup_policy != null) {
16316
+ throw new TypeError(`${context} returned an invalid catchup_policy`);
16317
+ }
16318
+ if (typeof record.overlap_policy !== "string" || !SCHEDULE_OVERLAP_POLICIES.has(record.overlap_policy)) {
16319
+ throw new TypeError(`${context} response missing or invalid overlap_policy`);
16320
+ }
16321
+ safeNonNegativeInteger(record, "created_at_ms", context, true);
16322
+ const everyMs = requiredNullableNonNegativeInteger(record, "every_ms", context);
16323
+ const cron = requiredNullableResponseText(record, "cron", context);
16324
+ const timezone = requiredNullableResponseText(record, "timezone", context);
16325
+ const overlapRetryMs = requiredNullableNonNegativeInteger(
16326
+ record,
16327
+ "overlap_retry_ms",
16328
+ context
16329
+ );
16330
+ validateRecurrence(record, context, everyMs, cron, timezone, overlapRetryMs);
16331
+ let coalescedCount = 0;
16332
+ let lastCoalescedCount = 0;
16333
+ for (const field3 of REQUIRED_SCHEDULE_INTEGER_FIELDS) {
16334
+ const value2 = safeNonNegativeInteger(record, field3, context, true);
16335
+ if (field3 === "coalesced_count") coalescedCount = value2;
16336
+ if (field3 === "last_coalesced_count") lastCoalescedCount = value2;
16337
+ }
16338
+ for (const field3 of SCHEDULE_INTEGER_FIELDS) {
16339
+ if (record[field3] != null) safeNonNegativeInteger(record, field3, context);
16340
+ }
16341
+ for (const field3 of OPTIONAL_SCHEDULE_TEXT_FIELDS) {
16342
+ optionalResponseText(record, field3, context);
16343
+ }
16344
+ validateCatchupState(record, context, coalescedCount, lastCoalescedCount);
16345
+ return record;
16346
+ }
16347
+ function validateRecurrence(record, context, everyMs, cron, timezone, overlapRetryMs) {
16348
+ if (record.kind === "interval") {
16349
+ if (everyMs == null || everyMs <= 0) {
16350
+ throw new TypeError(`${context} interval every_ms must be positive`);
16351
+ }
16352
+ } else if (everyMs != null) {
16353
+ throw new TypeError(`${context} every_ms is only valid for interval schedules`);
16354
+ }
16355
+ if (record.kind === "cron") {
16356
+ if (cron == null) throw new TypeError(`${context} cron schedule is missing cron`);
16357
+ if (timezone == null) throw new TypeError(`${context} cron schedule is missing timezone`);
16358
+ } else if (cron != null) {
16359
+ throw new TypeError(`${context} cron is only valid for cron schedules`);
16360
+ } else if (timezone != null) {
16361
+ throw new TypeError(`${context} timezone is only valid for cron schedules`);
16362
+ }
16363
+ if (record.kind !== "interval" && record.kind !== "cron" && record.overlap_policy !== "allow") {
16364
+ throw new TypeError(`${context} overlap_policy is only valid for recurring schedules`);
16365
+ }
16366
+ if (overlapRetryMs != null) {
16367
+ if (overlapRetryMs <= 0) {
16368
+ throw new TypeError(`${context} overlap_retry_ms must be positive`);
16369
+ }
16370
+ if (record.overlap_policy !== "queue_after_previous") {
16371
+ throw new TypeError(`${context} overlap_retry_ms requires queue_after_previous`);
16372
+ }
16373
+ }
16374
+ }
16375
+ function validateCatchupState(record, context, coalescedCount, lastCoalescedCount) {
16376
+ const lastCatchupAt = record.last_catchup_at_ms;
16377
+ if (record.kind !== "interval") {
16378
+ if (coalescedCount !== 0) {
16379
+ throw new TypeError(`${context} non-interval coalesced_count must be zero`);
16380
+ }
16381
+ if (lastCoalescedCount !== 0) {
16382
+ throw new TypeError(`${context} non-interval last_coalesced_count must be zero`);
16383
+ }
16384
+ if (lastCatchupAt != null) {
16385
+ throw new TypeError(`${context} non-interval last_catchup_at_ms must be null`);
16386
+ }
16387
+ return;
16388
+ }
16389
+ if (lastCoalescedCount > coalescedCount) {
16390
+ throw new TypeError(`${context} last_coalesced_count exceeds coalesced_count`);
16391
+ }
16392
+ if (lastCoalescedCount > 0 && lastCatchupAt == null) {
16393
+ throw new TypeError(`${context} response missing last_catchup_at_ms after catch-up`);
16394
+ }
16395
+ if (lastCoalescedCount === 0 && lastCatchupAt != null) {
16396
+ throw new TypeError(`${context} last_catchup_at_ms requires a catch-up`);
16397
+ }
16398
+ }
16399
+ function optionalScheduleRecord(value, context) {
16400
+ return value == null ? null : scheduleRecordResponse(value, context);
16401
+ }
16402
+ function scheduleRecordList(value, context) {
16403
+ return arrayResponse(value).map((item) => scheduleRecordResponse(item, context));
16404
+ }
16405
+ function scheduleFireDueResponse(value) {
16406
+ const context = "FLOW.SCHEDULE.FIRE_DUE";
16407
+ const record = adminRecordResponse(value, context);
16408
+ const claimed = safeNonNegativeInteger(record, "claimed", context, true);
16409
+ const fired = safeNonNegativeInteger(record, "fired", context, true);
16410
+ const skipped = safeNonNegativeInteger(record, "skipped", context, true);
16411
+ const coalesced = safeNonNegativeInteger(record, "coalesced", context, true);
16412
+ if (!Array.isArray(record.errors)) {
16413
+ throw new TypeError(`${context} response missing errors`);
16414
+ }
16415
+ for (const error of record.errors) {
16416
+ if (!Array.isArray(error) || error.length !== 2 || typeof error[0] !== "string" || error[0].length === 0 || typeof error[1] !== "string" || error[1].length === 0) {
16417
+ throw new TypeError(`${context} returned an invalid error entry`);
16418
+ }
15869
16419
  }
16420
+ if (fired + skipped + record.errors.length !== claimed) {
16421
+ throw new TypeError(`${context} outcomes do not equal claimed`);
16422
+ }
16423
+ optionalResponseText(record, "claim_error", context);
16424
+ const lastTargetId = optionalResponseText(record, "last_target_id", context);
16425
+ const lastSkipReason = optionalResponseText(record, "last_skip_reason", context);
16426
+ if (fired > 0 && lastTargetId == null) {
16427
+ throw new TypeError(`${context} response missing last_target_id`);
16428
+ }
16429
+ if (fired === 0 && lastTargetId != null) {
16430
+ throw new TypeError(`${context} last_target_id requires a fired outcome`);
16431
+ }
16432
+ if (skipped > 0 && lastSkipReason == null) {
16433
+ throw new TypeError(`${context} response missing last_skip_reason`);
16434
+ }
16435
+ if (skipped === 0 && lastSkipReason != null) {
16436
+ throw new TypeError(`${context} last_skip_reason requires a skipped outcome`);
16437
+ }
16438
+ if (coalesced > 0 && fired + skipped === 0) {
16439
+ throw new TypeError(`${context} coalesced count requires a fired or skipped outcome`);
16440
+ }
16441
+ return record;
16442
+ }
16443
+ function scheduleFireResponse(value) {
16444
+ const context = "FLOW.SCHEDULE.FIRE";
16445
+ const record = adminRecordResponse(value, context);
16446
+ const schedule = scheduleRecordResponse(record.schedule, `${context} schedule`);
16447
+ const fired = safeNonNegativeInteger(record, "fired", context, true);
16448
+ const skipped = record.skipped == null ? 0 : safeNonNegativeInteger(record, "skipped", context);
16449
+ if (fired > 1 || skipped > 1 || fired + skipped !== 1) {
16450
+ throw new TypeError(`${context} outcomes must equal one`);
16451
+ }
16452
+ if (fired === 1 && (typeof record.target_id !== "string" || record.target_id.length === 0)) {
16453
+ throw new TypeError(`${context} response missing target_id`);
16454
+ }
16455
+ if (skipped === 1 && (typeof record.reason !== "string" || record.reason.length === 0)) {
16456
+ throw new TypeError(`${context} response missing reason`);
16457
+ }
16458
+ if (fired === 0 && record.target_id != null) {
16459
+ throw new TypeError(`${context} target_id requires a fired outcome`);
16460
+ }
16461
+ if (skipped === 0 && record.reason != null) {
16462
+ throw new TypeError(`${context} reason requires a skipped outcome`);
16463
+ }
16464
+ return { ...record, fired, skipped, schedule };
16465
+ }
16466
+ function optionalResponseText(record, field3, context) {
16467
+ const value = record[field3];
16468
+ if (value == null) return void 0;
16469
+ if (typeof value !== "string" || value.length === 0) {
16470
+ throw new TypeError(`${context} ${field3} must be non-empty text`);
16471
+ }
16472
+ return value;
16473
+ }
16474
+ function requiredNullableResponseText(record, field3, context) {
16475
+ if (!(field3 in record)) throw new TypeError(`${context} response missing ${field3}`);
16476
+ if (record[field3] === void 0) {
16477
+ throw new TypeError(`${context} response missing ${field3}`);
16478
+ }
16479
+ return optionalResponseText(record, field3, context) ?? null;
16480
+ }
16481
+ function requiredNullableNonNegativeInteger(record, field3, context) {
16482
+ if (!(field3 in record)) throw new TypeError(`${context} response missing ${field3}`);
16483
+ if (record[field3] === void 0) {
16484
+ throw new TypeError(`${context} response missing ${field3}`);
16485
+ }
16486
+ if (record[field3] === null) return null;
16487
+ return safeNonNegativeInteger(record, field3, context);
16488
+ }
16489
+ function safeNonNegativeInteger(record, field3, context, required = false) {
16490
+ if (!(field3 in record) || record[field3] == null) {
16491
+ if (required) throw new TypeError(`${context} response missing ${field3}`);
16492
+ return 0;
16493
+ }
16494
+ const value = record[field3];
16495
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
16496
+ throw new TypeError(`${context} ${field3} must be a safe non-negative integer`);
16497
+ }
16498
+ return value;
16499
+ }
16500
+
16501
+ // src/client-schedules.ts
16502
+ var FerricStoreScheduleClient = class extends FerricStoreClientCore {
15870
16503
  async scheduleCreate(id, options) {
16504
+ validateScheduleCreate(id, options);
15871
16505
  const args = ["FLOW.SCHEDULE.CREATE", id];
15872
16506
  append(args, "KIND", options.kind);
15873
16507
  append(args, "AT_MS", options.atMs);
@@ -15877,6 +16511,7 @@ var FerricStoreManagementClient = class extends FerricStoreClientCore {
15877
16511
  append(args, "CRON", options.cron);
15878
16512
  append(args, "TIMEZONE", options.timezone);
15879
16513
  append(args, "TARGET", options.target);
16514
+ append(args, "CATCHUP_POLICY", options.catchupPolicy);
15880
16515
  append(args, "OVERLAP_POLICY", options.overlapPolicy);
15881
16516
  append(args, "OVERLAP_RETRY_MS", options.overlapRetryMs);
15882
16517
  append(args, "MAX_FIRES", options.maxFires);
@@ -15886,34 +16521,55 @@ var FerricStoreManagementClient = class extends FerricStoreClientCore {
15886
16521
  for (const [name, value] of Object.entries(options.extraOptions ?? {})) {
15887
16522
  args.push(name.toUpperCase(), value);
15888
16523
  }
15889
- return adminRecordResponse(await this.commandArgs(args), "FLOW.SCHEDULE.CREATE");
16524
+ return scheduleRecordResponse(await this.commandArgs(args), "FLOW.SCHEDULE.CREATE");
15890
16525
  }
15891
- async scheduleGet(id, options = {}) {
15892
- const args = ["FLOW.SCHEDULE.GET", id];
15893
- append(args, "NOW", options.nowMs);
15894
- return optionalAdminRecord(await this.commandArgs(args), "FLOW.SCHEDULE.GET");
16526
+ async scheduleGet(id) {
16527
+ validateScheduleID(id);
16528
+ return optionalScheduleRecord(
16529
+ await this.commandArgs(["FLOW.SCHEDULE.GET", id]),
16530
+ "FLOW.SCHEDULE.GET"
16531
+ );
15895
16532
  }
15896
16533
  async scheduleFire(id, options = {}) {
15897
- return await this.scheduleStatus("FLOW.SCHEDULE.FIRE", id, options.nowMs);
16534
+ validateScheduleFire(id, options);
16535
+ const args = ["FLOW.SCHEDULE.FIRE", id];
16536
+ append(args, "FIRE_AT_MS", options.fireAtMs);
16537
+ append(args, "NOW", options.nowMs);
16538
+ return scheduleFireResponse(await this.commandArgs(args));
15898
16539
  }
15899
16540
  async schedulePause(id, options = {}) {
15900
- return await this.scheduleStatus("FLOW.SCHEDULE.PAUSE", id, options.nowMs);
16541
+ validateScheduleStatus(id, options.nowMs);
16542
+ return scheduleRecordResponse(
16543
+ await this.scheduleStatusResponse("FLOW.SCHEDULE.PAUSE", id, options.nowMs),
16544
+ "FLOW.SCHEDULE.PAUSE"
16545
+ );
15901
16546
  }
15902
16547
  async scheduleResume(id, options = {}) {
15903
- return await this.scheduleStatus("FLOW.SCHEDULE.RESUME", id, options.nowMs);
16548
+ validateScheduleStatus(id, options.nowMs);
16549
+ return scheduleRecordResponse(
16550
+ await this.scheduleStatusResponse("FLOW.SCHEDULE.RESUME", id, options.nowMs),
16551
+ "FLOW.SCHEDULE.RESUME"
16552
+ );
15904
16553
  }
15905
16554
  async scheduleDelete(id, options = {}) {
15906
- return await this.scheduleStatus("FLOW.SCHEDULE.DELETE", id, options.nowMs);
16555
+ validateScheduleStatus(id, options.nowMs);
16556
+ const response = await this.scheduleStatusResponse("FLOW.SCHEDULE.DELETE", id, options.nowMs);
16557
+ if (!okLike(response)) {
16558
+ throw new TypeError("FLOW.SCHEDULE.DELETE response must be OK");
16559
+ }
15907
16560
  }
15908
16561
  async scheduleFireDue(options = {}) {
16562
+ validateScheduleFireDue(options);
15909
16563
  const args = ["FLOW.SCHEDULE.FIRE_DUE"];
15910
16564
  append(args, "NOW", options.nowMs);
15911
16565
  append(args, "WORKER", options.worker);
16566
+ append(args, "LEASE_MS", options.leaseMs);
15912
16567
  append(args, "BLOCK", options.blockMs);
15913
16568
  append(args, "LIMIT", options.limit);
15914
- return adminRecordResponse(await this.commandArgs(args), "FLOW.SCHEDULE.FIRE_DUE");
16569
+ return scheduleFireDueResponse(await this.commandArgs(args));
15915
16570
  }
15916
16571
  async scheduleList(options = {}) {
16572
+ validateScheduleList(options);
15917
16573
  const args = ["FLOW.SCHEDULE.LIST"];
15918
16574
  append(args, "KIND", options.kind);
15919
16575
  append(args, "STATE", options.state);
@@ -15923,14 +16579,40 @@ var FerricStoreManagementClient = class extends FerricStoreClientCore {
15923
16579
  append(args, "TO_MS", options.toMs);
15924
16580
  append(args, "COUNT", options.count);
15925
16581
  appendBool(args, "REV", options.rev);
15926
- return adminRecordList(await this.commandArgs(args), "FLOW.SCHEDULE.LIST");
16582
+ return scheduleRecordList(await this.commandArgs(args), "FLOW.SCHEDULE.LIST");
15927
16583
  }
15928
- async scheduleStatus(command, id, now) {
16584
+ async scheduleStatusResponse(command, id, now) {
15929
16585
  const args = [command, id];
15930
16586
  append(args, "NOW", now);
15931
- const response = await this.commandArgs(args);
15932
- if (okLike(response)) return { id, status: "deleted" };
15933
- return adminRecordResponse(response, command);
16587
+ return await this.commandArgs(args);
16588
+ }
16589
+ };
16590
+
16591
+ // src/client-management.ts
16592
+ var FerricStoreManagementClient = class extends FerricStoreScheduleClient {
16593
+ async stats(type, options = {}) {
16594
+ const args = ["FLOW.STATS", type];
16595
+ append(args, "STATE", options.state);
16596
+ append(args, "COUNT", options.count);
16597
+ append(args, "PARTITION", options.partitionKey);
16598
+ appendAttributes(args, options.attributes);
16599
+ appendBool(args, "CONSISTENT_PROJECTION", options.consistentProjection);
16600
+ return adminRecordResponse(await this.commandArgs(args), "FLOW.STATS");
16601
+ }
16602
+ async countByState(type, state, options = {}) {
16603
+ const stats = await this.stats(type, { ...options, state });
16604
+ if (!("count" in stats)) throw new TypeError("FLOW.STATS response missing count");
16605
+ return integer(stats.count);
16606
+ }
16607
+ async attributes(type, options = {}) {
16608
+ const args = ["FLOW.ATTRIBUTES", type];
16609
+ appendAttributeQueryOptions(args, options);
16610
+ return adminRecordList(await this.commandArgs(args), "FLOW.ATTRIBUTES");
16611
+ }
16612
+ async attributeValues(type, attribute, options = {}) {
16613
+ const args = ["FLOW.ATTRIBUTE_VALUES", type, attribute];
16614
+ appendAttributeQueryOptions(args, options);
16615
+ return adminRecordList(await this.commandArgs(args), "FLOW.ATTRIBUTE_VALUES");
15934
16616
  }
15935
16617
  async effectReserve(id, effectKey, effectType, options) {
15936
16618
  const args = [
@@ -16268,15 +16950,15 @@ function assertFlowPolicyGeneration(value) {
16268
16950
  function flowPolicySnapshotFromResp(value) {
16269
16951
  const policy = requiredRecord(value, "FLOW policy snapshot");
16270
16952
  const maxActiveMs = optionalPositiveInteger(field(policy, "max_active_ms"), "max_active_ms");
16271
- const state = optionalText3(field(policy, "state"), "state");
16953
+ const state = optionalText4(field(policy, "state"), "state");
16272
16954
  const mode = optionalMode(field(policy, "mode"), "mode");
16273
16955
  const version = optionalVersion(field(policy, "version"));
16274
- const indexedStateMeta = optionalText3(field(policy, "indexed_state_meta"), "indexed_state_meta");
16956
+ const indexedStateMeta = optionalText4(field(policy, "indexed_state_meta"), "indexed_state_meta");
16275
16957
  const governance = optionalRecord(field(policy, "governance"), "governance");
16276
16958
  const states = optionalStates(field(policy, "states"));
16277
16959
  return {
16278
- type: requiredText3(field(policy, "type"), "type"),
16279
- generation: nonNegativeInteger2(field(policy, "generation"), "generation"),
16960
+ type: requiredText4(field(policy, "type"), "type"),
16961
+ generation: nonNegativeInteger3(field(policy, "generation"), "generation"),
16280
16962
  ...state == null ? {} : { state },
16281
16963
  ...version == null ? {} : { version },
16282
16964
  ...mode == null ? {} : { mode },
@@ -16294,21 +16976,21 @@ function retrySnapshot(value, context) {
16294
16976
  const retry2 = requiredRecord(value, `FLOW policy ${context}`);
16295
16977
  const backoff = requiredRecord(field(retry2, "backoff"), `FLOW policy ${context}.backoff`);
16296
16978
  return {
16297
- maxRetries: nonNegativeInteger2(field(retry2, "max_retries"), `${context}.max_retries`),
16979
+ maxRetries: nonNegativeInteger3(field(retry2, "max_retries"), `${context}.max_retries`),
16298
16980
  backoff: {
16299
16981
  kind: backoffKind(field(backoff, "kind"), `${context}.backoff.kind`),
16300
- baseMs: nonNegativeInteger2(field(backoff, "base_ms"), `${context}.backoff.base_ms`),
16301
- maxMs: nonNegativeInteger2(field(backoff, "max_ms"), `${context}.backoff.max_ms`),
16302
- jitterPct: nonNegativeInteger2(field(backoff, "jitter_pct"), `${context}.backoff.jitter_pct`)
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`)
16303
16985
  },
16304
- exhaustedTo: requiredText3(field(retry2, "exhausted_to"), `${context}.exhausted_to`)
16986
+ exhaustedTo: requiredText4(field(retry2, "exhausted_to"), `${context}.exhausted_to`)
16305
16987
  };
16306
16988
  }
16307
16989
  function retentionSnapshot(value, context) {
16308
16990
  const retention = requiredRecord(value, `FLOW policy ${context}`);
16309
16991
  return {
16310
- ttlMs: nonNegativeInteger2(field(retention, "ttl_ms"), `${context}.ttl_ms`),
16311
- historyMaxEvents: nonNegativeInteger2(
16992
+ ttlMs: nonNegativeInteger3(field(retention, "ttl_ms"), `${context}.ttl_ms`),
16993
+ historyMaxEvents: nonNegativeInteger3(
16312
16994
  field(retention, "history_max_events"),
16313
16995
  `${context}.history_max_events`
16314
16996
  )
@@ -16344,7 +17026,7 @@ function requiredRecord(value, context) {
16344
17026
  if (value instanceof Map) {
16345
17027
  const result = {};
16346
17028
  for (const [key, item] of value.entries()) {
16347
- setOwnValue(result, requiredText3(key, `${context} key`), item);
17029
+ setOwnValue(result, requiredText4(key, `${context} key`), item);
16348
17030
  }
16349
17031
  return result;
16350
17032
  }
@@ -16363,21 +17045,21 @@ function stringArray(value, context) {
16363
17045
  if (!Object.hasOwn(value, index)) {
16364
17046
  throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
16365
17047
  }
16366
- result[index] = requiredText3(value[index], `${context}[${index}]`);
17048
+ result[index] = requiredText4(value[index], `${context}[${index}]`);
16367
17049
  }
16368
17050
  return result;
16369
17051
  }
16370
- function requiredText3(value, context) {
17052
+ function requiredText4(value, context) {
16371
17053
  if (typeof value === "string") return value;
16372
17054
  if (import_node_buffer54.Buffer.isBuffer(value) || value instanceof Uint8Array) {
16373
17055
  return import_node_buffer54.Buffer.from(value).toString("utf8");
16374
17056
  }
16375
17057
  throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
16376
17058
  }
16377
- function optionalText3(value, context) {
16378
- return value == null ? void 0 : requiredText3(value, context);
17059
+ function optionalText4(value, context) {
17060
+ return value == null ? void 0 : requiredText4(value, context);
16379
17061
  }
16380
- function nonNegativeInteger2(value, context) {
17062
+ function nonNegativeInteger3(value, context) {
16381
17063
  let parsed;
16382
17064
  try {
16383
17065
  parsed = integer(value);
@@ -16389,26 +17071,26 @@ function nonNegativeInteger2(value, context) {
16389
17071
  }
16390
17072
  function optionalPositiveInteger(value, context) {
16391
17073
  if (value == null) return void 0;
16392
- const parsed = nonNegativeInteger2(value, context);
17074
+ const parsed = nonNegativeInteger3(value, context);
16393
17075
  if (parsed === 0) throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
16394
17076
  return parsed;
16395
17077
  }
16396
17078
  function optionalVersion(value) {
16397
17079
  if (value == null) return void 0;
16398
17080
  if (typeof value === "number" || typeof value === "bigint") {
16399
- return nonNegativeInteger2(value, "version");
17081
+ return nonNegativeInteger3(value, "version");
16400
17082
  }
16401
- return requiredText3(value, "version");
17083
+ return requiredText4(value, "version");
16402
17084
  }
16403
17085
  function backoffKind(value, context) {
16404
- const kind = requiredText3(value, context).toLowerCase();
17086
+ const kind = requiredText4(value, context).toLowerCase();
16405
17087
  if (kind === "none" || kind === "fixed" || kind === "linear" || kind === "exponential") {
16406
17088
  return kind;
16407
17089
  }
16408
17090
  throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
16409
17091
  }
16410
17092
  function requiredMode(value, context) {
16411
- const mode = requiredText3(value, context).toLowerCase();
17093
+ const mode = requiredText4(value, context).toLowerCase();
16412
17094
  if (mode === "fifo" || mode === "parallel") return mode;
16413
17095
  throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
16414
17096
  }
@@ -17940,7 +18622,7 @@ var LeaseRenewalGuard = class {
17940
18622
  if (options.leaseRenewal === false) {
17941
18623
  return;
17942
18624
  }
17943
- const intervalMs = positiveInteger2(options.leaseRenewIntervalMs, Math.max(1, Math.trunc(leaseMs / 2)));
18625
+ const intervalMs = positiveInteger3(options.leaseRenewIntervalMs, Math.max(1, Math.trunc(leaseMs / 2)));
17944
18626
  this.timer = setLongInterval(() => this.renew(), intervalMs);
17945
18627
  this.timer.unref();
17946
18628
  }
@@ -18012,7 +18694,7 @@ function snapshotLeasedJob(job) {
18012
18694
  return snapshot;
18013
18695
  }
18014
18696
  function workerConcurrency(options) {
18015
- return positiveInteger2(options.concurrency ?? options.workers, 1);
18697
+ return positiveInteger3(options.concurrency ?? options.workers, 1);
18016
18698
  }
18017
18699
  function workerRefillStrategy(options) {
18018
18700
  return options.refillStrategy === "wave" ? "wave" : "continuous";
@@ -18055,18 +18737,18 @@ function workerErrorPayload(error, options, codec) {
18055
18737
  }
18056
18738
  function workerBatchSize(options, flowManyBatchLimit = DEFAULT_FLOW_MANY_BATCH_LIMIT2) {
18057
18739
  return Math.min(
18058
- positiveInteger2(options.batchSize, 10),
18059
- positiveInteger2(flowManyBatchLimit, DEFAULT_FLOW_MANY_BATCH_LIMIT2)
18740
+ positiveInteger3(options.batchSize, 10),
18741
+ positiveInteger3(flowManyBatchLimit, DEFAULT_FLOW_MANY_BATCH_LIMIT2)
18060
18742
  );
18061
18743
  }
18062
18744
  function workerClaimLimit(options, flowManyBatchLimit = DEFAULT_FLOW_MANY_BATCH_LIMIT2) {
18063
18745
  return Math.min(workerBatchSize(options, flowManyBatchLimit), workerConcurrency(options));
18064
18746
  }
18065
18747
  function workerDrainBatches(options) {
18066
- return positiveInteger2(options.claimDrainBatches, 1);
18748
+ return positiveInteger3(options.claimDrainBatches, 1);
18067
18749
  }
18068
18750
  function workerLeaseMs(options, fallback = 3e4) {
18069
- return positiveInteger2(options.leaseMs, positiveInteger2(fallback, 3e4));
18751
+ return positiveInteger3(options.leaseMs, positiveInteger3(fallback, 3e4));
18070
18752
  }
18071
18753
  function workerIdleSleepMs(options) {
18072
18754
  return nonNegativeDuration(options.idleSleepMs, 250);
@@ -18078,7 +18760,7 @@ function workerClaimBlockMs(options, useBlocking) {
18078
18760
  if (options.signal == null || !Number.isFinite(options.blockMs) || options.blockMs < 0) {
18079
18761
  return options.blockMs;
18080
18762
  }
18081
- const abortPollMs = positiveInteger2(options.abortPollMs, 1e3);
18763
+ const abortPollMs = positiveInteger3(options.abortPollMs, 1e3);
18082
18764
  return options.blockMs === 0 ? abortPollMs : Math.min(Math.trunc(options.blockMs), abortPollMs);
18083
18765
  }
18084
18766
  function workerMaxIdleSleepMs(options, idleSleepMs = workerIdleSleepMs(options)) {
@@ -18089,14 +18771,14 @@ function nextWorkerIdleSleepMs(currentIdleSleepMs, maxIdleSleepMs) {
18089
18771
  return Math.min(maxIdleSleepMs, Math.max(1, currentIdleSleepMs * 2));
18090
18772
  }
18091
18773
  async function runContinuousWorkerPool(options) {
18092
- const concurrency = positiveInteger2(options.concurrency, 1);
18093
- const maxClaimSize = positiveInteger2(options.maxClaimSize, concurrency);
18774
+ const concurrency = positiveInteger3(options.concurrency, 1);
18775
+ const maxClaimSize = positiveInteger3(options.maxClaimSize, concurrency);
18094
18776
  const initialIdleSleepMs = nonNegativeDuration(options.idleSleepMs, 250);
18095
18777
  const maxIdleSleepMs = Math.max(
18096
18778
  initialIdleSleepMs,
18097
18779
  nonNegativeDuration(options.maxIdleSleepMs, 5e3)
18098
18780
  );
18099
- const refillDelayMs = nonNegativeInteger3(options.refillDelayMs, 0);
18781
+ const refillDelayMs = nonNegativeInteger4(options.refillDelayMs, 0);
18100
18782
  const active = /* @__PURE__ */ new Set();
18101
18783
  const pending = [];
18102
18784
  let pendingIndex = 0;
@@ -18212,10 +18894,10 @@ function normalizeWorkflowWorkerConfig(options) {
18212
18894
  ...captured
18213
18895
  });
18214
18896
  }
18215
- function positiveInteger2(value, fallback) {
18897
+ function positiveInteger3(value, fallback) {
18216
18898
  return value == null || !Number.isFinite(value) ? fallback : Math.max(1, Math.trunc(value));
18217
18899
  }
18218
- function nonNegativeInteger3(value, fallback) {
18900
+ function nonNegativeInteger4(value, fallback) {
18219
18901
  return value == null || !Number.isFinite(value) ? fallback : Math.max(0, Math.trunc(value));
18220
18902
  }
18221
18903
  function nonNegativeDuration(value, fallback) {
@@ -19099,13 +19781,13 @@ var QueueWorker = class {
19099
19781
 
19100
19782
  // src/flow-client-options.ts
19101
19783
  function snapshotFlowClientOptions(options, context) {
19102
- const own = { ...options };
19103
- if (typeof own.type !== "string" || own.type.length === 0) {
19784
+ const own2 = { ...options };
19785
+ if (typeof own2.type !== "string" || own2.type.length === 0) {
19104
19786
  throw new TypeError(`${context} type must be an own non-empty string`);
19105
19787
  }
19106
- const valueConfig = own.valueConfig;
19788
+ const valueConfig = own2.valueConfig;
19107
19789
  return Object.freeze({
19108
- ...own,
19790
+ ...own2,
19109
19791
  ...valueConfig == null ? {} : { valueConfig: Object.freeze({ ...valueConfig }) }
19110
19792
  });
19111
19793
  }
@@ -19528,19 +20210,19 @@ async function applyFail(client, ctx, outcome, returnRecord) {
19528
20210
 
19529
20211
  // src/workflow-registration.ts
19530
20212
  function createWorkflowStateRegistration(name, handler, options, defaultValueMaxBytes) {
19531
- const own = { ...options };
19532
- const claimValues = own.claimValues == null ? void 0 : snapshotOwnStringArray(own.claimValues, "claimValues");
19533
- const retryPolicy = own.retryPolicy == null ? void 0 : Object.freeze({ ...own.retryPolicy });
20213
+ const own2 = { ...options };
20214
+ const claimValues = own2.claimValues == null ? void 0 : snapshotOwnStringArray(own2.claimValues, "claimValues");
20215
+ const retryPolicy = own2.retryPolicy == null ? void 0 : Object.freeze({ ...own2.retryPolicy });
19534
20216
  return Object.freeze({
19535
- claimPayload: own.claimPayload ?? true,
19536
- claimRecord: own.claimRecord ?? true,
19537
- exceptionPolicy: normalizeExceptionPolicy(own.exceptionPolicy),
20217
+ claimPayload: own2.claimPayload ?? true,
20218
+ claimRecord: own2.claimRecord ?? true,
20219
+ exceptionPolicy: normalizeExceptionPolicy(own2.exceptionPolicy),
19538
20220
  handler,
19539
- leaseMs: own.leaseMs ?? 3e4,
19540
- ...own.mode == null ? {} : { mode: normalizeStateMode(own.mode) },
20221
+ leaseMs: own2.leaseMs ?? 3e4,
20222
+ ...own2.mode == null ? {} : { mode: normalizeStateMode(own2.mode) },
19541
20223
  name,
19542
- returnRecord: own.returnRecord ?? false,
19543
- valueMaxBytes: own.valueMaxBytes ?? defaultValueMaxBytes,
20224
+ returnRecord: own2.returnRecord ?? false,
20225
+ valueMaxBytes: own2.valueMaxBytes ?? defaultValueMaxBytes,
19544
20226
  ...claimValues == null ? {} : { claimValues },
19545
20227
  ...retryPolicy == null ? {} : { retryPolicy }
19546
20228
  });
@@ -19844,8 +20526,8 @@ var WorkflowWorker = class {
19844
20526
  };
19845
20527
 
19846
20528
  // src/version.ts
19847
- var FERRICSTORE_SDK_VERSION = "0.5.2";
19848
- var FERRICSTORE_MINIMUM_SERVER_VERSION = "0.11.0";
20529
+ var FERRICSTORE_SDK_VERSION = "0.11.5";
20530
+ var FERRICSTORE_MINIMUM_SERVER_VERSION = "0.11.4";
19849
20531
  var FERRICSTORE_NATIVE_PROTOCOL_VERSION = 1;
19850
20532
  // Annotate the CommonJS export names for ESM import in node:
19851
20533
  0 && (module.exports = {