@lostgradient/weft 0.12.0 → 0.14.0

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 (226) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/api.d.ts +2 -0
  3. package/dist/cli/api.js +3 -4
  4. package/dist/cli/generated/operation-catalog.snapshot.json +508 -12
  5. package/dist/cli/generated/operation-client.generated.d.ts +118 -10
  6. package/dist/cli/generated/operation-client.generated.js +74 -1
  7. package/dist/cli/help-text.d.ts +3 -3
  8. package/dist/cli/help-text.js +4 -4
  9. package/dist/cli/operation-catalog-snapshot.d.ts +12 -3
  10. package/dist/cli/operation-catalog-snapshot.js +14 -5
  11. package/dist/cli/operation-client-runtime.d.ts +29 -0
  12. package/dist/cli/schedule.js +1 -3
  13. package/dist/cli/serve-registrations.d.ts +3 -3
  14. package/dist/cli/serve-registrations.js +2 -2
  15. package/dist/cli/shutdown.d.ts +11 -0
  16. package/dist/cli/shutdown.js +25 -0
  17. package/dist/cli/validate.d.ts +1 -1
  18. package/dist/cli/version-check.d.ts +1 -1
  19. package/dist/cli/version-check.js +1 -1
  20. package/dist/cli-main.js +10 -29
  21. package/dist/client/client-storage.d.ts +24 -0
  22. package/dist/client/client-storage.js +14 -0
  23. package/dist/client/handle-delegation.d.ts +3 -3
  24. package/dist/client/handle-delegation.js +2 -2
  25. package/dist/client/http-client-requests.d.ts +5 -3
  26. package/dist/client/http-client-requests.js +20 -2
  27. package/dist/client/http-client-storage.d.ts +3 -0
  28. package/dist/client/http-client-storage.js +82 -0
  29. package/dist/client/http-client.d.ts +9 -6
  30. package/dist/client/http-client.js +13 -18
  31. package/dist/client/http-operations.d.ts +3 -1
  32. package/dist/client/http-operations.js +77 -1
  33. package/dist/client/http-request.d.ts +20 -14
  34. package/dist/client/http-request.js +21 -31
  35. package/dist/client/in-process-operations.d.ts +2 -2
  36. package/dist/client/in-process-operations.js +2 -2
  37. package/dist/client/index.d.ts +5 -1
  38. package/dist/client/index.js +13 -2
  39. package/dist/client/interface.d.ts +26 -26
  40. package/dist/client/local.d.ts +9 -6
  41. package/dist/client/local.js +9 -4
  42. package/dist/client/search-params.js +10 -6
  43. package/dist/client/start-body.d.ts +3 -1
  44. package/dist/client/start-body.js +9 -0
  45. package/dist/core/bulk-workflow-filter.d.ts +2 -1
  46. package/dist/core/bulk-workflow-filter.js +5 -1
  47. package/dist/core/context/parallel-operations.d.ts +0 -2
  48. package/dist/core/context/parallel-operations.js +0 -7
  49. package/dist/core/engine/async-activity-records.d.ts +12 -1
  50. package/dist/core/engine/async-activity-records.js +81 -2
  51. package/dist/core/engine/bulk-operations-purge.js +16 -1
  52. package/dist/core/engine/bulk-operations-shared.js +2 -0
  53. package/dist/core/engine/callback-checkpoint-persistence.d.ts +2 -0
  54. package/dist/core/engine/callback-checkpoint-persistence.js +6 -3
  55. package/dist/core/engine/callback-creators-schedule.d.ts +2 -1
  56. package/dist/core/engine/callback-creators-schedule.js +3 -3
  57. package/dist/core/engine/callback-creators.js +4 -22
  58. package/dist/core/engine/checkpoint-io.d.ts +1 -1
  59. package/dist/core/engine/checkpoint-reads.js +11 -1
  60. package/dist/core/engine/child-workflow.js +15 -6
  61. package/dist/core/engine/construction.js +3 -0
  62. package/dist/core/engine/disposal.js +2 -0
  63. package/dist/core/engine/engine-internal-types.d.ts +4 -1
  64. package/dist/core/engine/fenced-write.d.ts +5 -3
  65. package/dist/core/engine/finalizer-status.d.ts +10 -0
  66. package/dist/core/engine/finalizer-status.js +82 -0
  67. package/dist/core/engine/index.d.ts +26 -2
  68. package/dist/core/engine/index.js +71 -8
  69. package/dist/core/engine/internals.d.ts +3 -0
  70. package/dist/core/engine/lease-health.d.ts +64 -0
  71. package/dist/core/engine/lease-health.js +0 -0
  72. package/dist/core/engine/lease-manager.d.ts +4 -2
  73. package/dist/core/engine/lease-manager.js +32 -4
  74. package/dist/core/engine/lifecycle/recovered-services.js +0 -2
  75. package/dist/core/engine/lifecycle/shared.d.ts +11 -8
  76. package/dist/core/engine/lifecycle/start-batch.js +12 -0
  77. package/dist/core/engine/lifecycle/start.d.ts +1 -1
  78. package/dist/core/engine/lifecycle/start.js +34 -5
  79. package/dist/core/engine/operations-coordination.d.ts +1 -12
  80. package/dist/core/engine/operations-coordination.js +58 -11
  81. package/dist/core/engine/operations-speculate.d.ts +1 -1
  82. package/dist/core/engine/operations-speculate.js +19 -5
  83. package/dist/core/engine/parallel-dispatch.d.ts +1 -1
  84. package/dist/core/engine/parallel-dispatch.js +1 -1
  85. package/dist/core/engine/registration.js +14 -0
  86. package/dist/core/engine/review-list-entries.d.ts +1 -1
  87. package/dist/core/engine/review-list-entries.js +6 -30
  88. package/dist/core/engine/schedule-handle.d.ts +4 -4
  89. package/dist/core/engine/schedule-handle.js +2 -2
  90. package/dist/core/engine/schedule-overlap.d.ts +11 -0
  91. package/dist/core/engine/schedule-overlap.js +50 -0
  92. package/dist/core/engine/schedule-run.d.ts +11 -3
  93. package/dist/core/engine/schedule-run.js +27 -4
  94. package/dist/core/engine/schedule-timer.js +10 -1
  95. package/dist/core/engine/schedules.d.ts +5 -4
  96. package/dist/core/engine/schedules.js +62 -56
  97. package/dist/core/engine/state-utilities.js +1 -1
  98. package/dist/core/engine/storage-io.d.ts +12 -0
  99. package/dist/core/engine/storage-io.js +49 -10
  100. package/dist/core/engine/termination/finalizer-claim.d.ts +8 -6
  101. package/dist/core/engine/termination/finalizer-claim.js +2 -1
  102. package/dist/core/engine/termination/finalizer.js +10 -14
  103. package/dist/core/engine/timeline-coordinator-constants.d.ts +3 -0
  104. package/dist/core/engine/timeline-coordinator-constants.js +1 -0
  105. package/dist/core/engine/timeline-coordinator-detail.d.ts +13 -0
  106. package/dist/core/engine/timeline-coordinator-detail.js +76 -0
  107. package/dist/core/engine/validation/schedule-options.d.ts +8 -1
  108. package/dist/core/engine/validation/schedule-options.js +18 -0
  109. package/dist/core/engine/validation/schedule.d.ts +1 -1
  110. package/dist/core/engine/validation/schedule.js +27 -3
  111. package/dist/core/engine/validation.js +66 -2
  112. package/dist/core/engine/workflow-state-stream.d.ts +5 -1
  113. package/dist/core/engine/workflow-state-stream.js +37 -14
  114. package/dist/core/events/schedule-events.d.ts +3 -4
  115. package/dist/core/events/workflow-events.d.ts +2 -1
  116. package/dist/core/list-filter-validation.d.ts +3 -0
  117. package/dist/core/list-filter-validation.js +11 -0
  118. package/dist/core/registry-snapshot.d.ts +32 -0
  119. package/dist/core/registry-snapshot.js +28 -0
  120. package/dist/core/review/index.d.ts +91 -4
  121. package/dist/core/review/index.js +29 -0
  122. package/dist/core/types/activity.d.ts +52 -5
  123. package/dist/core/types/bulk.d.ts +1 -0
  124. package/dist/core/types/list-options.d.ts +6 -0
  125. package/dist/core/types/options.d.ts +6 -5
  126. package/dist/core/types/reviews.d.ts +2 -2
  127. package/dist/core/types/schedules.d.ts +45 -2
  128. package/dist/core/types/services-resolution.d.ts +5 -5
  129. package/dist/core/types/state.d.ts +64 -0
  130. package/dist/core/types/workflow-log.d.ts +3 -2
  131. package/dist/core/types/workflow-observability.d.ts +50 -0
  132. package/dist/core/types/workflow-observability.js +0 -0
  133. package/dist/core/types/workflow-registry.d.ts +7 -0
  134. package/dist/core/types.d.ts +1 -0
  135. package/dist/core/types.js +1 -0
  136. package/dist/diagnostics/validate.d.ts +9 -30
  137. package/dist/diagnostics/validate.js +83 -21
  138. package/dist/diagnostics/version-check.d.ts +2 -2
  139. package/dist/http.js +2 -2
  140. package/dist/index.d.ts +4 -3
  141. package/dist/indexeddb.js +1 -1
  142. package/dist/server/access-policy-metadata.d.ts +92 -0
  143. package/dist/server/access-policy-metadata.js +78 -0
  144. package/dist/server/fault-to-http.d.ts +3 -7
  145. package/dist/server/fault-to-http.js +2 -34
  146. package/dist/server/handler/index.js +1 -1
  147. package/dist/server/handler/route-dispatch.d.ts +10 -3
  148. package/dist/server/handler/route-dispatch.js +19 -4
  149. package/dist/server/index.d.ts +1 -1
  150. package/dist/server/index.js +1 -0
  151. package/dist/server/interactive-operations.js +2 -0
  152. package/dist/server/openapi-error-responses.js +41 -4
  153. package/dist/server/openapi.d.ts +3 -1
  154. package/dist/server/openapi.js +4 -0
  155. package/dist/server/openrpc-document-schema.d.ts +64 -0
  156. package/dist/server/openrpc-document-schema.js +6 -26
  157. package/dist/server/openrpc.d.ts +4 -0
  158. package/dist/server/openrpc.js +9 -33
  159. package/dist/server/operation-catalog/index.d.ts +1 -1
  160. package/dist/server/operation-catalog/raise-fault.d.ts +2 -1
  161. package/dist/server/operation-catalog/types.d.ts +2 -1
  162. package/dist/server/operation-fault.d.ts +22 -8
  163. package/dist/server/operation-fault.js +65 -13
  164. package/dist/server/operation-registry.d.ts +1 -1
  165. package/dist/server/operations/aggregate-workflows.d.ts +6 -0
  166. package/dist/server/operations/aggregate-workflows.js +3 -2
  167. package/dist/server/operations/async-activity.d.ts +14 -0
  168. package/dist/server/operations/async-activity.js +88 -4
  169. package/dist/server/operations/bulk-filter-helpers.d.ts +3 -0
  170. package/dist/server/operations/bulk-filter-helpers.js +27 -3
  171. package/dist/server/operations/bulk-mutate-workflow-tags.d.ts +6 -0
  172. package/dist/server/operations/bulk-signal-workflows.d.ts +6 -0
  173. package/dist/server/operations/get-stream-chunks.js +2 -7
  174. package/dist/server/operations/get-system-lease.d.ts +19 -0
  175. package/dist/server/operations/get-system-lease.js +48 -0
  176. package/dist/server/operations/get-workflow-observability.d.ts +24 -0
  177. package/dist/server/operations/get-workflow-observability.js +80 -0
  178. package/dist/server/operations/get-workflow-result.js +2 -2
  179. package/dist/server/operations/get-workflow.d.ts +2 -2
  180. package/dist/server/operations/list-filter-query-extractor.js +15 -0
  181. package/dist/server/operations/list-reviews.js +2 -19
  182. package/dist/server/operations/list-workflows.d.ts +6 -0
  183. package/dist/server/operations/list-workflows.js +12 -3
  184. package/dist/server/operations/operation-helpers.d.ts +9 -18
  185. package/dist/server/operations/operation-helpers.js +5 -23
  186. package/dist/server/operations/purge-workflows.d.ts +3 -0
  187. package/dist/server/operations/recover-all.js +1 -9
  188. package/dist/server/operations/single-workflow-control-operation.d.ts +2 -1
  189. package/dist/server/operations/single-workflow-tag-mutation.js +2 -2
  190. package/dist/server/operations/sse-stream.js +2 -7
  191. package/dist/server/operations/storage-capabilities.d.ts +34 -0
  192. package/dist/server/operations/storage-capabilities.js +38 -0
  193. package/dist/server/operations/storage.js +8 -17
  194. package/dist/server/operations/stream-workflow-sse.js +3 -9
  195. package/dist/server/operations/update-schedule.d.ts +8 -0
  196. package/dist/server/operations/update-schedule.js +70 -7
  197. package/dist/server/operations/workflow-events-sse.js +2 -2
  198. package/dist/server/rest-binding.d.ts +7 -6
  199. package/dist/server/rest-bindings.d.ts +2 -13
  200. package/dist/server/rest-bindings.js +19 -10
  201. package/dist/server/task-queue.d.ts +7 -5
  202. package/dist/storage/bounded-ndjson-response.d.ts +5 -0
  203. package/dist/storage/bounded-ndjson-response.js +33 -0
  204. package/dist/storage/capabilities.d.ts +1 -1
  205. package/dist/storage/cloudflare-value-codec.d.ts +5 -3
  206. package/dist/storage/cloudflare-value-codec.js +1 -1
  207. package/dist/storage/compressed-storage.js +1 -1
  208. package/dist/storage/http.js +5 -37
  209. package/dist/storage/index.d.ts +7 -1
  210. package/dist/storage/interface.d.ts +16 -4
  211. package/dist/storage/interface.js +1 -1
  212. package/dist/storage/key-prefixes.d.ts +1 -1
  213. package/dist/storage/key-prefixes.js +4 -0
  214. package/dist/storage/lmdb.js +1 -1
  215. package/dist/storage/memory.js +1 -1
  216. package/dist/storage/neon.d.ts +3 -16
  217. package/dist/storage/neon.js +4 -4
  218. package/dist/storage/postgres.js +4 -4
  219. package/dist/storage/resolve.js +1 -1
  220. package/dist/storage/scoped-storage.js +1 -1
  221. package/dist/storage/testing.js +1 -1
  222. package/dist/storage/turso.js +2 -2
  223. package/dist/version.d.ts +1 -1
  224. package/dist/version.js +1 -1
  225. package/dist/web-extension.js +1 -1
  226. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Design-time workflow validation for `weft validate`.
3
3
  *
4
- * Analyses workflow registrations for common anti-patterns:
4
+ * Analyses workflow definitions for common anti-patterns:
5
5
  *
6
6
  * 1. **Unbounded retry policy** — an activity whose `retry.maxAttempts` is
7
7
  * `Infinity` (or the workflow registration specifies `retry.maxAttempts`
@@ -21,27 +21,7 @@
21
21
  *
22
22
  * @module diagnostics/validate
23
23
  */
24
- import type { ConstraintDefinition } from '../core/constraint.ts';
25
- import type { ActivityDefinition, DefinitionSchema, RetentionPolicy, SearchAttributeSchema, WorkflowFunction } from '../core/types.ts';
26
- /**
27
- * Loosely-typed workflow registration shape used only by the `weft validate`
28
- * and `weft schedule` CLIs when loading workflow modules from disk. This is
29
- * intentionally separate from the public `WorkflowDefinition` type because
30
- * loaded modules historically export bare `{ handler, ... }` objects that
31
- * do not carry a `name` field — the registration key comes from the export
32
- * key, not the object itself.
33
- */
34
- export interface WorkflowRegistration<TInput = unknown, TOutput = unknown> {
35
- version?: string;
36
- description?: string;
37
- tags?: ReadonlyArray<string>;
38
- inputSchema?: DefinitionSchema<unknown, TInput>;
39
- outputSchema?: DefinitionSchema<unknown, TOutput>;
40
- handler: WorkflowFunction<TInput, TOutput>;
41
- searchAttributes?: SearchAttributeSchema;
42
- retention?: RetentionPolicy;
43
- constraints?: ConstraintDefinition[];
44
- }
24
+ import type { ActivityDefinition, WorkflowDefinition } from '../core/types.ts';
45
25
  export type ValidationIssueSeverity = 'error' | 'warning';
46
26
  export type ValidationIssueCode = 'unbounded-retry' | 'stateful-without-compensator' | 'non-serializable-input';
47
27
  export interface ValidationIssue {
@@ -52,7 +32,7 @@ export interface ValidationIssue {
52
32
  message: string;
53
33
  }
54
34
  export interface ValidationReport {
55
- /** Total number of workflow registrations scanned. */
35
+ /** Total number of workflow definitions scanned. */
56
36
  workflowCount: number;
57
37
  /** All detected issues across all registrations. */
58
38
  issues: ValidationIssue[];
@@ -60,16 +40,15 @@ export interface ValidationReport {
60
40
  valid: boolean;
61
41
  }
62
42
  /**
63
- * Validate a collection of workflow registrations for common anti-patterns.
43
+ * Validate a collection of workflow definitions for common anti-patterns.
64
44
  *
65
- * @param registrations A record of workflow type name WorkflowRegistration.
66
- * @param activities Optional list of ActivityDefinition objects to check.
67
- * Activities are not reachable from WorkflowRegistration
68
- * alone, so pass them explicitly when available.
45
+ * @param registrations A record of workflow type name to WorkflowDefinition.
46
+ * @param activities Optional standalone ActivityDefinition objects to check
47
+ * in addition to activities embedded in workflow definitions.
69
48
  */
70
- export declare function validateRegistrations(registrations: Record<string, WorkflowRegistration>, activities?: ActivityDefinition[]): ValidationReport;
49
+ export declare function validateRegistrations(registrations: Record<string, WorkflowDefinition>, activities?: ActivityDefinition[]): ValidationReport;
71
50
  export declare function loadRegistrationsFromModule(modulePath: string): Promise<{
72
- registrations: Record<string, WorkflowRegistration>;
51
+ registrations: Record<string, WorkflowDefinition>;
73
52
  activities: ActivityDefinition[];
74
53
  }>;
75
54
  /**
@@ -24,14 +24,11 @@ function checkStatefulWithoutCompensator(workflowType, activity) {
24
24
  }
25
25
  export function validateRegistrations(registrations, activities = []) {
26
26
  const issues = [], workflowTypes = Object.keys(registrations);
27
- for (const activity of activities) {
28
- const retryIssue = checkUnboundedRetry("(standalone)", activity);
29
- if (retryIssue)
30
- issues.push(retryIssue);
31
- const compensatorIssue = checkStatefulWithoutCompensator("(standalone)", activity);
32
- if (compensatorIssue)
33
- issues.push(compensatorIssue);
34
- }
27
+ for (const definition of Object.values(registrations))
28
+ for (const activity of workflowActivities(definition))
29
+ appendActivityIssues(issues, definition.name, activity);
30
+ for (const activity of activities)
31
+ appendActivityIssues(issues, "(standalone)", activity);
35
32
  const hasErrors = issues.some((i) => i.severity === "error");
36
33
  return {
37
34
  workflowCount: workflowTypes.length,
@@ -39,26 +36,91 @@ export function validateRegistrations(registrations, activities = []) {
39
36
  valid: !hasErrors
40
37
  };
41
38
  }
39
+ function appendActivityIssues(issues, workflowType, activity) {
40
+ const retryIssue = checkUnboundedRetry(workflowType, activity);
41
+ if (retryIssue)
42
+ issues.push(retryIssue);
43
+ const compensatorIssue = checkStatefulWithoutCompensator(workflowType, activity);
44
+ if (compensatorIssue)
45
+ issues.push(compensatorIssue);
46
+ }
47
+ function workflowActivities(definition) {
48
+ if (!("activities" in definition) || !isObject(definition.activities))
49
+ return [];
50
+ return Object.values(definition.activities).filter(isActivityDefinition);
51
+ }
42
52
  function collectFromExports(entries, registrations, activities, options) {
43
53
  for (const [key, value] of entries)
44
- if (isWorkflowRegistration(value)) {
45
- if (options.allowOverwrite || !(key in registrations))
46
- registrations[key] = value;
47
- } else if (isActivityDefinition(value)) {
48
- if (options.allowOverwrite || !activities.includes(value))
49
- activities.push(value);
50
- }
54
+ collectExport(key, value, registrations, activities, options);
55
+ }
56
+ function collectExport(key, value, registrations, activities, options) {
57
+ if (isWorkflowDefinition(value)) {
58
+ if (options.allowOverwrite || !Object.hasOwn(registrations, value.name))
59
+ registrations[value.name] = value;
60
+ return;
61
+ }
62
+ if (isActivityDefinition(value)) {
63
+ if (options.allowOverwrite || !activities.includes(value))
64
+ activities.push(value);
65
+ return;
66
+ }
67
+ if (!isObject(value))
68
+ return;
69
+ if (options.depth === 0 && isDefinitionMap(value)) {
70
+ collectFromExports(Object.entries(value), registrations, activities, {
71
+ ...options,
72
+ depth: options.depth + 1
73
+ });
74
+ return;
75
+ }
76
+ assertNotRemovedWorkflowShape(key, value);
51
77
  }
52
78
  export async function loadRegistrationsFromModule(modulePath) {
53
- const mod = await import(resolve(process.cwd(), modulePath)), registrations = {}, activities = [], defaultExport = mod.default;
54
- if (defaultExport !== null && typeof defaultExport === "object")
55
- collectFromExports(Object.entries(defaultExport), registrations, activities, { allowOverwrite: !0 });
79
+ const mod = await import(resolve(process.cwd(), modulePath)), registrations = Object.create(null), activities = [], defaultExport = mod.default;
80
+ if (defaultExport !== void 0)
81
+ collectFromExports([["default", defaultExport]], registrations, activities, {
82
+ allowOverwrite: !0,
83
+ depth: 0
84
+ });
56
85
  const namedEntries = Object.entries(mod).filter(([key]) => key !== "default");
57
- collectFromExports(namedEntries, registrations, activities, { allowOverwrite: !1 });
86
+ collectFromExports(namedEntries, registrations, activities, {
87
+ allowOverwrite: !1,
88
+ depth: 0
89
+ });
58
90
  return { registrations, activities };
59
91
  }
60
- function isWorkflowRegistration(value) {
61
- return typeof value === "object" && value !== null && "handler" in value && typeof value.handler === "function";
92
+ function isObject(value) {
93
+ return typeof value === "object" && value !== null;
94
+ }
95
+ function isRemovedWorkflowShape(value) {
96
+ if (!isObject(value) || !Object.hasOwn(value, "handler"))
97
+ return !1;
98
+ const handler = value.handler;
99
+ if (typeof handler !== "function")
100
+ return !1;
101
+ const functionKind = Object.prototype.toString.call(handler);
102
+ if (functionKind === "[object AsyncGeneratorFunction]")
103
+ return !0;
104
+ if ([
105
+ "version",
106
+ "description",
107
+ "tags",
108
+ "inputSchema",
109
+ "outputSchema",
110
+ "searchAttributes"
111
+ ].some((key) => Object.hasOwn(value, key)))
112
+ return !0;
113
+ return functionKind === "[object Function]" && Object.keys(value).length === 1;
114
+ }
115
+ function assertNotRemovedWorkflowShape(exportName, value) {
116
+ if (isRemovedWorkflowShape(value))
117
+ throw TypeError(`Workflow export "${exportName}" must be a builder-produced workflow definition with its own name. Create it with \`workflow({ name }).execute(handler)\`.`);
118
+ }
119
+ function isDefinitionMap(value) {
120
+ return Object.values(value).some((entry) => isWorkflowDefinition(entry) || isActivityDefinition(entry) || isRemovedWorkflowShape(entry));
121
+ }
122
+ function isWorkflowDefinition(value) {
123
+ return isObject(value) && typeof value.name === "string" && "handler" in value && typeof value.handler === "function";
62
124
  }
63
125
  function isActivityDefinition(value) {
64
126
  if (value === null || typeof value !== "object" && typeof value !== "function")
@@ -7,9 +7,9 @@
7
7
  *
8
8
  * @module diagnostics/version-check
9
9
  */
10
+ import type { WorkflowDefinition } from '../core/types.ts';
10
11
  import type { Storage } from '../storage/interface.ts';
11
12
  import type { VersionCheckReport } from './types.ts';
12
- import type { WorkflowRegistration } from './validate.ts';
13
13
  /**
14
14
  * Scans active (running and pending) workflows in `storage`, groups them by
15
15
  * type, and compares stored workflow versions against currently registered
@@ -31,4 +31,4 @@ import type { WorkflowRegistration } from './validate.ts';
31
31
  * console.log(report.overallVerdict); // 'safe'
32
32
  * ```
33
33
  */
34
- export declare function runVersionCheck(storage: Storage, registrations: Record<string, WorkflowRegistration>): Promise<VersionCheckReport>;
34
+ export declare function runVersionCheck(storage: Storage, registrations: Record<string, WorkflowDefinition>): Promise<VersionCheckReport>;
package/dist/http.js CHANGED
@@ -1,2 +1,2 @@
1
- function L(F){let G=[];for(let J=0;J<F.length;J+=512)G.push(String.fromCharCode(...F.subarray(J,J+512)));return btoa(G.join(""))}function A(F){let G=atob(F),J=new Uint8Array(G.length);for(let Q=0;Q<G.length;Q+=1)J[Q]=G.charCodeAt(Q);return J}function U(F){return typeof F==="object"&&F!==null&&!Array.isArray(F)}async function j(F,G){return await F.get(G)!==null}async function*X(F,G,J){for await(let[Q]of F.scan(G,J))yield Q}async function _(F,G){let J=0;for await(let Q of X(F,G))J++;return J}async function H(F,G){let J=[];for await(let Q of X(F,G))J.push({type:"delete",key:Q});if(J.length===0)return 0;return await F.batch(J),J.length}async function W(F,G,J){let Q=[];for await(let Z of X(F,G,J))Q.push({type:"delete",key:Z});if(Q.length===0)return 0;return await F.batch(Q),Q.length}function B(F,G,J){if(!F.capabilities()[G])throw Error(`Feature "${J}" requires storage capability "${G}", but this storage backend does not provide it.`)}var N=1e4;class R extends Error{code="StorageBatchOperationLimitExceededError";cap=N;count;target;constructor(F,G){super(`${F} count ${G} exceeds MAX_BATCH_OPERATIONS (${N}).`);this.name="StorageBatchOperationLimitExceededError",this.target=F,this.count=G}}function M(F,G){if(G>N)throw new R(F,G)}function C(F){return F.length>0?F.slice(0,-1)+String.fromCharCode(F.charCodeAt(F.length-1)+1):"ÿ"}function o(F,G={}){if(G.gt!==void 0&&F<=G.gt)return!1;if(G.gte!==void 0&&F<G.gte)return!1;if(G.lt!==void 0&&F>=G.lt)return!1;if(G.lte!==void 0&&F>G.lte)return!1;return!0}function e(F,G){if(F===null||G===null)return F===G;if(F.byteLength!==G.byteLength)return!1;for(let J=0;J<F.byteLength;J++)if(F[J]!==G[J])return!1;return!0}async function P(F,G){if(F.has)return F.has(G);return j(F,G)}function K(F,G,J){if(F.keys)return F.keys(G,J);return X(F,G,J)}async function S(F,G){if(F.count)return F.count(G);return _(F,G)}async function O(F,G){if(F.deletePrefix)return F.deletePrefix(G);return H(F,G)}async function b(F,G,J){if(M("conditionalBatch conditions",G.length),M("conditionalBatch operations",J.length),B(F,"conditionalBatch","storageConditionalBatch"),!F.conditionalBatch)throw Error("This storage backend reports conditionalBatch capability but does not implement the conditionalBatch() method.");return F.conditionalBatch(G,J)}function c(F){if(F===void 0)return;if(typeof F!=="number"||!Number.isInteger(F)||F<0)throw Error("deleteRange limit must be a finite non-negative integer");return F===0?0:F}function V(F){let G={},J=!1;for(let Z of["gt","gte","lt","lte"]){let $=F[Z];if($===void 0)continue;if(typeof $!=="string")throw Error("deleteRange bounds must be strings");G[Z]=$,J=!0}if(!J)throw Error("deleteRange requires at least one of gt/gte/lt/lte; use deletePrefix to delete a whole prefix");let Q=c(F.limit);if(Q!==void 0)G.limit=Q;return G}async function v(F,G,J){let Q=V(J);if(F.deleteRange)return F.deleteRange(G,Q);return W(F,G,Q)}function I(F,G){let J={key:F,open:!1};if(G.gte!==void 0&&G.gte>J.key)J.key=G.gte,J.open=!1;if(G.gt!==void 0&&G.gt>=J.key)J.key=G.gt,J.open=!0;return J}function g(F,G){let J={key:C(F),open:!0};if(G.lt!==void 0&&G.lt<=J.key)J.key=G.lt,J.open=!0;if(G.lte!==void 0&&G.lte<J.key)J.key=G.lte,J.open=!1;return J}function QF(F,G){let J=I(F,G),Q=g(F,G);if(J.key>Q.key||J.key===Q.key&&(J.open||Q.open))return null;return{lower:J,upper:Q}}function q(F){return F.replaceAll(/:+$/g,"")}function y(F,G){let J=q(F),Q=q(G);if(J.length===0)return Q;if(Q.length===0)return J;return`${J}:${Q}`}class D{#G;#J;constructor(F,G){this.#G=F,this.#J=q(G)}#F(F){if(this.#J.length===0)return F;return F.length===0?`${this.#J}:`:`${this.#J}:${F}`}#Q(F){if(this.#J.length===0)return F;return F.slice(this.#J.length+1)}#Z(F={}){let G={};if(F.limit!==void 0)G.limit=F.limit;if(F.reverse!==void 0)G.reverse=F.reverse;if(F.gt!==void 0)G.gt=this.#F(F.gt);if(F.gte!==void 0)G.gte=this.#F(F.gte);if(F.lt!==void 0)G.lt=this.#F(F.lt);if(F.lte!==void 0)G.lte=this.#F(F.lte);return G}#M(F){let G={};if(F.limit!==void 0)G.limit=F.limit;if(F.gt!==void 0)G.gt=this.#F(F.gt);if(F.gte!==void 0)G.gte=this.#F(F.gte);if(F.lt!==void 0)G.lt=this.#F(F.lt);if(F.lte!==void 0)G.lte=this.#F(F.lte);return G}capabilities(){return this.#G.capabilities()}scoped(F){return new D(this.#G,y(this.#J,F))}async get(F){return this.#G.get(this.#F(F))}async put(F,G){await this.#G.put(this.#F(F),G)}async delete(F){await this.#G.delete(this.#F(F))}async*scan(F,G){for await(let[J,Q]of this.#G.scan(this.#F(F),this.#Z(G)))yield[this.#Q(J),Q]}async batch(F){M("batch operations",F.length),await this.#G.batch(F.map((G)=>{if(G.type==="put")return{type:"put",key:this.#F(G.key),value:G.value};return{type:"delete",key:this.#F(G.key)}}))}async conditionalBatch(F,G){return b(this.#G,F.map((J)=>({key:this.#F(J.key),expectedValue:J.expectedValue})),G.map((J)=>{if(J.type==="put")return{type:"put",key:this.#F(J.key),value:J.value};return{type:"delete",key:this.#F(J.key)}}))}async has(F){return P(this.#G,this.#F(F))}async deletePrefix(F){return O(this.#G,this.#F(F))}async deleteRange(F,G){let J=this.#M(V(G));return v(this.#G,this.#F(F),J)}async*keys(F,G){for await(let J of K(this.#G,this.#F(F),this.#Z(G)))yield this.#Q(J)}async count(F){return S(this.#G,this.#F(F))}[Symbol.dispose](){this.#G[Symbol.dispose]()}}function h(F,G){return new D(F,G)}var u=67108864;function m(F){if(F.type==="put")return{type:"put",key:F.key,value:L(F.value)};return{type:"delete",key:F.key}}function k(F){return{key:F.key,expectedValue:F.expectedValue===null?null:L(F.expectedValue)}}function w(F){if(!U(F)||typeof F.key!=="string"||typeof F.value!=="string")throw Error("HTTPStorage scan response contained an invalid NDJSON entry.");return{key:F.key,value:F.value}}function f(F){if(!U(F)||typeof F.applied!=="boolean")throw Error('HTTPStorage conditional batch response must include a boolean "applied" field.');return F.applied}function Y(F,G,J){if(J!==void 0)F.searchParams.set(G,String(J))}function l(F){if(F.trim().length===0)return null;let G=w(JSON.parse(F));return[G.key,A(G.value)]}function d(F){if(F>u)throw Error("HTTPStorage scan response exceeded the maximum allowed size.")}async function*p(F){if(F.body===null)return;let G=F.body.getReader(),J=new TextDecoder,Q="",Z=0,$=!1;try{while(!0){let{done:E,value:T}=await G.read();if(E){$=!0;break}Z+=T.byteLength,d(Z),Q+=J.decode(T,{stream:!0});let z=Q.split(`
2
- `);Q=z.pop()??"";for(let x of z)yield x}if(Q+=J.decode(),Q.length>0)yield Q}finally{try{if(!$)await G.cancel()}catch{}G.releaseLock()}}class a{#G;#J;#F;constructor(F){this.#G=F.baseUrl instanceof URL?F.baseUrl:new URL(F.baseUrl),this.#J={...F.headers},this.#F=F.remoteConditionalBatch??!1}capabilities(){return{persistence:"remote",readAfterWrite:"eventual",scanConsistency:"best-effort",atomicBatch:!0,conditionalBatch:this.#F,boundedRangeDelete:!1}}#Q(F){let G=this.#G.href.endsWith("/")?this.#G.href:`${this.#G.href}/`;return new URL(F.replace(/^\/+/,""),G)}#Z(F){return this.#Q(`/v1/storage/${encodeURIComponent(F)}`)}#M(F,G){let J=this.#Q("/v1/storage");return J.searchParams.set("prefix",F),Y(J,"limit",G.limit),Y(J,"reverse",G.reverse),Y(J,"gt",G.gt),Y(J,"gte",G.gte),Y(J,"lt",G.lt),Y(J,"lte",G.lte),J}async#$(F,G={},J=[]){let Q=new Headers(this.#J);for(let[$,E]of new Headers(G.headers).entries())Q.set($,E);let Z=await fetch(F,{...G,headers:Q});if(!Z.ok&&!J.includes(Z.status))throw Error(`HTTPStorage request failed: ${G.method??"GET"} ${F.pathname} returned ${String(Z.status)}.`);return Z}async get(F){let G=await this.#$(this.#Z(F),{method:"GET"},[404]);if(G.status===404)return null;return new Uint8Array(await G.arrayBuffer())}async put(F,G){await this.#$(this.#Z(F),{method:"PUT",headers:{"content-type":"application/octet-stream"},body:new Blob([G])})}async delete(F){await this.#$(this.#Z(F),{method:"DELETE"})}async*scan(F,G={}){let J=await this.#$(this.#M(F,G),{method:"GET",headers:{accept:"application/x-ndjson"}});for await(let Q of p(J)){let Z=l(Q);if(Z!==null)yield Z}}async batch(F){M("batch operations",F.length),await this.#$(this.#Q("/v1/storage/-/batch"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({operations:F.map(m)})})}async conditionalBatch(F,G){M("conditionalBatch conditions",F.length),M("conditionalBatch operations",G.length);let J=await this.#$(this.#Q("/v1/storage/-/conditional-batch"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({conditions:F.map(k),operations:G.map(m)})});return f(await J.json())}has(F){return j(this,F)}async*keys(F,G){yield*X(this,F,G)}count(F){return _(this,F)}deletePrefix(F){return H(this,F)}deleteRange(F,G){return W(this,F,V(G))}scoped(F){return h(this,F)}[Symbol.dispose](){}}export{a as HTTPStorage};
1
+ async function*R(F,G){if(F.body===null)return;let J=F.body.getReader(),Q=new TextDecoder,Z="",$=0,j=!1;try{while(!0){let{done:y,value:z}=await J.read();if(y){j=!0;break}if($+=z.byteLength,$>G.maximumBytes)throw G.sizeLimitError();Z+=Q.decode(z,{stream:!0});let A=Z.split(`
2
+ `);Z=A.pop()??"";for(let g of A)yield g}if(Z+=Q.decode(),Z.length>0)yield Z}finally{if(!j)try{await J.cancel()}catch{}J.releaseLock()}}function N(F){let G=[];for(let J=0;J<F.length;J+=512)G.push(String.fromCharCode(...F.subarray(J,J+512)));return btoa(G.join(""))}function B(F){let G=atob(F),J=new Uint8Array(G.length);for(let Q=0;Q<G.length;Q+=1)J[Q]=G.charCodeAt(Q);return J}function q(F){return typeof F==="object"&&F!==null&&!Array.isArray(F)}async function _(F,G){return await F.get(G)!==null}async function*X(F,G,J){for await(let[Q]of F.scan(G,J))yield Q}async function H(F,G){let J=0;for await(let Q of X(F,G))J++;return J}async function L(F,G){let J=[];for await(let Q of X(F,G))J.push({type:"delete",key:Q});if(J.length===0)return 0;return await F.batch(J),J.length}async function U(F,G,J){let Q=[];for await(let Z of X(F,G,J))Q.push({type:"delete",key:Z});if(Q.length===0)return 0;return await F.batch(Q),Q.length}function C(F,G,J){if(!F.capabilities()[G])throw Error(`Feature "${J}" requires storage capability "${G}", but this storage backend does not provide it.`)}var D=1e4;class T extends Error{code="StorageBatchOperationLimitExceededError";cap=D;count;target;constructor(F,G){super(`${F} count ${G} exceeds MAX_BATCH_OPERATIONS (${D}).`);this.name="StorageBatchOperationLimitExceededError",this.target=F,this.count=G}}function M(F,G){if(G>D)throw new T(F,G)}function S(F){return F.length>0?F.slice(0,-1)+String.fromCharCode(F.charCodeAt(F.length-1)+1):"ÿ"}function e(F,G={}){if(G.gt!==void 0&&F<=G.gt)return!1;if(G.gte!==void 0&&F<G.gte)return!1;if(G.lt!==void 0&&F>=G.lt)return!1;if(G.lte!==void 0&&F>G.lte)return!1;return!0}function FF(F,G){if(F===null||G===null)return F===G;if(F.byteLength!==G.byteLength)return!1;for(let J=0;J<F.byteLength;J++)if(F[J]!==G[J])return!1;return!0}async function K(F,G){if(F.has)return F.has(G);return _(F,G)}function P(F,G,J){if(F.keys)return F.keys(G,J);return X(F,G,J)}async function O(F,G){if(F.count)return F.count(G);return H(F,G)}async function b(F,G){if(F.deletePrefix)return F.deletePrefix(G);return L(F,G)}async function v(F,G,J){if(M("conditionalBatch conditions",G.length),M("conditionalBatch operations",J.length),C(F,"conditionalBatch","storageConditionalBatch"),!F.conditionalBatch)throw Error("This storage backend reports conditionalBatch capability but does not implement the conditionalBatch() method.");return F.conditionalBatch(G,J)}function c(F){if(F===void 0)return;if(typeof F!=="number"||!Number.isInteger(F)||F<0)throw Error("deleteRange limit must be a finite non-negative integer");return F===0?0:F}function V(F){let G={},J=!1;for(let Z of["gt","gte","lt","lte"]){let $=F[Z];if($===void 0)continue;if(typeof $!=="string")throw Error("deleteRange bounds must be strings");G[Z]=$,J=!0}if(!J)throw Error("deleteRange requires at least one of gt/gte/lt/lte; use deletePrefix to delete a whole prefix");let Q=c(F.limit);if(Q!==void 0)G.limit=Q;return G}async function h(F,G,J){let Q=V(J);if(F.deleteRange)return F.deleteRange(G,Q);return U(F,G,Q)}function I(F,G){let J={key:F,open:!1};if(G.gte!==void 0&&G.gte>J.key)J.key=G.gte,J.open=!1;if(G.gt!==void 0&&G.gt>=J.key)J.key=G.gt,J.open=!0;return J}function u(F,G){let J={key:S(F),open:!0};if(G.lt!==void 0&&G.lt<=J.key)J.key=G.lt,J.open=!0;if(G.lte!==void 0&&G.lte<J.key)J.key=G.lte,J.open=!1;return J}function ZF(F,G){let J=I(F,G),Q=u(F,G);if(J.key>Q.key||J.key===Q.key&&(J.open||Q.open))return null;return{lower:J,upper:Q}}function E(F){return F.replaceAll(/:+$/g,"")}function k(F,G){let J=E(F),Q=E(G);if(J.length===0)return Q;if(Q.length===0)return J;return`${J}:${Q}`}class W{#G;#J;constructor(F,G){this.#G=F,this.#J=E(G)}#F(F){if(this.#J.length===0)return F;return F.length===0?`${this.#J}:`:`${this.#J}:${F}`}#Q(F){if(this.#J.length===0)return F;return F.slice(this.#J.length+1)}#Z(F={}){let G={};if(F.limit!==void 0)G.limit=F.limit;if(F.reverse!==void 0)G.reverse=F.reverse;if(F.gt!==void 0)G.gt=this.#F(F.gt);if(F.gte!==void 0)G.gte=this.#F(F.gte);if(F.lt!==void 0)G.lt=this.#F(F.lt);if(F.lte!==void 0)G.lte=this.#F(F.lte);return G}#M(F){let G={};if(F.limit!==void 0)G.limit=F.limit;if(F.gt!==void 0)G.gt=this.#F(F.gt);if(F.gte!==void 0)G.gte=this.#F(F.gte);if(F.lt!==void 0)G.lt=this.#F(F.lt);if(F.lte!==void 0)G.lte=this.#F(F.lte);return G}capabilities(){return this.#G.capabilities()}scoped(F){return new W(this.#G,k(this.#J,F))}async get(F){return this.#G.get(this.#F(F))}async put(F,G){await this.#G.put(this.#F(F),G)}async delete(F){await this.#G.delete(this.#F(F))}async*scan(F,G){for await(let[J,Q]of this.#G.scan(this.#F(F),this.#Z(G)))yield[this.#Q(J),Q]}async batch(F){M("batch operations",F.length),await this.#G.batch(F.map((G)=>{if(G.type==="put")return{type:"put",key:this.#F(G.key),value:G.value};return{type:"delete",key:this.#F(G.key)}}))}async conditionalBatch(F,G){return v(this.#G,F.map((J)=>({key:this.#F(J.key),expectedValue:J.expectedValue})),G.map((J)=>{if(J.type==="put")return{type:"put",key:this.#F(J.key),value:J.value};return{type:"delete",key:this.#F(J.key)}}))}async has(F){return K(this.#G,this.#F(F))}async deletePrefix(F){return b(this.#G,this.#F(F))}async deleteRange(F,G){let J=this.#M(V(G));return h(this.#G,this.#F(F),J)}async*keys(F,G){for await(let J of P(this.#G,this.#F(F),this.#Z(G)))yield this.#Q(J)}async count(F){return O(this.#G,this.#F(F))}[Symbol.dispose](){this.#G[Symbol.dispose]()}}function m(F,G){return new W(F,G)}var w=67108864;function x(F){if(F.type==="put")return{type:"put",key:F.key,value:N(F.value)};return{type:"delete",key:F.key}}function f(F){return{key:F.key,expectedValue:F.expectedValue===null?null:N(F.expectedValue)}}function d(F){if(!q(F)||typeof F.key!=="string"||typeof F.value!=="string")throw Error("HTTPStorage scan response contained an invalid NDJSON entry.");return{key:F.key,value:F.value}}function l(F){if(!q(F)||typeof F.applied!=="boolean")throw Error('HTTPStorage conditional batch response must include a boolean "applied" field.');return F.applied}function Y(F,G,J){if(J!==void 0)F.searchParams.set(G,String(J))}function p(F){if(F.trim().length===0)return null;let G=d(JSON.parse(F));return[G.key,B(G.value)]}class a{#G;#J;#F;constructor(F){this.#G=F.baseUrl instanceof URL?F.baseUrl:new URL(F.baseUrl),this.#J={...F.headers},this.#F=F.remoteConditionalBatch??!1}capabilities(){return{persistence:"remote",readAfterWrite:"eventual",scanConsistency:"best-effort",atomicBatch:!0,conditionalBatch:this.#F,boundedRangeDelete:!1}}#Q(F){let G=this.#G.href.endsWith("/")?this.#G.href:`${this.#G.href}/`;return new URL(F.replace(/^\/+/,""),G)}#Z(F){return this.#Q(`/v1/storage/${encodeURIComponent(F)}`)}#M(F,G){let J=this.#Q("/v1/storage");return J.searchParams.set("prefix",F),Y(J,"limit",G.limit),Y(J,"reverse",G.reverse),Y(J,"gt",G.gt),Y(J,"gte",G.gte),Y(J,"lt",G.lt),Y(J,"lte",G.lte),J}async#$(F,G={},J=[]){let Q=new Headers(this.#J);for(let[$,j]of new Headers(G.headers).entries())Q.set($,j);let Z=await fetch(F,{...G,headers:Q});if(!Z.ok&&!J.includes(Z.status))throw Error(`HTTPStorage request failed: ${G.method??"GET"} ${F.pathname} returned ${String(Z.status)}.`);return Z}async get(F){let G=await this.#$(this.#Z(F),{method:"GET"},[404]);if(G.status===404)return null;return new Uint8Array(await G.arrayBuffer())}async put(F,G){await this.#$(this.#Z(F),{method:"PUT",headers:{"content-type":"application/octet-stream"},body:new Blob([G])})}async delete(F){await this.#$(this.#Z(F),{method:"DELETE"})}async*scan(F,G={}){let J=await this.#$(this.#M(F,G),{method:"GET",headers:{accept:"application/x-ndjson"}});for await(let Q of R(J,{maximumBytes:w,sizeLimitError:()=>Error("HTTPStorage scan response exceeded the maximum allowed size.")})){let Z=p(Q);if(Z!==null)yield Z}}async batch(F){M("batch operations",F.length),await this.#$(this.#Q("/v1/storage/-/batch"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({operations:F.map(x)})})}async conditionalBatch(F,G){M("conditionalBatch conditions",F.length),M("conditionalBatch operations",G.length);let J=await this.#$(this.#Q("/v1/storage/-/conditional-batch"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({conditions:F.map(f),operations:G.map(x)})});return l(await J.json())}has(F){return _(this,F)}async*keys(F,G){yield*X(this,F,G)}count(F){return H(this,F)}deletePrefix(F){return L(this,F)}deleteRange(F,G){return U(this,F,V(G))}scoped(F){return m(this,F)}[Symbol.dispose](){}}export{a as HTTPStorage};
package/dist/index.d.ts CHANGED
@@ -22,9 +22,9 @@ export { FAULT_CODE_TO_FAILURE_CATEGORY, failureCategoryForFaultCode, isFaultCod
22
22
  export type { FaultCode } from './core/fault-code.ts';
23
23
  export { DurableActivityScopeError, DurableActivityUnsupportedError, durableActivity, } from './core/context/durable-activity.ts';
24
24
  export { ActivityReconciliationCapabilityError, ActivityReconciliationConflictError, ActivityReconciliationIndeterminateError, ActivityResolutionError, AsyncActivityTokenNotFoundError, BulkDeleteRequiresTerminalWorkflowsError, BulkOperationConfirmationError, ENGINE_LEASE_LOST_WARNING_NAME, ENGINE_LEASE_SYNCHRONOUS_DISPOSE_WARNING_NAME, Engine, EngineCreateNameMismatchError, EngineDisposedError, EngineLeaseAcquisitionTimeoutError, EngineLeaseCorruptedError, EngineLeaseNotHeldError, IdempotencyKeyPurgedError, PersistedDataIncompatibleError, ScheduleHandle, StartOrSignalConflictError, WorkflowAlreadyExistsError, WorkflowConcurrencyLimitExceededError, WorkflowHandle, WorkflowNotFoundError, WorkflowNotRegisteredError, WorkflowSuspendNotSupportedError, WorkflowTeardownPendingError, WorkflowTypeNotRegisteredForRecoveryError, } from './core/engine';
25
- export type { EngineCreateOptions, EngineStateNamespace, RecoverAllOptions, RecoveredWorkflowInfo, } from './core/engine';
25
+ export type { EngineCreateOptions, EngineLeaseHealth, EngineStateNamespace, LeaseLostReason, RecoverAllOptions, RecoveredWorkflowInfo, } from './core/engine';
26
26
  export { DEFAULT_CHECKPOINT_SIZE_WARNING_THRESHOLD, DEFAULT_MAX_NESTING_DEPTH, DEFAULT_POLL_INTERVAL_MS, DEFAULT_RETRY_POLICY, DEFAULT_VISIBILITY_TIMEOUT_MS, HISTORY_CIRCUIT_BREAKER_REASON, WorkflowBuilderError, query, schedule, signal, update, workflow, } from './core/types';
27
- export type { ActivityArgsFor, ActivityCallOptions, ActivityCallable, ActivityContext, ActivityDefinition, ActivityEntryInput, ActivityFunction, ActivityMap, ActivityMapInput, ActivityObjectInput, ActivityResultFor, ActivityVerificationContext, ActivityVerificationPhase, ActivityVerificationResult, AnyActivityDefinition, AnyWorkflowDefinition, ArchiveAdapter, BuilderState, BuiltWorkflowDefinition, BulkCancelResult, BulkDeleteResult, BulkOperationAction, BulkOperationAuditEvent, BulkOperationCommitOptions, BulkOperationDryRunOptions, BulkOperationDryRunResult, BulkOperationError, BulkOperationFilterSummary, BulkOperationOptions, BulkOperationPrincipal, BulkOperationScopeSummary, BulkRetryFailedResult, BulkSignalAllCommitOptions, BulkSignalAllDryRunOptions, BulkSignalAllOptions, BulkSignalResult, BulkTagResult, Checkpoint, CheckpointState, CheckpointSummary, CompletedReviewEntry, CoordinatedUpdateResult, DefinitionSchema, Duration, EngineOptions, FailureCategory, ForkLineage, ForkOptions, HistoryPolicy, InferActivityEntries, InferActivityEntry, InferWorkflowEntries, InferWorkflowEntry, InitialBuilderState, LaunchMetadata, ListFilter, ListOptions, MarkBuilderState, NormalizeActivities, NormalizedActivityEntry, NormalizedRetentionPolicy, PaginatedResult, PayloadSizePolicy, PendingReviewEntry, PurgeResult, QueryDefinition, QueryMap, QueryShape, RegisteredWorkflowDefinition, RetentionOverview, RetentionPolicy, RetryPolicy, ReviewListEntry, ReviewListFilter, ReviewStatus, ScheduleDefinition, ScheduleFilter, ScheduleOptions, ScheduleOverlapPolicy, ScheduleSpec, ScheduleState, ScheduleStatus, ScheduleSummary, SearchAttributeDefinition, SearchAttributeHandle, SearchAttributeSchema, SearchAttributeValue, Serializer, SignalDefinition, SignalDeliveryOptions, SignalMap, SignalPayload, StartOptions, StartOrSignalOptions, StartOrSignalSignal, SubmitReviewOptions, TerminationReason, UpdateDefinition, UpdateMap, UpdatePayload, WorkerReplayOperationFailure, WorkerReplayOperationSignature, WorkflowAlreadyRegistered, WorkflowAtomicState, WorkflowAtomicStateOptions, WorkflowBuilder, WorkflowBuilderOptions, WorkflowConcurrencyOptions, WorkflowContext, WorkflowDefinition, WorkflowEvent, WorkflowFunction, WorkflowGenerator, WorkflowId, WorkflowKeyedRaceResult, WorkflowLogLevel, WorkflowLogRecord, WorkflowLogger, WorkflowRegistry, WorkflowReplay, WorkflowServicesResolution, WorkflowServicesResolverInfo, WorkflowServicesResolverLaunchOptions, WorkflowServicesResolverScheduleInfo, WorkflowSessionState, WorkflowSnapshot, WorkflowState, WorkflowStateNamespace, WorkflowStatus, WorkflowSummary, WorkflowTimelineEntry, WorkflowTimelineStatus, WorkflowTypeRetentionPolicy, } from './core/types';
27
+ export type { ActivityArgsFor, ActivityCallOptions, ActivityCallable, ActivityContext, ActivityDefinition, ActivityEntryInput, ActivityFunction, ActivityMap, ActivityMapInput, ActivityObjectInput, ActivityResultFor, ActivityVerificationContext, ActivityVerificationPhase, ActivityVerificationResult, AnyActivityDefinition, AnyWorkflowDefinition, ArchiveAdapter, BuilderState, BuiltWorkflowDefinition, BulkCancelResult, BulkDeleteResult, BulkOperationAction, BulkOperationAuditEvent, BulkOperationCommitOptions, BulkOperationDryRunOptions, BulkOperationDryRunResult, BulkOperationError, BulkOperationFilterSummary, BulkOperationOptions, BulkOperationPrincipal, BulkOperationScopeSummary, BulkRetryFailedResult, BulkSignalAllCommitOptions, BulkSignalAllDryRunOptions, BulkSignalAllOptions, BulkSignalResult, BulkTagResult, Checkpoint, CheckpointState, CheckpointSummary, CompletedReviewEntry, CoordinatedUpdateResult, DefinitionSchema, Duration, EngineOptions, FailureCategory, ForkLineage, ForkOptions, HistoryPolicy, InferActivityEntries, InferActivityEntry, InferWorkflowEntries, InferWorkflowEntry, InitialBuilderState, LaunchMetadata, ListFilter, ListOptions, MarkBuilderState, NormalizeActivities, NormalizedActivityEntry, NormalizedRetentionPolicy, PaginatedResult, PayloadSizePolicy, PendingAsyncActivityInfo, PendingAsyncActivityListOptions, PendingAsyncActivityPage, PendingReviewEntry, PurgeResult, QueryDefinition, QueryMap, QueryShape, RegisteredWorkflowDefinition, RestartLineage, RetentionOverview, RetentionPolicy, RetryPolicy, ReviewDecision, ReviewListEntry, ReviewListFilter, ReviewStatus, ScheduleDefinition, ScheduleFilter, ScheduleOptions, ScheduleOverlapPolicy, ScheduleQueuedRun, ScheduleSpec, ScheduleState, ScheduleStatus, ScheduleSummary, ScheduleUpdateOptions, SearchAttributeDefinition, SearchAttributeHandle, SearchAttributeSchema, SearchAttributeValue, Serializer, SignalDefinition, SignalDeliveryOptions, SignalMap, SignalPayload, StartOptions, StartOrSignalOptions, StartOrSignalSignal, SubmitReviewOptions, TerminationReason, UpdateDefinition, UpdateMap, UpdatePayload, WorkerReplayOperationFailure, WorkerReplayOperationSignature, WorkflowAlreadyRegistered, WorkflowAtomicState, WorkflowAtomicStateOptions, WorkflowBuilder, WorkflowBuilderOptions, WorkflowConcurrencyOptions, WorkflowContext, WorkflowDefinition, WorkflowEvent, WorkflowFinalizerStatus, WorkflowFunction, WorkflowGenerator, WorkflowId, WorkflowKeyedRaceResult, WorkflowLogLevel, WorkflowLogRecord, WorkflowLogger, WorkflowRegistry, WorkflowReplay, WorkflowScheduleProvenance, WorkflowServicesResolution, WorkflowServicesResolverInfo, WorkflowServicesResolverLaunchOptions, WorkflowServicesResolverScheduleInfo, WorkflowSessionState, WorkflowSnapshot, WorkflowState, WorkflowStateNamespace, WorkflowStatus, WorkflowSummary, WorkflowTimelineEntry, WorkflowTimelineOperationDetail, WorkflowTimelineStatus, WorkflowTypeRetentionPolicy, } from './core/types';
28
28
  export { AlertManager } from './alerting/index';
29
29
  export type { AlertAction, AlertMetric, AlertRule, AlertState, AlertStatus, AlertingOptions, WebhookTarget, } from './alerting/types';
30
30
  export { ActivityAsyncPendingEvent, ActivityCompletedEvent, ActivityFailedEvent, ActivityStartedEvent, AlertFiredEvent, AlertResolvedEvent, AttributesChangedEvent, CheckpointSizeWarningEvent, ConstraintViolatedEvent, DevelopmentWarningEvent, ScheduleFiredEvent, ScheduleMissedFireEvent, SignalDeliveredEvent, SignalReceivedEvent, StorageSizeReportedEvent, TaskResultDeadLetteredEvent, UpdateCompletedEvent, UpdateReceivedEvent, WorkflowCancelledEvent, WorkflowCompletedEvent, WorkflowDefinitionRegisteredEvent, WorkflowFailedEvent, WorkflowRecoverySkippedEvent, WorkflowResumedEvent, WorkflowStartedEvent, WorkflowSuspendedEvent, WorkflowTeardownEvent, WorkflowTimedOutEvent, } from './core/events';
@@ -81,7 +81,7 @@ export type { AuthConfig, AuthMethod, AuthResult, Authenticator, JWTAlgorithm, J
81
81
  export { ReviewCompletedEvent, ReviewRequestedEvent } from './core/review/events.ts';
82
82
  export type { WeftReviewEventMap } from './core/review/events.ts';
83
83
  export { ReviewCoordinator, ReviewTimeoutError } from './core/review/index.ts';
84
- export type { EscalationAction, EscalationStep, HumanReviewOptions, HumanReviewResult, ReviewCoordinatorOptions, ReviewDecision, ReviewOptions, ReviewRequest, } from './core/review/index.ts';
84
+ export type { EscalationAction, EscalationStep, HumanReviewOptions, HumanReviewResult, ReviewCoordinatorOptions, ReviewDecisionRecord, ReviewOptions, ReviewRequest, } from './core/review/index.ts';
85
85
  export { EffectLog, EffectReplayConflictError, computeSemanticHash, } from './core/effect-log/index.ts';
86
86
  export type { EffectLogLike, EffectRecord } from './core/effect-log/index.ts';
87
87
  export { isJSONValue, normalizeJSONValue } from './core/json.ts';
@@ -106,6 +106,7 @@ export { WorkerRegistry } from './worker/registry';
106
106
  export { WorkerProtocolIncompatibleError, workerProtocolIncompatibleMessage, } from './worker/worker-protocol-incompatible-error';
107
107
  export { buildQualifiedActivityTable } from './worker/workflow-activity-binding';
108
108
  export type { RemoteWorkerActivityFunction, RemoteWorkerActivityImplementation, RemoteWorkerWorkflowDefinition, } from './worker/workflow-activity-binding';
109
+ export type { WeftClientStorage } from './client/client-storage';
109
110
  export type { WorkflowEventTail } from './client/event-tail';
110
111
  export { HttpClient, HttpClientError } from './client/index';
111
112
  export type { HttpClientOptions, WorkflowEventStreamOptions, WorkflowEventTransport, } from './client/index';
package/dist/indexeddb.js CHANGED
@@ -1 +1 @@
1
- async function q(G,J){return await G.get(J)!==null}async function*T(G,J,Q){for await(let[X]of G.scan(J,Q))yield X}async function O(G,J){let Q=0;for await(let X of T(G,J))Q++;return Q}async function h(G,J){let Q=[];for await(let X of T(G,J))Q.push({type:"delete",key:X});if(Q.length===0)return 0;return await G.batch(Q),Q.length}async function R(G,J,Q){let X=[];for await(let Y of T(G,J,Q))X.push({type:"delete",key:Y});if(X.length===0)return 0;return await G.batch(X),X.length}function E(G,J,Q){if(!G.capabilities()[J])throw Error(`Feature "${Q}" requires storage capability "${J}", but this storage backend does not provide it.`)}var A=1e4;class v extends Error{code="StorageBatchOperationLimitExceededError";cap=A;count;target;constructor(G,J){super(`${G} count ${J} exceeds MAX_BATCH_OPERATIONS (${A}).`);this.name="StorageBatchOperationLimitExceededError",this.target=G,this.count=J}}function M(G,J){if(J>A)throw new v(G,J)}function j(G){return G.length>0?G.slice(0,-1)+String.fromCharCode(G.charCodeAt(G.length-1)+1):"ÿ"}function S(G,J={}){if(J.gt!==void 0&&G<=J.gt)return!1;if(J.gte!==void 0&&G<J.gte)return!1;if(J.lt!==void 0&&G>=J.lt)return!1;if(J.lte!==void 0&&G>J.lte)return!1;return!0}function b(G,J){if(G===null||J===null)return G===J;if(G.byteLength!==J.byteLength)return!1;for(let Q=0;Q<G.byteLength;Q++)if(G[Q]!==J[Q])return!1;return!0}async function m(G,J){if(G.has)return G.has(J);return q(G,J)}function x(G,J,Q){if(G.keys)return G.keys(J,Q);return T(G,J,Q)}async function y(G,J){if(G.count)return G.count(J);return O(G,J)}async function I(G,J){if(G.deletePrefix)return G.deletePrefix(J);return h(G,J)}async function g(G,J,Q){if(M("conditionalBatch conditions",J.length),M("conditionalBatch operations",Q.length),E(G,"conditionalBatch","storageConditionalBatch"),!G.conditionalBatch)throw Error("This storage backend reports conditionalBatch capability but does not implement the conditionalBatch() method.");return G.conditionalBatch(J,Q)}function l(G){if(G===void 0)return;if(typeof G!=="number"||!Number.isInteger(G)||G<0)throw Error("deleteRange limit must be a finite non-negative integer");return G===0?0:G}function N(G){let J={},Q=!1;for(let Y of["gt","gte","lt","lte"]){let $=G[Y];if($===void 0)continue;if(typeof $!=="string")throw Error("deleteRange bounds must be strings");J[Y]=$,Q=!0}if(!Q)throw Error("deleteRange requires at least one of gt/gte/lt/lte; use deletePrefix to delete a whole prefix");let X=l(G.limit);if(X!==void 0)J.limit=X;return J}async function k(G,J,Q){let X=N(Q);if(G.deleteRange)return G.deleteRange(J,X);return R(G,J,X)}function d(G,J){let Q={key:G,open:!1};if(J.gte!==void 0&&J.gte>Q.key)Q.key=J.gte,Q.open=!1;if(J.gt!==void 0&&J.gt>=Q.key)Q.key=J.gt,Q.open=!0;return Q}function p(G,J){let Q={key:j(G),open:!0};if(J.lt!==void 0&&J.lt<=Q.key)Q.key=J.lt,Q.open=!0;if(J.lte!==void 0&&J.lte<Q.key)Q.key=J.lte,Q.open=!1;return Q}function c(G,J){let Q=d(G,J),X=p(G,J);if(Q.key>X.key||Q.key===X.key&&(Q.open||X.open))return null;return{lower:Q,upper:X}}function P(G){return G.replaceAll(/:+$/g,"")}function a(G,J){let Q=P(G),X=P(J);if(Q.length===0)return X;if(X.length===0)return Q;return`${Q}:${X}`}class C{#J;#Q;constructor(G,J){this.#J=G,this.#Q=P(J)}#G(G){if(this.#Q.length===0)return G;return G.length===0?`${this.#Q}:`:`${this.#Q}:${G}`}#X(G){if(this.#Q.length===0)return G;return G.slice(this.#Q.length+1)}#Y(G={}){let J={};if(G.limit!==void 0)J.limit=G.limit;if(G.reverse!==void 0)J.reverse=G.reverse;if(G.gt!==void 0)J.gt=this.#G(G.gt);if(G.gte!==void 0)J.gte=this.#G(G.gte);if(G.lt!==void 0)J.lt=this.#G(G.lt);if(G.lte!==void 0)J.lte=this.#G(G.lte);return J}#Z(G){let J={};if(G.limit!==void 0)J.limit=G.limit;if(G.gt!==void 0)J.gt=this.#G(G.gt);if(G.gte!==void 0)J.gte=this.#G(G.gte);if(G.lt!==void 0)J.lt=this.#G(G.lt);if(G.lte!==void 0)J.lte=this.#G(G.lte);return J}capabilities(){return this.#J.capabilities()}scoped(G){return new C(this.#J,a(this.#Q,G))}async get(G){return this.#J.get(this.#G(G))}async put(G,J){await this.#J.put(this.#G(G),J)}async delete(G){await this.#J.delete(this.#G(G))}async*scan(G,J){for await(let[Q,X]of this.#J.scan(this.#G(G),this.#Y(J)))yield[this.#X(Q),X]}async batch(G){M("batch operations",G.length),await this.#J.batch(G.map((J)=>{if(J.type==="put")return{type:"put",key:this.#G(J.key),value:J.value};return{type:"delete",key:this.#G(J.key)}}))}async conditionalBatch(G,J){return g(this.#J,G.map((Q)=>({key:this.#G(Q.key),expectedValue:Q.expectedValue})),J.map((Q)=>{if(Q.type==="put")return{type:"put",key:this.#G(Q.key),value:Q.value};return{type:"delete",key:this.#G(Q.key)}}))}async has(G){return m(this.#J,this.#G(G))}async deletePrefix(G){return I(this.#J,this.#G(G))}async deleteRange(G,J){let Q=this.#Z(N(J));return k(this.#J,this.#G(G),Q)}async*keys(G,J){for await(let Q of x(this.#J,this.#G(G),this.#Y(J)))yield this.#X(Q)}async count(G){return y(this.#J,this.#G(G))}[Symbol.dispose](){this.#J[Symbol.dispose]()}}function u(G,J){return new C(G,J)}var U="kv";function s(G=globalThis){let{indexedDB:J,IDBKeyRange:Q}=G;if(J===void 0||Q===void 0)throw Error("IndexedDBStorage requires both indexedDB and IDBKeyRange runtime globals.");return{indexedDB:J,IDBKeyRange:Q}}function K(G){return new Promise((J,Q)=>{G.onsuccess=()=>J(G.result),G.onerror=()=>Q(G.error)})}function w(G,J){let Q=null,X=null,Y=null,$=(Z,V)=>{let H=Z??Error(V);if(X){let L=X;Q=null,X=null,L(H);return}Y=H};return G.onsuccess=()=>{if(!Q)return;let Z=Q;Q=null,X=null,Z(G.result)},G.onerror=()=>{$(G.error,"IndexedDB cursor request failed.")},J.onerror=()=>{$(J.error,"IndexedDB transaction failed.")},J.onabort=()=>{$(J.error,"IndexedDB transaction aborted.")},()=>{return new Promise((Z,V)=>{if(Y){let H=Y;Y=null,V(H);return}if(Q=Z,X=V,G.readyState==="done"){let H=Q;Q=null,X=null,H?.(G.result)}})}}class n{#J;#Q=null;#G;#X;constructor(G="weft",J=s()){this.#J=G,this.#X=J,this.#G=this.#Y()}capabilities(){return{persistence:"local",readAfterWrite:"linearizable",scanConsistency:"best-effort",atomicBatch:!0,conditionalBatch:!0,boundedRangeDelete:!0}}#Y(){let G=this.#X.indexedDB.open(this.#J,1);return G.onupgradeneeded=()=>{let J=G.result;if(!J.objectStoreNames.contains(U))J.createObjectStore(U)},K(G).then((J)=>{return this.#Q=J,J})}async get(G){let X=(await this.#G).transaction(U,"readonly").objectStore(U),Y=await K(X.get(G));return Y===void 0?null:new Uint8Array(Y)}async put(G,J){let Y=(await this.#G).transaction(U,"readwrite").objectStore(U);await K(Y.put(J,G))}async delete(G){let X=(await this.#G).transaction(U,"readwrite").objectStore(U);await K(X.delete(G))}async has(G){let X=(await this.#G).transaction(U,"readonly").objectStore(U);return await K(X.count(G))>0}async deletePrefix(G){let J=await this.#G,Q=j(G),X=this.#X.IDBKeyRange.bound(G,Q,!1,!0);return new Promise((Y,$)=>{let Z=J.transaction(U,"readwrite"),V=Z.objectStore(U),H=0,L=V.count(X);L.onsuccess=()=>{H=L.result,V.delete(X)},Z.oncomplete=()=>Y(H),Z.onerror=()=>$(Z.error)})}async deleteRange(G,J){let Q=N(J),X=c(G,Q);if(X===null)return 0;let Y=this.#X.IDBKeyRange.bound(X.lower.key,X.upper.key,X.lower.open,X.upper.open),$=await this.#G,{limit:Z}=Q;return new Promise((V,H)=>{let L=$.transaction(U,"readwrite"),z=L.objectStore(U),B=0;if(Z===void 0){let F=z.count(Y);F.onsuccess=()=>{B=F.result,z.delete(Y)}}else{let F=z.openCursor(Y,"next");F.onsuccess=()=>{let D=F.result;if(D===null||B>=Z)return;if(D.delete(),B++,B<Z)D.continue()}}L.oncomplete=()=>V(B),L.onerror=()=>H(L.error)})}async*scan(G,J={}){let{limit:Q,reverse:X}=J,Y=await this.#G,$=j(G),Z=this.#X.IDBKeyRange.bound(G,$,!1,!0),V=X?"prev":"next",H=Y.transaction(U,"readonly"),z=H.objectStore(U).openCursor(Z,V),B=0,F=w(z,H),D=!1;try{let W=await F();while(W){if(Q!==void 0&&B>=Q)break;let _=W.key;if(S(_,J))yield[_,new Uint8Array(W.value)],B++;W.continue(),W=await F()}D=!0}finally{if(!D)try{H.abort()}catch{}}}async batch(G){if(M("batch operations",G.length),G.length===0)return;let J=await this.#G;return new Promise((Q,X)=>{let Y=J.transaction(U,"readwrite"),$=Y.objectStore(U);for(let Z of G)if(Z.type==="put")$.put(Z.value,Z.key);else $.delete(Z.key);Y.oncomplete=()=>Q(),Y.onerror=()=>X(Y.error)})}async conditionalBatch(G,J){M("conditionalBatch conditions",G.length),M("conditionalBatch operations",J.length);let Q=await this.#G;return new Promise((X,Y)=>{let $=Q.transaction(U,"readwrite"),Z=$.objectStore(U),V=!1,H=!1,L=(F,D)=>{if(V)return;V=!0,Y(F??Error(D))};$.oncomplete=()=>{if(V)return;V=!0,X(!0)},$.onerror=()=>{L($.error,"IndexedDB conditionalBatch transaction failed.")},$.onabort=()=>{if(V)return;if(V=!0,H){X(!1);return}Y($.error??Error("IndexedDB conditionalBatch transaction aborted."))};let z=()=>{for(let F of J)if(F.type==="put")Z.put(F.value,F.key);else Z.delete(F.key)},B=(F)=>{if(F>=G.length){z();return}let D=G[F],W=Z.get(D.key);W.onsuccess=()=>{let _=W.result,f=_===void 0?null:new Uint8Array(_);if(!b(f,D.expectedValue)){H=!0,$.abort();return}B(F+1)},W.onerror=()=>{L(W.error,"IndexedDB conditionalBatch condition check failed.")}};B(0)})}async*keys(G,J={}){let{limit:Q,reverse:X}=J,Y=await this.#G,$=j(G),Z=this.#X.IDBKeyRange.bound(G,$,!1,!0),V=X?"prev":"next",H=Y.transaction(U,"readonly"),z=H.objectStore(U).openKeyCursor(Z,V),B=0,F=w(z,H),D=!1;try{let W=await F();while(W){if(Q!==void 0&&B>=Q)break;let _=W.key;if(S(_,J))yield _,B++;W.continue(),W=await F()}D=!0}finally{if(!D)try{H.abort()}catch{}}}async count(G){let J=await this.#G,Q=j(G),Y=J.transaction(U,"readonly").objectStore(U);return K(Y.count(this.#X.IDBKeyRange.bound(G,Q,!1,!0)))}scoped(G){return u(this,G)}[Symbol.dispose](){if(this.#Q)this.#Q.close(),this.#Q=null}}export{n as IndexedDBStorage};
1
+ async function q(G,J){return await G.get(J)!==null}async function*N(G,J,Q){for await(let[X]of G.scan(J,Q))yield X}async function O(G,J){let Q=0;for await(let X of N(G,J))Q++;return Q}async function R(G,J){let Q=[];for await(let X of N(G,J))Q.push({type:"delete",key:X});if(Q.length===0)return 0;return await G.batch(Q),Q.length}async function h(G,J,Q){let X=[];for await(let Y of N(G,J,Q))X.push({type:"delete",key:Y});if(X.length===0)return 0;return await G.batch(X),X.length}function v(G,J,Q){if(!G.capabilities()[J])throw Error(`Feature "${Q}" requires storage capability "${J}", but this storage backend does not provide it.`)}var A=1e4;class E extends Error{code="StorageBatchOperationLimitExceededError";cap=A;count;target;constructor(G,J){super(`${G} count ${J} exceeds MAX_BATCH_OPERATIONS (${A}).`);this.name="StorageBatchOperationLimitExceededError",this.target=G,this.count=J}}function M(G,J){if(J>A)throw new E(G,J)}function j(G){return G.length>0?G.slice(0,-1)+String.fromCharCode(G.charCodeAt(G.length-1)+1):"ÿ"}function S(G,J={}){if(J.gt!==void 0&&G<=J.gt)return!1;if(J.gte!==void 0&&G<J.gte)return!1;if(J.lt!==void 0&&G>=J.lt)return!1;if(J.lte!==void 0&&G>J.lte)return!1;return!0}function b(G,J){if(G===null||J===null)return G===J;if(G.byteLength!==J.byteLength)return!1;for(let Q=0;Q<G.byteLength;Q++)if(G[Q]!==J[Q])return!1;return!0}async function m(G,J){if(G.has)return G.has(J);return q(G,J)}function x(G,J,Q){if(G.keys)return G.keys(J,Q);return N(G,J,Q)}async function y(G,J){if(G.count)return G.count(J);return O(G,J)}async function I(G,J){if(G.deletePrefix)return G.deletePrefix(J);return R(G,J)}async function g(G,J,Q){if(M("conditionalBatch conditions",J.length),M("conditionalBatch operations",Q.length),v(G,"conditionalBatch","storageConditionalBatch"),!G.conditionalBatch)throw Error("This storage backend reports conditionalBatch capability but does not implement the conditionalBatch() method.");return G.conditionalBatch(J,Q)}function l(G){if(G===void 0)return;if(typeof G!=="number"||!Number.isInteger(G)||G<0)throw Error("deleteRange limit must be a finite non-negative integer");return G===0?0:G}function T(G){let J={},Q=!1;for(let Y of["gt","gte","lt","lte"]){let $=G[Y];if($===void 0)continue;if(typeof $!=="string")throw Error("deleteRange bounds must be strings");J[Y]=$,Q=!0}if(!Q)throw Error("deleteRange requires at least one of gt/gte/lt/lte; use deletePrefix to delete a whole prefix");let X=l(G.limit);if(X!==void 0)J.limit=X;return J}async function k(G,J,Q){let X=T(Q);if(G.deleteRange)return G.deleteRange(J,X);return h(G,J,X)}function p(G,J){let Q={key:G,open:!1};if(J.gte!==void 0&&J.gte>Q.key)Q.key=J.gte,Q.open=!1;if(J.gt!==void 0&&J.gt>=Q.key)Q.key=J.gt,Q.open=!0;return Q}function d(G,J){let Q={key:j(G),open:!0};if(J.lt!==void 0&&J.lt<=Q.key)Q.key=J.lt,Q.open=!0;if(J.lte!==void 0&&J.lte<Q.key)Q.key=J.lte,Q.open=!1;return Q}function c(G,J){let Q=p(G,J),X=d(G,J);if(Q.key>X.key||Q.key===X.key&&(Q.open||X.open))return null;return{lower:Q,upper:X}}function P(G){return G.replaceAll(/:+$/g,"")}function a(G,J){let Q=P(G),X=P(J);if(Q.length===0)return X;if(X.length===0)return Q;return`${Q}:${X}`}class C{#J;#Q;constructor(G,J){this.#J=G,this.#Q=P(J)}#G(G){if(this.#Q.length===0)return G;return G.length===0?`${this.#Q}:`:`${this.#Q}:${G}`}#X(G){if(this.#Q.length===0)return G;return G.slice(this.#Q.length+1)}#Y(G={}){let J={};if(G.limit!==void 0)J.limit=G.limit;if(G.reverse!==void 0)J.reverse=G.reverse;if(G.gt!==void 0)J.gt=this.#G(G.gt);if(G.gte!==void 0)J.gte=this.#G(G.gte);if(G.lt!==void 0)J.lt=this.#G(G.lt);if(G.lte!==void 0)J.lte=this.#G(G.lte);return J}#Z(G){let J={};if(G.limit!==void 0)J.limit=G.limit;if(G.gt!==void 0)J.gt=this.#G(G.gt);if(G.gte!==void 0)J.gte=this.#G(G.gte);if(G.lt!==void 0)J.lt=this.#G(G.lt);if(G.lte!==void 0)J.lte=this.#G(G.lte);return J}capabilities(){return this.#J.capabilities()}scoped(G){return new C(this.#J,a(this.#Q,G))}async get(G){return this.#J.get(this.#G(G))}async put(G,J){await this.#J.put(this.#G(G),J)}async delete(G){await this.#J.delete(this.#G(G))}async*scan(G,J){for await(let[Q,X]of this.#J.scan(this.#G(G),this.#Y(J)))yield[this.#X(Q),X]}async batch(G){M("batch operations",G.length),await this.#J.batch(G.map((J)=>{if(J.type==="put")return{type:"put",key:this.#G(J.key),value:J.value};return{type:"delete",key:this.#G(J.key)}}))}async conditionalBatch(G,J){return g(this.#J,G.map((Q)=>({key:this.#G(Q.key),expectedValue:Q.expectedValue})),J.map((Q)=>{if(Q.type==="put")return{type:"put",key:this.#G(Q.key),value:Q.value};return{type:"delete",key:this.#G(Q.key)}}))}async has(G){return m(this.#J,this.#G(G))}async deletePrefix(G){return I(this.#J,this.#G(G))}async deleteRange(G,J){let Q=this.#Z(T(J));return k(this.#J,this.#G(G),Q)}async*keys(G,J){for await(let Q of x(this.#J,this.#G(G),this.#Y(J)))yield this.#X(Q)}async count(G){return y(this.#J,this.#G(G))}[Symbol.dispose](){this.#J[Symbol.dispose]()}}function u(G,J){return new C(G,J)}var U="kv";function s(G=globalThis){let{indexedDB:J,IDBKeyRange:Q}=G;if(J===void 0||Q===void 0)throw Error("IndexedDBStorage requires both indexedDB and IDBKeyRange runtime globals.");return{indexedDB:J,IDBKeyRange:Q}}function K(G){return new Promise((J,Q)=>{G.onsuccess=()=>J(G.result),G.onerror=()=>Q(G.error)})}function w(G,J){let Q=null,X=null,Y=null,$=(Z,V)=>{let H=Z??Error(V);if(X){let B=X;Q=null,X=null,B(H);return}Y=H};return G.onsuccess=()=>{if(!Q)return;let Z=Q;Q=null,X=null,Z(G.result)},G.onerror=()=>{$(G.error,"IndexedDB cursor request failed.")},J.onerror=()=>{$(J.error,"IndexedDB transaction failed.")},J.onabort=()=>{$(J.error,"IndexedDB transaction aborted.")},()=>{return new Promise((Z,V)=>{if(Y){let H=Y;Y=null,V(H);return}if(Q=Z,X=V,G.readyState==="done"){let H=Q;Q=null,X=null,H?.(G.result)}})}}class n{#J;#Q=null;#G;#X;constructor(G="weft",J=s()){this.#J=G,this.#X=J,this.#G=this.#Y()}capabilities(){return{persistence:"local",readAfterWrite:"linearizable",scanConsistency:"best-effort",atomicBatch:!0,conditionalBatch:!0,boundedRangeDelete:!0}}#Y(){let G=this.#X.indexedDB.open(this.#J,1);return G.onupgradeneeded=()=>{let J=G.result;if(!J.objectStoreNames.contains(U))J.createObjectStore(U)},K(G).then((J)=>{return this.#Q=J,J})}async get(G){let X=(await this.#G).transaction(U,"readonly").objectStore(U),Y=await K(X.get(G));return Y===void 0?null:new Uint8Array(Y)}async put(G,J){let Y=(await this.#G).transaction(U,"readwrite").objectStore(U);await K(Y.put(J,G))}async delete(G){let X=(await this.#G).transaction(U,"readwrite").objectStore(U);await K(X.delete(G))}async has(G){let X=(await this.#G).transaction(U,"readonly").objectStore(U);return await K(X.count(G))>0}async deletePrefix(G){let J=await this.#G,Q=j(G),X=this.#X.IDBKeyRange.bound(G,Q,!1,!0);return new Promise((Y,$)=>{let Z=J.transaction(U,"readwrite"),V=Z.objectStore(U),H=0,B=V.count(X);B.onsuccess=()=>{H=B.result,V.delete(X)},Z.oncomplete=()=>Y(H),Z.onerror=()=>$(Z.error)})}async deleteRange(G,J){let Q=T(J),X=c(G,Q);if(X===null)return 0;let Y=this.#X.IDBKeyRange.bound(X.lower.key,X.upper.key,X.lower.open,X.upper.open),$=await this.#G,{limit:Z}=Q;return new Promise((V,H)=>{let B=$.transaction(U,"readwrite"),z=B.objectStore(U),D=0;if(Z===void 0){let F=z.count(Y);F.onsuccess=()=>{D=F.result,z.delete(Y)}}else{let F=z.openCursor(Y,"next");F.onsuccess=()=>{let W=F.result;if(W===null||D>=Z)return;if(W.delete(),D++,D<Z)W.continue()}}B.oncomplete=()=>V(D),B.onerror=()=>H(B.error)})}async*scan(G,J={}){let{limit:Q,reverse:X}=J,Y=await this.#G,$=j(G),Z=this.#X.IDBKeyRange.bound(G,$,!1,!0),V=X?"prev":"next",H=Y.transaction(U,"readonly"),z=H.objectStore(U).openCursor(Z,V),D=0,F=w(z,H),W=!1;try{let L=await F();while(L){if(Q!==void 0&&D>=Q)break;let _=L.key;if(S(_,J))yield[_,new Uint8Array(L.value)],D++;L.continue(),L=await F()}W=!0}finally{if(!W)try{H.abort()}catch{}}}async batch(G){if(M("batch operations",G.length),G.length===0)return;let J=await this.#G;return new Promise((Q,X)=>{let Y=J.transaction(U,"readwrite"),$=Y.objectStore(U);for(let Z of G)if(Z.type==="put")$.put(Z.value,Z.key);else $.delete(Z.key);Y.oncomplete=()=>Q(),Y.onerror=()=>X(Y.error)})}async conditionalBatch(G,J){M("conditionalBatch conditions",G.length),M("conditionalBatch operations",J.length);let Q=await this.#G;return new Promise((X,Y)=>{let $=Q.transaction(U,"readwrite"),Z=$.objectStore(U),V=!1,H=!1,B=(F,W)=>{if(V)return;V=!0,Y(F??Error(W))};$.oncomplete=()=>{if(V)return;V=!0,X(!0)},$.onerror=()=>{B($.error,"IndexedDB conditionalBatch transaction failed.")},$.onabort=()=>{if(V)return;if(V=!0,H){X(!1);return}Y($.error??Error("IndexedDB conditionalBatch transaction aborted."))};let z=()=>{for(let F of J)if(F.type==="put")Z.put(F.value,F.key);else Z.delete(F.key)},D=(F)=>{if(F>=G.length){z();return}let W=G[F],L=Z.get(W.key);L.onsuccess=()=>{let _=L.result,f=_===void 0?null:new Uint8Array(_);if(!b(f,W.expectedValue)){H=!0,$.abort();return}D(F+1)},L.onerror=()=>{B(L.error,"IndexedDB conditionalBatch condition check failed.")}};D(0)})}async*keys(G,J={}){let{limit:Q,reverse:X}=J,Y=await this.#G,$=j(G),Z=this.#X.IDBKeyRange.bound(G,$,!1,!0),V=X?"prev":"next",H=Y.transaction(U,"readonly"),z=H.objectStore(U).openKeyCursor(Z,V),D=0,F=w(z,H),W=!1;try{let L=await F();while(L){if(Q!==void 0&&D>=Q)break;let _=L.key;if(S(_,J))yield _,D++;L.continue(),L=await F()}W=!0}finally{if(!W)try{H.abort()}catch{}}}async count(G){let J=await this.#G,Q=j(G),Y=J.transaction(U,"readonly").objectStore(U);return K(Y.count(this.#X.IDBKeyRange.bound(G,Q,!1,!0)))}scoped(G){return u(this,G)}[Symbol.dispose](){if(this.#Q)this.#Q.close(),this.#Q=null}}export{n as IndexedDBStorage};
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Canonical discovery-document metadata for operation access policies.
3
+ *
4
+ * @module server/access-policy-metadata
5
+ */
6
+ import { z } from 'zod';
7
+ import type { AccessPolicy } from './authorization.ts';
8
+ import type { ParameterizedAccessHint } from './operation-catalog/types.ts';
9
+ export declare const ScopeRequirementMetadataSchema: z.ZodObject<{
10
+ kind: z.ZodEnum<{
11
+ anyOf: "anyOf";
12
+ allOf: "allOf";
13
+ }>;
14
+ scopes: z.ZodArray<z.ZodString>;
15
+ }, z.core.$strict>;
16
+ export declare const AccessPolicyMetadataSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
17
+ kind: z.ZodLiteral<"public">;
18
+ }, z.core.$strict>, z.ZodObject<{
19
+ kind: z.ZodLiteral<"authenticated">;
20
+ }, z.core.$strict>, z.ZodObject<{
21
+ kind: z.ZodLiteral<"scoped">;
22
+ scopes: z.ZodObject<{
23
+ kind: z.ZodEnum<{
24
+ anyOf: "anyOf";
25
+ allOf: "allOf";
26
+ }>;
27
+ scopes: z.ZodArray<z.ZodString>;
28
+ }, z.core.$strict>;
29
+ }, z.core.$strict>, z.ZodObject<{
30
+ kind: z.ZodLiteral<"optionalAuth">;
31
+ authenticatedScopes: z.ZodObject<{
32
+ kind: z.ZodEnum<{
33
+ anyOf: "anyOf";
34
+ allOf: "allOf";
35
+ }>;
36
+ scopes: z.ZodArray<z.ZodString>;
37
+ }, z.core.$strict>;
38
+ }, z.core.$strict>, z.ZodObject<{
39
+ kind: z.ZodLiteral<"scopedAlternatives">;
40
+ alternatives: z.ZodArray<z.ZodObject<{
41
+ kind: z.ZodEnum<{
42
+ anyOf: "anyOf";
43
+ allOf: "allOf";
44
+ }>;
45
+ scopes: z.ZodArray<z.ZodString>;
46
+ }, z.core.$strict>>;
47
+ }, z.core.$strict>], "kind">;
48
+ export declare const ParameterizedAccessMetadataSchema: z.ZodObject<{
49
+ discriminator: z.ZodString;
50
+ defaultValue: z.ZodOptional<z.ZodString>;
51
+ variants: z.ZodArray<z.ZodObject<{
52
+ value: z.ZodString;
53
+ access: z.ZodDiscriminatedUnion<[z.ZodObject<{
54
+ kind: z.ZodLiteral<"public">;
55
+ }, z.core.$strict>, z.ZodObject<{
56
+ kind: z.ZodLiteral<"authenticated">;
57
+ }, z.core.$strict>, z.ZodObject<{
58
+ kind: z.ZodLiteral<"scoped">;
59
+ scopes: z.ZodObject<{
60
+ kind: z.ZodEnum<{
61
+ anyOf: "anyOf";
62
+ allOf: "allOf";
63
+ }>;
64
+ scopes: z.ZodArray<z.ZodString>;
65
+ }, z.core.$strict>;
66
+ }, z.core.$strict>, z.ZodObject<{
67
+ kind: z.ZodLiteral<"optionalAuth">;
68
+ authenticatedScopes: z.ZodObject<{
69
+ kind: z.ZodEnum<{
70
+ anyOf: "anyOf";
71
+ allOf: "allOf";
72
+ }>;
73
+ scopes: z.ZodArray<z.ZodString>;
74
+ }, z.core.$strict>;
75
+ }, z.core.$strict>, z.ZodObject<{
76
+ kind: z.ZodLiteral<"scopedAlternatives">;
77
+ alternatives: z.ZodArray<z.ZodObject<{
78
+ kind: z.ZodEnum<{
79
+ anyOf: "anyOf";
80
+ allOf: "allOf";
81
+ }>;
82
+ scopes: z.ZodArray<z.ZodString>;
83
+ }, z.core.$strict>>;
84
+ }, z.core.$strict>], "kind">;
85
+ }, z.core.$strict>>;
86
+ }, z.core.$strict>;
87
+ export type AccessPolicyMetadata = z.infer<typeof AccessPolicyMetadataSchema>;
88
+ export type ParameterizedAccessMetadata = z.infer<typeof ParameterizedAccessMetadataSchema>;
89
+ /** Serialize an operation's static access policy for discovery documents. */
90
+ export declare function serializeAccessPolicy(policy: AccessPolicy): AccessPolicyMetadata;
91
+ /** Serialize discriminator-specific access overrides for discovery documents. */
92
+ export declare function serializeParameterizedAccess(hint: ParameterizedAccessHint): ParameterizedAccessMetadata;
@@ -0,0 +1,78 @@
1
+ import { z } from "zod";
2
+ import { compareStrings } from "./json-schema-utilities.js";
3
+ export const ScopeRequirementMetadataSchema = z.strictObject({
4
+ kind: z.enum(["anyOf", "allOf"]),
5
+ scopes: z.array(z.string()).min(1)
6
+ }), AccessPolicyMetadataSchema = z.discriminatedUnion("kind", [
7
+ z.strictObject({ kind: z.literal("public") }),
8
+ z.strictObject({ kind: z.literal("authenticated") }),
9
+ z.strictObject({
10
+ kind: z.literal("scoped"),
11
+ scopes: ScopeRequirementMetadataSchema
12
+ }),
13
+ z.strictObject({
14
+ kind: z.literal("optionalAuth"),
15
+ authenticatedScopes: ScopeRequirementMetadataSchema
16
+ }),
17
+ z.strictObject({
18
+ kind: z.literal("scopedAlternatives"),
19
+ alternatives: z.array(ScopeRequirementMetadataSchema).min(1)
20
+ })
21
+ ]), ParameterizedAccessMetadataSchema = z.strictObject({
22
+ discriminator: z.string(),
23
+ defaultValue: z.string().optional(),
24
+ variants: z.array(z.strictObject({
25
+ value: z.string(),
26
+ access: AccessPolicyMetadataSchema
27
+ }))
28
+ });
29
+ export function serializeAccessPolicy(policy) {
30
+ switch (policy.kind) {
31
+ case "public":
32
+ return { kind: "public" };
33
+ case "authenticated":
34
+ return { kind: "authenticated" };
35
+ case "scoped":
36
+ return { kind: "scoped", scopes: serializeScopeRequirement(policy.scopes) };
37
+ case "optionalAuth":
38
+ return {
39
+ kind: "optionalAuth",
40
+ authenticatedScopes: serializeScopeRequirement(policy.authenticatedScopes)
41
+ };
42
+ case "scopedAlternatives":
43
+ return {
44
+ kind: "scopedAlternatives",
45
+ alternatives: policy.alternatives.map(serializeScopeRequirement)
46
+ };
47
+ default:
48
+ return unsupportedAccessPolicy(policy);
49
+ }
50
+ }
51
+ export function serializeParameterizedAccess(hint) {
52
+ return {
53
+ discriminator: hint.discriminator,
54
+ ...hint.defaultValue === void 0 ? {} : { defaultValue: hint.defaultValue },
55
+ variants: hint.variants.map((variant) => ({
56
+ value: variant.value,
57
+ access: serializeAccessPolicy(variant.access)
58
+ }))
59
+ };
60
+ }
61
+ function serializeScopeRequirement(requirement) {
62
+ switch (requirement.kind) {
63
+ case "anyOf":
64
+ case "allOf":
65
+ return {
66
+ kind: requirement.kind,
67
+ scopes: [...requirement.scopes].toSorted(compareStrings)
68
+ };
69
+ default:
70
+ return unsupportedScopeRequirement(requirement);
71
+ }
72
+ }
73
+ function unsupportedAccessPolicy(policy) {
74
+ throw Error(`cannot serialize unsupported access policy: ${String(policy)}`);
75
+ }
76
+ function unsupportedScopeRequirement(requirement) {
77
+ throw Error(`cannot serialize unsupported scope requirement: ${String(requirement)}`);
78
+ }
@@ -2,13 +2,9 @@
2
2
  * `faultToHttpResponse` — pure mapper from a transport-neutral
3
3
  * `OperationFault` into a `Response` shaped for the REST surface.
4
4
  *
5
- * Body shape: `{ error: { code, message, data? } }`. The `code` matches the
6
- * fault discriminant verbatim so REST clients can switch on the same names
7
- * that JSON-RPC clients see in their `data.weftCode`.
8
- *
9
- * Pure: no engine, no I/O, no logging. Errors visible to clients are
10
- * exactly what the fault carries; internal `EngineFailure` detail belongs
11
- * in server logs, not the response body.
5
+ * This fallback uses the same flat, audited projection as every explicit REST
6
+ * binding. Keeping one mapper prevents a binding that omits `shapeFault` from
7
+ * accidentally exposing a broader nested payload or raw EngineFailure detail.
12
8
  */
13
9
  import { type OperationFault } from './operation-fault.ts';
14
10
  export declare function faultToHttpResponse(fault: OperationFault): Response;
@@ -1,36 +1,4 @@
1
- import { FAULT_CODE_TO_HTTP_STATUS } from "./operation-fault.js";
1
+ import { shapeRestFaultAsJson } from "./operation-fault.js";
2
2
  export function faultToHttpResponse(fault) {
3
- const status = FAULT_CODE_TO_HTTP_STATUS[fault.code], body = JSON.stringify({ error: shapeErrorBody(fault) }), headers = new Headers({ "content-type": "application/json; charset=utf-8" });
4
- return new Response(body, { status, headers });
5
- }
6
- function shapeErrorBody(fault) {
7
- const base = { code: fault.code, message: fault.message };
8
- if (fault.code === "EngineFailure" || fault.code === "NotImplemented")
9
- return base;
10
- if (fault.code === "Timeout")
11
- return shapeTimeoutBody(base, fault.data);
12
- if (fault.code === "NotFound")
13
- return shapeNotFoundBody(base, fault.data);
14
- return { ...base, data: fault.data };
15
- }
16
- function shapeTimeoutBody(base, data) {
17
- const defined = filterDefined(data);
18
- return Object.keys(defined).length === 0 ? base : { ...base, data: defined };
19
- }
20
- function shapeNotFoundBody(base, data) {
21
- const shaped = {
22
- resource: data.resource
23
- };
24
- if (data.identifier !== void 0)
25
- shaped.identifier = data.identifier;
26
- if (data.weftCode !== void 0)
27
- shaped.weftCode = data.weftCode;
28
- return { ...base, data: shaped };
29
- }
30
- function filterDefined(input) {
31
- const output = {};
32
- for (const [key, value] of Object.entries(input))
33
- if (value !== void 0)
34
- output[key] = value;
35
- return output;
3
+ return shapeRestFaultAsJson(fault);
36
4
  }
@@ -75,7 +75,7 @@ async function dispatchMatchedRoute(request, engine, options, url) {
75
75
  return directRouteLookup.response;
76
76
  if (directRouteLookup.value !== null)
77
77
  return dispatchDirectRoute(request, engine, directRouteLookup.value, options, url);
78
- const restBindings = options?.restBindings ?? defaultRestBindings(), operationRegistry = options?.operationRegistry ?? defaultOperationRegistry(), bindingLookup = matchRouteBoundary(() => matchRestBinding(request.method, url.pathname, restBindings));
78
+ const restBindings = options?.restBindings ?? defaultRestBindings(), operationRegistry = options?.operationRegistry ?? defaultOperationRegistry(options), bindingLookup = matchRouteBoundary(() => matchRestBinding(request.method, url.pathname, restBindings));
79
79
  if (bindingLookup.kind === "malformed")
80
80
  return bindingLookup.response;
81
81
  if (bindingLookup.value !== null)