@lostgradient/weft 0.7.0 → 0.9.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.
- package/README.md +9 -3
- package/dist/cli/generated/operation-client.generated.d.ts +1 -0
- package/dist/cli-main.js +78 -78
- package/dist/core/context/activity-retry-state.d.ts +6 -5
- package/dist/core/context/activity-retry-state.js +31 -21
- package/dist/core/context/durable-activity.d.ts +117 -0
- package/dist/core/context/durable-activity.js +79 -0
- package/dist/core/context/durable-operations.js +1 -1
- package/dist/core/context/index.d.ts +1 -0
- package/dist/core/context/index.js +2 -0
- package/dist/core/context/operation-request.d.ts +17 -0
- package/dist/core/context/parallel-operations.js +1 -0
- package/dist/core/context/run-operation-cached-request.d.ts +8 -0
- package/dist/core/context/run-operation-cached-request.js +59 -0
- package/dist/core/context/run-operation.d.ts +23 -5
- package/dist/core/context/run-operation.js +63 -47
- package/dist/core/context/speculative-child.js +1 -0
- package/dist/core/context/types.d.ts +1 -0
- package/dist/core/engine/activity-heartbeat-tracking.d.ts +8 -17
- package/dist/core/engine/activity-heartbeat-tracking.js +12 -2
- package/dist/core/engine/activity-reconciliation.d.ts +1 -0
- package/dist/core/engine/activity-reconciliation.js +7 -2
- package/dist/core/engine/anonymous-signal-sequence.js +6 -6
- package/dist/core/engine/async-activity-completion.d.ts +5 -7
- package/dist/core/engine/async-activity-completion.js +13 -9
- package/dist/core/engine/bulk-operations-purge.js +2 -1
- package/dist/core/engine/bulk-operations.js +18 -36
- package/dist/core/engine/callback-checkpoint-persistence.d.ts +3 -0
- package/dist/core/engine/callback-checkpoint-persistence.js +25 -0
- package/dist/core/engine/callback-creators-bundles.js +5 -2
- package/dist/core/engine/checkpoint-io.d.ts +4 -1
- package/dist/core/engine/checkpoint-io.js +19 -10
- package/dist/core/engine/completed-review-storage.d.ts +2 -1
- package/dist/core/engine/completed-review-storage.js +4 -3
- package/dist/core/engine/disposal.js +1 -0
- package/dist/core/engine/engine-internal-types.d.ts +1 -0
- package/dist/core/engine/index.d.ts +31 -0
- package/dist/core/engine/index.js +19 -10
- package/dist/core/engine/inline-launch-queue.js +1 -1
- package/dist/core/engine/internals.d.ts +25 -2
- package/dist/core/engine/lease-manager.js +2 -2
- package/dist/core/engine/lifecycle/fork-helpers.js +1 -0
- package/dist/core/engine/lifecycle/resume.js +6 -0
- package/dist/core/engine/lifecycle/start-exec.d.ts +2 -2
- package/dist/core/engine/lifecycle/start-exec.js +6 -4
- package/dist/core/engine/lifecycle/start.js +1 -0
- package/dist/core/engine/lifecycle/transition.js +6 -0
- package/dist/core/engine/memo-durable-activity.d.ts +11 -0
- package/dist/core/engine/memo-durable-activity.js +282 -0
- package/dist/core/engine/operations-activity.d.ts +6 -2
- package/dist/core/engine/operations-activity.js +24 -10
- package/dist/core/engine/operations-data.d.ts +4 -1
- package/dist/core/engine/operations-data.js +3 -3
- package/dist/core/engine/operations-time.d.ts +2 -2
- package/dist/core/engine/operations-time.js +40 -6
- package/dist/core/engine/reviews.js +7 -4
- package/dist/core/engine/schedule-timer.js +2 -0
- package/dist/core/engine/schedules.js +3 -0
- package/dist/core/engine/storage-io.js +1 -1
- package/dist/core/engine/termination/cleanup.js +15 -13
- package/dist/core/engine/termination/finalizer-activity.d.ts +1 -1
- package/dist/core/engine/termination/finalizer-activity.js +5 -1
- package/dist/core/engine/termination/finalizer.js +1 -1
- package/dist/core/engine/validation/schedule-options.d.ts +9 -0
- package/dist/core/engine/validation/schedule-options.js +59 -0
- package/dist/core/engine/validation/schedule.d.ts +3 -8
- package/dist/core/engine/validation/schedule.js +40 -56
- package/dist/core/engine/validation.js +1 -0
- package/dist/core/execution-strategy.d.ts +1 -0
- package/dist/core/inline-execution-strategy.context-options.d.ts +1 -0
- package/dist/core/inline-execution-strategy.context-options.js +3 -0
- package/dist/core/json.js +1 -1
- package/dist/core/types/activity.d.ts +11 -0
- package/dist/core/types/checkpoint.d.ts +1 -0
- package/dist/core/types/schedules.d.ts +10 -0
- package/dist/core/types/state.d.ts +6 -0
- package/dist/core/types/workflow-context.d.ts +13 -0
- package/dist/core/weft-error.d.ts +1 -1
- package/dist/core/weft-error.js +2 -0
- package/dist/core/worker-execution-strategy.d.ts +1 -0
- package/dist/core/worker-inbound-message.d.ts +1 -0
- package/dist/core/worker-inbound-message.js +3 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +6 -0
- package/dist/json-schema.js +2 -2
- package/dist/mcp/cli.js +32 -32
- package/dist/observability/index.js +2 -2
- package/dist/runtime/portable.d.ts +1 -1
- package/dist/server/handler.js +27 -27
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.js +32 -32
- package/dist/server/operations/create-schedule.d.ts +2 -0
- package/dist/server/operations/create-schedule.js +13 -2
- package/dist/server/rest-binding.d.ts +1 -1
- package/dist/server/runtime/task-dispatch.js +6 -0
- package/dist/server/runtime/task-polling.js +9 -1
- package/dist/server/runtime/task-reconciliation.js +2 -1
- package/dist/server/runtime/websocket-worker.js +7 -2
- package/dist/server/serve-internals.d.ts +28 -0
- package/dist/server/serve-internals.js +4 -2
- package/dist/server/task-queue-types.d.ts +2 -0
- package/dist/server/task-state.d.ts +4 -0
- package/dist/service-worker/index.d.ts +15 -14
- package/dist/service-worker/index.js +28 -28
- package/dist/service-worker/scheduler.d.ts +41 -1
- package/dist/service-worker/setup.d.ts +18 -1
- package/dist/service-worker/setup.js +7 -4
- package/dist/storage/auto.d.ts +36 -18
- package/dist/storage/auto.js +1 -1
- package/dist/storage/compressed-storage.js +1 -1
- package/dist/storage/indexeddb.d.ts +6 -1
- package/dist/storage/indexeddb.js +1 -1
- package/dist/storage/interface.js +1 -1
- package/dist/storage/lmdb.js +1 -1
- package/dist/storage/memory.js +1 -1
- package/dist/storage/neon.js +1 -1
- package/dist/storage/resolve.js +1 -1
- package/dist/storage/scoped-storage.js +1 -1
- package/dist/storage/testing.js +1 -1
- package/dist/storage/turso.js +1 -1
- package/dist/storage/typed-storage.d.ts +1 -1
- package/dist/storage/typed-storage.js +1 -1
- package/dist/storage/web-extension.d.ts +1 -1
- package/dist/storage/web-extension.js +1 -1
- package/dist/testing/index.js +32 -32
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker/execute-with-interceptors.d.ts +9 -3
- package/dist/worker/execute-with-interceptors.js +14 -2
- package/dist/worker/long-poll.d.ts +2 -1
- package/dist/worker/long-poll.js +1 -1
- package/dist/worker/protocol-messages.d.ts +2 -0
- package/dist/worker/protocol-schemas.d.ts +8 -0
- package/dist/worker/protocol-schemas.js +1 -0
- package/dist/worker/protocol.js +1 -1
- package/dist/worker/remote-activity-context.d.ts +2 -0
- package/dist/workers/activity-runner.d.ts +2 -0
- package/dist/workers/activity-runner.js +9 -1
- package/dist/workers/workflow-runner.d.ts +2 -1
- package/dist/workers/workflow-runner.js +1 -0
- package/package.json +1 -1
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = "0.
|
|
1
|
+
export const VERSION = "0.9.0";
|
|
@@ -10,10 +10,17 @@ export interface TaskInfo {
|
|
|
10
10
|
attempt?: number;
|
|
11
11
|
input: unknown;
|
|
12
12
|
headers?: Record<string, string>;
|
|
13
|
+
workflowExecutionToken?: string;
|
|
14
|
+
attemptToken?: string;
|
|
13
15
|
}
|
|
14
16
|
export interface ComposedInterceptor {
|
|
15
17
|
execute: ReturnType<typeof composeActivityInterceptors>['execute'];
|
|
16
18
|
}
|
|
19
|
+
type ActivityExecutionContext = {
|
|
20
|
+
signal: AbortSignal;
|
|
21
|
+
workflowExecutionToken?: string;
|
|
22
|
+
activityAttemptToken?: string;
|
|
23
|
+
};
|
|
17
24
|
/**
|
|
18
25
|
* Pre-compose interceptors once (at construction time) so the chain
|
|
19
26
|
* is not rebuilt on every task execution.
|
|
@@ -23,6 +30,5 @@ export declare function buildComposedInterceptor(interceptors: ActivityIntercept
|
|
|
23
30
|
* Execute an activity function, optionally wrapped by a pre-composed interceptor chain.
|
|
24
31
|
* Provides a consistent AbortSignal and headers Map to the interception context.
|
|
25
32
|
*/
|
|
26
|
-
export declare function executeWithInterceptors(activityFunction: (input: unknown, context?:
|
|
27
|
-
|
|
28
|
-
}) => Promise<unknown>, task: TaskInfo, composed: ComposedInterceptor | null, signal?: AbortSignal): Promise<unknown>;
|
|
33
|
+
export declare function executeWithInterceptors(activityFunction: (input: unknown, context?: ActivityExecutionContext) => Promise<unknown>, task: TaskInfo, composed: ComposedInterceptor | null, signal?: AbortSignal): Promise<unknown>;
|
|
34
|
+
export {};
|
|
@@ -5,8 +5,9 @@ export function buildComposedInterceptor(interceptors) {
|
|
|
5
5
|
return composeActivityInterceptors(interceptors);
|
|
6
6
|
}
|
|
7
7
|
export async function executeWithInterceptors(activityFunction, task, composed, signal) {
|
|
8
|
+
const activityContext = createActivityExecutionContext(task, signal);
|
|
8
9
|
if (!composed)
|
|
9
|
-
return activityFunction(task.input,
|
|
10
|
+
return activityFunction(task.input, activityContext);
|
|
10
11
|
const headers = new Map(Object.entries(task.headers ?? {}));
|
|
11
12
|
return composed.execute({
|
|
12
13
|
activityName: task.activityName,
|
|
@@ -16,6 +17,17 @@ export async function executeWithInterceptors(activityFunction, task, composed,
|
|
|
16
17
|
headers,
|
|
17
18
|
...signal && { signal }
|
|
18
19
|
}, async (interception) => {
|
|
19
|
-
return activityFunction(interception.input,
|
|
20
|
+
return activityFunction(interception.input, activityContext);
|
|
20
21
|
});
|
|
21
22
|
}
|
|
23
|
+
function createActivityExecutionContext(task, signal) {
|
|
24
|
+
if (signal === void 0 && task.workflowExecutionToken === void 0 && task.attemptToken === void 0)
|
|
25
|
+
return;
|
|
26
|
+
return {
|
|
27
|
+
signal: signal ?? new AbortController().signal,
|
|
28
|
+
...task.workflowExecutionToken !== void 0 && {
|
|
29
|
+
workflowExecutionToken: task.workflowExecutionToken
|
|
30
|
+
},
|
|
31
|
+
...task.attemptToken !== void 0 && { activityAttemptToken: task.attemptToken }
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { ActivityInterceptor } from '../core/interceptor.ts';
|
|
2
|
+
import type { RemoteWorkerActivityFunction } from './workflow-activity-binding.ts';
|
|
2
3
|
export interface LongPollWorkerOptions {
|
|
3
4
|
serverUrl: string;
|
|
4
|
-
activities: Record<string,
|
|
5
|
+
activities: Record<string, RemoteWorkerActivityFunction>;
|
|
5
6
|
concurrency?: number;
|
|
6
7
|
queue?: string;
|
|
7
8
|
pollTimeout?: number;
|
package/dist/worker/long-poll.js
CHANGED
|
@@ -103,7 +103,7 @@ export class LongPollWorker {
|
|
|
103
103
|
});
|
|
104
104
|
return;
|
|
105
105
|
}
|
|
106
|
-
const result = await executeWithInterceptors(activityFunction, task, this.#composedInterceptor);
|
|
106
|
+
const result = await executeWithInterceptors(activityFunction, task, this.#composedInterceptor, this.#abortController.signal);
|
|
107
107
|
await fetch(resultUrl, {
|
|
108
108
|
method: "POST",
|
|
109
109
|
headers: { ...this.#options.headers, "Content-Type": "application/json" },
|
|
@@ -245,6 +245,8 @@ export type TaskMessage = {
|
|
|
245
245
|
readonly input: RemoteWorkerJsonValue;
|
|
246
246
|
readonly attempt?: number;
|
|
247
247
|
readonly headers?: Readonly<Record<string, string>>;
|
|
248
|
+
/** Durable token for the workflow run that launched this activity, when known. */
|
|
249
|
+
readonly workflowExecutionToken?: string;
|
|
248
250
|
/**
|
|
249
251
|
* Unique, unguessable token identifying this specific dispatch attempt. The
|
|
250
252
|
* current server always stamps one, and the worker must echo it back on the
|
|
@@ -183,6 +183,10 @@ export declare const REMOTE_WORKER_MESSAGE_SCHEMAS: {
|
|
|
183
183
|
readonly minimum: 1;
|
|
184
184
|
};
|
|
185
185
|
readonly headers: JsonSchemaObject;
|
|
186
|
+
readonly workflowExecutionToken: {
|
|
187
|
+
readonly type: "string";
|
|
188
|
+
readonly minLength: 1;
|
|
189
|
+
};
|
|
186
190
|
readonly attemptToken: {
|
|
187
191
|
readonly type: "string";
|
|
188
192
|
readonly minLength: 1;
|
|
@@ -485,6 +489,10 @@ export declare const REMOTE_WORKER_PROTOCOL_JSON_SCHEMA: {
|
|
|
485
489
|
readonly minimum: 1;
|
|
486
490
|
};
|
|
487
491
|
readonly headers: JsonSchemaObject;
|
|
492
|
+
readonly workflowExecutionToken: {
|
|
493
|
+
readonly type: "string";
|
|
494
|
+
readonly minLength: 1;
|
|
495
|
+
};
|
|
488
496
|
readonly attemptToken: {
|
|
489
497
|
readonly type: "string";
|
|
490
498
|
readonly minLength: 1;
|
|
@@ -94,6 +94,7 @@ export const REMOTE_WORKER_MESSAGE_SCHEMAS = {
|
|
|
94
94
|
input: jsonValueSchema,
|
|
95
95
|
attempt: { type: "number", minimum: 1 },
|
|
96
96
|
headers: stringMapSchema,
|
|
97
|
+
workflowExecutionToken: { type: "string", minLength: 1 },
|
|
97
98
|
attemptToken: { type: "string", minLength: 1 }
|
|
98
99
|
}
|
|
99
100
|
},
|
package/dist/worker/protocol.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var h=Object.defineProperty;var M=(z)=>z;function I(z,B){this[z]=M.bind(null,B)}var r=(z,B)=>{for(var D in B)h(z,D,{get:B[D],enumerable:!0,configurable:!0,set:I.bind(B,D)})};var o=(z,B)=>()=>(z&&(B=z(z=0)),B);var e=(z,B,D)=>{if(B!=null){if(typeof B!=="object"&&typeof B!=="function")throw TypeError('Object expected to be assigned to "using" declaration');let X;if(D)X=B[Symbol.asyncDispose];if(X===void 0)X=B[Symbol.dispose];if(typeof X!=="function")throw TypeError("Object not disposable");z.push([D,X,B])}else if(D)z.push([D]);return B},zz=(z,B,D)=>{let X=(U)=>B=D?new SuppressedError(U,B,"An error was suppressed during disposal"):(D=!0,U),Y=(U)=>{while(U=z.pop())try{var L=U[1]&&U[1].call(U[2]);if(U[0])return Promise.resolve(L).then(Y,(G)=>(X(G),Y()))}catch(G){X(G)}if(D)throw B};return Y()};function b(z){return z!==null&&typeof z==="object"&&!Array.isArray(z)}function $(z){if(z===null||typeof z==="string"||typeof z==="boolean"||typeof z==="number"&&Number.isFinite(z))return!0;if(Array.isArray(z))return z.every($);if(!b(z))return!1;return Object.values(z).every($)}function Z(z){return typeof z==="string"&&z.length>0}function J(z){return Array.isArray(z)&&z.every(Z)}function w(z){if(!b(z))return!1;return Object.values(z).every((B)=>typeof B==="string")}function q(z){if(!b(z))return!1;return Object.values(z).every($)}function H(z){return typeof z==="number"&&Number.isFinite(z)}function Q(z,B,D){return{ok:!1,error:{code:z,message:B,...D!==void 0?{requestedProtocolVersion:D}:{}}}}function f(z,B,D){let X={};for(let[Y,U,L,G]of D){let j=B[Y];if(j===void 0){if(U)return{ok:!1,error:Q(z,G)};continue}if(!L(j))return{ok:!1,error:Q(z,G)};X[Y]=j}return{ok:!0,values:X}}var x=2,P=2,g=2,_=[2];var K={$ref:"#/$defs/jsonValue"},A={type:"object",additionalProperties:K},y={type:"object",additionalProperties:{type:"string"}},F={const:x},N={register:{type:"object",additionalProperties:!1,required:["type","protocolVersion","workerId","activities"],properties:{type:{const:"register"},protocolVersion:F,workerId:{type:"string",minLength:1},activities:{type:"array",items:{type:"string",minLength:1}},concurrency:{type:"number",minimum:1,maximum:1000},queue:{type:"string",minLength:1},deploymentName:{type:"string",minLength:1},buildId:{type:"string",minLength:1},runtimeVersion:{type:"string",minLength:1},gitSha:{type:"string",minLength:1},startedAt:{type:"number"},capabilities:A}},heartbeat:{type:"object",additionalProperties:!1,required:["type","workerId"],properties:{type:{const:"heartbeat"},workerId:{type:"string",minLength:1}}},taskResult:{oneOf:[{type:"object",additionalProperties:!1,required:["type","operationId","status","value"],properties:{type:{const:"taskResult"},operationId:{type:"string",minLength:1},status:{const:"completed"},value:K,attemptToken:{type:"string",minLength:1}}},{type:"object",additionalProperties:!1,required:["type","operationId","status","error"],properties:{type:{const:"taskResult"},operationId:{type:"string",minLength:1},status:{const:"failed"},error:{type:"string"},attemptToken:{type:"string",minLength:1}}},{type:"object",additionalProperties:!1,required:["type","operationId","status","error"],properties:{type:{const:"taskResult"},operationId:{type:"string",minLength:1},status:{const:"cancelled"},error:{type:"string"},cancelled:{const:!0},attemptToken:{type:"string",minLength:1}}}]},task:{type:"object",additionalProperties:!1,required:["type","operationId","activityName","input"],properties:{type:{const:"task"},operationId:{type:"string",minLength:1},activityName:{type:"string",minLength:1},input:K,attempt:{type:"number",minimum:1},headers:y,attemptToken:{type:"string",minLength:1}}},cancel:{type:"object",additionalProperties:!1,required:["type","operationId"],properties:{type:{const:"cancel"},operationId:{type:"string",minLength:1}}},shutdown:{type:"object",additionalProperties:!1,required:["type"],properties:{type:{const:"shutdown"}}},registerAck:{type:"object",additionalProperties:!1,required:["type","protocolVersion","workerId","queue","activities","concurrency"],properties:{type:{const:"registerAck"},protocolVersion:F,workerId:{type:"string",minLength:1},queue:{type:"string",minLength:1},activities:{type:"array",items:{type:"string",minLength:1}},concurrency:{type:"number",minimum:1,maximum:1000}}},registerError:{type:"object",additionalProperties:!1,required:["type","code","message","supportedProtocolVersions"],properties:{type:{const:"registerError"},code:{enum:["invalid_registration","unsupported_protocol_version"]},message:{type:"string"},supportedProtocolVersions:{type:"array",items:F},requestedProtocolVersion:{type:"number"}}},protocolError:{type:"object",additionalProperties:!1,required:["type","code","message"],properties:{type:{const:"protocolError"},code:{enum:["invalid_json","invalid_message","unknown_message_type","registration_required"]},message:{type:"string"}}}},T={$schema:"https://json-schema.org/draft/2020-12/schema",$id:"https://weft.dev/schemas/remote-worker-protocol.v1.json",title:"Weft RemoteWorker Protocol v1",oneOf:Object.keys(N).map((z)=>({$ref:`#/$defs/messages/${z}`})),$defs:{jsonValue:{oneOf:[{type:"null"},{type:"boolean"},{type:"number"},{type:"string"},{type:"array",items:{$ref:"#/$defs/jsonValue"}},{type:"object",additionalProperties:{$ref:"#/$defs/jsonValue"}}]},jsonObject:A,messages:N}};function C(z){let B=z.attemptToken;if(B===void 0)return{ok:!0,message:{}};if(!Z(B))return Q("invalid_message","taskResult.attemptToken must be a non-empty string when present");return{ok:!0,message:{attemptToken:B}}}function O(z,B){let D=B.value;if(!$(D))return Q("invalid_message","completed taskResult.value must be valid JSON");let X=C(B);if(!X.ok)return X;return{ok:!0,message:{type:"taskResult",operationId:z,status:"completed",value:D,...X.message}}}function V(z,B){let D=B.error;if(typeof D!=="string")return Q("invalid_message","failed taskResult.error must be a string");let X=C(B);if(!X.ok)return X;return{ok:!0,message:{type:"taskResult",operationId:z,status:"failed",error:D,...X.message}}}function S(z,B){let D=B.error;if(typeof D!=="string")return Q("invalid_message","cancelled taskResult.error must be a string");let X=B.cancelled;if(X!==void 0&&X!==!0)return Q("invalid_message","taskResult.cancelled must be true when present");let Y=C(B);if(!Y.ok)return Y;return{ok:!0,message:{type:"taskResult",operationId:z,status:"cancelled",error:D,...X===!0?{cancelled:X}:{},...Y.message}}}var k={completed:O,failed:V,cancelled:S};function E(z){return z==="completed"||z==="failed"||z==="cancelled"}function W(z){let B=z.operationId;if(!Z(B))return Q("invalid_message","taskResult.operationId must be a non-empty string");let D=z.status;if(!E(D))return Q("invalid_message","taskResult.status must be completed, failed, or cancelled");return k[D](B,z)}var m=new Set(["register","heartbeat","taskResult"]),R=new Set(["registerAck","registerError","protocolError","task","cancel","shutdown"]);function p(z){if(z===x)return{ok:!0,message:z};let B=H(z)?z:void 0;return Q("unsupported_protocol_version",`Unsupported RemoteWorker protocol version: ${String(z)}`,B)}var n=[["workerId",!0,Z,"register.workerId must be a non-empty string"],["activities",!0,J,"register.activities must be an array of non-empty strings"],["concurrency",!1,H,"register.concurrency must be a finite number"],["queue",!1,Z,"register.queue must be a non-empty string"],["deploymentName",!1,Z,"register.deploymentName must be a non-empty string when present"],["buildId",!1,Z,"register.buildId must be a non-empty string when present"],["runtimeVersion",!1,Z,"register.runtimeVersion must be a non-empty string when present"],["gitSha",!1,Z,"register.gitSha must be a non-empty string when present"],["startedAt",!1,H,"register.startedAt must be a finite number when present"],["capabilities",!1,q,"register.capabilities must be a JSON object when present"]];function i(z){let B=p(z.protocolVersion);if(!B.ok)return B;let D=f("invalid_registration",z,n);if(!D.ok)return D.error;return{ok:!0,message:{type:"register",protocolVersion:B.message,...D.values}}}function v(z){let B=z.workerId;if(!Z(B))return Q("invalid_message","heartbeat.workerId must be a non-empty string");return{ok:!0,message:{type:"heartbeat",workerId:B}}}var d=[["operationId",!0,Z,"task.operationId must be a non-empty string"],["activityName",!0,Z,"task.activityName must be a non-empty string"],["input",!0,$,"task.input must be valid JSON"],["attempt",!1,H,"task.attempt must be a finite number"],["headers",!1,w,"task.headers must be a string map"],["attemptToken",!1,Z,"task.attemptToken must be a non-empty string"]];function u(z){let B=f("invalid_message",z,d);if(!B.ok)return B.error;return{ok:!0,message:{type:"task",...B.values}}}function s(z){let B=z.operationId;if(!Z(B))return Q("invalid_message","cancel.operationId must be a non-empty string");return{ok:!0,message:{type:"cancel",operationId:B}}}function c(){return{ok:!0,message:{type:"shutdown"}}}function t(z){let B=z.protocolVersion;if(B!==x)return Q("invalid_message",`registerAck.protocolVersion must be ${String(x)}`);let{workerId:D,queue:X,activities:Y,concurrency:U}=z;if(!Z(D))return Q("invalid_message","registerAck.workerId must be a non-empty string");if(!Z(X))return Q("invalid_message","registerAck.queue must be a non-empty string");if(!J(Y))return Q("invalid_message","registerAck.activities must be a string array");if(typeof U!=="number"||!Number.isFinite(U))return Q("invalid_message","registerAck.concurrency must be a finite number");return{ok:!0,message:{type:"registerAck",protocolVersion:B,workerId:D,queue:X,activities:Y,concurrency:U}}}function l(z){let{code:B,message:D,supportedProtocolVersions:X,requestedProtocolVersion:Y}=z;if(B!=="invalid_registration"&&B!=="unsupported_protocol_version")return Q("invalid_message","registerError.code is not recognized");if(typeof D!=="string")return Q("invalid_message","registerError.message must be a string");if(!Array.isArray(X)||!X.every((L)=>L===x))return Q("invalid_message","registerError.supportedProtocolVersions is invalid");if(Y!==void 0&&!H(Y))return Q("invalid_message","registerError.requestedProtocolVersion must be a finite number");return{ok:!0,message:{type:"registerError",code:B,message:D,supportedProtocolVersions:X,...Y!==void 0?{requestedProtocolVersion:Y}:{}}}}function a(z){let{code:B,message:D}=z;if(B!=="invalid_json"&&B!=="invalid_message"&&B!=="unknown_message_type"&&B!=="registration_required")return Q("invalid_message","protocolError.code is not recognized");if(typeof D!=="string")return Q("invalid_message","protocolError.message must be a string");return{ok:!0,message:{type:"protocolError",code:B,message:D}}}function Hz(z){if(!b(z))return Q("invalid_message","Worker protocol message must be a JSON object");let B=z.type;if(typeof B!=="string")return Q("invalid_message","Worker protocol message.type must be a string");if(!m.has(B))return Q("unknown_message_type",`Unknown worker message type: ${B}`);switch(B){case"register":return i(z);case"heartbeat":return v(z);case"taskResult":return W(z);default:return Q("unknown_message_type",`Unknown worker message type: ${B}`)}}function Lz(z){if(!b(z))return Q("invalid_message","Server protocol message must be a JSON object");let B=z.type;if(typeof B!=="string")return Q("invalid_message","Server protocol message.type must be a string");if(!R.has(B))return Q("unknown_message_type",`Unknown server message type: ${B}`);switch(B){case"registerAck":return t(z);case"registerError":return l(z);case"protocolError":return a(z);case"task":return u(z);case"cancel":return s(z);case"shutdown":return c();default:return Q("unknown_message_type",`Unknown server message type: ${B}`)}}export{Hz as parseWorkerToServerMessage,Lz as parseServerToWorkerMessage,$ as isRemoteWorkerJsonValue,_ as REMOTE_WORKER_SUPPORTED_PROTOCOL_VERSIONS,x as REMOTE_WORKER_PROTOCOL_VERSION,T as REMOTE_WORKER_PROTOCOL_JSON_SCHEMA,P as REMOTE_WORKER_MIN_PROTOCOL_VERSION,N as REMOTE_WORKER_MESSAGE_SCHEMAS,g as REMOTE_WORKER_MAX_PROTOCOL_VERSION};
|
|
2
|
+
var h=Object.defineProperty;var M=(z)=>z;function I(z,B){this[z]=M.bind(null,B)}var r=(z,B)=>{for(var D in B)h(z,D,{get:B[D],enumerable:!0,configurable:!0,set:I.bind(B,D)})};var o=(z,B)=>()=>(z&&(B=z(z=0)),B);var e=import.meta.require,zz=(z,B,D)=>{if(B!=null){if(typeof B!=="object"&&typeof B!=="function")throw TypeError('Object expected to be assigned to "using" declaration');let X;if(D)X=B[Symbol.asyncDispose];if(X===void 0)X=B[Symbol.dispose];if(typeof X!=="function")throw TypeError("Object not disposable");z.push([D,X,B])}else if(D)z.push([D]);return B},Bz=(z,B,D)=>{let X=(U)=>B=D?new SuppressedError(U,B,"An error was suppressed during disposal"):(D=!0,U),Z=(U)=>{while(U=z.pop())try{var L=U[1]&&U[1].call(U[2]);if(U[0])return Promise.resolve(L).then(Z,(G)=>(X(G),Z()))}catch(G){X(G)}if(D)throw B};return Z()};function b(z){return z!==null&&typeof z==="object"&&!Array.isArray(z)}function $(z){if(z===null||typeof z==="string"||typeof z==="boolean"||typeof z==="number"&&Number.isFinite(z))return!0;if(Array.isArray(z))return z.every($);if(!b(z))return!1;return Object.values(z).every($)}function Y(z){return typeof z==="string"&&z.length>0}function J(z){return Array.isArray(z)&&z.every(Y)}function w(z){if(!b(z))return!1;return Object.values(z).every((B)=>typeof B==="string")}function q(z){if(!b(z))return!1;return Object.values(z).every($)}function H(z){return typeof z==="number"&&Number.isFinite(z)}function Q(z,B,D){return{ok:!1,error:{code:z,message:B,...D!==void 0?{requestedProtocolVersion:D}:{}}}}function f(z,B,D){let X={};for(let[Z,U,L,G]of D){let j=B[Z];if(j===void 0){if(U)return{ok:!1,error:Q(z,G)};continue}if(!L(j))return{ok:!1,error:Q(z,G)};X[Z]=j}return{ok:!0,values:X}}var x=2,P=2,g=2,_=[2];var K={$ref:"#/$defs/jsonValue"},A={type:"object",additionalProperties:K},y={type:"object",additionalProperties:{type:"string"}},F={const:x},N={register:{type:"object",additionalProperties:!1,required:["type","protocolVersion","workerId","activities"],properties:{type:{const:"register"},protocolVersion:F,workerId:{type:"string",minLength:1},activities:{type:"array",items:{type:"string",minLength:1}},concurrency:{type:"number",minimum:1,maximum:1000},queue:{type:"string",minLength:1},deploymentName:{type:"string",minLength:1},buildId:{type:"string",minLength:1},runtimeVersion:{type:"string",minLength:1},gitSha:{type:"string",minLength:1},startedAt:{type:"number"},capabilities:A}},heartbeat:{type:"object",additionalProperties:!1,required:["type","workerId"],properties:{type:{const:"heartbeat"},workerId:{type:"string",minLength:1}}},taskResult:{oneOf:[{type:"object",additionalProperties:!1,required:["type","operationId","status","value"],properties:{type:{const:"taskResult"},operationId:{type:"string",minLength:1},status:{const:"completed"},value:K,attemptToken:{type:"string",minLength:1}}},{type:"object",additionalProperties:!1,required:["type","operationId","status","error"],properties:{type:{const:"taskResult"},operationId:{type:"string",minLength:1},status:{const:"failed"},error:{type:"string"},attemptToken:{type:"string",minLength:1}}},{type:"object",additionalProperties:!1,required:["type","operationId","status","error"],properties:{type:{const:"taskResult"},operationId:{type:"string",minLength:1},status:{const:"cancelled"},error:{type:"string"},cancelled:{const:!0},attemptToken:{type:"string",minLength:1}}}]},task:{type:"object",additionalProperties:!1,required:["type","operationId","activityName","input"],properties:{type:{const:"task"},operationId:{type:"string",minLength:1},activityName:{type:"string",minLength:1},input:K,attempt:{type:"number",minimum:1},headers:y,workflowExecutionToken:{type:"string",minLength:1},attemptToken:{type:"string",minLength:1}}},cancel:{type:"object",additionalProperties:!1,required:["type","operationId"],properties:{type:{const:"cancel"},operationId:{type:"string",minLength:1}}},shutdown:{type:"object",additionalProperties:!1,required:["type"],properties:{type:{const:"shutdown"}}},registerAck:{type:"object",additionalProperties:!1,required:["type","protocolVersion","workerId","queue","activities","concurrency"],properties:{type:{const:"registerAck"},protocolVersion:F,workerId:{type:"string",minLength:1},queue:{type:"string",minLength:1},activities:{type:"array",items:{type:"string",minLength:1}},concurrency:{type:"number",minimum:1,maximum:1000}}},registerError:{type:"object",additionalProperties:!1,required:["type","code","message","supportedProtocolVersions"],properties:{type:{const:"registerError"},code:{enum:["invalid_registration","unsupported_protocol_version"]},message:{type:"string"},supportedProtocolVersions:{type:"array",items:F},requestedProtocolVersion:{type:"number"}}},protocolError:{type:"object",additionalProperties:!1,required:["type","code","message"],properties:{type:{const:"protocolError"},code:{enum:["invalid_json","invalid_message","unknown_message_type","registration_required"]},message:{type:"string"}}}},T={$schema:"https://json-schema.org/draft/2020-12/schema",$id:"https://weft.dev/schemas/remote-worker-protocol.v1.json",title:"Weft RemoteWorker Protocol v1",oneOf:Object.keys(N).map((z)=>({$ref:`#/$defs/messages/${z}`})),$defs:{jsonValue:{oneOf:[{type:"null"},{type:"boolean"},{type:"number"},{type:"string"},{type:"array",items:{$ref:"#/$defs/jsonValue"}},{type:"object",additionalProperties:{$ref:"#/$defs/jsonValue"}}]},jsonObject:A,messages:N}};function C(z){let B=z.attemptToken;if(B===void 0)return{ok:!0,message:{}};if(!Y(B))return Q("invalid_message","taskResult.attemptToken must be a non-empty string when present");return{ok:!0,message:{attemptToken:B}}}function O(z,B){let D=B.value;if(!$(D))return Q("invalid_message","completed taskResult.value must be valid JSON");let X=C(B);if(!X.ok)return X;return{ok:!0,message:{type:"taskResult",operationId:z,status:"completed",value:D,...X.message}}}function V(z,B){let D=B.error;if(typeof D!=="string")return Q("invalid_message","failed taskResult.error must be a string");let X=C(B);if(!X.ok)return X;return{ok:!0,message:{type:"taskResult",operationId:z,status:"failed",error:D,...X.message}}}function S(z,B){let D=B.error;if(typeof D!=="string")return Q("invalid_message","cancelled taskResult.error must be a string");let X=B.cancelled;if(X!==void 0&&X!==!0)return Q("invalid_message","taskResult.cancelled must be true when present");let Z=C(B);if(!Z.ok)return Z;return{ok:!0,message:{type:"taskResult",operationId:z,status:"cancelled",error:D,...X===!0?{cancelled:X}:{},...Z.message}}}var k={completed:O,failed:V,cancelled:S};function E(z){return z==="completed"||z==="failed"||z==="cancelled"}function W(z){let B=z.operationId;if(!Y(B))return Q("invalid_message","taskResult.operationId must be a non-empty string");let D=z.status;if(!E(D))return Q("invalid_message","taskResult.status must be completed, failed, or cancelled");return k[D](B,z)}var m=new Set(["register","heartbeat","taskResult"]),R=new Set(["registerAck","registerError","protocolError","task","cancel","shutdown"]);function p(z){if(z===x)return{ok:!0,message:z};let B=H(z)?z:void 0;return Q("unsupported_protocol_version",`Unsupported RemoteWorker protocol version: ${String(z)}`,B)}var n=[["workerId",!0,Y,"register.workerId must be a non-empty string"],["activities",!0,J,"register.activities must be an array of non-empty strings"],["concurrency",!1,H,"register.concurrency must be a finite number"],["queue",!1,Y,"register.queue must be a non-empty string"],["deploymentName",!1,Y,"register.deploymentName must be a non-empty string when present"],["buildId",!1,Y,"register.buildId must be a non-empty string when present"],["runtimeVersion",!1,Y,"register.runtimeVersion must be a non-empty string when present"],["gitSha",!1,Y,"register.gitSha must be a non-empty string when present"],["startedAt",!1,H,"register.startedAt must be a finite number when present"],["capabilities",!1,q,"register.capabilities must be a JSON object when present"]];function i(z){let B=p(z.protocolVersion);if(!B.ok)return B;let D=f("invalid_registration",z,n);if(!D.ok)return D.error;return{ok:!0,message:{type:"register",protocolVersion:B.message,...D.values}}}function v(z){let B=z.workerId;if(!Y(B))return Q("invalid_message","heartbeat.workerId must be a non-empty string");return{ok:!0,message:{type:"heartbeat",workerId:B}}}var d=[["operationId",!0,Y,"task.operationId must be a non-empty string"],["activityName",!0,Y,"task.activityName must be a non-empty string"],["input",!0,$,"task.input must be valid JSON"],["attempt",!1,H,"task.attempt must be a finite number"],["headers",!1,w,"task.headers must be a string map"],["workflowExecutionToken",!1,Y,"task.workflowExecutionToken must be a non-empty string"],["attemptToken",!1,Y,"task.attemptToken must be a non-empty string"]];function u(z){let B=f("invalid_message",z,d);if(!B.ok)return B.error;return{ok:!0,message:{type:"task",...B.values}}}function s(z){let B=z.operationId;if(!Y(B))return Q("invalid_message","cancel.operationId must be a non-empty string");return{ok:!0,message:{type:"cancel",operationId:B}}}function c(){return{ok:!0,message:{type:"shutdown"}}}function t(z){let B=z.protocolVersion;if(B!==x)return Q("invalid_message",`registerAck.protocolVersion must be ${String(x)}`);let{workerId:D,queue:X,activities:Z,concurrency:U}=z;if(!Y(D))return Q("invalid_message","registerAck.workerId must be a non-empty string");if(!Y(X))return Q("invalid_message","registerAck.queue must be a non-empty string");if(!J(Z))return Q("invalid_message","registerAck.activities must be a string array");if(typeof U!=="number"||!Number.isFinite(U))return Q("invalid_message","registerAck.concurrency must be a finite number");return{ok:!0,message:{type:"registerAck",protocolVersion:B,workerId:D,queue:X,activities:Z,concurrency:U}}}function l(z){let{code:B,message:D,supportedProtocolVersions:X,requestedProtocolVersion:Z}=z;if(B!=="invalid_registration"&&B!=="unsupported_protocol_version")return Q("invalid_message","registerError.code is not recognized");if(typeof D!=="string")return Q("invalid_message","registerError.message must be a string");if(!Array.isArray(X)||!X.every((L)=>L===x))return Q("invalid_message","registerError.supportedProtocolVersions is invalid");if(Z!==void 0&&!H(Z))return Q("invalid_message","registerError.requestedProtocolVersion must be a finite number");return{ok:!0,message:{type:"registerError",code:B,message:D,supportedProtocolVersions:X,...Z!==void 0?{requestedProtocolVersion:Z}:{}}}}function a(z){let{code:B,message:D}=z;if(B!=="invalid_json"&&B!=="invalid_message"&&B!=="unknown_message_type"&&B!=="registration_required")return Q("invalid_message","protocolError.code is not recognized");if(typeof D!=="string")return Q("invalid_message","protocolError.message must be a string");return{ok:!0,message:{type:"protocolError",code:B,message:D}}}function Lz(z){if(!b(z))return Q("invalid_message","Worker protocol message must be a JSON object");let B=z.type;if(typeof B!=="string")return Q("invalid_message","Worker protocol message.type must be a string");if(!m.has(B))return Q("unknown_message_type",`Unknown worker message type: ${B}`);switch(B){case"register":return i(z);case"heartbeat":return v(z);case"taskResult":return W(z);default:return Q("unknown_message_type",`Unknown worker message type: ${B}`)}}function jz(z){if(!b(z))return Q("invalid_message","Server protocol message must be a JSON object");let B=z.type;if(typeof B!=="string")return Q("invalid_message","Server protocol message.type must be a string");if(!R.has(B))return Q("unknown_message_type",`Unknown server message type: ${B}`);switch(B){case"registerAck":return t(z);case"registerError":return l(z);case"protocolError":return a(z);case"task":return u(z);case"cancel":return s(z);case"shutdown":return c();default:return Q("unknown_message_type",`Unknown server message type: ${B}`)}}export{Lz as parseWorkerToServerMessage,jz as parseServerToWorkerMessage,$ as isRemoteWorkerJsonValue,_ as REMOTE_WORKER_SUPPORTED_PROTOCOL_VERSIONS,x as REMOTE_WORKER_PROTOCOL_VERSION,T as REMOTE_WORKER_PROTOCOL_JSON_SCHEMA,P as REMOTE_WORKER_MIN_PROTOCOL_VERSION,N as REMOTE_WORKER_MESSAGE_SCHEMAS,g as REMOTE_WORKER_MAX_PROTOCOL_VERSION};
|
|
@@ -27,6 +27,8 @@ export interface ActivityExecutionRequest {
|
|
|
27
27
|
activityName: string;
|
|
28
28
|
input: unknown;
|
|
29
29
|
attempt: number;
|
|
30
|
+
workflowExecutionToken?: string;
|
|
31
|
+
activityAttemptToken?: string;
|
|
30
32
|
}
|
|
31
33
|
/**
|
|
32
34
|
* Result payload returned by {@link executeActivity} and posted back by the
|
|
@@ -7,7 +7,15 @@ export async function executeActivity(request, activityFunction, signal) {
|
|
|
7
7
|
errorName: "AbortError"
|
|
8
8
|
};
|
|
9
9
|
try {
|
|
10
|
-
const result = await activityFunction(request.input
|
|
10
|
+
const activitySignal = signal ?? new AbortController().signal, result = await activityFunction(request.input, {
|
|
11
|
+
signal: activitySignal,
|
|
12
|
+
...request.workflowExecutionToken !== void 0 && {
|
|
13
|
+
workflowExecutionToken: request.workflowExecutionToken
|
|
14
|
+
},
|
|
15
|
+
...request.activityAttemptToken !== void 0 && {
|
|
16
|
+
activityAttemptToken: request.activityAttemptToken
|
|
17
|
+
}
|
|
18
|
+
});
|
|
11
19
|
return {
|
|
12
20
|
operationId: request.operationId,
|
|
13
21
|
status: "completed",
|
|
@@ -8,13 +8,14 @@ import { type WorkerReplayState } from './worker-replay-state.ts';
|
|
|
8
8
|
* in particular) are stub values because the worker has no clock authority —
|
|
9
9
|
* any user code reading them will see static numbers, not live deadlines.
|
|
10
10
|
*/
|
|
11
|
-
export type WorkerWorkflowContext = Pick<WorkflowContext, 'workflowId' | 'workflowType' | 'signal' | 'startedAt'> & {
|
|
11
|
+
export type WorkerWorkflowContext = Pick<WorkflowContext, 'workflowId' | 'workflowExecutionToken' | 'workflowType' | 'signal' | 'startedAt'> & {
|
|
12
12
|
readonly state: WorkflowStateNamespace;
|
|
13
13
|
readonly log: WorkflowLogger;
|
|
14
14
|
getVersion(changeId: string, minSupported: number, maxSupported: number): Generator<ContextOperationRequest, number, unknown>;
|
|
15
15
|
};
|
|
16
16
|
interface RunMessageShape {
|
|
17
17
|
workflowId: string;
|
|
18
|
+
workflowExecutionToken?: string;
|
|
18
19
|
workflowType: string;
|
|
19
20
|
input: unknown;
|
|
20
21
|
executionStateOwnerId?: string;
|
|
@@ -27,6 +27,7 @@ export function createWorkerWorkflowContext(message, controller, getReplayState,
|
|
|
27
27
|
}) {
|
|
28
28
|
return {
|
|
29
29
|
workflowId: message.workflowId,
|
|
30
|
+
workflowExecutionToken: message.workflowExecutionToken,
|
|
30
31
|
workflowType: message.workflowType,
|
|
31
32
|
signal: controller.signal,
|
|
32
33
|
startedAt: Date.now(),
|