@ferricstore/ferricstore 0.5.2 → 0.11.4

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 +44 -5
  2. package/dist/index.cjs +825 -298
  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 +825 -298
  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 +34 -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.js CHANGED
@@ -3090,6 +3090,7 @@ var FLOW_ADMIN_FIELDS = {
3090
3090
  AT_MS: "at_ms",
3091
3091
  BLOCK: "block_ms",
3092
3092
  BLOCK_MS: "block_ms",
3093
+ CATCHUP_POLICY: "catchup_policy",
3093
3094
  CONSISTENT_PROJECTION: "consistent_projection",
3094
3095
  CORRELATION_ID: "correlation_id",
3095
3096
  COUNT: "count",
@@ -5523,15 +5524,15 @@ function requiredMap(value, context) {
5523
5524
  }
5524
5525
  throw incompatibleServer(`${context} is missing or invalid`);
5525
5526
  }
5526
- function requiredBoundedText(mapping, name) {
5527
- const value = strictText(field(mapping, name));
5527
+ function requiredBoundedText(mapping2, name) {
5528
+ const value = strictText(field(mapping2, name));
5528
5529
  if (value == null || value.length === 0 || Buffer20.byteLength(value) > 256) {
5529
5530
  throw incompatibleServer(`HELLO flow_query ${name} must be bounded non-empty text`);
5530
5531
  }
5531
5532
  return value;
5532
5533
  }
5533
- function boundedTextSet(mapping, name, maximum) {
5534
- const raw = field(mapping, name);
5534
+ function boundedTextSet(mapping2, name, maximum) {
5535
+ const raw = field(mapping2, name);
5535
5536
  if (!Array.isArray(raw) || raw.length < 1 || raw.length > maximum) {
5536
5537
  throw incompatibleServer(`HELLO ${name} must contain 1..${maximum} entries`);
5537
5538
  }
@@ -6854,15 +6855,15 @@ function snapshotOwnStringArray(values, name) {
6854
6855
 
6855
6856
  // src/client-native-options.ts
6856
6857
  function snapshotNativeClientOptions(options) {
6857
- const own = { ...options };
6858
+ const own2 = { ...options };
6858
6859
  const snapshot = {
6859
- ...own,
6860
- ...typeof own.autoReconnect === "object" && own.autoReconnect != null ? { autoReconnect: Object.freeze({ ...own.autoReconnect }) } : {},
6861
- ...own.endpointPolicy == null ? {} : { endpointPolicy: snapshotEndpointPolicy(own.endpointPolicy) },
6862
- ...own.events == null ? {} : { events: snapshotOwnStringArray(own.events, "events") },
6863
- ...own.seeds == null ? {} : { seeds: snapshotOwnStringArray(own.seeds, "seeds") },
6864
- ...own.tlsOptions == null ? {} : { tlsOptions: snapshotTlsOptions(own.tlsOptions) },
6865
- ...own.trustedHosts == null ? {} : { trustedHosts: snapshotOwnStringArray(own.trustedHosts, "trustedHosts") }
6860
+ ...own2,
6861
+ ...typeof own2.autoReconnect === "object" && own2.autoReconnect != null ? { autoReconnect: Object.freeze({ ...own2.autoReconnect }) } : {},
6862
+ ...own2.endpointPolicy == null ? {} : { endpointPolicy: snapshotEndpointPolicy(own2.endpointPolicy) },
6863
+ ...own2.events == null ? {} : { events: snapshotOwnStringArray(own2.events, "events") },
6864
+ ...own2.seeds == null ? {} : { seeds: snapshotOwnStringArray(own2.seeds, "seeds") },
6865
+ ...own2.tlsOptions == null ? {} : { tlsOptions: snapshotTlsOptions(own2.tlsOptions) },
6866
+ ...own2.trustedHosts == null ? {} : { trustedHosts: snapshotOwnStringArray(own2.trustedHosts, "trustedHosts") }
6866
6867
  };
6867
6868
  return Object.freeze(snapshot);
6868
6869
  }
@@ -6903,12 +6904,12 @@ function topologyNativeOptions(options) {
6903
6904
  }
6904
6905
  function snapshotEndpointPolicy(policy) {
6905
6906
  if (typeof policy !== "object") return policy;
6906
- const own = { ...policy };
6907
- if (!Object.hasOwn(own, "allowHosts") || !Array.isArray(own.allowHosts)) {
6907
+ const own2 = { ...policy };
6908
+ if (!Object.hasOwn(own2, "allowHosts") || !Array.isArray(own2.allowHosts)) {
6908
6909
  throw new TypeError("endpointPolicy.allowHosts must be an own array of strings");
6909
6910
  }
6910
6911
  return Object.freeze({
6911
- allowHosts: snapshotOwnStringArray(own.allowHosts, "endpointPolicy.allowHosts")
6912
+ allowHosts: snapshotOwnStringArray(own2.allowHosts, "endpointPolicy.allowHosts")
6912
6913
  });
6913
6914
  }
6914
6915
  function snapshotTlsOptions(options) {
@@ -11988,36 +11989,36 @@ function isPlainObject6(value) {
11988
11989
  const prototype = Object.getPrototypeOf(value);
11989
11990
  return prototype === Object.prototype || prototype === null;
11990
11991
  }
11991
- function requireContract(mapping, name, expected, context) {
11992
- const actual = requiredText2(mapping, name, context);
11992
+ function requireContract(mapping2, name, expected, context) {
11993
+ const actual = requiredText2(mapping2, name, context);
11993
11994
  if (actual !== expected) {
11994
11995
  throw decodeError(
11995
11996
  `${context} has unsupported contract ${JSON.stringify(actual)}`,
11996
- mapping
11997
+ mapping2
11997
11998
  );
11998
11999
  }
11999
12000
  }
12000
- function requiredText2(mapping, name, context) {
12001
- const value = strictText2(field(mapping, name));
12001
+ function requiredText2(mapping2, name, context) {
12002
+ const value = strictText2(field(mapping2, name));
12002
12003
  if (value == null || value.length === 0) {
12003
- throw decodeError(`${context} ${name} must be non-empty text`, mapping);
12004
+ throw decodeError(`${context} ${name} must be non-empty text`, mapping2);
12004
12005
  }
12005
12006
  return value;
12006
12007
  }
12007
- function optionalText2(mapping, name, context) {
12008
- const raw = field(mapping, name);
12008
+ function optionalText2(mapping2, name, context) {
12009
+ const raw = field(mapping2, name);
12009
12010
  if (raw == null) return void 0;
12010
12011
  const value = strictText2(raw);
12011
12012
  if (value == null)
12012
- throw decodeError(`${context} ${name} must be text`, mapping);
12013
+ throw decodeError(`${context} ${name} must be text`, mapping2);
12013
12014
  return value;
12014
12015
  }
12015
- function requiredBoundedText2(mapping, name, context, maximumBytes) {
12016
- const value = requiredText2(mapping, name, context);
12016
+ function requiredBoundedText2(mapping2, name, context, maximumBytes) {
12017
+ const value = requiredText2(mapping2, name, context);
12017
12018
  if (Buffer45.byteLength(value, "utf8") > maximumBytes) {
12018
12019
  throw decodeError(
12019
12020
  `${context} ${name} exceeds ${maximumBytes} bytes`,
12020
- mapping
12021
+ mapping2
12021
12022
  );
12022
12023
  }
12023
12024
  return value;
@@ -12032,10 +12033,10 @@ function boundedText(value, context, maximumBytes) {
12032
12033
  }
12033
12034
  return decoded;
12034
12035
  }
12035
- function requiredBoolean(mapping, name, context) {
12036
- const value = field(mapping, name);
12036
+ function requiredBoolean(mapping2, name, context) {
12037
+ const value = field(mapping2, name);
12037
12038
  if (typeof value !== "boolean") {
12038
- throw decodeError(`${context} ${name} must be boolean`, mapping);
12039
+ throw decodeError(`${context} ${name} must be boolean`, mapping2);
12039
12040
  }
12040
12041
  return value;
12041
12042
  }
@@ -12078,11 +12079,11 @@ function positiveBoundedInteger(value, maximum, context) {
12078
12079
  if (parsed === 0) throw decodeError(`${context} must be positive`, value);
12079
12080
  return parsed;
12080
12081
  }
12081
- function hasKey(mapping, name) {
12082
- if (!(mapping instanceof Map)) return Object.hasOwn(mapping, name);
12083
- if (mapping.has(name)) return true;
12082
+ function hasKey(mapping2, name) {
12083
+ if (!(mapping2 instanceof Map)) return Object.hasOwn(mapping2, name);
12084
+ if (mapping2.has(name)) return true;
12084
12085
  const binaryName = Buffer45.from(name);
12085
- for (const key of mapping.keys()) {
12086
+ for (const key of mapping2.keys()) {
12086
12087
  if (Buffer45.isBuffer(key) && key.equals(binaryName)) return true;
12087
12088
  if (key instanceof Uint8Array && Buffer45.from(key).equals(binaryName))
12088
12089
  return true;
@@ -12139,28 +12140,28 @@ var DIAGNOSTIC_CONTEXT_DEPTH = 6;
12139
12140
  var DIAGNOSTIC_CONTEXT_NODES = 512;
12140
12141
  function tryDecodeFlowQueryError(value, cause) {
12141
12142
  try {
12142
- const mapping = requiredMap2(value, "FLOW.QUERY diagnostic");
12143
- const context = decodeDiagnosticContext(field(mapping, "context"));
12144
- const position = decodePosition(field(mapping, "position"));
12143
+ const mapping2 = requiredMap2(value, "FLOW.QUERY diagnostic");
12144
+ const context = decodeDiagnosticContext(field(mapping2, "context"));
12145
+ const position = decodePosition(field(mapping2, "position"));
12145
12146
  return new FlowQueryError({
12146
12147
  code: requiredBoundedText2(
12147
- mapping,
12148
+ mapping2,
12148
12149
  "code",
12149
12150
  "FLOW.QUERY diagnostic",
12150
12151
  DIAGNOSTIC_TEXT_BYTES
12151
12152
  ),
12152
12153
  message: requiredBoundedText2(
12153
- mapping,
12154
+ mapping2,
12154
12155
  "message",
12155
12156
  "FLOW.QUERY diagnostic",
12156
12157
  DIAGNOSTIC_TEXT_BYTES
12157
12158
  ),
12158
- detail: optionalDiagnosticText(mapping, "detail"),
12159
- hint: optionalDiagnosticText(mapping, "hint"),
12160
- retryable: requiredBoolean(mapping, "retryable", "FLOW.QUERY diagnostic"),
12161
- safeToRetry: requiredBoolean(mapping, "safe_to_retry", "FLOW.QUERY diagnostic"),
12159
+ detail: optionalDiagnosticText(mapping2, "detail"),
12160
+ hint: optionalDiagnosticText(mapping2, "hint"),
12161
+ retryable: requiredBoolean(mapping2, "retryable", "FLOW.QUERY diagnostic"),
12162
+ safeToRetry: requiredBoolean(mapping2, "safe_to_retry", "FLOW.QUERY diagnostic"),
12162
12163
  retryAfterMs: nonNegativeInteger(
12163
- field(mapping, "retry_after_ms"),
12164
+ field(mapping2, "retry_after_ms"),
12164
12165
  "FLOW.QUERY diagnostic retry_after_ms"
12165
12166
  ),
12166
12167
  position,
@@ -12173,29 +12174,29 @@ function tryDecodeFlowQueryError(value, cause) {
12173
12174
  throw error;
12174
12175
  }
12175
12176
  }
12176
- function optionalDiagnosticText(mapping, name) {
12177
- const value = optionalText2(mapping, name, "FLOW.QUERY diagnostic");
12177
+ function optionalDiagnosticText(mapping2, name) {
12178
+ const value = optionalText2(mapping2, name, "FLOW.QUERY diagnostic");
12178
12179
  if (value != null && Buffer46.byteLength(value, "utf8") > DIAGNOSTIC_TEXT_BYTES) {
12179
12180
  throw decodeError(
12180
12181
  `FLOW.QUERY diagnostic ${name} exceeds ${DIAGNOSTIC_TEXT_BYTES} bytes`,
12181
- mapping
12182
+ mapping2
12182
12183
  );
12183
12184
  }
12184
12185
  return value;
12185
12186
  }
12186
12187
  function decodeDiagnosticContext(value) {
12187
12188
  if (value == null) return void 0;
12188
- const mapping = requiredMap2(value, "FLOW.QUERY diagnostic context");
12189
- const size = mapping instanceof Map ? mapping.size : Object.keys(mapping).length;
12189
+ const mapping2 = requiredMap2(value, "FLOW.QUERY diagnostic context");
12190
+ const size = mapping2 instanceof Map ? mapping2.size : Object.keys(mapping2).length;
12190
12191
  if (size > DIAGNOSTIC_CONTEXT_ENTRIES) {
12191
12192
  throw decodeError("FLOW.QUERY diagnostic context contains too many entries", value);
12192
12193
  }
12193
12194
  validateDiagnosticContextValue(
12194
- mapping,
12195
+ mapping2,
12195
12196
  DIAGNOSTIC_CONTEXT_DEPTH,
12196
12197
  { remaining: DIAGNOSTIC_CONTEXT_NODES }
12197
12198
  );
12198
- return freezeMetadataMap(mapping, "FLOW.QUERY diagnostic context");
12199
+ return freezeMetadataMap(mapping2, "FLOW.QUERY diagnostic context");
12199
12200
  }
12200
12201
  function validateDiagnosticContextValue(value, depth, budget) {
12201
12202
  consumeDiagnosticContextNode(value, budget);
@@ -12267,12 +12268,12 @@ function isDiagnosticContextRecord(value) {
12267
12268
  }
12268
12269
  function decodePosition(value) {
12269
12270
  if (value == null) return void 0;
12270
- const mapping = requiredMap2(value, "FLOW.QUERY diagnostic position");
12271
+ const mapping2 = requiredMap2(value, "FLOW.QUERY diagnostic position");
12271
12272
  return Object.freeze({
12272
- byte: positiveInteger(field(mapping, "byte"), "FLOW.QUERY diagnostic position byte"),
12273
- line: positiveInteger(field(mapping, "line"), "FLOW.QUERY diagnostic position line"),
12273
+ byte: positiveInteger(field(mapping2, "byte"), "FLOW.QUERY diagnostic position byte"),
12274
+ line: positiveInteger(field(mapping2, "line"), "FLOW.QUERY diagnostic position line"),
12274
12275
  column: positiveInteger(
12275
- field(mapping, "column"),
12276
+ field(mapping2, "column"),
12276
12277
  "FLOW.QUERY diagnostic position column"
12277
12278
  )
12278
12279
  });
@@ -12572,25 +12573,25 @@ function decodeUniqueTextArray(value, context, maximum, maximumBytes) {
12572
12573
  }
12573
12574
  return Object.freeze(result);
12574
12575
  }
12575
- function requiredChoice(mapping, name, context, choices) {
12576
- const value = requiredBoundedText2(mapping, name, context, 64);
12576
+ function requiredChoice(mapping2, name, context, choices) {
12577
+ const value = requiredBoundedText2(mapping2, name, context, 64);
12577
12578
  if (!choices.includes(value)) {
12578
- throw decodeError(`${context} ${name} is unsupported`, mapping);
12579
+ throw decodeError(`${context} ${name} is unsupported`, mapping2);
12579
12580
  }
12580
12581
  return value;
12581
12582
  }
12582
- function optionalBoundedText(mapping, name, context, maximumBytes) {
12583
- const value = field(mapping, name);
12583
+ function optionalBoundedText(mapping2, name, context, maximumBytes) {
12584
+ const value = field(mapping2, name);
12584
12585
  if (value == null) return void 0;
12585
12586
  return boundedText(value, `${context} ${name}`, maximumBytes);
12586
12587
  }
12587
- function optionalIndexInteger(mapping, name, context) {
12588
- const value = field(mapping, name);
12588
+ function optionalIndexInteger(mapping2, name, context) {
12589
+ const value = field(mapping2, name);
12589
12590
  return value == null ? void 0 : unsignedIndexInteger(value, `${context} ${name}`);
12590
12591
  }
12591
- function indexCounter(mapping, name, section) {
12592
+ function indexCounter(mapping2, name, section) {
12592
12593
  return unsignedIndexInteger(
12593
- field(mapping, name),
12594
+ field(mapping2, name),
12594
12595
  `FLOW.QUERY.INDEXES index ${section} ${name}`
12595
12596
  );
12596
12597
  }
@@ -12607,13 +12608,13 @@ function indexInteger2(value) {
12607
12608
  // src/flow-query-index-lifecycle-response.ts
12608
12609
  function decodeIndexCoverage(value) {
12609
12610
  const context = "FLOW.QUERY.INDEXES index coverage";
12610
- const mapping = requiredMap2(value, context);
12611
+ const mapping2 = requiredMap2(value, context);
12611
12612
  const completeShards = unsignedIndexInteger(
12612
- field(mapping, "complete_shards"),
12613
+ field(mapping2, "complete_shards"),
12613
12614
  `${context} complete_shards`
12614
12615
  );
12615
12616
  const totalShards = positiveIndexInteger(
12616
- field(mapping, "total_shards"),
12617
+ field(mapping2, "total_shards"),
12617
12618
  `${context} total_shards`
12618
12619
  );
12619
12620
  if (indexInteger2(completeShards) > indexInteger2(totalShards)) {
@@ -12622,60 +12623,60 @@ function decodeIndexCoverage(value) {
12622
12623
  return Object.freeze({
12623
12624
  completeShards,
12624
12625
  totalShards,
12625
- validation: requiredChoice(mapping, "validation", context, [
12626
+ validation: requiredChoice(mapping2, "validation", context, [
12626
12627
  "pending",
12627
12628
  "passed",
12628
12629
  "failed"
12629
12630
  ]),
12630
- raw: freezeMap(mapping)
12631
+ raw: freezeMap(mapping2)
12631
12632
  });
12632
12633
  }
12633
12634
  function decodeIndexBuild(value) {
12634
- const mapping = requiredMap2(value, "FLOW.QUERY.INDEXES index build");
12635
+ const mapping2 = requiredMap2(value, "FLOW.QUERY.INDEXES index build");
12635
12636
  const progress = decodeIndexProgress(
12636
- mapping,
12637
+ mapping2,
12637
12638
  "build",
12638
12639
  FLOW_QUERY_BUILD_PHASES
12639
12640
  );
12640
12641
  return Object.freeze({
12641
12642
  ...progress,
12642
- scannedRecords: indexCounter(mapping, "scanned_records", "build"),
12643
- writtenEntries: indexCounter(mapping, "written_entries", "build"),
12644
- writtenBytes: indexCounter(mapping, "written_bytes", "build")
12643
+ scannedRecords: indexCounter(mapping2, "scanned_records", "build"),
12644
+ writtenEntries: indexCounter(mapping2, "written_entries", "build"),
12645
+ writtenBytes: indexCounter(mapping2, "written_bytes", "build")
12645
12646
  });
12646
12647
  }
12647
12648
  function decodeIndexValidation(value) {
12648
- const mapping = requiredMap2(value, "FLOW.QUERY.INDEXES index validation");
12649
- if (!hasKey(mapping, "failure_reason") || !hasKey(mapping, "validated_at_ms")) {
12649
+ const mapping2 = requiredMap2(value, "FLOW.QUERY.INDEXES index validation");
12650
+ if (!hasKey(mapping2, "failure_reason") || !hasKey(mapping2, "validated_at_ms")) {
12650
12651
  throw decodeError(
12651
12652
  "FLOW.QUERY.INDEXES index validation is missing nullable fields",
12652
12653
  value
12653
12654
  );
12654
12655
  }
12655
12656
  const progress = decodeIndexProgress(
12656
- mapping,
12657
+ mapping2,
12657
12658
  "validation",
12658
12659
  FLOW_QUERY_VALIDATION_PHASES
12659
12660
  );
12660
12661
  return Object.freeze({
12661
12662
  ...progress,
12662
12663
  status: requiredChoice(
12663
- mapping,
12664
+ mapping2,
12664
12665
  "status",
12665
12666
  "FLOW.QUERY.INDEXES index validation",
12666
12667
  ["pending", "passed", "failed"]
12667
12668
  ),
12668
- checkedRecords: indexCounter(mapping, "checked_records", "validation"),
12669
- checkedEntries: indexCounter(mapping, "checked_entries", "validation"),
12670
- mismatches: indexCounter(mapping, "mismatches", "validation"),
12669
+ checkedRecords: indexCounter(mapping2, "checked_records", "validation"),
12670
+ checkedEntries: indexCounter(mapping2, "checked_entries", "validation"),
12671
+ mismatches: indexCounter(mapping2, "mismatches", "validation"),
12671
12672
  failureReason: optionalBoundedText(
12672
- mapping,
12673
+ mapping2,
12673
12674
  "failure_reason",
12674
12675
  "FLOW.QUERY.INDEXES index validation",
12675
12676
  128
12676
12677
  ),
12677
12678
  validatedAtMs: optionalIndexInteger(
12678
- mapping,
12679
+ mapping2,
12679
12680
  "validated_at_ms",
12680
12681
  "FLOW.QUERY.INDEXES index validation"
12681
12682
  )
@@ -12683,77 +12684,77 @@ function decodeIndexValidation(value) {
12683
12684
  }
12684
12685
  function decodeIndexRetirement(value) {
12685
12686
  const context = "FLOW.QUERY.INDEXES index retirement";
12686
- const mapping = requiredMap2(value, context);
12687
- const status = requiredChoice(mapping, "status", context, [
12687
+ const mapping2 = requiredMap2(value, context);
12688
+ const status = requiredChoice(mapping2, "status", context, [
12688
12689
  "not_applicable",
12689
12690
  "pending",
12690
12691
  "complete"
12691
12692
  ]);
12692
12693
  if (status === "not_applicable") {
12693
- return Object.freeze({ status, raw: freezeMap(mapping) });
12694
+ return Object.freeze({ status, raw: freezeMap(mapping2) });
12694
12695
  }
12695
12696
  const completedShards = unsignedIndexInteger(
12696
- field(mapping, "completed_shards"),
12697
+ field(mapping2, "completed_shards"),
12697
12698
  `${context} completed_shards`
12698
12699
  );
12699
12700
  const totalShards = positiveIndexInteger(
12700
- field(mapping, "total_shards"),
12701
+ field(mapping2, "total_shards"),
12701
12702
  `${context} total_shards`
12702
12703
  );
12703
12704
  if (indexInteger2(completedShards) > indexInteger2(totalShards)) {
12704
12705
  throw decodeError(
12705
12706
  `${context} completed_shards exceeds total_shards`,
12706
- mapping
12707
+ mapping2
12707
12708
  );
12708
12709
  }
12709
12710
  return Object.freeze({
12710
12711
  status,
12711
12712
  phaseCounts: decodePhaseCounts(
12712
- field(mapping, "phase_counts"),
12713
+ field(mapping2, "phase_counts"),
12713
12714
  "retirement"
12714
12715
  ),
12715
12716
  currentPhases: decodeAllowedPhases(
12716
- field(mapping, "current_phases"),
12717
+ field(mapping2, "current_phases"),
12717
12718
  "retirement",
12718
12719
  FLOW_QUERY_RETIREMENT_PHASES
12719
12720
  ),
12720
12721
  completedShards,
12721
12722
  totalShards,
12722
- deletedEntries: indexCounter(mapping, "deleted_entries", "retirement"),
12723
- deletedBytes: indexCounter(mapping, "deleted_bytes", "retirement"),
12723
+ deletedEntries: indexCounter(mapping2, "deleted_entries", "retirement"),
12724
+ deletedBytes: indexCounter(mapping2, "deleted_bytes", "retirement"),
12724
12725
  rewrittenReverseRows: indexCounter(
12725
- mapping,
12726
+ mapping2,
12726
12727
  "rewritten_reverse_rows",
12727
12728
  "retirement"
12728
12729
  ),
12729
- raw: freezeMap(mapping)
12730
+ raw: freezeMap(mapping2)
12730
12731
  });
12731
12732
  }
12732
12733
  function decodeIndexStatistics(value) {
12733
12734
  const context = "FLOW.QUERY.INDEXES index statistics";
12734
- const mapping = requiredMap2(value, context);
12735
+ const mapping2 = requiredMap2(value, context);
12735
12736
  for (const name of [
12736
12737
  "oldest_collected_at_ms",
12737
12738
  "newest_collected_at_ms",
12738
12739
  "oldest_age_ms",
12739
12740
  "newest_age_ms"
12740
12741
  ]) {
12741
- if (!hasKey(mapping, name)) {
12742
+ if (!hasKey(mapping2, name)) {
12742
12743
  throw decodeError(
12743
12744
  `${context} is missing required nullable fields`,
12744
12745
  value
12745
12746
  );
12746
12747
  }
12747
12748
  }
12748
- const samples = indexCounter(mapping, "samples", "statistics");
12749
- const freshSamples = indexCounter(mapping, "fresh_samples", "statistics");
12750
- const staleSamples = indexCounter(mapping, "stale_samples", "statistics");
12751
- const futureSamples = indexCounter(mapping, "future_samples", "statistics");
12749
+ const samples = indexCounter(mapping2, "samples", "statistics");
12750
+ const freshSamples = indexCounter(mapping2, "fresh_samples", "statistics");
12751
+ const staleSamples = indexCounter(mapping2, "stale_samples", "statistics");
12752
+ const futureSamples = indexCounter(mapping2, "future_samples", "statistics");
12752
12753
  if (indexInteger2(freshSamples) + indexInteger2(staleSamples) !== indexInteger2(samples) || indexInteger2(futureSamples) > indexInteger2(staleSamples)) {
12753
12754
  throw decodeError(`${context} counters are inconsistent`, value);
12754
12755
  }
12755
12756
  return Object.freeze({
12756
- status: requiredChoice(mapping, "status", context, [
12757
+ status: requiredChoice(mapping2, "status", context, [
12757
12758
  "fresh",
12758
12759
  "stale",
12759
12760
  "future",
@@ -12766,53 +12767,53 @@ function decodeIndexStatistics(value) {
12766
12767
  staleSamples,
12767
12768
  futureSamples,
12768
12769
  oldestCollectedAtMs: optionalIndexInteger(
12769
- mapping,
12770
+ mapping2,
12770
12771
  "oldest_collected_at_ms",
12771
12772
  context
12772
12773
  ),
12773
12774
  newestCollectedAtMs: optionalIndexInteger(
12774
- mapping,
12775
+ mapping2,
12775
12776
  "newest_collected_at_ms",
12776
12777
  context
12777
12778
  ),
12778
- oldestAgeMs: optionalIndexInteger(mapping, "oldest_age_ms", context),
12779
- newestAgeMs: optionalIndexInteger(mapping, "newest_age_ms", context),
12780
- raw: freezeMap(mapping)
12779
+ oldestAgeMs: optionalIndexInteger(mapping2, "oldest_age_ms", context),
12780
+ newestAgeMs: optionalIndexInteger(mapping2, "newest_age_ms", context),
12781
+ raw: freezeMap(mapping2)
12781
12782
  });
12782
12783
  }
12783
- function decodeIndexProgress(mapping, section, allowedPhases) {
12784
+ function decodeIndexProgress(mapping2, section, allowedPhases) {
12784
12785
  const context = `FLOW.QUERY.INDEXES index ${section}`;
12785
12786
  const completedShards = unsignedIndexInteger(
12786
- field(mapping, "completed_shards"),
12787
+ field(mapping2, "completed_shards"),
12787
12788
  `${context} completed_shards`
12788
12789
  );
12789
12790
  const totalShards = positiveIndexInteger(
12790
- field(mapping, "total_shards"),
12791
+ field(mapping2, "total_shards"),
12791
12792
  `${context} total_shards`
12792
12793
  );
12793
12794
  if (indexInteger2(completedShards) > indexInteger2(totalShards)) {
12794
12795
  throw decodeError(
12795
12796
  `${context} completed_shards exceeds total_shards`,
12796
- mapping
12797
+ mapping2
12797
12798
  );
12798
12799
  }
12799
12800
  return Object.freeze({
12800
- scope: requiredChoice(mapping, "scope", context, ["catalog_build"]),
12801
- phaseCounts: decodePhaseCounts(field(mapping, "phase_counts"), section),
12801
+ scope: requiredChoice(mapping2, "scope", context, ["catalog_build"]),
12802
+ phaseCounts: decodePhaseCounts(field(mapping2, "phase_counts"), section),
12802
12803
  currentPhases: decodeAllowedPhases(
12803
- field(mapping, "current_phases"),
12804
+ field(mapping2, "current_phases"),
12804
12805
  section,
12805
12806
  allowedPhases
12806
12807
  ),
12807
12808
  completedShards,
12808
12809
  totalShards,
12809
- raw: freezeMap(mapping)
12810
+ raw: freezeMap(mapping2)
12810
12811
  });
12811
12812
  }
12812
12813
  function decodePhaseCounts(value, section) {
12813
12814
  const context = `FLOW.QUERY.INDEXES index ${section} phase_counts`;
12814
- const mapping = requiredMap2(value, context);
12815
- const entries = mapping instanceof Map ? [...mapping.entries()] : Object.entries(mapping);
12815
+ const mapping2 = requiredMap2(value, context);
12816
+ const entries = mapping2 instanceof Map ? [...mapping2.entries()] : Object.entries(mapping2);
12816
12817
  if (entries.length > 16) {
12817
12818
  throw decodeError(`${context} contains too many entries`, value);
12818
12819
  }
@@ -12845,19 +12846,19 @@ function decodeAllowedPhases(value, section, allowed) {
12845
12846
  // src/flow-query-index-response.ts
12846
12847
  var FLOW_QUERY_INDEXES_CONTRACT = "ferric.flow.query.indexes/v1";
12847
12848
  function decodeFlowQueryIndexStatus(value, expectedId) {
12848
- const mapping = requiredMap2(value, "FLOW.QUERY.INDEXES");
12849
+ const mapping2 = requiredMap2(value, "FLOW.QUERY.INDEXES");
12849
12850
  requireContract(
12850
- mapping,
12851
+ mapping2,
12851
12852
  "contract_version",
12852
12853
  FLOW_QUERY_INDEXES_CONTRACT,
12853
12854
  "FLOW.QUERY.INDEXES"
12854
12855
  );
12855
12856
  const registry = requiredMap2(
12856
- field(mapping, "registry"),
12857
+ field(mapping2, "registry"),
12857
12858
  "FLOW.QUERY.INDEXES registry"
12858
12859
  );
12859
- const services = decodeIndexServices(field(mapping, "services"));
12860
- const rawIndexes = field(mapping, "indexes");
12860
+ const services = decodeIndexServices(field(mapping2, "services"));
12861
+ const rawIndexes = field(mapping2, "indexes");
12861
12862
  if (!Array.isArray(rawIndexes) || rawIndexes.length > 32) {
12862
12863
  throw decodeError(
12863
12864
  "FLOW.QUERY.INDEXES indexes must contain at most 32 entries",
@@ -12877,11 +12878,11 @@ function decodeFlowQueryIndexStatus(value, expectedId) {
12877
12878
  const status = Object.freeze({
12878
12879
  contractVersion: FLOW_QUERY_INDEXES_CONTRACT,
12879
12880
  observedAtMs: unsignedIndexInteger(
12880
- field(mapping, "observed_at_ms"),
12881
+ field(mapping2, "observed_at_ms"),
12881
12882
  "FLOW.QUERY.INDEXES observed_at_ms"
12882
12883
  ),
12883
12884
  statisticsMaxAgeMs: unsignedIndexInteger(
12884
- field(mapping, "statistics_max_age_ms"),
12885
+ field(mapping2, "statistics_max_age_ms"),
12885
12886
  "FLOW.QUERY.INDEXES statistics_max_age_ms"
12886
12887
  ),
12887
12888
  registry: Object.freeze({
@@ -12896,30 +12897,30 @@ function decodeFlowQueryIndexStatus(value, expectedId) {
12896
12897
  }),
12897
12898
  services,
12898
12899
  indexes: Object.freeze(indexes),
12899
- raw: freezeMap(mapping)
12900
+ raw: freezeMap(mapping2)
12900
12901
  });
12901
12902
  validateFlowQueryIndexContract(status, expectedId);
12902
12903
  return status;
12903
12904
  }
12904
12905
  function decodeIndex(value, index) {
12905
- const mapping = requiredMap2(value, `FLOW.QUERY.INDEXES index ${index}`);
12906
- const fields = decodeIndexFields(field(mapping, "fields"));
12906
+ const mapping2 = requiredMap2(value, `FLOW.QUERY.INDEXES index ${index}`);
12907
+ const fields = decodeIndexFields(field(mapping2, "fields"));
12907
12908
  return Object.freeze({
12908
- id: requiredBoundedText2(mapping, "id", "FLOW.QUERY.INDEXES index", 64),
12909
+ id: requiredBoundedText2(mapping2, "id", "FLOW.QUERY.INDEXES index", 64),
12909
12910
  version: positiveIndexInteger(
12910
- field(mapping, "version"),
12911
+ field(mapping2, "version"),
12911
12912
  "FLOW.QUERY.INDEXES index version"
12912
12913
  ),
12913
12914
  buildId: requiredBoundedText2(
12914
- mapping,
12915
+ mapping2,
12915
12916
  "build_id",
12916
12917
  "FLOW.QUERY.INDEXES index",
12917
12918
  128
12918
12919
  ),
12919
- source: requiredChoice(mapping, "source", "FLOW.QUERY.INDEXES index", [
12920
+ source: requiredChoice(mapping2, "source", "FLOW.QUERY.INDEXES index", [
12920
12921
  "runs"
12921
12922
  ]),
12922
- state: requiredChoice(mapping, "state", "FLOW.QUERY.INDEXES index", [
12923
+ state: requiredChoice(mapping2, "state", "FLOW.QUERY.INDEXES index", [
12923
12924
  "building",
12924
12925
  "validating",
12925
12926
  "active",
@@ -12927,60 +12928,60 @@ function decodeIndex(value, index) {
12927
12928
  "failed"
12928
12929
  ]),
12929
12930
  queryable: requiredBoolean(
12930
- mapping,
12931
+ mapping2,
12931
12932
  "queryable",
12932
12933
  "FLOW.QUERY.INDEXES index"
12933
12934
  ),
12934
12935
  fields,
12935
12936
  workloads: decodeUniqueTextArray(
12936
- field(mapping, "workloads"),
12937
+ field(mapping2, "workloads"),
12937
12938
  "FLOW.QUERY.INDEXES index workloads",
12938
12939
  16,
12939
12940
  64
12940
12941
  ),
12941
12942
  countPrefixes: decodeCountPrefixes(
12942
- field(mapping, "count_prefixes"),
12943
+ field(mapping2, "count_prefixes"),
12943
12944
  fields.length
12944
12945
  ),
12945
- coveringFields: decodeCoveringFields(mapping),
12946
- format: decodeIndexFormat(mapping),
12947
- coverage: decodeIndexCoverage(field(mapping, "coverage")),
12948
- build: decodeIndexBuild(field(mapping, "build")),
12949
- validation: decodeIndexValidation(field(mapping, "validation")),
12950
- retirement: decodeIndexRetirement(field(mapping, "retirement")),
12951
- statistics: decodeIndexStatistics(field(mapping, "statistics")),
12952
- raw: freezeMap(mapping)
12946
+ coveringFields: decodeCoveringFields(mapping2),
12947
+ format: decodeIndexFormat(mapping2),
12948
+ coverage: decodeIndexCoverage(field(mapping2, "coverage")),
12949
+ build: decodeIndexBuild(field(mapping2, "build")),
12950
+ validation: decodeIndexValidation(field(mapping2, "validation")),
12951
+ retirement: decodeIndexRetirement(field(mapping2, "retirement")),
12952
+ statistics: decodeIndexStatistics(field(mapping2, "statistics")),
12953
+ raw: freezeMap(mapping2)
12953
12954
  });
12954
12955
  }
12955
12956
  function decodeIndexServices(value) {
12956
- const mapping = requiredMap2(value, "FLOW.QUERY.INDEXES services");
12957
+ const mapping2 = requiredMap2(value, "FLOW.QUERY.INDEXES services");
12957
12958
  const choices = ["ready", "unavailable"];
12958
12959
  return Object.freeze({
12959
12960
  registry: requiredChoice(
12960
- mapping,
12961
+ mapping2,
12961
12962
  "registry",
12962
12963
  "FLOW.QUERY.INDEXES services",
12963
12964
  choices
12964
12965
  ),
12965
12966
  lifecycleWorker: requiredChoice(
12966
- mapping,
12967
+ mapping2,
12967
12968
  "lifecycle_worker",
12968
12969
  "FLOW.QUERY.INDEXES services",
12969
12970
  choices
12970
12971
  ),
12971
12972
  statisticsStore: requiredChoice(
12972
- mapping,
12973
+ mapping2,
12973
12974
  "statistics_store",
12974
12975
  "FLOW.QUERY.INDEXES services",
12975
12976
  choices
12976
12977
  ),
12977
12978
  statisticsWorker: requiredChoice(
12978
- mapping,
12979
+ mapping2,
12979
12980
  "statistics_worker",
12980
12981
  "FLOW.QUERY.INDEXES services",
12981
12982
  choices
12982
12983
  ),
12983
- raw: freezeMap(mapping)
12984
+ raw: freezeMap(mapping2)
12984
12985
  });
12985
12986
  }
12986
12987
  function decodeIndexFields(value) {
@@ -12994,12 +12995,12 @@ function decodeIndexFields(value) {
12994
12995
  if (!Object.hasOwn(value, index)) {
12995
12996
  throw decodeError(`${context} must be dense`, value);
12996
12997
  }
12997
- const mapping = requiredMap2(
12998
+ const mapping2 = requiredMap2(
12998
12999
  value[index],
12999
13000
  `FLOW.QUERY.INDEXES index field ${index}`
13000
13001
  );
13001
13002
  const name = requiredBoundedText2(
13002
- mapping,
13003
+ mapping2,
13003
13004
  "name",
13004
13005
  "FLOW.QUERY.INDEXES index field",
13005
13006
  512
@@ -13011,18 +13012,18 @@ function decodeIndexFields(value) {
13011
13012
  fields[index] = Object.freeze({
13012
13013
  name,
13013
13014
  direction: requiredChoice(
13014
- mapping,
13015
+ mapping2,
13015
13016
  "direction",
13016
13017
  "FLOW.QUERY.INDEXES index field",
13017
13018
  ["asc", "desc"]
13018
13019
  ),
13019
13020
  encoding: requiredChoice(
13020
- mapping,
13021
+ mapping2,
13021
13022
  "encoding",
13022
13023
  "FLOW.QUERY.INDEXES index field",
13023
13024
  ["hashed", "ordered"]
13024
13025
  ),
13025
- raw: freezeMap(mapping)
13026
+ raw: freezeMap(mapping2)
13026
13027
  });
13027
13028
  }
13028
13029
  return Object.freeze(fields);
@@ -13047,8 +13048,8 @@ function decodeCountPrefixes(value, fieldCount) {
13047
13048
  }
13048
13049
  return Object.freeze(prefixes);
13049
13050
  }
13050
- function decodeCoveringFields(mapping) {
13051
- const raw = field(mapping, "covering_fields");
13051
+ function decodeCoveringFields(mapping2) {
13052
+ const raw = field(mapping2, "covering_fields");
13052
13053
  if (!Array.isArray(raw) || raw.length > 32) {
13053
13054
  throw decodeError(
13054
13055
  "FLOW.QUERY.INDEXES index covering_fields must contain at most 32 entries",
@@ -13080,9 +13081,9 @@ function decodeCoveringFields(mapping) {
13080
13081
  }
13081
13082
  return Object.freeze(fields);
13082
13083
  }
13083
- function decodeIndexFormat(mapping) {
13084
+ function decodeIndexFormat(mapping2) {
13084
13085
  const raw = requiredMap2(
13085
- field(mapping, "format"),
13086
+ field(mapping2, "format"),
13086
13087
  "FLOW.QUERY.INDEXES index format"
13087
13088
  );
13088
13089
  if (!hasKey(raw, "counter")) {
@@ -13151,7 +13152,7 @@ var QUALITY_VALUES2 = {
13151
13152
  pagination: ["none", "complete", "authenticated_seek", "live_seek"]
13152
13153
  };
13153
13154
  function decodeFlowQueryResult(value) {
13154
- const result = decodeFlowQueryResponse(value, (mapping) => freezeMap(mapping));
13155
+ const result = decodeFlowQueryResponse(value, (mapping2) => freezeMap(mapping2));
13155
13156
  if (result.kind === "records") {
13156
13157
  return Object.freeze({
13157
13158
  kind: "records",
@@ -13175,7 +13176,7 @@ function decodeFlowQueryResult(value) {
13175
13176
  function decodeFlowQueryRecords(value, decodeRecord) {
13176
13177
  const result = decodeFlowQueryResponse(
13177
13178
  value,
13178
- (mapping, index) => decodeRecord(mapping instanceof Map ? freezeMap(mapping) : mapping, index)
13179
+ (mapping2, index) => decodeRecord(mapping2 instanceof Map ? freezeMap(mapping2) : mapping2, index)
13179
13180
  );
13180
13181
  if (result.kind === "count") {
13181
13182
  throw new FerricStoreError("Flow record convenience query returned a count result", {
@@ -13185,18 +13186,18 @@ function decodeFlowQueryRecords(value, decodeRecord) {
13185
13186
  return result.records;
13186
13187
  }
13187
13188
  function decodeFlowQueryResponse(value, decodeRecord) {
13188
- const mapping = requiredMap2(value, "FLOW.QUERY result");
13189
- requireContract(mapping, "version", FLOW_QUERY_RESULT_CONTRACT, "FLOW.QUERY result");
13190
- const quality = decodeQuality(field(mapping, "quality"));
13191
- const usage = decodeUsage(field(mapping, "usage"));
13192
- const hasRecords = hasKey(mapping, "records");
13193
- const hasCount = hasKey(mapping, "result");
13189
+ const mapping2 = requiredMap2(value, "FLOW.QUERY result");
13190
+ requireContract(mapping2, "version", FLOW_QUERY_RESULT_CONTRACT, "FLOW.QUERY result");
13191
+ const quality = decodeQuality(field(mapping2, "quality"));
13192
+ const usage = decodeUsage(field(mapping2, "usage"));
13193
+ const hasRecords = hasKey(mapping2, "records");
13194
+ const hasCount = hasKey(mapping2, "result");
13194
13195
  if (hasRecords === hasCount) {
13195
13196
  throw decodeError("FLOW.QUERY result must contain exactly one records or count shape", value);
13196
13197
  }
13197
- const raw = freezeMap(mapping);
13198
+ const raw = freezeMap(mapping2);
13198
13199
  if (hasRecords) {
13199
- const rawRecords = field(mapping, "records");
13200
+ const rawRecords = field(mapping2, "records");
13200
13201
  if (!Array.isArray(rawRecords) || rawRecords.length > 100) {
13201
13202
  throw decodeError("FLOW.QUERY records must be an array of at most 100 maps", value);
13202
13203
  }
@@ -13216,16 +13217,16 @@ function decodeFlowQueryResponse(value, decodeRecord) {
13216
13217
  return {
13217
13218
  kind: "records",
13218
13219
  records,
13219
- page: decodePage(field(mapping, "page")),
13220
+ page: decodePage(field(mapping2, "page")),
13220
13221
  quality,
13221
13222
  usage,
13222
13223
  raw
13223
13224
  };
13224
13225
  }
13225
- if (hasKey(mapping, "page")) {
13226
+ if (hasKey(mapping2, "page")) {
13226
13227
  throw decodeError("FLOW.QUERY count result contains an unexpected page", value);
13227
13228
  }
13228
- const countResult = requiredMap2(field(mapping, "result"), "FLOW.QUERY count result");
13229
+ const countResult = requiredMap2(field(mapping2, "result"), "FLOW.QUERY count result");
13229
13230
  if (requiredText2(countResult, "kind", "FLOW.QUERY count result") !== "count") {
13230
13231
  throw decodeError("FLOW.QUERY count result kind must be count", value);
13231
13232
  }
@@ -13246,31 +13247,31 @@ function decodeFlowQueryResponse(value, decodeRecord) {
13246
13247
  };
13247
13248
  }
13248
13249
  function decodeFlowExplainResult(value) {
13249
- const mapping = requiredMap2(value, "FLOW.QUERY explain");
13250
- requireContract(mapping, "version", FLOW_EXPLAIN_CONTRACT, "FLOW.QUERY explain");
13251
- const queryFingerprint = requiredText2(mapping, "query_fingerprint", "FLOW.QUERY explain");
13250
+ const mapping2 = requiredMap2(value, "FLOW.QUERY explain");
13251
+ requireContract(mapping2, "version", FLOW_EXPLAIN_CONTRACT, "FLOW.QUERY explain");
13252
+ const queryFingerprint = requiredText2(mapping2, "query_fingerprint", "FLOW.QUERY explain");
13252
13253
  if (!/^[0-9a-f]{64}$/iu.test(queryFingerprint)) {
13253
13254
  throw decodeError("FLOW.QUERY explain query_fingerprint is invalid", value);
13254
13255
  }
13255
- const status = requiredText2(mapping, "status", "FLOW.QUERY explain");
13256
+ const status = requiredText2(mapping2, "status", "FLOW.QUERY explain");
13256
13257
  if (status !== "planned" && status !== "rejected" && status !== "executed") {
13257
13258
  throw decodeError(`FLOW.QUERY explain status ${JSON.stringify(status)} is unsupported`, value);
13258
13259
  }
13259
13260
  const plan = freezeMetadataMap(
13260
- requiredMap2(field(mapping, "plan"), "FLOW.QUERY explain plan"),
13261
+ requiredMap2(field(mapping2, "plan"), "FLOW.QUERY explain plan"),
13261
13262
  "FLOW.QUERY explain plan"
13262
13263
  );
13263
13264
  const estimate = freezeMetadataMap(
13264
- requiredMap2(field(mapping, "estimate"), "FLOW.QUERY explain estimate"),
13265
+ requiredMap2(field(mapping2, "estimate"), "FLOW.QUERY explain estimate"),
13265
13266
  "FLOW.QUERY explain estimate"
13266
13267
  );
13267
13268
  const bounds = freezeMetadataMap(
13268
- requiredMap2(field(mapping, "bounds"), "FLOW.QUERY explain bounds"),
13269
+ requiredMap2(field(mapping2, "bounds"), "FLOW.QUERY explain bounds"),
13269
13270
  "FLOW.QUERY explain bounds"
13270
13271
  );
13271
- const capabilities = decodeExplainCapabilities(mapping);
13272
+ const capabilities = decodeExplainCapabilities(mapping2);
13272
13273
  const extendedFields = ["stats", "quality", "pressure", "decision", "alternatives"];
13273
- const extendedPresence = extendedFields.map((name) => hasKey(mapping, name));
13274
+ const extendedPresence = extendedFields.map((name) => hasKey(mapping2, name));
13274
13275
  const specialized = capabilities != null && !extendedPresence.some(Boolean);
13275
13276
  let stats;
13276
13277
  let quality;
@@ -13281,30 +13282,30 @@ function decodeFlowExplainResult(value) {
13281
13282
  if (status !== "planned") {
13282
13283
  throw decodeError("FLOW.QUERY specialized explain must be planned", value);
13283
13284
  }
13284
- if (hasKey(mapping, "actual") || hasKey(mapping, "diagnostic")) {
13285
+ if (hasKey(mapping2, "actual") || hasKey(mapping2, "diagnostic")) {
13285
13286
  throw decodeError("FLOW.QUERY specialized explain has extended status fields", value);
13286
13287
  }
13287
13288
  alternatives = Object.freeze([]);
13288
13289
  } else {
13289
- if (!extendedPresence.every(Boolean) || !hasKey(mapping, "actual") || !hasKey(mapping, "diagnostic")) {
13290
+ if (!extendedPresence.every(Boolean) || !hasKey(mapping2, "actual") || !hasKey(mapping2, "diagnostic")) {
13290
13291
  throw decodeError("FLOW.QUERY explain is missing required v1 fields", value);
13291
13292
  }
13292
13293
  stats = freezeMetadataMap(
13293
- requiredMap2(field(mapping, "stats"), "FLOW.QUERY explain stats"),
13294
+ requiredMap2(field(mapping2, "stats"), "FLOW.QUERY explain stats"),
13294
13295
  "FLOW.QUERY explain stats"
13295
13296
  );
13296
- quality = decodeQuality(field(mapping, "quality"));
13297
+ quality = decodeQuality(field(mapping2, "quality"));
13297
13298
  pressure = freezeMetadataMap(
13298
- requiredMap2(field(mapping, "pressure"), "FLOW.QUERY explain pressure"),
13299
+ requiredMap2(field(mapping2, "pressure"), "FLOW.QUERY explain pressure"),
13299
13300
  "FLOW.QUERY explain pressure"
13300
13301
  );
13301
13302
  decision = freezeMetadataMap(
13302
- requiredMap2(field(mapping, "decision"), "FLOW.QUERY explain decision"),
13303
+ requiredMap2(field(mapping2, "decision"), "FLOW.QUERY explain decision"),
13303
13304
  "FLOW.QUERY explain decision"
13304
13305
  );
13305
- alternatives = decodeExplainAlternatives(field(mapping, "alternatives"));
13306
+ alternatives = decodeExplainAlternatives(field(mapping2, "alternatives"));
13306
13307
  }
13307
- const actualValue = field(mapping, "actual");
13308
+ const actualValue = field(mapping2, "actual");
13308
13309
  let actual;
13309
13310
  if (status === "executed") {
13310
13311
  if (actualValue == null) {
@@ -13314,7 +13315,7 @@ function decodeFlowExplainResult(value) {
13314
13315
  } else if (actualValue != null) {
13315
13316
  throw decodeError("FLOW.QUERY non-executed explain contains actual usage", value);
13316
13317
  }
13317
- const diagnosticValue = field(mapping, "diagnostic");
13318
+ const diagnosticValue = field(mapping2, "diagnostic");
13318
13319
  let diagnostic;
13319
13320
  if (status === "rejected") {
13320
13321
  diagnostic = tryDecodeFlowQueryError(diagnosticValue);
@@ -13339,13 +13340,13 @@ function decodeFlowExplainResult(value) {
13339
13340
  capabilities,
13340
13341
  actual,
13341
13342
  diagnostic,
13342
- raw: freezeMap(mapping)
13343
+ raw: freezeMap(mapping2)
13343
13344
  });
13344
13345
  }
13345
- function decodeExplainCapabilities(mapping) {
13346
- if (!hasKey(mapping, "capabilities")) return void 0;
13346
+ function decodeExplainCapabilities(mapping2) {
13347
+ if (!hasKey(mapping2, "capabilities")) return void 0;
13347
13348
  const value = requiredMap2(
13348
- field(mapping, "capabilities"),
13349
+ field(mapping2, "capabilities"),
13349
13350
  "FLOW.QUERY explain capabilities"
13350
13351
  );
13351
13352
  return Object.freeze({
@@ -13401,27 +13402,27 @@ function decodeExplainAlternatives(value) {
13401
13402
  return Object.freeze(alternatives);
13402
13403
  }
13403
13404
  function decodeQuality(value) {
13404
- const mapping = requiredMap2(value, "FLOW.QUERY quality");
13405
+ const mapping2 = requiredMap2(value, "FLOW.QUERY quality");
13405
13406
  return Object.freeze({
13406
- exactness: decodeQualityValue(mapping, "exactness", QUALITY_VALUES2.exactness),
13407
- freshness: decodeQualityValue(mapping, "freshness", QUALITY_VALUES2.freshness),
13408
- coverage: decodeQualityValue(mapping, "coverage", QUALITY_VALUES2.coverage),
13409
- pagination: decodeQualityValue(mapping, "pagination", QUALITY_VALUES2.pagination)
13407
+ exactness: decodeQualityValue(mapping2, "exactness", QUALITY_VALUES2.exactness),
13408
+ freshness: decodeQualityValue(mapping2, "freshness", QUALITY_VALUES2.freshness),
13409
+ coverage: decodeQualityValue(mapping2, "coverage", QUALITY_VALUES2.coverage),
13410
+ pagination: decodeQualityValue(mapping2, "pagination", QUALITY_VALUES2.pagination)
13410
13411
  });
13411
13412
  }
13412
- function decodeQualityValue(mapping, name, allowed) {
13413
- const value = requiredBoundedText2(mapping, name, "FLOW.QUERY quality", 64);
13413
+ function decodeQualityValue(mapping2, name, allowed) {
13414
+ const value = requiredBoundedText2(mapping2, name, "FLOW.QUERY quality", 64);
13414
13415
  if (!allowed.includes(value)) {
13415
- throw decodeError(`FLOW.QUERY quality ${name} is unsupported`, mapping);
13416
+ throw decodeError(`FLOW.QUERY quality ${name} is unsupported`, mapping2);
13416
13417
  }
13417
13418
  return value;
13418
13419
  }
13419
13420
  function decodeUsage(value) {
13420
- const mapping = requiredMap2(value, "FLOW.QUERY usage");
13421
+ const mapping2 = requiredMap2(value, "FLOW.QUERY usage");
13421
13422
  const usage = /* @__PURE__ */ Object.create(null);
13422
13423
  for (const [wireName, property] of USAGE_FIELDS2) {
13423
13424
  usage[property] = nonNegativeInteger(
13424
- field(mapping, wireName),
13425
+ field(mapping2, wireName),
13425
13426
  `FLOW.QUERY usage ${wireName}`
13426
13427
  );
13427
13428
  }
@@ -13432,9 +13433,9 @@ function decodeUsage(value) {
13432
13433
  return Object.freeze(decoded);
13433
13434
  }
13434
13435
  function decodePage(value) {
13435
- const mapping = requiredMap2(value, "FLOW.QUERY page");
13436
- const hasMore = requiredBoolean(mapping, "has_more", "FLOW.QUERY page");
13437
- const cursor = optionalText2(mapping, "cursor", "FLOW.QUERY page");
13436
+ const mapping2 = requiredMap2(value, "FLOW.QUERY page");
13437
+ const hasMore = requiredBoolean(mapping2, "has_more", "FLOW.QUERY page");
13438
+ const cursor = optionalText2(mapping2, "cursor", "FLOW.QUERY page");
13438
13439
  if (cursor != null && (!cursor.startsWith("fqc1_") || Buffer48.byteLength(cursor) < 16 || Buffer48.byteLength(cursor) > 4096)) {
13439
13440
  throw decodeError("FLOW.QUERY page cursor is invalid", value);
13440
13441
  }
@@ -13550,12 +13551,12 @@ var ErrorMappingExecutor = class {
13550
13551
 
13551
13552
  // src/client-config.ts
13552
13553
  function snapshotClientOptions(options) {
13553
- const own = { ...options };
13554
+ const own2 = { ...options };
13554
13555
  const snapshot = {
13555
- ...own,
13556
- ...typeof own.autoBatch === "object" && own.autoBatch != null ? { autoBatch: Object.freeze({ ...own.autoBatch }) } : {},
13557
- ...own.backpressure == null ? {} : { backpressure: Object.freeze({ ...own.backpressure }) },
13558
- ...typeof own.reconnect === "object" && own.reconnect != null ? { reconnect: Object.freeze({ ...own.reconnect }) } : {}
13556
+ ...own2,
13557
+ ...typeof own2.autoBatch === "object" && own2.autoBatch != null ? { autoBatch: Object.freeze({ ...own2.autoBatch }) } : {},
13558
+ ...own2.backpressure == null ? {} : { backpressure: Object.freeze({ ...own2.backpressure }) },
13559
+ ...typeof own2.reconnect === "object" && own2.reconnect != null ? { reconnect: Object.freeze({ ...own2.reconnect }) } : {}
13559
13560
  };
13560
13561
  return Object.freeze(snapshot);
13561
13562
  }
@@ -15744,33 +15745,511 @@ var FerricStoreClientCore = class extends FerricStoreAdministrationClient {
15744
15745
  }
15745
15746
  };
15746
15747
 
15747
- // src/client-management.ts
15748
- var FerricStoreManagementClient = class extends FerricStoreClientCore {
15749
- async stats(type, options = {}) {
15750
- const args = ["FLOW.STATS", type];
15751
- append(args, "STATE", options.state);
15752
- append(args, "COUNT", options.count);
15753
- append(args, "PARTITION", options.partitionKey);
15754
- appendAttributes(args, options.attributes);
15755
- appendBool(args, "CONSISTENT_PROJECTION", options.consistentProjection);
15756
- return adminRecordResponse(await this.commandArgs(args), "FLOW.STATS");
15748
+ // src/schedule-request.ts
15749
+ var MAX_EXACT_INTEGER = Number.MAX_SAFE_INTEGER;
15750
+ var SCHEDULE_KINDS = /* @__PURE__ */ new Set(["one_shot", "delay", "interval", "cron"]);
15751
+ var RECURRING_KINDS = /* @__PURE__ */ new Set(["interval", "cron"]);
15752
+ var OVERLAP_POLICIES = /* @__PURE__ */ new Set([
15753
+ "allow",
15754
+ "skip",
15755
+ "queue_after_previous",
15756
+ "fail_schedule"
15757
+ ]);
15758
+ var SCHEDULE_STATES = /* @__PURE__ */ new Set([
15759
+ "active",
15760
+ "paused",
15761
+ "running",
15762
+ "completed",
15763
+ "failed",
15764
+ "cancelled",
15765
+ "all"
15766
+ ]);
15767
+ var TARGET_FIELDS = /* @__PURE__ */ new Set([
15768
+ "correlation_id",
15769
+ "id",
15770
+ "id_prefix",
15771
+ "parent_flow_id",
15772
+ "partition_key",
15773
+ "payload",
15774
+ "payload_ref",
15775
+ "priority",
15776
+ "root_flow_id",
15777
+ "run_at_ms",
15778
+ "state",
15779
+ "type",
15780
+ "value_refs",
15781
+ "values"
15782
+ ]);
15783
+ var TARGET_TEXT_FIELDS = [
15784
+ "state",
15785
+ "id",
15786
+ "id_prefix",
15787
+ "partition_key",
15788
+ "correlation_id",
15789
+ "parent_flow_id",
15790
+ "root_flow_id",
15791
+ "payload_ref"
15792
+ ];
15793
+ var INTERNAL_SCHEDULE_TYPE = "__ferricstore_schedule";
15794
+ var INTERNAL_SCHEDULE_ID_PREFIX = "__ferricstore_schedule__:";
15795
+ function validateScheduleCreate(id, options) {
15796
+ requiredText3(id, "id");
15797
+ if (!mapping(options)) throw new TypeError("schedule options must be a mapping");
15798
+ const kind = effectiveKind(options);
15799
+ validateTiming(kind, options);
15800
+ const recurring = RECURRING_KINDS.has(kind);
15801
+ validateTarget(options.target, recurring);
15802
+ nonNegativeInteger2(options.atMs, "at_ms");
15803
+ nonNegativeInteger2(options.delayMs, "delay_ms");
15804
+ nonNegativeInteger2(options.startAtMs, "start_at_ms");
15805
+ positiveInteger2(options.everyMs, "every_ms");
15806
+ positiveInteger2(options.overlapRetryMs, "overlap_retry_ms");
15807
+ positiveInteger2(options.maxFires, "max_fires");
15808
+ nonNegativeInteger2(options.endAtMs, "end_at_ms");
15809
+ nonNegativeInteger2(options.nowMs, "now_ms");
15810
+ optionalBoolean(options.overwrite, "overwrite");
15811
+ if (kind === "delay") {
15812
+ if (options.delayMs == null) throw new TypeError("delay_ms is required for delay schedules");
15813
+ if (options.nowMs != null && options.nowMs > MAX_EXACT_INTEGER - options.delayMs) {
15814
+ throw new TypeError("now_ms plus delay_ms exceeds the exact integer range");
15815
+ }
15816
+ }
15817
+ if (kind === "interval" && options.everyMs == null) {
15818
+ throw new TypeError("every_ms is required for interval schedules");
15819
+ }
15820
+ if (kind === "cron") {
15821
+ requiredText3(options.cron, "cron");
15822
+ optionalText3(options.timezone, "timezone");
15823
+ } else if (options.timezone != null) {
15824
+ throw new TypeError("timezone is only supported for cron schedules");
15825
+ }
15826
+ if (kind === "interval") {
15827
+ if (options.catchupPolicy != null && options.catchupPolicy !== "fire_once") {
15828
+ throw new TypeError("catchup_policy must be fire_once");
15829
+ }
15830
+ } else if (options.catchupPolicy != null) {
15831
+ throw new TypeError("catchup_policy is only supported for interval schedules");
15832
+ }
15833
+ if (recurring) {
15834
+ if (options.overlapPolicy != null && !OVERLAP_POLICIES.has(options.overlapPolicy)) {
15835
+ throw new TypeError(
15836
+ "overlap_policy must be allow, skip, queue_after_previous, or fail_schedule"
15837
+ );
15838
+ }
15839
+ if (options.overlapRetryMs != null && options.overlapPolicy !== "queue_after_previous") {
15840
+ throw new TypeError("overlap_retry_ms requires overlap_policy queue_after_previous");
15841
+ }
15842
+ const firstRun = knownFirstRun(kind, options);
15843
+ if (options.endAtMs != null && firstRun != null && options.endAtMs < firstRun) {
15844
+ throw new TypeError("end_at_ms must be at or after first run");
15845
+ }
15846
+ } else {
15847
+ if (options.overlapPolicy != null) {
15848
+ throw new TypeError("overlap_policy is only supported for recurring schedules");
15849
+ }
15850
+ if (options.overlapRetryMs != null) {
15851
+ throw new TypeError("overlap_retry_ms requires overlap_policy queue_after_previous");
15852
+ }
15853
+ if (options.maxFires != null) {
15854
+ throw new TypeError("max_fires is only supported for recurring schedules");
15855
+ }
15856
+ if (options.endAtMs != null) {
15857
+ throw new TypeError("end_at_ms is only supported for recurring schedules");
15858
+ }
15757
15859
  }
15758
- async countByState(type, state, options = {}) {
15759
- const stats = await this.stats(type, { ...options, state });
15760
- if (!("count" in stats)) throw new TypeError("FLOW.STATS response missing count");
15761
- return integer(stats.count);
15860
+ }
15861
+ function validateScheduleID(id) {
15862
+ requiredText3(id, "id");
15863
+ }
15864
+ function validateScheduleFire(id, options) {
15865
+ validateScheduleID(id);
15866
+ nonNegativeInteger2(options.fireAtMs, "fire_at_ms");
15867
+ nonNegativeInteger2(options.nowMs, "now_ms");
15868
+ }
15869
+ function validateScheduleStatus(id, nowMs2) {
15870
+ validateScheduleID(id);
15871
+ nonNegativeInteger2(nowMs2, "now_ms");
15872
+ }
15873
+ function validateScheduleFireDue(options) {
15874
+ if (!mapping(options)) throw new TypeError("schedule fire-due options must be a mapping");
15875
+ nonNegativeInteger2(options.nowMs, "now_ms");
15876
+ optionalText3(options.worker, "worker");
15877
+ positiveInteger2(options.leaseMs, "lease_ms");
15878
+ nonNegativeInteger2(options.blockMs, "block_ms");
15879
+ positiveInteger2(options.limit, "limit");
15880
+ const leaseMs = options.leaseMs ?? 3e4;
15881
+ if (options.nowMs != null && options.nowMs > MAX_EXACT_INTEGER - leaseMs) {
15882
+ throw new TypeError("now_ms plus lease_ms exceeds the exact integer range");
15762
15883
  }
15763
- async attributes(type, options = {}) {
15764
- const args = ["FLOW.ATTRIBUTES", type];
15765
- appendAttributeQueryOptions(args, options);
15766
- return adminRecordList(await this.commandArgs(args), "FLOW.ATTRIBUTES");
15884
+ }
15885
+ function validateScheduleList(options) {
15886
+ if (!mapping(options)) throw new TypeError("schedule list options must be a mapping");
15887
+ if (options.kind != null && !SCHEDULE_KINDS.has(options.kind)) {
15888
+ throw new TypeError("kind must be one_shot, delay, interval, or cron");
15767
15889
  }
15768
- async attributeValues(type, attribute, options = {}) {
15769
- const args = ["FLOW.ATTRIBUTE_VALUES", type, attribute];
15770
- appendAttributeQueryOptions(args, options);
15771
- return adminRecordList(await this.commandArgs(args), "FLOW.ATTRIBUTE_VALUES");
15890
+ if (options.state != null && !SCHEDULE_STATES.has(options.state)) {
15891
+ throw new TypeError("state is invalid");
15892
+ }
15893
+ optionalText3(options.timezone, "timezone");
15894
+ optionalText3(options.targetType, "target_type");
15895
+ nonNegativeInteger2(options.fromMs, "from_ms");
15896
+ nonNegativeInteger2(options.toMs, "to_ms");
15897
+ if (options.fromMs != null && options.toMs != null && options.fromMs > options.toMs) {
15898
+ throw new TypeError("from_ms must not exceed to_ms");
15899
+ }
15900
+ positiveInteger2(options.count, "count");
15901
+ optionalBoolean(options.rev, "rev");
15902
+ }
15903
+ function effectiveKind(options) {
15904
+ if (options.kind != null) {
15905
+ if (!SCHEDULE_KINDS.has(options.kind)) {
15906
+ throw new TypeError("kind must be one_shot, delay, interval, or cron");
15907
+ }
15908
+ return options.kind;
15909
+ }
15910
+ if (options.cron != null) return "cron";
15911
+ if (options.everyMs != null) return "interval";
15912
+ if (options.delayMs != null) return "delay";
15913
+ return "one_shot";
15914
+ }
15915
+ function validateTiming(kind, options) {
15916
+ if (options.atMs != null && options.startAtMs != null) {
15917
+ throw new TypeError("cannot set both at_ms and start_at_ms");
15918
+ }
15919
+ if (options.delayMs != null && kind !== "delay") {
15920
+ throw new TypeError("delay_ms is only supported for delay schedules");
15921
+ }
15922
+ if (options.everyMs != null && kind !== "interval") {
15923
+ throw new TypeError("every_ms is only supported for interval schedules");
15924
+ }
15925
+ if (options.cron != null && kind !== "cron") {
15926
+ throw new TypeError("cron is only supported for cron schedules");
15927
+ }
15928
+ if (kind === "delay" && (options.atMs != null || options.startAtMs != null)) {
15929
+ throw new TypeError("at_ms and start_at_ms are not supported for delay schedules");
15930
+ }
15931
+ }
15932
+ function validateTarget(value, recurring) {
15933
+ if (!mapping(value)) throw new TypeError("target must be a mapping with a non-empty type");
15934
+ const target = value;
15935
+ for (const key of Object.keys(target)) {
15936
+ if (!TARGET_FIELDS.has(key)) throw new TypeError(`target contains unknown field ${key}`);
15937
+ }
15938
+ const type = own(target, "type");
15939
+ requiredText3(type, "target type");
15940
+ if (type === INTERNAL_SCHEDULE_TYPE) {
15941
+ throw new TypeError("target type is reserved for internal use");
15942
+ }
15943
+ for (const key of TARGET_TEXT_FIELDS) optionalText3(own(target, key), `target ${key}`);
15944
+ const id = own(target, "id");
15945
+ const idPrefix = own(target, "id_prefix");
15946
+ if (id != null && idPrefix != null) {
15947
+ throw new TypeError("target cannot set both id and id_prefix");
15948
+ }
15949
+ if (recurring && id != null) {
15950
+ throw new TypeError("target id is not supported for recurring schedules; use id_prefix");
15951
+ }
15952
+ if (typeof id === "string" && id.startsWith(INTERNAL_SCHEDULE_ID_PREFIX)) {
15953
+ throw new TypeError("target id is reserved for internal use");
15954
+ }
15955
+ if (typeof idPrefix === "string" && idPrefix.startsWith(INTERNAL_SCHEDULE_ID_PREFIX)) {
15956
+ throw new TypeError("target id_prefix is reserved for internal use");
15957
+ }
15958
+ nonNegativeInteger2(own(target, "run_at_ms"), "target run_at_ms");
15959
+ const priority = own(target, "priority");
15960
+ if (priority != null && (typeof priority !== "number" || !Number.isSafeInteger(priority) || priority < 0 || priority > 2)) {
15961
+ throw new TypeError("target priority must be an integer between 0 and 2");
15962
+ }
15963
+ }
15964
+ function knownFirstRun(kind, options) {
15965
+ if (kind === "delay") {
15966
+ if (options.nowMs == null || options.delayMs == null) return void 0;
15967
+ return options.nowMs + options.delayMs;
15968
+ }
15969
+ if (kind === "cron") return options.startAtMs ?? options.atMs ?? options.nowMs;
15970
+ return options.atMs ?? options.startAtMs ?? options.nowMs;
15971
+ }
15972
+ function requiredText3(value, name) {
15973
+ if (typeof value !== "string" || value.length === 0) {
15974
+ throw new TypeError(`${name} must be a non-empty string`);
15975
+ }
15976
+ }
15977
+ function optionalText3(value, name) {
15978
+ if (value != null) requiredText3(value, name);
15979
+ }
15980
+ function nonNegativeInteger2(value, name) {
15981
+ if (value != null && (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0)) {
15982
+ throw new TypeError(`${name} must be a non-negative exact integer`);
15983
+ }
15984
+ }
15985
+ function positiveInteger2(value, name) {
15986
+ if (value != null && (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0)) {
15987
+ throw new TypeError(`${name} must be a positive exact integer`);
15988
+ }
15989
+ }
15990
+ function optionalBoolean(value, name) {
15991
+ if (value != null && typeof value !== "boolean") {
15992
+ throw new TypeError(`${name} must be a boolean`);
15993
+ }
15994
+ }
15995
+ function mapping(value) {
15996
+ return typeof value === "object" && value !== null && !Array.isArray(value);
15997
+ }
15998
+ function own(mapping2, key) {
15999
+ return Object.prototype.hasOwnProperty.call(mapping2, key) ? mapping2[key] : void 0;
16000
+ }
16001
+
16002
+ // src/schedule-response.ts
16003
+ var SCHEDULE_INTEGER_FIELDS = [
16004
+ "end_at_ms",
16005
+ "last_catchup_at_ms",
16006
+ "last_fire_at_ms",
16007
+ "last_overlap_at_ms",
16008
+ "last_skipped_at_ms",
16009
+ "max_fires",
16010
+ "next_run_at_ms",
16011
+ "overlap_queued_due_at_ms"
16012
+ ];
16013
+ var REQUIRED_SCHEDULE_INTEGER_FIELDS = [
16014
+ "attempts",
16015
+ "coalesced_count",
16016
+ "fire_count",
16017
+ "last_coalesced_count",
16018
+ "skipped_count"
16019
+ ];
16020
+ var OPTIONAL_SCHEDULE_TEXT_FIELDS = [
16021
+ "cron",
16022
+ "end_reason",
16023
+ "flow_id",
16024
+ "last_overlap_reason",
16025
+ "last_overlap_target_id",
16026
+ "last_planning_error",
16027
+ "last_target_id",
16028
+ "timezone"
16029
+ ];
16030
+ var SCHEDULE_KINDS2 = /* @__PURE__ */ new Set(["one_shot", "delay", "interval", "cron"]);
16031
+ var SCHEDULE_STATES2 = /* @__PURE__ */ new Set([
16032
+ "active",
16033
+ "paused",
16034
+ "running",
16035
+ "completed",
16036
+ "failed",
16037
+ "cancelled"
16038
+ ]);
16039
+ var SCHEDULE_OVERLAP_POLICIES = /* @__PURE__ */ new Set([
16040
+ "allow",
16041
+ "skip",
16042
+ "queue_after_previous",
16043
+ "fail_schedule"
16044
+ ]);
16045
+ function scheduleRecordResponse(value, context) {
16046
+ const record = adminRecordResponse(value, context);
16047
+ if (typeof record.id !== "string" || record.id.length === 0) {
16048
+ throw new TypeError(`${context} response missing id`);
16049
+ }
16050
+ if (typeof record.kind !== "string" || !SCHEDULE_KINDS2.has(record.kind)) {
16051
+ throw new TypeError(`${context} response missing or invalid kind`);
16052
+ }
16053
+ if (typeof record.state !== "string" || !SCHEDULE_STATES2.has(record.state)) {
16054
+ throw new TypeError(`${context} response missing or invalid state`);
16055
+ }
16056
+ if (typeof record.target !== "object" || record.target == null || Array.isArray(record.target)) {
16057
+ throw new TypeError(`${context} response missing or invalid target`);
16058
+ }
16059
+ const target = record.target;
16060
+ if (typeof target.type !== "string" || target.type.length === 0) {
16061
+ throw new TypeError(`${context} response missing or invalid target type`);
16062
+ }
16063
+ if (!("catchup_policy" in record) || record.kind === "interval" && record.catchup_policy !== "fire_once" || record.kind !== "interval" && record.catchup_policy != null) {
16064
+ throw new TypeError(`${context} returned an invalid catchup_policy`);
16065
+ }
16066
+ if (typeof record.overlap_policy !== "string" || !SCHEDULE_OVERLAP_POLICIES.has(record.overlap_policy)) {
16067
+ throw new TypeError(`${context} response missing or invalid overlap_policy`);
16068
+ }
16069
+ safeNonNegativeInteger(record, "created_at_ms", context, true);
16070
+ const everyMs = requiredNullableNonNegativeInteger(record, "every_ms", context);
16071
+ const cron = requiredNullableResponseText(record, "cron", context);
16072
+ const timezone = requiredNullableResponseText(record, "timezone", context);
16073
+ const overlapRetryMs = requiredNullableNonNegativeInteger(
16074
+ record,
16075
+ "overlap_retry_ms",
16076
+ context
16077
+ );
16078
+ validateRecurrence(record, context, everyMs, cron, timezone, overlapRetryMs);
16079
+ let coalescedCount = 0;
16080
+ let lastCoalescedCount = 0;
16081
+ for (const field3 of REQUIRED_SCHEDULE_INTEGER_FIELDS) {
16082
+ const value2 = safeNonNegativeInteger(record, field3, context, true);
16083
+ if (field3 === "coalesced_count") coalescedCount = value2;
16084
+ if (field3 === "last_coalesced_count") lastCoalescedCount = value2;
16085
+ }
16086
+ for (const field3 of SCHEDULE_INTEGER_FIELDS) {
16087
+ if (record[field3] != null) safeNonNegativeInteger(record, field3, context);
16088
+ }
16089
+ for (const field3 of OPTIONAL_SCHEDULE_TEXT_FIELDS) {
16090
+ optionalResponseText(record, field3, context);
16091
+ }
16092
+ validateCatchupState(record, context, coalescedCount, lastCoalescedCount);
16093
+ return record;
16094
+ }
16095
+ function validateRecurrence(record, context, everyMs, cron, timezone, overlapRetryMs) {
16096
+ if (record.kind === "interval") {
16097
+ if (everyMs == null || everyMs <= 0) {
16098
+ throw new TypeError(`${context} interval every_ms must be positive`);
16099
+ }
16100
+ } else if (everyMs != null) {
16101
+ throw new TypeError(`${context} every_ms is only valid for interval schedules`);
16102
+ }
16103
+ if (record.kind === "cron") {
16104
+ if (cron == null) throw new TypeError(`${context} cron schedule is missing cron`);
16105
+ if (timezone == null) throw new TypeError(`${context} cron schedule is missing timezone`);
16106
+ } else if (cron != null) {
16107
+ throw new TypeError(`${context} cron is only valid for cron schedules`);
16108
+ } else if (timezone != null) {
16109
+ throw new TypeError(`${context} timezone is only valid for cron schedules`);
16110
+ }
16111
+ if (record.kind !== "interval" && record.kind !== "cron" && record.overlap_policy !== "allow") {
16112
+ throw new TypeError(`${context} overlap_policy is only valid for recurring schedules`);
16113
+ }
16114
+ if (overlapRetryMs != null) {
16115
+ if (overlapRetryMs <= 0) {
16116
+ throw new TypeError(`${context} overlap_retry_ms must be positive`);
16117
+ }
16118
+ if (record.overlap_policy !== "queue_after_previous") {
16119
+ throw new TypeError(`${context} overlap_retry_ms requires queue_after_previous`);
16120
+ }
16121
+ }
16122
+ }
16123
+ function validateCatchupState(record, context, coalescedCount, lastCoalescedCount) {
16124
+ const lastCatchupAt = record.last_catchup_at_ms;
16125
+ if (record.kind !== "interval") {
16126
+ if (coalescedCount !== 0) {
16127
+ throw new TypeError(`${context} non-interval coalesced_count must be zero`);
16128
+ }
16129
+ if (lastCoalescedCount !== 0) {
16130
+ throw new TypeError(`${context} non-interval last_coalesced_count must be zero`);
16131
+ }
16132
+ if (lastCatchupAt != null) {
16133
+ throw new TypeError(`${context} non-interval last_catchup_at_ms must be null`);
16134
+ }
16135
+ return;
16136
+ }
16137
+ if (lastCoalescedCount > coalescedCount) {
16138
+ throw new TypeError(`${context} last_coalesced_count exceeds coalesced_count`);
16139
+ }
16140
+ if (lastCoalescedCount > 0 && lastCatchupAt == null) {
16141
+ throw new TypeError(`${context} response missing last_catchup_at_ms after catch-up`);
16142
+ }
16143
+ if (lastCoalescedCount === 0 && lastCatchupAt != null) {
16144
+ throw new TypeError(`${context} last_catchup_at_ms requires a catch-up`);
16145
+ }
16146
+ }
16147
+ function optionalScheduleRecord(value, context) {
16148
+ return value == null ? null : scheduleRecordResponse(value, context);
16149
+ }
16150
+ function scheduleRecordList(value, context) {
16151
+ return arrayResponse(value).map((item) => scheduleRecordResponse(item, context));
16152
+ }
16153
+ function scheduleFireDueResponse(value) {
16154
+ const context = "FLOW.SCHEDULE.FIRE_DUE";
16155
+ const record = adminRecordResponse(value, context);
16156
+ const claimed = safeNonNegativeInteger(record, "claimed", context, true);
16157
+ const fired = safeNonNegativeInteger(record, "fired", context, true);
16158
+ const skipped = safeNonNegativeInteger(record, "skipped", context, true);
16159
+ const coalesced = safeNonNegativeInteger(record, "coalesced", context, true);
16160
+ if (!Array.isArray(record.errors)) {
16161
+ throw new TypeError(`${context} response missing errors`);
16162
+ }
16163
+ for (const error of record.errors) {
16164
+ if (!Array.isArray(error) || error.length !== 2 || typeof error[0] !== "string" || error[0].length === 0 || typeof error[1] !== "string" || error[1].length === 0) {
16165
+ throw new TypeError(`${context} returned an invalid error entry`);
16166
+ }
16167
+ }
16168
+ if (fired + skipped + record.errors.length !== claimed) {
16169
+ throw new TypeError(`${context} outcomes do not equal claimed`);
16170
+ }
16171
+ optionalResponseText(record, "claim_error", context);
16172
+ const lastTargetId = optionalResponseText(record, "last_target_id", context);
16173
+ const lastSkipReason = optionalResponseText(record, "last_skip_reason", context);
16174
+ if (fired > 0 && lastTargetId == null) {
16175
+ throw new TypeError(`${context} response missing last_target_id`);
16176
+ }
16177
+ if (fired === 0 && lastTargetId != null) {
16178
+ throw new TypeError(`${context} last_target_id requires a fired outcome`);
16179
+ }
16180
+ if (skipped > 0 && lastSkipReason == null) {
16181
+ throw new TypeError(`${context} response missing last_skip_reason`);
16182
+ }
16183
+ if (skipped === 0 && lastSkipReason != null) {
16184
+ throw new TypeError(`${context} last_skip_reason requires a skipped outcome`);
16185
+ }
16186
+ if (coalesced > 0 && fired + skipped === 0) {
16187
+ throw new TypeError(`${context} coalesced count requires a fired or skipped outcome`);
16188
+ }
16189
+ return record;
16190
+ }
16191
+ function scheduleFireResponse(value) {
16192
+ const context = "FLOW.SCHEDULE.FIRE";
16193
+ const record = adminRecordResponse(value, context);
16194
+ const schedule = scheduleRecordResponse(record.schedule, `${context} schedule`);
16195
+ const fired = safeNonNegativeInteger(record, "fired", context, true);
16196
+ const skipped = record.skipped == null ? 0 : safeNonNegativeInteger(record, "skipped", context);
16197
+ if (fired > 1 || skipped > 1 || fired + skipped !== 1) {
16198
+ throw new TypeError(`${context} outcomes must equal one`);
16199
+ }
16200
+ if (fired === 1 && (typeof record.target_id !== "string" || record.target_id.length === 0)) {
16201
+ throw new TypeError(`${context} response missing target_id`);
16202
+ }
16203
+ if (skipped === 1 && (typeof record.reason !== "string" || record.reason.length === 0)) {
16204
+ throw new TypeError(`${context} response missing reason`);
16205
+ }
16206
+ if (fired === 0 && record.target_id != null) {
16207
+ throw new TypeError(`${context} target_id requires a fired outcome`);
16208
+ }
16209
+ if (skipped === 0 && record.reason != null) {
16210
+ throw new TypeError(`${context} reason requires a skipped outcome`);
16211
+ }
16212
+ return { ...record, fired, skipped, schedule };
16213
+ }
16214
+ function optionalResponseText(record, field3, context) {
16215
+ const value = record[field3];
16216
+ if (value == null) return void 0;
16217
+ if (typeof value !== "string" || value.length === 0) {
16218
+ throw new TypeError(`${context} ${field3} must be non-empty text`);
15772
16219
  }
16220
+ return value;
16221
+ }
16222
+ function requiredNullableResponseText(record, field3, context) {
16223
+ if (!(field3 in record)) throw new TypeError(`${context} response missing ${field3}`);
16224
+ if (record[field3] === void 0) {
16225
+ throw new TypeError(`${context} response missing ${field3}`);
16226
+ }
16227
+ return optionalResponseText(record, field3, context) ?? null;
16228
+ }
16229
+ function requiredNullableNonNegativeInteger(record, field3, context) {
16230
+ if (!(field3 in record)) throw new TypeError(`${context} response missing ${field3}`);
16231
+ if (record[field3] === void 0) {
16232
+ throw new TypeError(`${context} response missing ${field3}`);
16233
+ }
16234
+ if (record[field3] === null) return null;
16235
+ return safeNonNegativeInteger(record, field3, context);
16236
+ }
16237
+ function safeNonNegativeInteger(record, field3, context, required = false) {
16238
+ if (!(field3 in record) || record[field3] == null) {
16239
+ if (required) throw new TypeError(`${context} response missing ${field3}`);
16240
+ return 0;
16241
+ }
16242
+ const value = record[field3];
16243
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
16244
+ throw new TypeError(`${context} ${field3} must be a safe non-negative integer`);
16245
+ }
16246
+ return value;
16247
+ }
16248
+
16249
+ // src/client-schedules.ts
16250
+ var FerricStoreScheduleClient = class extends FerricStoreClientCore {
15773
16251
  async scheduleCreate(id, options) {
16252
+ validateScheduleCreate(id, options);
15774
16253
  const args = ["FLOW.SCHEDULE.CREATE", id];
15775
16254
  append(args, "KIND", options.kind);
15776
16255
  append(args, "AT_MS", options.atMs);
@@ -15780,6 +16259,7 @@ var FerricStoreManagementClient = class extends FerricStoreClientCore {
15780
16259
  append(args, "CRON", options.cron);
15781
16260
  append(args, "TIMEZONE", options.timezone);
15782
16261
  append(args, "TARGET", options.target);
16262
+ append(args, "CATCHUP_POLICY", options.catchupPolicy);
15783
16263
  append(args, "OVERLAP_POLICY", options.overlapPolicy);
15784
16264
  append(args, "OVERLAP_RETRY_MS", options.overlapRetryMs);
15785
16265
  append(args, "MAX_FIRES", options.maxFires);
@@ -15789,34 +16269,55 @@ var FerricStoreManagementClient = class extends FerricStoreClientCore {
15789
16269
  for (const [name, value] of Object.entries(options.extraOptions ?? {})) {
15790
16270
  args.push(name.toUpperCase(), value);
15791
16271
  }
15792
- return adminRecordResponse(await this.commandArgs(args), "FLOW.SCHEDULE.CREATE");
16272
+ return scheduleRecordResponse(await this.commandArgs(args), "FLOW.SCHEDULE.CREATE");
15793
16273
  }
15794
- async scheduleGet(id, options = {}) {
15795
- const args = ["FLOW.SCHEDULE.GET", id];
15796
- append(args, "NOW", options.nowMs);
15797
- return optionalAdminRecord(await this.commandArgs(args), "FLOW.SCHEDULE.GET");
16274
+ async scheduleGet(id) {
16275
+ validateScheduleID(id);
16276
+ return optionalScheduleRecord(
16277
+ await this.commandArgs(["FLOW.SCHEDULE.GET", id]),
16278
+ "FLOW.SCHEDULE.GET"
16279
+ );
15798
16280
  }
15799
16281
  async scheduleFire(id, options = {}) {
15800
- return await this.scheduleStatus("FLOW.SCHEDULE.FIRE", id, options.nowMs);
16282
+ validateScheduleFire(id, options);
16283
+ const args = ["FLOW.SCHEDULE.FIRE", id];
16284
+ append(args, "FIRE_AT_MS", options.fireAtMs);
16285
+ append(args, "NOW", options.nowMs);
16286
+ return scheduleFireResponse(await this.commandArgs(args));
15801
16287
  }
15802
16288
  async schedulePause(id, options = {}) {
15803
- return await this.scheduleStatus("FLOW.SCHEDULE.PAUSE", id, options.nowMs);
16289
+ validateScheduleStatus(id, options.nowMs);
16290
+ return scheduleRecordResponse(
16291
+ await this.scheduleStatusResponse("FLOW.SCHEDULE.PAUSE", id, options.nowMs),
16292
+ "FLOW.SCHEDULE.PAUSE"
16293
+ );
15804
16294
  }
15805
16295
  async scheduleResume(id, options = {}) {
15806
- return await this.scheduleStatus("FLOW.SCHEDULE.RESUME", id, options.nowMs);
16296
+ validateScheduleStatus(id, options.nowMs);
16297
+ return scheduleRecordResponse(
16298
+ await this.scheduleStatusResponse("FLOW.SCHEDULE.RESUME", id, options.nowMs),
16299
+ "FLOW.SCHEDULE.RESUME"
16300
+ );
15807
16301
  }
15808
16302
  async scheduleDelete(id, options = {}) {
15809
- return await this.scheduleStatus("FLOW.SCHEDULE.DELETE", id, options.nowMs);
16303
+ validateScheduleStatus(id, options.nowMs);
16304
+ const response = await this.scheduleStatusResponse("FLOW.SCHEDULE.DELETE", id, options.nowMs);
16305
+ if (!okLike(response)) {
16306
+ throw new TypeError("FLOW.SCHEDULE.DELETE response must be OK");
16307
+ }
15810
16308
  }
15811
16309
  async scheduleFireDue(options = {}) {
16310
+ validateScheduleFireDue(options);
15812
16311
  const args = ["FLOW.SCHEDULE.FIRE_DUE"];
15813
16312
  append(args, "NOW", options.nowMs);
15814
16313
  append(args, "WORKER", options.worker);
16314
+ append(args, "LEASE_MS", options.leaseMs);
15815
16315
  append(args, "BLOCK", options.blockMs);
15816
16316
  append(args, "LIMIT", options.limit);
15817
- return adminRecordResponse(await this.commandArgs(args), "FLOW.SCHEDULE.FIRE_DUE");
16317
+ return scheduleFireDueResponse(await this.commandArgs(args));
15818
16318
  }
15819
16319
  async scheduleList(options = {}) {
16320
+ validateScheduleList(options);
15820
16321
  const args = ["FLOW.SCHEDULE.LIST"];
15821
16322
  append(args, "KIND", options.kind);
15822
16323
  append(args, "STATE", options.state);
@@ -15826,14 +16327,40 @@ var FerricStoreManagementClient = class extends FerricStoreClientCore {
15826
16327
  append(args, "TO_MS", options.toMs);
15827
16328
  append(args, "COUNT", options.count);
15828
16329
  appendBool(args, "REV", options.rev);
15829
- return adminRecordList(await this.commandArgs(args), "FLOW.SCHEDULE.LIST");
16330
+ return scheduleRecordList(await this.commandArgs(args), "FLOW.SCHEDULE.LIST");
15830
16331
  }
15831
- async scheduleStatus(command, id, now) {
16332
+ async scheduleStatusResponse(command, id, now) {
15832
16333
  const args = [command, id];
15833
16334
  append(args, "NOW", now);
15834
- const response = await this.commandArgs(args);
15835
- if (okLike(response)) return { id, status: "deleted" };
15836
- return adminRecordResponse(response, command);
16335
+ return await this.commandArgs(args);
16336
+ }
16337
+ };
16338
+
16339
+ // src/client-management.ts
16340
+ var FerricStoreManagementClient = class extends FerricStoreScheduleClient {
16341
+ async stats(type, options = {}) {
16342
+ const args = ["FLOW.STATS", type];
16343
+ append(args, "STATE", options.state);
16344
+ append(args, "COUNT", options.count);
16345
+ append(args, "PARTITION", options.partitionKey);
16346
+ appendAttributes(args, options.attributes);
16347
+ appendBool(args, "CONSISTENT_PROJECTION", options.consistentProjection);
16348
+ return adminRecordResponse(await this.commandArgs(args), "FLOW.STATS");
16349
+ }
16350
+ async countByState(type, state, options = {}) {
16351
+ const stats = await this.stats(type, { ...options, state });
16352
+ if (!("count" in stats)) throw new TypeError("FLOW.STATS response missing count");
16353
+ return integer(stats.count);
16354
+ }
16355
+ async attributes(type, options = {}) {
16356
+ const args = ["FLOW.ATTRIBUTES", type];
16357
+ appendAttributeQueryOptions(args, options);
16358
+ return adminRecordList(await this.commandArgs(args), "FLOW.ATTRIBUTES");
16359
+ }
16360
+ async attributeValues(type, attribute, options = {}) {
16361
+ const args = ["FLOW.ATTRIBUTE_VALUES", type, attribute];
16362
+ appendAttributeQueryOptions(args, options);
16363
+ return adminRecordList(await this.commandArgs(args), "FLOW.ATTRIBUTE_VALUES");
15837
16364
  }
15838
16365
  async effectReserve(id, effectKey, effectType, options) {
15839
16366
  const args = [
@@ -16171,15 +16698,15 @@ function assertFlowPolicyGeneration(value) {
16171
16698
  function flowPolicySnapshotFromResp(value) {
16172
16699
  const policy = requiredRecord(value, "FLOW policy snapshot");
16173
16700
  const maxActiveMs = optionalPositiveInteger(field(policy, "max_active_ms"), "max_active_ms");
16174
- const state = optionalText3(field(policy, "state"), "state");
16701
+ const state = optionalText4(field(policy, "state"), "state");
16175
16702
  const mode = optionalMode(field(policy, "mode"), "mode");
16176
16703
  const version = optionalVersion(field(policy, "version"));
16177
- const indexedStateMeta = optionalText3(field(policy, "indexed_state_meta"), "indexed_state_meta");
16704
+ const indexedStateMeta = optionalText4(field(policy, "indexed_state_meta"), "indexed_state_meta");
16178
16705
  const governance = optionalRecord(field(policy, "governance"), "governance");
16179
16706
  const states = optionalStates(field(policy, "states"));
16180
16707
  return {
16181
- type: requiredText3(field(policy, "type"), "type"),
16182
- generation: nonNegativeInteger2(field(policy, "generation"), "generation"),
16708
+ type: requiredText4(field(policy, "type"), "type"),
16709
+ generation: nonNegativeInteger3(field(policy, "generation"), "generation"),
16183
16710
  ...state == null ? {} : { state },
16184
16711
  ...version == null ? {} : { version },
16185
16712
  ...mode == null ? {} : { mode },
@@ -16197,21 +16724,21 @@ function retrySnapshot(value, context) {
16197
16724
  const retry2 = requiredRecord(value, `FLOW policy ${context}`);
16198
16725
  const backoff = requiredRecord(field(retry2, "backoff"), `FLOW policy ${context}.backoff`);
16199
16726
  return {
16200
- maxRetries: nonNegativeInteger2(field(retry2, "max_retries"), `${context}.max_retries`),
16727
+ maxRetries: nonNegativeInteger3(field(retry2, "max_retries"), `${context}.max_retries`),
16201
16728
  backoff: {
16202
16729
  kind: backoffKind(field(backoff, "kind"), `${context}.backoff.kind`),
16203
- baseMs: nonNegativeInteger2(field(backoff, "base_ms"), `${context}.backoff.base_ms`),
16204
- maxMs: nonNegativeInteger2(field(backoff, "max_ms"), `${context}.backoff.max_ms`),
16205
- jitterPct: nonNegativeInteger2(field(backoff, "jitter_pct"), `${context}.backoff.jitter_pct`)
16730
+ baseMs: nonNegativeInteger3(field(backoff, "base_ms"), `${context}.backoff.base_ms`),
16731
+ maxMs: nonNegativeInteger3(field(backoff, "max_ms"), `${context}.backoff.max_ms`),
16732
+ jitterPct: nonNegativeInteger3(field(backoff, "jitter_pct"), `${context}.backoff.jitter_pct`)
16206
16733
  },
16207
- exhaustedTo: requiredText3(field(retry2, "exhausted_to"), `${context}.exhausted_to`)
16734
+ exhaustedTo: requiredText4(field(retry2, "exhausted_to"), `${context}.exhausted_to`)
16208
16735
  };
16209
16736
  }
16210
16737
  function retentionSnapshot(value, context) {
16211
16738
  const retention = requiredRecord(value, `FLOW policy ${context}`);
16212
16739
  return {
16213
- ttlMs: nonNegativeInteger2(field(retention, "ttl_ms"), `${context}.ttl_ms`),
16214
- historyMaxEvents: nonNegativeInteger2(
16740
+ ttlMs: nonNegativeInteger3(field(retention, "ttl_ms"), `${context}.ttl_ms`),
16741
+ historyMaxEvents: nonNegativeInteger3(
16215
16742
  field(retention, "history_max_events"),
16216
16743
  `${context}.history_max_events`
16217
16744
  )
@@ -16247,7 +16774,7 @@ function requiredRecord(value, context) {
16247
16774
  if (value instanceof Map) {
16248
16775
  const result = {};
16249
16776
  for (const [key, item] of value.entries()) {
16250
- setOwnValue(result, requiredText3(key, `${context} key`), item);
16777
+ setOwnValue(result, requiredText4(key, `${context} key`), item);
16251
16778
  }
16252
16779
  return result;
16253
16780
  }
@@ -16266,21 +16793,21 @@ function stringArray(value, context) {
16266
16793
  if (!Object.hasOwn(value, index)) {
16267
16794
  throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
16268
16795
  }
16269
- result[index] = requiredText3(value[index], `${context}[${index}]`);
16796
+ result[index] = requiredText4(value[index], `${context}[${index}]`);
16270
16797
  }
16271
16798
  return result;
16272
16799
  }
16273
- function requiredText3(value, context) {
16800
+ function requiredText4(value, context) {
16274
16801
  if (typeof value === "string") return value;
16275
16802
  if (Buffer54.isBuffer(value) || value instanceof Uint8Array) {
16276
16803
  return Buffer54.from(value).toString("utf8");
16277
16804
  }
16278
16805
  throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
16279
16806
  }
16280
- function optionalText3(value, context) {
16281
- return value == null ? void 0 : requiredText3(value, context);
16807
+ function optionalText4(value, context) {
16808
+ return value == null ? void 0 : requiredText4(value, context);
16282
16809
  }
16283
- function nonNegativeInteger2(value, context) {
16810
+ function nonNegativeInteger3(value, context) {
16284
16811
  let parsed;
16285
16812
  try {
16286
16813
  parsed = integer(value);
@@ -16292,26 +16819,26 @@ function nonNegativeInteger2(value, context) {
16292
16819
  }
16293
16820
  function optionalPositiveInteger(value, context) {
16294
16821
  if (value == null) return void 0;
16295
- const parsed = nonNegativeInteger2(value, context);
16822
+ const parsed = nonNegativeInteger3(value, context);
16296
16823
  if (parsed === 0) throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
16297
16824
  return parsed;
16298
16825
  }
16299
16826
  function optionalVersion(value) {
16300
16827
  if (value == null) return void 0;
16301
16828
  if (typeof value === "number" || typeof value === "bigint") {
16302
- return nonNegativeInteger2(value, "version");
16829
+ return nonNegativeInteger3(value, "version");
16303
16830
  }
16304
- return requiredText3(value, "version");
16831
+ return requiredText4(value, "version");
16305
16832
  }
16306
16833
  function backoffKind(value, context) {
16307
- const kind = requiredText3(value, context).toLowerCase();
16834
+ const kind = requiredText4(value, context).toLowerCase();
16308
16835
  if (kind === "none" || kind === "fixed" || kind === "linear" || kind === "exponential") {
16309
16836
  return kind;
16310
16837
  }
16311
16838
  throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
16312
16839
  }
16313
16840
  function requiredMode(value, context) {
16314
- const mode = requiredText3(value, context).toLowerCase();
16841
+ const mode = requiredText4(value, context).toLowerCase();
16315
16842
  if (mode === "fifo" || mode === "parallel") return mode;
16316
16843
  throw new TypeError(`FLOW policy ${context} returned an unexpected response`);
16317
16844
  }
@@ -17843,7 +18370,7 @@ var LeaseRenewalGuard = class {
17843
18370
  if (options.leaseRenewal === false) {
17844
18371
  return;
17845
18372
  }
17846
- const intervalMs = positiveInteger2(options.leaseRenewIntervalMs, Math.max(1, Math.trunc(leaseMs / 2)));
18373
+ const intervalMs = positiveInteger3(options.leaseRenewIntervalMs, Math.max(1, Math.trunc(leaseMs / 2)));
17847
18374
  this.timer = setLongInterval(() => this.renew(), intervalMs);
17848
18375
  this.timer.unref();
17849
18376
  }
@@ -17915,7 +18442,7 @@ function snapshotLeasedJob(job) {
17915
18442
  return snapshot;
17916
18443
  }
17917
18444
  function workerConcurrency(options) {
17918
- return positiveInteger2(options.concurrency ?? options.workers, 1);
18445
+ return positiveInteger3(options.concurrency ?? options.workers, 1);
17919
18446
  }
17920
18447
  function workerRefillStrategy(options) {
17921
18448
  return options.refillStrategy === "wave" ? "wave" : "continuous";
@@ -17958,18 +18485,18 @@ function workerErrorPayload(error, options, codec) {
17958
18485
  }
17959
18486
  function workerBatchSize(options, flowManyBatchLimit = DEFAULT_FLOW_MANY_BATCH_LIMIT2) {
17960
18487
  return Math.min(
17961
- positiveInteger2(options.batchSize, 10),
17962
- positiveInteger2(flowManyBatchLimit, DEFAULT_FLOW_MANY_BATCH_LIMIT2)
18488
+ positiveInteger3(options.batchSize, 10),
18489
+ positiveInteger3(flowManyBatchLimit, DEFAULT_FLOW_MANY_BATCH_LIMIT2)
17963
18490
  );
17964
18491
  }
17965
18492
  function workerClaimLimit(options, flowManyBatchLimit = DEFAULT_FLOW_MANY_BATCH_LIMIT2) {
17966
18493
  return Math.min(workerBatchSize(options, flowManyBatchLimit), workerConcurrency(options));
17967
18494
  }
17968
18495
  function workerDrainBatches(options) {
17969
- return positiveInteger2(options.claimDrainBatches, 1);
18496
+ return positiveInteger3(options.claimDrainBatches, 1);
17970
18497
  }
17971
18498
  function workerLeaseMs(options, fallback = 3e4) {
17972
- return positiveInteger2(options.leaseMs, positiveInteger2(fallback, 3e4));
18499
+ return positiveInteger3(options.leaseMs, positiveInteger3(fallback, 3e4));
17973
18500
  }
17974
18501
  function workerIdleSleepMs(options) {
17975
18502
  return nonNegativeDuration(options.idleSleepMs, 250);
@@ -17981,7 +18508,7 @@ function workerClaimBlockMs(options, useBlocking) {
17981
18508
  if (options.signal == null || !Number.isFinite(options.blockMs) || options.blockMs < 0) {
17982
18509
  return options.blockMs;
17983
18510
  }
17984
- const abortPollMs = positiveInteger2(options.abortPollMs, 1e3);
18511
+ const abortPollMs = positiveInteger3(options.abortPollMs, 1e3);
17985
18512
  return options.blockMs === 0 ? abortPollMs : Math.min(Math.trunc(options.blockMs), abortPollMs);
17986
18513
  }
17987
18514
  function workerMaxIdleSleepMs(options, idleSleepMs = workerIdleSleepMs(options)) {
@@ -17992,14 +18519,14 @@ function nextWorkerIdleSleepMs(currentIdleSleepMs, maxIdleSleepMs) {
17992
18519
  return Math.min(maxIdleSleepMs, Math.max(1, currentIdleSleepMs * 2));
17993
18520
  }
17994
18521
  async function runContinuousWorkerPool(options) {
17995
- const concurrency = positiveInteger2(options.concurrency, 1);
17996
- const maxClaimSize = positiveInteger2(options.maxClaimSize, concurrency);
18522
+ const concurrency = positiveInteger3(options.concurrency, 1);
18523
+ const maxClaimSize = positiveInteger3(options.maxClaimSize, concurrency);
17997
18524
  const initialIdleSleepMs = nonNegativeDuration(options.idleSleepMs, 250);
17998
18525
  const maxIdleSleepMs = Math.max(
17999
18526
  initialIdleSleepMs,
18000
18527
  nonNegativeDuration(options.maxIdleSleepMs, 5e3)
18001
18528
  );
18002
- const refillDelayMs = nonNegativeInteger3(options.refillDelayMs, 0);
18529
+ const refillDelayMs = nonNegativeInteger4(options.refillDelayMs, 0);
18003
18530
  const active = /* @__PURE__ */ new Set();
18004
18531
  const pending = [];
18005
18532
  let pendingIndex = 0;
@@ -18115,10 +18642,10 @@ function normalizeWorkflowWorkerConfig(options) {
18115
18642
  ...captured
18116
18643
  });
18117
18644
  }
18118
- function positiveInteger2(value, fallback) {
18645
+ function positiveInteger3(value, fallback) {
18119
18646
  return value == null || !Number.isFinite(value) ? fallback : Math.max(1, Math.trunc(value));
18120
18647
  }
18121
- function nonNegativeInteger3(value, fallback) {
18648
+ function nonNegativeInteger4(value, fallback) {
18122
18649
  return value == null || !Number.isFinite(value) ? fallback : Math.max(0, Math.trunc(value));
18123
18650
  }
18124
18651
  function nonNegativeDuration(value, fallback) {
@@ -19002,13 +19529,13 @@ var QueueWorker = class {
19002
19529
 
19003
19530
  // src/flow-client-options.ts
19004
19531
  function snapshotFlowClientOptions(options, context) {
19005
- const own = { ...options };
19006
- if (typeof own.type !== "string" || own.type.length === 0) {
19532
+ const own2 = { ...options };
19533
+ if (typeof own2.type !== "string" || own2.type.length === 0) {
19007
19534
  throw new TypeError(`${context} type must be an own non-empty string`);
19008
19535
  }
19009
- const valueConfig = own.valueConfig;
19536
+ const valueConfig = own2.valueConfig;
19010
19537
  return Object.freeze({
19011
- ...own,
19538
+ ...own2,
19012
19539
  ...valueConfig == null ? {} : { valueConfig: Object.freeze({ ...valueConfig }) }
19013
19540
  });
19014
19541
  }
@@ -19431,19 +19958,19 @@ async function applyFail(client, ctx, outcome, returnRecord) {
19431
19958
 
19432
19959
  // src/workflow-registration.ts
19433
19960
  function createWorkflowStateRegistration(name, handler, options, defaultValueMaxBytes) {
19434
- const own = { ...options };
19435
- const claimValues = own.claimValues == null ? void 0 : snapshotOwnStringArray(own.claimValues, "claimValues");
19436
- const retryPolicy = own.retryPolicy == null ? void 0 : Object.freeze({ ...own.retryPolicy });
19961
+ const own2 = { ...options };
19962
+ const claimValues = own2.claimValues == null ? void 0 : snapshotOwnStringArray(own2.claimValues, "claimValues");
19963
+ const retryPolicy = own2.retryPolicy == null ? void 0 : Object.freeze({ ...own2.retryPolicy });
19437
19964
  return Object.freeze({
19438
- claimPayload: own.claimPayload ?? true,
19439
- claimRecord: own.claimRecord ?? true,
19440
- exceptionPolicy: normalizeExceptionPolicy(own.exceptionPolicy),
19965
+ claimPayload: own2.claimPayload ?? true,
19966
+ claimRecord: own2.claimRecord ?? true,
19967
+ exceptionPolicy: normalizeExceptionPolicy(own2.exceptionPolicy),
19441
19968
  handler,
19442
- leaseMs: own.leaseMs ?? 3e4,
19443
- ...own.mode == null ? {} : { mode: normalizeStateMode(own.mode) },
19969
+ leaseMs: own2.leaseMs ?? 3e4,
19970
+ ...own2.mode == null ? {} : { mode: normalizeStateMode(own2.mode) },
19444
19971
  name,
19445
- returnRecord: own.returnRecord ?? false,
19446
- valueMaxBytes: own.valueMaxBytes ?? defaultValueMaxBytes,
19972
+ returnRecord: own2.returnRecord ?? false,
19973
+ valueMaxBytes: own2.valueMaxBytes ?? defaultValueMaxBytes,
19447
19974
  ...claimValues == null ? {} : { claimValues },
19448
19975
  ...retryPolicy == null ? {} : { retryPolicy }
19449
19976
  });
@@ -19747,8 +20274,8 @@ var WorkflowWorker = class {
19747
20274
  };
19748
20275
 
19749
20276
  // src/version.ts
19750
- var FERRICSTORE_SDK_VERSION = "0.5.2";
19751
- var FERRICSTORE_MINIMUM_SERVER_VERSION = "0.11.0";
20277
+ var FERRICSTORE_SDK_VERSION = "0.11.4";
20278
+ var FERRICSTORE_MINIMUM_SERVER_VERSION = "0.11.4";
19752
20279
  var FERRICSTORE_NATIVE_PROTOCOL_VERSION = 1;
19753
20280
  export {
19754
20281
  BitmapStore,