@lostgradient/weft 0.12.0 → 0.13.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 (191) 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/operation-catalog-snapshot.d.ts +11 -2
  8. package/dist/cli/operation-catalog-snapshot.js +14 -5
  9. package/dist/cli/operation-client-runtime.d.ts +29 -0
  10. package/dist/client/client-storage.d.ts +24 -0
  11. package/dist/client/client-storage.js +14 -0
  12. package/dist/client/handle-delegation.d.ts +3 -3
  13. package/dist/client/handle-delegation.js +2 -2
  14. package/dist/client/http-client-requests.d.ts +5 -3
  15. package/dist/client/http-client-requests.js +20 -2
  16. package/dist/client/http-client-storage.d.ts +3 -0
  17. package/dist/client/http-client-storage.js +110 -0
  18. package/dist/client/http-client.d.ts +9 -6
  19. package/dist/client/http-client.js +13 -18
  20. package/dist/client/http-operations.d.ts +3 -1
  21. package/dist/client/http-operations.js +77 -1
  22. package/dist/client/http-request.d.ts +15 -8
  23. package/dist/client/http-request.js +19 -7
  24. package/dist/client/in-process-operations.d.ts +2 -2
  25. package/dist/client/in-process-operations.js +2 -2
  26. package/dist/client/index.d.ts +5 -1
  27. package/dist/client/index.js +13 -2
  28. package/dist/client/interface.d.ts +26 -26
  29. package/dist/client/local.d.ts +9 -6
  30. package/dist/client/local.js +9 -4
  31. package/dist/client/search-params.js +10 -6
  32. package/dist/client/start-body.d.ts +3 -1
  33. package/dist/client/start-body.js +9 -0
  34. package/dist/core/bulk-workflow-filter.d.ts +2 -1
  35. package/dist/core/bulk-workflow-filter.js +5 -1
  36. package/dist/core/engine/async-activity-records.d.ts +12 -1
  37. package/dist/core/engine/async-activity-records.js +81 -2
  38. package/dist/core/engine/bulk-operations-purge.js +16 -1
  39. package/dist/core/engine/bulk-operations-shared.js +2 -0
  40. package/dist/core/engine/callback-creators-schedule.d.ts +2 -1
  41. package/dist/core/engine/callback-creators-schedule.js +3 -3
  42. package/dist/core/engine/checkpoint-reads.js +11 -1
  43. package/dist/core/engine/child-workflow.js +15 -6
  44. package/dist/core/engine/construction.js +3 -0
  45. package/dist/core/engine/disposal.js +2 -0
  46. package/dist/core/engine/engine-internal-types.d.ts +4 -1
  47. package/dist/core/engine/fenced-write.d.ts +5 -3
  48. package/dist/core/engine/finalizer-status.d.ts +10 -0
  49. package/dist/core/engine/finalizer-status.js +82 -0
  50. package/dist/core/engine/index.d.ts +26 -2
  51. package/dist/core/engine/index.js +71 -8
  52. package/dist/core/engine/internals.d.ts +3 -0
  53. package/dist/core/engine/lease-health.d.ts +64 -0
  54. package/dist/core/engine/lease-health.js +0 -0
  55. package/dist/core/engine/lease-manager.d.ts +4 -2
  56. package/dist/core/engine/lease-manager.js +32 -4
  57. package/dist/core/engine/lifecycle/recovered-services.js +0 -2
  58. package/dist/core/engine/lifecycle/shared.d.ts +11 -8
  59. package/dist/core/engine/lifecycle/start-batch.js +12 -0
  60. package/dist/core/engine/lifecycle/start.d.ts +1 -1
  61. package/dist/core/engine/lifecycle/start.js +34 -5
  62. package/dist/core/engine/operations-coordination.d.ts +1 -12
  63. package/dist/core/engine/operations-coordination.js +57 -10
  64. package/dist/core/engine/operations-speculate.d.ts +1 -1
  65. package/dist/core/engine/operations-speculate.js +19 -5
  66. package/dist/core/engine/registration.js +14 -0
  67. package/dist/core/engine/schedule-handle.d.ts +4 -4
  68. package/dist/core/engine/schedule-handle.js +2 -2
  69. package/dist/core/engine/schedule-overlap.d.ts +11 -0
  70. package/dist/core/engine/schedule-overlap.js +50 -0
  71. package/dist/core/engine/schedule-run.d.ts +11 -3
  72. package/dist/core/engine/schedule-run.js +27 -4
  73. package/dist/core/engine/schedule-timer.js +10 -1
  74. package/dist/core/engine/schedules.d.ts +5 -4
  75. package/dist/core/engine/schedules.js +62 -56
  76. package/dist/core/engine/state-utilities.js +1 -1
  77. package/dist/core/engine/storage-io.d.ts +12 -0
  78. package/dist/core/engine/storage-io.js +49 -10
  79. package/dist/core/engine/termination/finalizer-claim.d.ts +8 -6
  80. package/dist/core/engine/termination/finalizer-claim.js +2 -1
  81. package/dist/core/engine/termination/finalizer.js +10 -14
  82. package/dist/core/engine/timeline-coordinator-constants.d.ts +3 -0
  83. package/dist/core/engine/timeline-coordinator-constants.js +1 -0
  84. package/dist/core/engine/timeline-coordinator-detail.d.ts +13 -0
  85. package/dist/core/engine/timeline-coordinator-detail.js +76 -0
  86. package/dist/core/engine/validation/schedule-options.d.ts +8 -1
  87. package/dist/core/engine/validation/schedule-options.js +18 -0
  88. package/dist/core/engine/validation/schedule.d.ts +1 -1
  89. package/dist/core/engine/validation/schedule.js +27 -3
  90. package/dist/core/engine/validation.js +66 -2
  91. package/dist/core/engine/workflow-state-stream.d.ts +5 -1
  92. package/dist/core/engine/workflow-state-stream.js +37 -14
  93. package/dist/core/events/schedule-events.d.ts +3 -4
  94. package/dist/core/events/workflow-events.d.ts +2 -1
  95. package/dist/core/list-filter-validation.d.ts +3 -0
  96. package/dist/core/list-filter-validation.js +11 -0
  97. package/dist/core/registry-snapshot.d.ts +32 -0
  98. package/dist/core/registry-snapshot.js +28 -0
  99. package/dist/core/review/index.d.ts +4 -4
  100. package/dist/core/types/activity.d.ts +52 -5
  101. package/dist/core/types/bulk.d.ts +1 -0
  102. package/dist/core/types/list-options.d.ts +6 -0
  103. package/dist/core/types/options.d.ts +6 -5
  104. package/dist/core/types/reviews.d.ts +2 -2
  105. package/dist/core/types/schedules.d.ts +45 -2
  106. package/dist/core/types/services-resolution.d.ts +5 -5
  107. package/dist/core/types/state.d.ts +64 -0
  108. package/dist/core/types/workflow-log.d.ts +3 -2
  109. package/dist/core/types/workflow-observability.d.ts +50 -0
  110. package/dist/core/types/workflow-observability.js +0 -0
  111. package/dist/core/types/workflow-registry.d.ts +7 -0
  112. package/dist/core/types.d.ts +1 -0
  113. package/dist/core/types.js +1 -0
  114. package/dist/http.js +2 -2
  115. package/dist/index.d.ts +4 -3
  116. package/dist/indexeddb.js +1 -1
  117. package/dist/server/access-policy-metadata.d.ts +92 -0
  118. package/dist/server/access-policy-metadata.js +78 -0
  119. package/dist/server/fault-to-http.d.ts +3 -7
  120. package/dist/server/fault-to-http.js +2 -34
  121. package/dist/server/handler/index.js +1 -1
  122. package/dist/server/handler/route-dispatch.d.ts +10 -3
  123. package/dist/server/handler/route-dispatch.js +19 -4
  124. package/dist/server/index.d.ts +1 -1
  125. package/dist/server/index.js +1 -0
  126. package/dist/server/interactive-operations.js +2 -0
  127. package/dist/server/openapi-error-responses.js +55 -4
  128. package/dist/server/openapi.d.ts +3 -1
  129. package/dist/server/openapi.js +4 -0
  130. package/dist/server/openrpc-document-schema.d.ts +64 -0
  131. package/dist/server/openrpc-document-schema.js +6 -26
  132. package/dist/server/openrpc.d.ts +4 -0
  133. package/dist/server/openrpc.js +9 -33
  134. package/dist/server/operation-fault.d.ts +24 -7
  135. package/dist/server/operation-fault.js +65 -13
  136. package/dist/server/operations/aggregate-workflows.d.ts +6 -0
  137. package/dist/server/operations/aggregate-workflows.js +3 -2
  138. package/dist/server/operations/async-activity.d.ts +14 -0
  139. package/dist/server/operations/async-activity.js +88 -4
  140. package/dist/server/operations/bulk-filter-helpers.d.ts +3 -0
  141. package/dist/server/operations/bulk-filter-helpers.js +27 -3
  142. package/dist/server/operations/bulk-mutate-workflow-tags.d.ts +6 -0
  143. package/dist/server/operations/bulk-signal-workflows.d.ts +6 -0
  144. package/dist/server/operations/get-stream-chunks.js +2 -7
  145. package/dist/server/operations/get-system-lease.d.ts +19 -0
  146. package/dist/server/operations/get-system-lease.js +48 -0
  147. package/dist/server/operations/get-workflow-observability.d.ts +24 -0
  148. package/dist/server/operations/get-workflow-observability.js +80 -0
  149. package/dist/server/operations/get-workflow-result.js +2 -2
  150. package/dist/server/operations/get-workflow.d.ts +2 -2
  151. package/dist/server/operations/list-filter-query-extractor.js +15 -0
  152. package/dist/server/operations/list-workflows.d.ts +6 -0
  153. package/dist/server/operations/list-workflows.js +12 -3
  154. package/dist/server/operations/operation-helpers.d.ts +9 -18
  155. package/dist/server/operations/operation-helpers.js +5 -23
  156. package/dist/server/operations/purge-workflows.d.ts +3 -0
  157. package/dist/server/operations/recover-all.js +2 -1
  158. package/dist/server/operations/single-workflow-tag-mutation.js +2 -2
  159. package/dist/server/operations/sse-stream.js +2 -7
  160. package/dist/server/operations/storage-capabilities.d.ts +34 -0
  161. package/dist/server/operations/storage-capabilities.js +38 -0
  162. package/dist/server/operations/storage.js +8 -17
  163. package/dist/server/operations/stream-workflow-sse.js +3 -9
  164. package/dist/server/operations/update-schedule.d.ts +8 -0
  165. package/dist/server/operations/update-schedule.js +70 -7
  166. package/dist/server/operations/workflow-events-sse.js +2 -2
  167. package/dist/server/rest-binding.d.ts +7 -6
  168. package/dist/server/rest-bindings.d.ts +2 -13
  169. package/dist/server/rest-bindings.js +19 -10
  170. package/dist/server/task-queue.d.ts +7 -5
  171. package/dist/storage/capabilities.d.ts +1 -1
  172. package/dist/storage/cloudflare-value-codec.d.ts +5 -3
  173. package/dist/storage/cloudflare-value-codec.js +1 -1
  174. package/dist/storage/compressed-storage.js +1 -1
  175. package/dist/storage/index.d.ts +7 -1
  176. package/dist/storage/interface.d.ts +16 -4
  177. package/dist/storage/interface.js +1 -1
  178. package/dist/storage/key-prefixes.d.ts +1 -1
  179. package/dist/storage/key-prefixes.js +4 -0
  180. package/dist/storage/lmdb.js +1 -1
  181. package/dist/storage/memory.js +1 -1
  182. package/dist/storage/neon.js +4 -4
  183. package/dist/storage/postgres.js +4 -4
  184. package/dist/storage/resolve.js +1 -1
  185. package/dist/storage/scoped-storage.js +1 -1
  186. package/dist/storage/testing.js +1 -1
  187. package/dist/storage/turso.js +2 -2
  188. package/dist/version.d.ts +1 -1
  189. package/dist/version.js +1 -1
  190. package/dist/web-extension.js +1 -1
  191. package/package.json +1 -1
@@ -1,14 +1,9 @@
1
- import { isWeftErrorCode } from "../../core/weft-error.js";
2
- import { FAULT_CODE_TO_HTTP_STATUS } from "../operation-fault.js";
1
+ import {
2
+ shapeRestFaultAsJson
3
+ } from "../operation-fault.js";
3
4
  export function isOperationFault(value) {
4
5
  return typeof value === "object" && value !== null && "code" in value && "message" in value && "data" in value;
5
6
  }
6
- export function jsonErrorResponse(message, status) {
7
- return new Response(JSON.stringify({ error: message }), {
8
- status,
9
- headers: { "Content-Type": "application/json" }
10
- });
11
- }
12
7
  export function invalidParamsFault(message, weftCode) {
13
8
  return {
14
9
  code: "InvalidParams",
@@ -16,19 +11,6 @@ export function invalidParamsFault(message, weftCode) {
16
11
  data: weftCode === void 0 ? { issues: [] } : { issues: [], weftCode }
17
12
  };
18
13
  }
19
- export function shapeRestFault(fault) {
20
- if (fault.code === "EngineFailure")
21
- return jsonErrorResponse("Internal server error", 500);
22
- const status = FAULT_CODE_TO_HTTP_STATUS[fault.code], weftCode = weftCodeFromFaultData(fault.data);
23
- if (weftCode === void 0)
24
- return jsonErrorResponse(fault.message, status);
25
- return new Response(JSON.stringify({ error: fault.message, weftCode }), {
26
- status,
27
- headers: { "Content-Type": "application/json" }
28
- });
29
- }
30
- function weftCodeFromFaultData(data) {
31
- if (typeof data !== "object" || data === null || !("weftCode" in data))
32
- return;
33
- return isWeftErrorCode(data.weftCode) ? data.weftCode : void 0;
14
+ export function shapeRestFault(fault, options) {
15
+ return shapeRestFaultAsJson(fault, options);
34
16
  }
@@ -6,6 +6,9 @@ export type PurgeWorkflowsOutput = PurgeResult;
6
6
  export declare const purgeWorkflowsOperation: import("../operation-catalog.ts").OperationDefinition<{
7
7
  status?: import("../../index.ts").WorkflowStatus | import("../../index.ts").WorkflowStatus[] | undefined;
8
8
  type?: string | undefined;
9
+ scheduleId?: string | undefined;
10
+ parentWorkflowId?: string | undefined;
11
+ parentWorkflowExecutionToken?: string | undefined;
9
12
  tags?: string[] | undefined;
10
13
  attributes?: {
11
14
  key: string;
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { WorkflowTypeNotRegisteredForRecoveryError } from "../../core/engine.js";
3
+ import { shapeRestFaultBody } from "../operation-fault.js";
3
4
  import { defineOperation } from "../operation-registry.js";
4
5
  import { shapeRestFault } from "./operation-helpers.js";
5
6
  const recoverAllInput = z.object({}), recoverAllOutput = z.object({
@@ -54,7 +55,7 @@ function shapeRecoverAllFault(fault) {
54
55
  if (fault.code !== "Conflict" || fault.data.missingTypes === void 0)
55
56
  return shapeRestFault(fault);
56
57
  return new Response(JSON.stringify({
57
- error: "workflow_type_not_registered_for_recovery",
58
+ ...shapeRestFaultBody(fault, "workflow_type_not_registered_for_recovery"),
58
59
  missingTypes: fault.data.missingTypes,
59
60
  missingWorkflowCount: fault.data.missingWorkflowCount,
60
61
  samplesTruncated: fault.data.samplesTruncated
@@ -6,7 +6,7 @@ import {
6
6
  } from "../../core/start-workflow-validation.js";
7
7
  import { defineOperation } from "../operation-registry.js";
8
8
  import { readRestJsonBody } from "../rest-body.js";
9
- import { isOperationFault, jsonErrorResponse, shapeRestFault } from "./operation-helpers.js";
9
+ import { isOperationFault, shapeRestFault } from "./operation-helpers.js";
10
10
  const singleWorkflowTagMutationInput = z.object({
11
11
  workflowId: z.string().min(1),
12
12
  tags: z.unknown().optional()
@@ -78,7 +78,7 @@ function shapeSingleWorkflowTagMutationSuccess(output) {
78
78
  }
79
79
  function shapeSingleWorkflowTagMutationFault(fault) {
80
80
  if (fault.code === "Unprocessable")
81
- return jsonErrorResponse(fault.message, 400);
81
+ return shapeRestFault(fault, { status: 400 });
82
82
  return shapeRestFault(fault);
83
83
  }
84
84
  function mapTagMutationErrorToFault(error, workflowId) {
@@ -1,10 +1,5 @@
1
1
  import { decodeCursor } from "../workflow-event-feed.js";
2
- import {
3
- invalidParamsFault,
4
- isOperationFault,
5
- jsonErrorResponse,
6
- shapeRestFault
7
- } from "./operation-helpers.js";
2
+ import { invalidParamsFault, isOperationFault, shapeRestFault } from "./operation-helpers.js";
8
3
  const textEncoder = new TextEncoder, DEFAULT_SSE_HEARTBEAT_INTERVAL_MS = 15000;
9
4
  export const SSE_ACCEPT_REQUIRED_MESSAGE = "Accept header must include text/event-stream";
10
5
  export function acceptsServerSentEvents(acceptHeader) {
@@ -30,7 +25,7 @@ export function readServerSentEventsCursor(value) {
30
25
  }
31
26
  export function shapeServerSentEventsFault(fault) {
32
27
  if (fault.code === "InvalidParams" && fault.message === SSE_ACCEPT_REQUIRED_MESSAGE)
33
- return jsonErrorResponse(fault.message, 406);
28
+ return shapeRestFault(fault, { status: 406 });
34
29
  return shapeRestFault(fault);
35
30
  }
36
31
  export function formatServerSentEvent(event) {
@@ -0,0 +1,34 @@
1
+ import { z } from 'zod';
2
+ import type { UnknownRestBinding } from '../rest-bindings.ts';
3
+ declare const storageCapabilitiesInput: z.ZodObject<{}, z.core.$strip>;
4
+ declare const storageCapabilitiesOutput: z.ZodObject<{
5
+ persistence: z.ZodEnum<{
6
+ ephemeral: "ephemeral";
7
+ local: "local";
8
+ remote: "remote";
9
+ }>;
10
+ readAfterWrite: z.ZodEnum<{
11
+ linearizable: "linearizable";
12
+ session: "session";
13
+ eventual: "eventual";
14
+ }>;
15
+ scanConsistency: z.ZodEnum<{
16
+ snapshot: "snapshot";
17
+ "best-effort": "best-effort";
18
+ }>;
19
+ atomicBatch: z.ZodBoolean;
20
+ conditionalBatch: z.ZodBoolean;
21
+ boundedRangeDelete: z.ZodBoolean;
22
+ }, z.core.$strict>;
23
+ export type StorageCapabilitiesInput = z.infer<typeof storageCapabilitiesInput>;
24
+ export type StorageCapabilitiesOutput = z.infer<typeof storageCapabilitiesOutput>;
25
+ export declare const storageCapabilitiesOperation: import("../operation-catalog.ts").OperationDefinition<Record<string, never>, {
26
+ persistence: "ephemeral" | "local" | "remote";
27
+ readAfterWrite: "linearizable" | "session" | "eventual";
28
+ scanConsistency: "snapshot" | "best-effort";
29
+ atomicBatch: boolean;
30
+ conditionalBatch: boolean;
31
+ boundedRangeDelete: boolean;
32
+ }, unknown>;
33
+ export declare const storageCapabilitiesRestBinding: UnknownRestBinding;
34
+ export {};
@@ -0,0 +1,38 @@
1
+ import { z } from "zod";
2
+ import { defineOperation } from "../operation-registry.js";
3
+ import { shapeRestFault } from "./operation-helpers.js";
4
+ const storageCapabilitiesInput = z.object({}), storageCapabilitiesOutput = z.object({
5
+ persistence: z.enum(["ephemeral", "local", "remote"]),
6
+ readAfterWrite: z.enum(["linearizable", "session", "eventual"]),
7
+ scanConsistency: z.enum(["snapshot", "best-effort"]),
8
+ atomicBatch: z.boolean(),
9
+ conditionalBatch: z.boolean(),
10
+ boundedRangeDelete: z.boolean()
11
+ }).strict();
12
+ export const storageCapabilitiesOperation = defineOperation({
13
+ name: "weft.storage.capabilities",
14
+ mcpExposable: !1,
15
+ summary: "Report the connected storage backend's capability profile",
16
+ destructive: !1,
17
+ tags: ["Storage"],
18
+ inputSchema: storageCapabilitiesInput,
19
+ outputSchema: storageCapabilitiesOutput,
20
+ access: {
21
+ kind: "scoped",
22
+ scopes: { kind: "anyOf", scopes: ["storage:read", "storage:admin"] }
23
+ },
24
+ discoverable: !0,
25
+ transports: { http: !0, jsonRpcHttp: !0, jsonRpcWebSocket: !0, jsonRpcStdio: !0 },
26
+ unknownKeyPolicy: { http: "strip", jsonRpc: "reject" },
27
+ invoke: async ({ engine }) => engine.storage.capabilities()
28
+ }), storageCapabilitiesRestBinding = {
29
+ method: "GET",
30
+ path: "/v1/storage/-/capabilities",
31
+ pathParamNames: [],
32
+ operationName: "weft.storage.capabilities",
33
+ inputSources: {},
34
+ extractInput: async () => ({}),
35
+ success: { kind: "json", status: 200 },
36
+ shapeSuccess: (output) => Response.json(output),
37
+ shapeFault: shapeRestFault
38
+ };
@@ -12,18 +12,9 @@ import { defineOperation } from "../operation-registry.js";
12
12
  import { isAuthenticated } from "../principal.js";
13
13
  import { readRestBodyBounded, readRestJsonBody } from "../rest-body.js";
14
14
  import { invalidParamsFault, isOperationFault, shapeRestFault } from "./operation-helpers.js";
15
- const storageReadAccess = {
15
+ const rawStorageAccess = {
16
16
  kind: "scoped",
17
- scopes: { kind: "anyOf", scopes: ["storage:read", "storage:admin"] }
18
- }, storageWriteAccess = {
19
- kind: "scoped",
20
- scopes: { kind: "anyOf", scopes: ["storage:write", "storage:admin"] }
21
- }, storageConditionalBatchAccess = {
22
- kind: "scopedAlternatives",
23
- alternatives: [
24
- { kind: "anyOf", scopes: ["storage:admin"] },
25
- { kind: "allOf", scopes: ["storage:read", "storage:write"] }
26
- ]
17
+ scopes: { kind: "anyOf", scopes: ["storage:admin"] }
27
18
  }, httpOnlyStorageTransports = {
28
19
  http: !0,
29
20
  jsonRpcHttp: !1,
@@ -187,7 +178,7 @@ export const storageGetOperation = defineOperation({
187
178
  tags: ["Storage"],
188
179
  inputSchema: storageGetInput,
189
180
  outputSchema: storageGetOutput,
190
- access: storageReadAccess,
181
+ access: rawStorageAccess,
191
182
  discoverable: !0,
192
183
  transports: httpOnlyStorageTransports,
193
184
  unknownKeyPolicy: { http: "strip", jsonRpc: "reject" },
@@ -202,7 +193,7 @@ export const storageGetOperation = defineOperation({
202
193
  tags: ["Storage"],
203
194
  inputSchema: storagePutInput,
204
195
  outputSchema: emptyOutput,
205
- access: storageWriteAccess,
196
+ access: rawStorageAccess,
206
197
  discoverable: !0,
207
198
  transports: httpOnlyStorageTransports,
208
199
  unknownKeyPolicy: { http: "strip", jsonRpc: "reject" },
@@ -218,7 +209,7 @@ export const storageGetOperation = defineOperation({
218
209
  tags: ["Storage"],
219
210
  inputSchema: storageDeleteInput,
220
211
  outputSchema: emptyOutput,
221
- access: storageWriteAccess,
212
+ access: rawStorageAccess,
222
213
  discoverable: !0,
223
214
  transports: httpOnlyStorageTransports,
224
215
  unknownKeyPolicy: { http: "strip", jsonRpc: "reject" },
@@ -234,7 +225,7 @@ export const storageGetOperation = defineOperation({
234
225
  tags: ["Storage"],
235
226
  inputSchema: storageScanInput,
236
227
  outputSchema: storageScanOutput,
237
- access: storageReadAccess,
228
+ access: rawStorageAccess,
238
229
  discoverable: !0,
239
230
  transports: httpOnlyStorageTransports,
240
231
  unknownKeyPolicy: { http: "strip", jsonRpc: "reject" },
@@ -250,7 +241,7 @@ export const storageGetOperation = defineOperation({
250
241
  tags: ["Storage"],
251
242
  inputSchema: storageBatchInput,
252
243
  outputSchema: emptyOutput,
253
- access: storageWriteAccess,
244
+ access: rawStorageAccess,
254
245
  discoverable: !0,
255
246
  transports: httpOnlyStorageTransports,
256
247
  unknownKeyPolicy: { http: "strip", jsonRpc: "reject" },
@@ -267,7 +258,7 @@ export const storageGetOperation = defineOperation({
267
258
  tags: ["Storage"],
268
259
  inputSchema: storageConditionalBatchInput,
269
260
  outputSchema: storageConditionalBatchOutput,
270
- access: storageConditionalBatchAccess,
261
+ access: rawStorageAccess,
271
262
  discoverable: !0,
272
263
  transports: httpOnlyStorageTransports,
273
264
  producibleFaults: ["NotImplemented"],
@@ -1,8 +1,7 @@
1
1
  import { z } from "zod";
2
- import { FAULT_CODE_TO_HTTP_STATUS } from "../operation-fault.js";
3
2
  import { defineOperation } from "../operation-registry.js";
4
3
  import { parseOptionalSequenceCursor } from "../sequence-cursor.js";
5
- import { invalidParamsFault, jsonErrorResponse } from "./operation-helpers.js";
4
+ import { invalidParamsFault, shapeRestFault } from "./operation-helpers.js";
6
5
  import { createStoredChunkSSEStream, SSE_RESPONSE_HEADERS } from "./sse-stream.js";
7
6
  const TOKENS_STREAM_KEY = "tokens", streamWorkflowSseInput = z.object({
8
7
  workflowId: z.string().min(1),
@@ -42,16 +41,11 @@ export const streamWorkflowSseOperation = defineOperation({
42
41
  });
43
42
  const ACCEPT_HEADER_MUST_INCLUDE_SSE = "Accept header must include text/event-stream";
44
43
  function shapeStreamWorkflowSseFault(fault) {
45
- if (fault.code === "NotFound")
46
- return jsonErrorResponse(fault.message, 404);
47
44
  if (fault.code === "InvalidParams") {
48
45
  if (fault.message === ACCEPT_HEADER_MUST_INCLUDE_SSE)
49
- return jsonErrorResponse(fault.message, 406);
50
- return jsonErrorResponse(fault.message, 400);
46
+ return shapeRestFault(fault, { status: 406 });
51
47
  }
52
- if (fault.code === "EngineFailure")
53
- return jsonErrorResponse("Internal server error", 500);
54
- return jsonErrorResponse(fault.message, FAULT_CODE_TO_HTTP_STATUS[fault.code]);
48
+ return shapeRestFault(fault);
55
49
  }
56
50
  function mapTokenChunkToText(chunk) {
57
51
  if (typeof chunk.value === "string")
@@ -4,12 +4,20 @@ declare const updateScheduleInput: z.ZodObject<{
4
4
  scheduleId: z.ZodString;
5
5
  cronExpression: z.ZodOptional<z.ZodUnknown>;
6
6
  every: z.ZodOptional<z.ZodUnknown>;
7
+ description: z.ZodOptional<z.ZodUnknown>;
8
+ overlap: z.ZodOptional<z.ZodUnknown>;
9
+ backfill: z.ZodOptional<z.ZodUnknown>;
10
+ jitter: z.ZodOptional<z.ZodUnknown>;
7
11
  }, z.core.$strip>;
8
12
  export type UpdateScheduleInput = z.infer<typeof updateScheduleInput>;
9
13
  export declare const updateScheduleOperation: import("../operation-catalog.ts").OperationDefinition<{
10
14
  scheduleId: string;
11
15
  cronExpression?: unknown;
12
16
  every?: unknown;
17
+ description?: unknown;
18
+ overlap?: unknown;
19
+ backfill?: unknown;
20
+ jitter?: unknown;
13
21
  }, null, unknown>;
14
22
  export declare const updateScheduleRestBinding: UnknownRestBinding;
15
23
  export {};
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { normalizeScheduleUpdateOptions } from "../../core/engine/validation/schedule.js";
2
3
  import { defineOperation } from "../operation-registry.js";
3
4
  import { readRestJsonBody } from "../rest-body.js";
4
5
  import { invalidParamsFault, isOperationFault, shapeRestFault } from "./operation-helpers.js";
@@ -6,25 +7,79 @@ import { mapScheduleErrorToFault, validateScheduleInputCadence } from "./schedul
6
7
  const updateScheduleInput = z.object({
7
8
  scheduleId: z.string().min(1),
8
9
  cronExpression: z.unknown().optional().describe("Cron expression. Supply exactly one of cronExpression or every; runtime validation requires a non-empty string."),
9
- every: z.unknown().optional().describe("Interval period (duration string or milliseconds). Supply exactly one of cronExpression or every.")
10
+ every: z.unknown().optional().describe("Interval period (duration string or milliseconds). Supply exactly one of cronExpression or every."),
11
+ description: z.unknown().optional().describe("Operator-facing schedule description. Runtime validation requires a string."),
12
+ overlap: z.unknown().optional(),
13
+ backfill: z.unknown().optional(),
14
+ jitter: z.unknown().optional()
10
15
  });
16
+ function isScheduleOverlapPolicy(value) {
17
+ return value === "skip" || value === "queue" || value === "cancel-running" || value === "allow";
18
+ }
19
+ function validateDescription(value) {
20
+ if (value === void 0)
21
+ return;
22
+ if (typeof value !== "string")
23
+ throw invalidParamsFault('Field "description" must be a string');
24
+ return value;
25
+ }
26
+ function validateOverlap(value) {
27
+ if (value === void 0)
28
+ return;
29
+ if (typeof value !== "string" || !isScheduleOverlapPolicy(value))
30
+ throw invalidParamsFault('Field "overlap" must be one of skip, queue, cancel-running, allow');
31
+ return value;
32
+ }
33
+ function validateBackfill(value) {
34
+ if (value === void 0)
35
+ return;
36
+ if (typeof value !== "boolean")
37
+ throw invalidParamsFault('Field "backfill" must be a boolean');
38
+ return value;
39
+ }
40
+ function formatJitterValidationMessage(message) {
41
+ const enginePrefix = "Invalid options.jitter: ", hasEnginePrefix = message.startsWith(enginePrefix), wireDetail = (hasEnginePrefix ? message.slice(enginePrefix.length) : message).replaceAll("options.jitter", 'Field "jitter"');
42
+ return hasEnginePrefix ? `Field "jitter" is invalid: ${wireDetail}` : wireDetail;
43
+ }
44
+ function validateJitter(value) {
45
+ if (value === void 0)
46
+ return;
47
+ if (typeof value !== "string" && typeof value !== "number")
48
+ throw invalidParamsFault('Field "jitter" must be a duration string or a number of milliseconds');
49
+ try {
50
+ normalizeScheduleUpdateOptions({ jitter: value });
51
+ } catch (error) {
52
+ const message = error instanceof Error ? error.message : String(error);
53
+ throw invalidParamsFault(formatJitterValidationMessage(message));
54
+ }
55
+ return value;
56
+ }
57
+ function validateScheduleUpdateOptions(input) {
58
+ const description = validateDescription(input.description), overlap = validateOverlap(input.overlap), backfill = validateBackfill(input.backfill), jitter = validateJitter(input.jitter);
59
+ return {
60
+ ...description !== void 0 ? { description } : {},
61
+ ...overlap !== void 0 ? { overlap } : {},
62
+ ...backfill !== void 0 ? { backfill } : {},
63
+ ...jitter !== void 0 ? { jitter } : {}
64
+ };
65
+ }
11
66
  export const updateScheduleOperation = defineOperation({
12
67
  name: "weft.schedules.update",
13
68
  mcpExposable: !1,
14
69
  summary: "Update a recurring schedule",
15
- description: "Update an existing recurring schedule by `id`, replacing its recurrence specification, target workflow input, or start options. Returns null on success. Faults with NotFound when no schedule with the given id exists and InvalidParams for a malformed recurrence specification.",
70
+ description: "Update an existing recurring schedule by `id`, replacing its recurrence specification and optionally changing description, overlap, backfill, or jitter. Omitted options retain their persisted values; schedule id, workflow type, and input remain unchanged. Returns null on success. Faults with NotFound when no schedule with the given id exists and InvalidParams for malformed fields.",
16
71
  destructive: !1,
17
72
  tags: ["Schedules"],
18
73
  inputSchema: updateScheduleInput,
19
74
  outputSchema: z.null(),
20
75
  access: { kind: "public" },
21
- producibleFaults: ["NotFound", "Conflict"],
76
+ producibleFaults: ["NotFound", "Conflict", "InvalidParams"],
22
77
  transports: { http: !0, jsonRpcHttp: !0, jsonRpcWebSocket: !0, jsonRpcStdio: !0 },
23
78
  unknownKeyPolicy: { http: "strip", jsonRpc: "reject" },
24
79
  invoke: async ({ input, engine }) => {
25
- const typedEngine = engine, spec = validateScheduleInputCadence(input);
80
+ const typedEngine = engine, spec = validateScheduleInputCadence(input), options = validateScheduleUpdateOptions(input);
26
81
  try {
27
- await typedEngine.updateSchedule(input.scheduleId, spec);
82
+ await typedEngine.updateSchedule(input.scheduleId, spec, options);
28
83
  return null;
29
84
  } catch (error) {
30
85
  throw mapScheduleErrorToFault(input.scheduleId, error);
@@ -38,7 +93,11 @@ export const updateScheduleOperation = defineOperation({
38
93
  inputSources: {
39
94
  scheduleId: { kind: "path", pathParam: "id" },
40
95
  cronExpression: { kind: "body-field", bodyField: "cronExpression" },
41
- every: { kind: "body-field", bodyField: "every" }
96
+ every: { kind: "body-field", bodyField: "every" },
97
+ description: { kind: "body-field", bodyField: "description" },
98
+ overlap: { kind: "body-field", bodyField: "overlap" },
99
+ backfill: { kind: "body-field", bodyField: "backfill" },
100
+ jitter: { kind: "body-field", bodyField: "jitter" }
42
101
  },
43
102
  extractInput: async (request, pathParams, context) => {
44
103
  let body;
@@ -55,7 +114,11 @@ export const updateScheduleOperation = defineOperation({
55
114
  return {
56
115
  scheduleId: pathParams.id ?? "",
57
116
  cronExpression: Object.hasOwn(record, "cronExpression") ? record.cronExpression : void 0,
58
- every: Object.hasOwn(record, "every") ? record.every : void 0
117
+ every: Object.hasOwn(record, "every") ? record.every : void 0,
118
+ description: record.description,
119
+ overlap: record.overlap,
120
+ backfill: record.backfill,
121
+ jitter: record.jitter
59
122
  };
60
123
  },
61
124
  success: { kind: "empty", status: 204 },
@@ -4,7 +4,7 @@ import { isAuthenticated } from "../principal.js";
4
4
  import {
5
5
  decodeCursor
6
6
  } from "../workflow-event-feed.js";
7
- import { invalidParamsFault, jsonErrorResponse } from "./operation-helpers.js";
7
+ import { invalidParamsFault, shapeRestFault } from "./operation-helpers.js";
8
8
  import {
9
9
  createEventEnvelopeSSEStream,
10
10
  readServerSentEventsCursor,
@@ -163,7 +163,7 @@ function shapeWorkflowEventsSseSuccess(output, request) {
163
163
  }
164
164
  function shapeWorkflowEventsSseFault(fault) {
165
165
  if (fault.code === "InvalidParams" && fault.message === MAXIMUM_WORKFLOW_STREAMS_MESSAGE)
166
- return jsonErrorResponse(fault.message, 429);
166
+ return shapeRestFault(fault, { status: 429 });
167
167
  return shapeServerSentEventsFault(fault);
168
168
  }
169
169
  function readSelector(request) {
@@ -114,16 +114,17 @@ export type RestBinding<Input, Output> = {
114
114
  /**
115
115
  * Optional override for fault → HTTP response mapping. When absent,
116
116
  * the transport adapter falls back to `faultToHttpResponse`, which emits
117
- * the REST fault body `{ error: { code, message, data? } }`. This is
118
- * distinct from the JSON-RPC fault object (`faultToJsonRpcError`): JSON-RPC
119
- * uses a flat `{ code, message, data }` with a numeric `code` and the
120
- * symbolic name relocated to `data.weftCode`. REST and JSON-RPC deliberately
121
- * differ in fault shape, so each transport owns its own projection.
117
+ * the same flat audited `{ error, weftCode?, data? }` body as
118
+ * `shapeRestFault`. This is distinct from the JSON-RPC fault object
119
+ * (`faultToJsonRpcError`), which uses `{ code, message, data }` with a numeric
120
+ * `code` and a broader data projection. REST and JSON-RPC deliberately differ
121
+ * in fault shape, so each transport owns its own projection.
122
122
  *
123
123
  * REST operations provide this to shape faults the way a REST client
124
124
  * expects: most use `shapeRestFault`, which masks an `EngineFailure` to a
125
125
  * flat `{ error: "Internal server error" }` with status `500` (never
126
- * leaking internal detail over REST) and maps the remaining fault codes to
126
+ * leaking internal detail over REST), adds audited safe context under a
127
+ * `data` sibling for other faults, and maps the remaining fault codes to
127
128
  * their HTTP statuses. A few operations supply a bespoke shaper to special-case
128
129
  * a particular fault — typically to override its message or to handle one code
129
130
  * explicitly — while delegating the rest. The status often matches what the
@@ -29,9 +29,8 @@ import type { TaskQueue } from './task-queue.ts';
29
29
  export type UnknownRestBinding = RestBinding<any, any>;
30
30
  /**
31
31
  * Static REST bindings for all operations that do not need per-server
32
- * configuration. The `weft.system.metrics` binding is excluded here
33
- * because it is constructed per-server via `createGetSystemMetricsRestBinding`
34
- * (to receive the metrics collector without module-level singletons).
32
+ * configuration. The `weft.system.metrics` binding is excluded because its
33
+ * factory receives the per-server metrics collector.
35
34
  * Use `createLiveRestBindings()` to get the full set for a given server.
36
35
  */
37
36
  export declare const REST_BINDINGS: ReadonlyArray<UnknownRestBinding>;
@@ -43,16 +42,6 @@ export declare const REST_BINDINGS: ReadonlyArray<UnknownRestBinding>;
43
42
  * are wired into the operations through {@link createLiveOperationRegistry}.
44
43
  */
45
44
  export declare function createLiveRestBindings(): ReadonlyArray<UnknownRestBinding>;
46
- /**
47
- * Live operation registry — populated with every operation that has a
48
- * `RestBinding`, a JSON-RPC mount, or an stdio mount. Exposed via a
49
- * factory so tests can spin up a fresh registry without inheriting
50
- * the live one's state.
51
- *
52
- * Concrete `OperationDefinition<Input, Output>` values are directly
53
- * assignable to `RegistrableOperation` by the variance design in
54
- * `operation-catalog.ts` — no `as ErasedOperation` cast is needed.
55
- */
56
45
  /**
57
46
  * Create the live operation registry for a server instance.
58
47
  *
@@ -7,12 +7,7 @@ import {
7
7
  aggregateWorkflowsOperation,
8
8
  aggregateWorkflowsRestBinding
9
9
  } from "./operations/aggregate-workflows.js";
10
- import {
11
- completeAsyncActivityOperation,
12
- completeAsyncActivityRestBinding,
13
- failAsyncActivityOperation,
14
- failAsyncActivityRestBinding
15
- } from "./operations/async-activity.js";
10
+ import * as asyncActivity from "./operations/async-activity.js";
16
11
  import {
17
12
  bulkCancelWorkflowsOperation,
18
13
  bulkCancelWorkflowsRestBinding
@@ -66,6 +61,10 @@ import {
66
61
  getStreamChunksOperation,
67
62
  getStreamChunksRestBinding
68
63
  } from "./operations/get-stream-chunks.js";
64
+ import {
65
+ getSystemLeaseOperation,
66
+ getSystemLeaseRestBinding
67
+ } from "./operations/get-system-lease.js";
69
68
  import {
70
69
  createGetSystemMetricsOperation,
71
70
  createGetSystemMetricsRestBinding
@@ -89,6 +88,7 @@ import {
89
88
  getWorkflowEventsOperation,
90
89
  getWorkflowEventsRestBinding
91
90
  } from "./operations/get-workflow-events.js";
91
+ import * as workflowObservability from "./operations/get-workflow-observability.js";
92
92
  import {
93
93
  getWorkflowResultOperation,
94
94
  getWorkflowResultRestBinding
@@ -155,6 +155,7 @@ import {
155
155
  startOrSignalWorkflowRestBinding
156
156
  } from "./operations/start-or-signal-workflow.js";
157
157
  import { startWorkflowOperation, startWorkflowRestBinding } from "./operations/start-workflow.js";
158
+ import * as storageCapabilities from "./operations/storage-capabilities.js";
158
159
  import {
159
160
  storageBatchOperation,
160
161
  storageBatchRestBinding,
@@ -228,11 +229,13 @@ export const REST_BINDINGS = [
228
229
  cancelWorkflowRestBinding,
229
230
  getWorkflowResultRestBinding,
230
231
  getWorkflowAttributesRestBinding,
232
+ ...workflowObservability.workflowObservabilityRestBindings,
231
233
  getWorkflowEventsRestBinding,
232
234
  setWorkflowAttributesRestBinding,
233
235
  signalWorkflowRestBinding,
234
- completeAsyncActivityRestBinding,
235
- failAsyncActivityRestBinding,
236
+ asyncActivity.listPendingAsyncActivitiesRestBinding,
237
+ asyncActivity.completeAsyncActivityRestBinding,
238
+ asyncActivity.failAsyncActivityRestBinding,
236
239
  queryWorkflowRestBinding,
237
240
  queryWorkflowWithInputRestBinding,
238
241
  resumeWorkflowRestBinding,
@@ -243,6 +246,7 @@ export const REST_BINDINGS = [
243
246
  createScheduleRestBinding,
244
247
  updateScheduleRestBinding,
245
248
  getRegistryRestBinding,
249
+ getSystemLeaseRestBinding,
246
250
  getRetentionOverviewRestBinding,
247
251
  getUpdateResultRestBinding,
248
252
  listReviewsRestBinding,
@@ -265,6 +269,7 @@ export const REST_BINDINGS = [
265
269
  listSchedulesRestBinding,
266
270
  getScheduleRestBinding,
267
271
  replayWorkflowRestBinding,
272
+ storageCapabilities.storageCapabilitiesRestBinding,
268
273
  storageGetRestBinding,
269
274
  storagePutRestBinding,
270
275
  storageDeleteRestBinding,
@@ -357,11 +362,13 @@ export function createLiveOperationRegistry(options) {
357
362
  cancelWorkflowOperation,
358
363
  getWorkflowResultOperation,
359
364
  getWorkflowAttributesOperation,
365
+ ...workflowObservability.workflowObservabilityOperations,
360
366
  getWorkflowEventsOperation,
361
367
  setWorkflowAttributesOperation,
362
368
  signalWorkflowOperation,
363
- completeAsyncActivityOperation,
364
- failAsyncActivityOperation,
369
+ asyncActivity.listPendingAsyncActivitiesOperation,
370
+ asyncActivity.completeAsyncActivityOperation,
371
+ asyncActivity.failAsyncActivityOperation,
365
372
  queryWorkflowOperation,
366
373
  resumeWorkflowOperation,
367
374
  suspendWorkflowOperation,
@@ -371,6 +378,7 @@ export function createLiveOperationRegistry(options) {
371
378
  createScheduleOperation,
372
379
  updateScheduleOperation,
373
380
  getRegistryOperation,
381
+ getSystemLeaseOperation,
374
382
  getRetentionOverviewOperation,
375
383
  getUpdateResultOperation,
376
384
  listReviewsOperation,
@@ -395,6 +403,7 @@ export function createLiveOperationRegistry(options) {
395
403
  listSchedulesOperation,
396
404
  getScheduleOperation,
397
405
  replayWorkflowOperation,
406
+ storageCapabilities.storageCapabilitiesOperation,
398
407
  storageGetOperation,
399
408
  storagePutOperation,
400
409
  storageDeleteOperation,
@@ -14,21 +14,23 @@ export declare function resetLifoStarvationWarningForTesting(): void;
14
14
  * until a task arrives or the timeout expires.
15
15
  *
16
16
  * `serve()` owns the live instance and exposes it as
17
- * {@link WeftServer.taskQueue} for inspection. Prefer the `WeftServer` methods
18
- * (`dispatchTask`, `shutdownWorker`, etc.) over mutating the queue directly
19
- * the type is re-exported so callers can name `server.taskQueue`, not as a
20
- * stable mutation surface.
17
+ * {@link WeftServer.taskQueue} for inspection. Direct `handleRequest()` hosts
18
+ * can construct an instance alongside a `WorkerRegistry` and inject both via
19
+ * `HandlerOptions`. Prefer the `WeftServer` methods (`dispatchTask`,
20
+ * `shutdownWorker`, etc.) over mutating a server-owned queue directly.
21
21
  *
22
22
  * @example
23
23
  * ```ts
24
- * import { serve, type TaskQueue } from '@lostgradient/weft/server';
24
+ * import { serve, TaskQueue } from '@lostgradient/weft/server';
25
25
  * import { Engine, MemoryStorage } from '@lostgradient/weft';
26
26
  *
27
27
  * await using engine = new Engine({ storage: new MemoryStorage() });
28
28
  * await using server = serve({ engine });
29
29
  *
30
30
  * const taskQueue: TaskQueue = server.taskQueue;
31
+ * const standaloneTaskQueue = new TaskQueue();
31
32
  * void taskQueue;
33
+ * standaloneTaskQueue[Symbol.dispose]();
32
34
  * ```
33
35
  */
34
36
  export declare class TaskQueue implements Disposable {
@@ -72,7 +72,7 @@ export type StorageCapabilities = {
72
72
  * - `remote`: data is owned by a remote service or synchronized storage area
73
73
  * whose durability and freshness depend on that service.
74
74
  */
75
- persistence?: 'ephemeral' | 'local' | 'remote';
75
+ persistence: 'ephemeral' | 'local' | 'remote';
76
76
  /**
77
77
  * Visibility of a completed write to a later read, scoped to one `Storage`
78
78
  * instance.
@@ -41,9 +41,11 @@ export type CloudflareValueEncoding = 'base64' | 'blob';
41
41
  * throws immediately, instead of silently misinterpreting the bytes.
42
42
  *
43
43
  * This is the cross-mode contract for
44
- * {@link CloudflareDurableObjectSQLiteStorageOptions.valueEncoding}: a table
45
- * must use a single `valueEncoding` for its lifetime. There is no dual-read
46
- * fallback and no migration path between encodings pick one per table.
44
+ * {@link CloudflareDurableObjectSQLiteStorageOptions.valueEncoding}:
45
+ * `valueEncoding` is a per-table storage-format decision, and every row in a
46
+ * table must use the same encoding. Each codec accepts only values written in
47
+ * its storage class, so cross-mode reads fail fast. Configure a distinct table
48
+ * name when one Durable Object needs both encodings.
47
49
  */
48
50
  type CloudflareValueCodec = {
49
51
  readonly sqlColumnType: 'TEXT' | 'BLOB';