@lostgradient/weft 0.14.0 → 0.16.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 +3 -8
- package/dist/alerting/alert-manager.d.ts +2 -0
- package/dist/alerting/alert-manager.js +3 -0
- package/dist/cli/api.js +5 -19
- package/dist/cli/console.d.ts +12 -0
- package/dist/cli/console.js +62 -0
- package/dist/cli/generated/operation-catalog.snapshot.json +1061 -90
- package/dist/cli/generated/operation-client.generated.d.ts +29 -23
- package/dist/cli/generated/operation-client.generated.js +2 -0
- package/dist/cli/help-text.d.ts +1 -1
- package/dist/cli/help-text.js +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +1 -0
- package/dist/cli/json-input.d.ts +20 -0
- package/dist/cli/json-input.js +33 -0
- package/dist/cli/parse-arguments.js +2 -0
- package/dist/cli/schedule.js +7 -9
- package/dist/cli/types.d.ts +1 -0
- package/dist/cli/workflow-commands.js +5 -25
- package/dist/cli-main.js +4 -2
- package/dist/core/aggregate-validation.d.ts +2 -5
- package/dist/core/aggregate-validation.js +2 -10
- package/dist/core/atomic-state.js +21 -24
- package/dist/core/engine/index.d.ts +3 -0
- package/dist/core/engine/index.js +3 -0
- package/dist/core/engine/schedules.js +4 -1
- package/dist/core/inline-execution-strategy.js +8 -46
- package/dist/core/list-filter-validation.d.ts +2 -5
- package/dist/core/list-filter-validation.js +2 -10
- package/dist/core/types/schedules.d.ts +13 -31
- package/dist/core/validation-issues.d.ts +13 -0
- package/dist/core/validation-issues.js +9 -0
- package/dist/diagnostics/recommendations.js +1 -9
- package/dist/http.js +2 -2
- package/dist/indexeddb.js +1 -1
- package/dist/mcp/session.js +2 -10
- package/dist/mcp/tools.js +2 -10
- package/dist/mcp/tuple-list-equality.d.ts +1 -0
- package/dist/mcp/tuple-list-equality.js +12 -0
- package/dist/server/authorization-scope.d.ts +1 -1
- package/dist/server/authorization-scope.js +0 -2
- package/dist/server/dashboard-assets.d.ts +26 -0
- package/dist/server/dashboard-assets.js +95 -0
- package/dist/server/index.d.ts +10 -1
- package/dist/server/index.js +11 -2
- package/dist/server/interactive-operations.js +1 -0
- package/dist/server/operation-catalog/types.d.ts +1 -1
- package/dist/server/operation-registry.d.ts +2 -31
- package/dist/server/operations/bulk-filter-helpers.d.ts +17 -17
- package/dist/server/operations/bulk-filter-helpers.js +16 -37
- package/dist/server/operations/bulk-mutate-workflow-tags.d.ts +27 -27
- package/dist/server/operations/bulk-signal-workflows.d.ts +26 -26
- package/dist/server/operations/create-schedule.js +26 -65
- package/dist/server/operations/event-stream-contracts.d.ts +20 -0
- package/dist/server/operations/event-stream-contracts.js +67 -0
- package/dist/server/operations/fleet-events-sse.js +21 -50
- package/dist/server/operations/fleet-events-subscription.js +8 -12
- package/dist/server/operations/list-alerts.d.ts +26 -0
- package/dist/server/operations/list-alerts.js +54 -0
- package/dist/server/operations/list-workflows.d.ts +43 -43
- package/dist/server/operations/list-workflows.js +9 -30
- package/dist/server/operations/purge-workflows.d.ts +11 -11
- package/dist/server/operations/schedule-faults.d.ts +9 -1
- package/dist/server/operations/schedule-faults.js +51 -0
- package/dist/server/operations/schedule-rest-body.d.ts +11 -0
- package/dist/server/operations/schedule-rest-body.js +28 -0
- package/dist/server/operations/update-schedule.js +13 -72
- package/dist/server/operations/workflow-events-sse.js +29 -67
- package/dist/server/operations/workflow-events-subscription.js +9 -27
- package/dist/server/rest-bindings.js +3 -0
- package/dist/server/runtime/task-polling.js +3 -5
- package/dist/server/task-state.d.ts +2 -8
- package/dist/server/task-state.js +10 -7
- package/dist/service-worker/index.d.ts +4 -1
- package/dist/service-worker/index.js +2 -2
- package/dist/service-worker/setup.d.ts +20 -0
- package/dist/service-worker/setup.js +5 -5
- package/dist/storage/bun-sql.js +65 -80
- package/dist/storage/conditional-batch-body.d.ts +7 -0
- package/dist/storage/conditional-batch-body.js +14 -0
- package/dist/storage/lmdb.js +1 -1
- package/dist/storage/memory.js +1 -1
- package/dist/storage/neon.js +2 -2
- package/dist/storage/node-sqlite-loader.d.ts +2 -2
- package/dist/storage/node-sqlite.js +32 -17
- package/dist/storage/postgres.js +2 -2
- 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 +2 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/web-extension.js +1 -1
- package/dist/worker/execute-with-interceptors.d.ts +1 -1
- package/dist/worker/execute-with-interceptors.js +2 -2
- package/dist/worker/index.js +5 -5
- package/dist/worker/long-poll.js +3 -4
- package/dist/worker/protocol-messages.d.ts +11 -19
- package/dist/worker/protocol-schemas.d.ts +8 -8
- package/dist/worker/protocol-schemas.js +4 -4
- package/dist/worker/protocol-task-result.d.ts +1 -0
- package/dist/worker/protocol-task-result.js +1 -3
- package/dist/worker/protocol.js +1 -1
- package/dist/worker/registry/types.d.ts +2 -7
- package/dist/worker/registry.d.ts +3 -9
- package/dist/worker/registry.js +2 -5
- package/package.json +5 -1
package/dist/worker/long-poll.js
CHANGED
|
@@ -85,7 +85,6 @@ export class LongPollWorker {
|
|
|
85
85
|
}
|
|
86
86
|
async#executeTask(task, resultUrl) {
|
|
87
87
|
this.#inFlight += 1;
|
|
88
|
-
const tokenEcho = task.attemptToken !== void 0 ? { attemptToken: task.attemptToken } : {};
|
|
89
88
|
try {
|
|
90
89
|
const activityFunction = this.#options.activities[task.activityName];
|
|
91
90
|
if (activityFunction === void 0) {
|
|
@@ -95,7 +94,7 @@ export class LongPollWorker {
|
|
|
95
94
|
body: JSON.stringify({
|
|
96
95
|
operationId: task.operationId,
|
|
97
96
|
workerId: task.workerId,
|
|
98
|
-
|
|
97
|
+
attemptToken: task.attemptToken,
|
|
99
98
|
status: "failed",
|
|
100
99
|
error: `Unknown activity: ${task.activityName}`
|
|
101
100
|
}),
|
|
@@ -110,7 +109,7 @@ export class LongPollWorker {
|
|
|
110
109
|
body: JSON.stringify({
|
|
111
110
|
operationId: task.operationId,
|
|
112
111
|
workerId: task.workerId,
|
|
113
|
-
|
|
112
|
+
attemptToken: task.attemptToken,
|
|
114
113
|
status: "completed",
|
|
115
114
|
value: result
|
|
116
115
|
}),
|
|
@@ -124,7 +123,7 @@ export class LongPollWorker {
|
|
|
124
123
|
body: JSON.stringify({
|
|
125
124
|
operationId: task.operationId,
|
|
126
125
|
workerId: task.workerId,
|
|
127
|
-
|
|
126
|
+
attemptToken: task.attemptToken,
|
|
128
127
|
status: "failed",
|
|
129
128
|
error: error instanceof Error ? error.message : String(error)
|
|
130
129
|
}),
|
|
@@ -92,6 +92,7 @@ export type HeartbeatMessage = {
|
|
|
92
92
|
* operationId: 'op-1',
|
|
93
93
|
* status: 'completed',
|
|
94
94
|
* value: null,
|
|
95
|
+
* attemptToken: 'attempt-token',
|
|
95
96
|
* };
|
|
96
97
|
* ```
|
|
97
98
|
*/
|
|
@@ -100,12 +101,8 @@ export type CompletedTaskResultMessage = {
|
|
|
100
101
|
readonly operationId: string;
|
|
101
102
|
readonly status: 'completed';
|
|
102
103
|
readonly value: RemoteWorkerJsonValue;
|
|
103
|
-
/**
|
|
104
|
-
|
|
105
|
-
* wire so older workers still parse, but the server's completion handler
|
|
106
|
-
* rejects a result whose token does not match the current attempt.
|
|
107
|
-
*/
|
|
108
|
-
readonly attemptToken?: string;
|
|
104
|
+
/** Required per-dispatch token echoed from the {@link TaskMessage}. */
|
|
105
|
+
readonly attemptToken: string;
|
|
109
106
|
};
|
|
110
107
|
/**
|
|
111
108
|
* Failed activity result message.
|
|
@@ -119,6 +116,7 @@ export type CompletedTaskResultMessage = {
|
|
|
119
116
|
* operationId: 'op-1',
|
|
120
117
|
* status: 'failed',
|
|
121
118
|
* error: 'SMTP rejected the message',
|
|
119
|
+
* attemptToken: 'attempt-token',
|
|
122
120
|
* };
|
|
123
121
|
* ```
|
|
124
122
|
*/
|
|
@@ -127,8 +125,8 @@ export type FailedTaskResultMessage = {
|
|
|
127
125
|
readonly operationId: string;
|
|
128
126
|
readonly status: 'failed';
|
|
129
127
|
readonly error: string;
|
|
130
|
-
/**
|
|
131
|
-
readonly attemptToken
|
|
128
|
+
/** Required per-dispatch token echoed from the {@link TaskMessage}. */
|
|
129
|
+
readonly attemptToken: string;
|
|
132
130
|
};
|
|
133
131
|
/**
|
|
134
132
|
* Cancelled activity result message.
|
|
@@ -143,6 +141,7 @@ export type FailedTaskResultMessage = {
|
|
|
143
141
|
* status: 'cancelled',
|
|
144
142
|
* error: 'Task cancelled',
|
|
145
143
|
* cancelled: true,
|
|
144
|
+
* attemptToken: 'attempt-token',
|
|
146
145
|
* };
|
|
147
146
|
* ```
|
|
148
147
|
*/
|
|
@@ -152,8 +151,8 @@ export type CancelledTaskResultMessage = {
|
|
|
152
151
|
readonly status: 'cancelled';
|
|
153
152
|
readonly error: string;
|
|
154
153
|
readonly cancelled?: true;
|
|
155
|
-
/**
|
|
156
|
-
readonly attemptToken
|
|
154
|
+
/** Required per-dispatch token echoed from the {@link TaskMessage}. */
|
|
155
|
+
readonly attemptToken: string;
|
|
157
156
|
};
|
|
158
157
|
/**
|
|
159
158
|
* Registration acknowledgement sent after a worker is accepted.
|
|
@@ -247,15 +246,8 @@ export type TaskMessage = {
|
|
|
247
246
|
readonly headers?: Readonly<Record<string, string>>;
|
|
248
247
|
/** Durable token for the workflow run that launched this activity, when known. */
|
|
249
248
|
readonly workflowExecutionToken?: string;
|
|
250
|
-
/**
|
|
251
|
-
|
|
252
|
-
* current server always stamps one, and the worker must echo it back on the
|
|
253
|
-
* {@link CompletedTaskResultMessage} (or failed/cancelled variant) so the server
|
|
254
|
-
* can reject a stale completion from an earlier attempt that was reassigned to
|
|
255
|
-
* the same worker. Optional on the type because a frame from an older server may
|
|
256
|
-
* omit it; the worker simply has no token to echo in that case.
|
|
257
|
-
*/
|
|
258
|
-
readonly attemptToken?: string;
|
|
249
|
+
/** Unique, unguessable token identifying this dispatch attempt. */
|
|
250
|
+
readonly attemptToken: string;
|
|
259
251
|
};
|
|
260
252
|
/**
|
|
261
253
|
* Activity cancellation request sent by the server.
|
|
@@ -92,7 +92,7 @@ export declare const REMOTE_WORKER_MESSAGE_SCHEMAS: {
|
|
|
92
92
|
readonly oneOf: readonly [{
|
|
93
93
|
readonly type: "object";
|
|
94
94
|
readonly additionalProperties: false;
|
|
95
|
-
readonly required: readonly ["type", "operationId", "status", "value"];
|
|
95
|
+
readonly required: readonly ["type", "operationId", "status", "value", "attemptToken"];
|
|
96
96
|
readonly properties: {
|
|
97
97
|
readonly type: {
|
|
98
98
|
readonly const: "taskResult";
|
|
@@ -113,7 +113,7 @@ export declare const REMOTE_WORKER_MESSAGE_SCHEMAS: {
|
|
|
113
113
|
}, {
|
|
114
114
|
readonly type: "object";
|
|
115
115
|
readonly additionalProperties: false;
|
|
116
|
-
readonly required: readonly ["type", "operationId", "status", "error"];
|
|
116
|
+
readonly required: readonly ["type", "operationId", "status", "error", "attemptToken"];
|
|
117
117
|
readonly properties: {
|
|
118
118
|
readonly type: {
|
|
119
119
|
readonly const: "taskResult";
|
|
@@ -136,7 +136,7 @@ export declare const REMOTE_WORKER_MESSAGE_SCHEMAS: {
|
|
|
136
136
|
}, {
|
|
137
137
|
readonly type: "object";
|
|
138
138
|
readonly additionalProperties: false;
|
|
139
|
-
readonly required: readonly ["type", "operationId", "status", "error"];
|
|
139
|
+
readonly required: readonly ["type", "operationId", "status", "error", "attemptToken"];
|
|
140
140
|
readonly properties: {
|
|
141
141
|
readonly type: {
|
|
142
142
|
readonly const: "taskResult";
|
|
@@ -164,7 +164,7 @@ export declare const REMOTE_WORKER_MESSAGE_SCHEMAS: {
|
|
|
164
164
|
readonly task: {
|
|
165
165
|
readonly type: "object";
|
|
166
166
|
readonly additionalProperties: false;
|
|
167
|
-
readonly required: readonly ["type", "operationId", "activityName", "input"];
|
|
167
|
+
readonly required: readonly ["type", "operationId", "activityName", "input", "attemptToken"];
|
|
168
168
|
readonly properties: {
|
|
169
169
|
readonly type: {
|
|
170
170
|
readonly const: "task";
|
|
@@ -398,7 +398,7 @@ export declare const REMOTE_WORKER_PROTOCOL_JSON_SCHEMA: {
|
|
|
398
398
|
readonly oneOf: readonly [{
|
|
399
399
|
readonly type: "object";
|
|
400
400
|
readonly additionalProperties: false;
|
|
401
|
-
readonly required: readonly ["type", "operationId", "status", "value"];
|
|
401
|
+
readonly required: readonly ["type", "operationId", "status", "value", "attemptToken"];
|
|
402
402
|
readonly properties: {
|
|
403
403
|
readonly type: {
|
|
404
404
|
readonly const: "taskResult";
|
|
@@ -419,7 +419,7 @@ export declare const REMOTE_WORKER_PROTOCOL_JSON_SCHEMA: {
|
|
|
419
419
|
}, {
|
|
420
420
|
readonly type: "object";
|
|
421
421
|
readonly additionalProperties: false;
|
|
422
|
-
readonly required: readonly ["type", "operationId", "status", "error"];
|
|
422
|
+
readonly required: readonly ["type", "operationId", "status", "error", "attemptToken"];
|
|
423
423
|
readonly properties: {
|
|
424
424
|
readonly type: {
|
|
425
425
|
readonly const: "taskResult";
|
|
@@ -442,7 +442,7 @@ export declare const REMOTE_WORKER_PROTOCOL_JSON_SCHEMA: {
|
|
|
442
442
|
}, {
|
|
443
443
|
readonly type: "object";
|
|
444
444
|
readonly additionalProperties: false;
|
|
445
|
-
readonly required: readonly ["type", "operationId", "status", "error"];
|
|
445
|
+
readonly required: readonly ["type", "operationId", "status", "error", "attemptToken"];
|
|
446
446
|
readonly properties: {
|
|
447
447
|
readonly type: {
|
|
448
448
|
readonly const: "taskResult";
|
|
@@ -470,7 +470,7 @@ export declare const REMOTE_WORKER_PROTOCOL_JSON_SCHEMA: {
|
|
|
470
470
|
readonly task: {
|
|
471
471
|
readonly type: "object";
|
|
472
472
|
readonly additionalProperties: false;
|
|
473
|
-
readonly required: readonly ["type", "operationId", "activityName", "input"];
|
|
473
|
+
readonly required: readonly ["type", "operationId", "activityName", "input", "attemptToken"];
|
|
474
474
|
readonly properties: {
|
|
475
475
|
readonly type: {
|
|
476
476
|
readonly const: "task";
|
|
@@ -47,7 +47,7 @@ export const REMOTE_WORKER_MESSAGE_SCHEMAS = {
|
|
|
47
47
|
{
|
|
48
48
|
type: "object",
|
|
49
49
|
additionalProperties: !1,
|
|
50
|
-
required: ["type", "operationId", "status", "value"],
|
|
50
|
+
required: ["type", "operationId", "status", "value", "attemptToken"],
|
|
51
51
|
properties: {
|
|
52
52
|
type: { const: "taskResult" },
|
|
53
53
|
operationId: { type: "string", minLength: 1 },
|
|
@@ -59,7 +59,7 @@ export const REMOTE_WORKER_MESSAGE_SCHEMAS = {
|
|
|
59
59
|
{
|
|
60
60
|
type: "object",
|
|
61
61
|
additionalProperties: !1,
|
|
62
|
-
required: ["type", "operationId", "status", "error"],
|
|
62
|
+
required: ["type", "operationId", "status", "error", "attemptToken"],
|
|
63
63
|
properties: {
|
|
64
64
|
type: { const: "taskResult" },
|
|
65
65
|
operationId: { type: "string", minLength: 1 },
|
|
@@ -71,7 +71,7 @@ export const REMOTE_WORKER_MESSAGE_SCHEMAS = {
|
|
|
71
71
|
{
|
|
72
72
|
type: "object",
|
|
73
73
|
additionalProperties: !1,
|
|
74
|
-
required: ["type", "operationId", "status", "error"],
|
|
74
|
+
required: ["type", "operationId", "status", "error", "attemptToken"],
|
|
75
75
|
properties: {
|
|
76
76
|
type: { const: "taskResult" },
|
|
77
77
|
operationId: { type: "string", minLength: 1 },
|
|
@@ -86,7 +86,7 @@ export const REMOTE_WORKER_MESSAGE_SCHEMAS = {
|
|
|
86
86
|
task: {
|
|
87
87
|
type: "object",
|
|
88
88
|
additionalProperties: !1,
|
|
89
|
-
required: ["type", "operationId", "activityName", "input"],
|
|
89
|
+
required: ["type", "operationId", "activityName", "input", "attemptToken"],
|
|
90
90
|
properties: {
|
|
91
91
|
type: { const: "task" },
|
|
92
92
|
operationId: { type: "string", minLength: 1 },
|
|
@@ -20,6 +20,7 @@ import type { CancelledTaskResultMessage, CompletedTaskResultMessage, FailedTask
|
|
|
20
20
|
*
|
|
21
21
|
* const message: TaskResultMessage = {
|
|
22
22
|
* type: 'taskResult', operationId: 'op-1', status: 'completed', value: { ok: true },
|
|
23
|
+
* attemptToken: 'attempt-token',
|
|
23
24
|
* };
|
|
24
25
|
* ```
|
|
25
26
|
*/
|
|
@@ -5,10 +5,8 @@ import {
|
|
|
5
5
|
} from "./protocol-internals.js";
|
|
6
6
|
function parseEchoedAttemptToken(record) {
|
|
7
7
|
const attemptToken = record.attemptToken;
|
|
8
|
-
if (attemptToken === void 0)
|
|
9
|
-
return { ok: !0, message: {} };
|
|
10
8
|
if (!isNonEmptyString(attemptToken))
|
|
11
|
-
return protocolFailure("invalid_message", "taskResult.attemptToken must be a non-empty string
|
|
9
|
+
return protocolFailure("invalid_message", "taskResult.attemptToken must be a non-empty string");
|
|
12
10
|
return { ok: !0, message: { attemptToken } };
|
|
13
11
|
}
|
|
14
12
|
function parseCompletedTaskResult(operationId, record) {
|
package/dist/worker/protocol.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var t=import.meta.require,l=(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},a=(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,h=2,M=2,I=[2];var K={$ref:"#/$defs/jsonValue"},A={type:"object",additionalProperties:K},P={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:P,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"}}}},g={$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 _(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 y(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 T(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 O={completed:_,failed:y,cancelled:T};function V(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(!V(D))return Q("invalid_message","taskResult.status must be completed, failed, or cancelled");return O[D](B,z)}var S=new Set(["register","heartbeat","taskResult"]),k=new Set(["registerAck","registerError","protocolError","task","cancel","shutdown"]);function E(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 m=[["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 R(z){let B=E(z.protocolVersion);if(!B.ok)return B;let D=f("invalid_registration",z,m);if(!D.ok)return D.error;return{ok:!0,message:{type:"register",protocolVersion:B.message,...D.values}}}function p(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 n=[["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 i(z){let B=f("invalid_message",z,n);if(!B.ok)return B.error;return{ok:!0,message:{type:"task",...B.values}}}function v(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 d(){return{ok:!0,message:{type:"shutdown"}}}function u(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 s(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 c(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 $z(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(!S.has(B))return Q("unknown_message_type",`Unknown worker message type: ${B}`);switch(B){case"register":return R(z);case"heartbeat":return p(z);case"taskResult":return W(z);default:return Q("unknown_message_type",`Unknown worker message type: ${B}`)}}function xz(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(!k.has(B))return Q("unknown_message_type",`Unknown server message type: ${B}`);switch(B){case"registerAck":return u(z);case"registerError":return s(z);case"protocolError":return c(z);case"task":return i(z);case"cancel":return v(z);case"shutdown":return d();default:return Q("unknown_message_type",`Unknown server message type: ${B}`)}}export{$z as parseWorkerToServerMessage,xz as parseServerToWorkerMessage,$ as isRemoteWorkerJsonValue,I as REMOTE_WORKER_SUPPORTED_PROTOCOL_VERSIONS,x as REMOTE_WORKER_PROTOCOL_VERSION,g as REMOTE_WORKER_PROTOCOL_JSON_SCHEMA,h as REMOTE_WORKER_MIN_PROTOCOL_VERSION,N as REMOTE_WORKER_MESSAGE_SCHEMAS,M as REMOTE_WORKER_MAX_PROTOCOL_VERSION};
|
|
2
|
+
var c=import.meta.require,l=(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},a=(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,h=2,M=2,I=[2];var K={$ref:"#/$defs/jsonValue"},A={type:"object",additionalProperties:K},P={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","attemptToken"],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","attemptToken"],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","attemptToken"],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","attemptToken"],properties:{type:{const:"task"},operationId:{type:"string",minLength:1},activityName:{type:"string",minLength:1},input:K,attempt:{type:"number",minimum:1},headers:P,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"}}}},g={$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(!Y(B))return Q("invalid_message","taskResult.attemptToken must be a non-empty string");return{ok:!0,message:{attemptToken:B}}}function _(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 T(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 y(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 O={completed:_,failed:T,cancelled:y};function V(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(!V(D))return Q("invalid_message","taskResult.status must be completed, failed, or cancelled");return O[D](B,z)}var S=new Set(["register","heartbeat","taskResult"]),k=new Set(["registerAck","registerError","protocolError","task","cancel","shutdown"]);function E(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 m=[["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 R(z){let B=E(z.protocolVersion);if(!B.ok)return B;let D=f("invalid_registration",z,m);if(!D.ok)return D.error;return{ok:!0,message:{type:"register",protocolVersion:B.message,...D.values}}}function p(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 n=[["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",!0,Y,"task.attemptToken must be a non-empty string"]];function i(z){let B=f("invalid_message",z,n);if(!B.ok)return B.error;return{ok:!0,message:{type:"task",...B.values}}}function v(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 d(){return{ok:!0,message:{type:"shutdown"}}}function u(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 s(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 t(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 $z(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(!S.has(B))return Q("unknown_message_type",`Unknown worker message type: ${B}`);switch(B){case"register":return R(z);case"heartbeat":return p(z);case"taskResult":return W(z);default:return Q("unknown_message_type",`Unknown worker message type: ${B}`)}}function xz(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(!k.has(B))return Q("unknown_message_type",`Unknown server message type: ${B}`);switch(B){case"registerAck":return u(z);case"registerError":return s(z);case"protocolError":return t(z);case"task":return i(z);case"cancel":return v(z);case"shutdown":return d();default:return Q("unknown_message_type",`Unknown server message type: ${B}`)}}export{$z as parseWorkerToServerMessage,xz as parseServerToWorkerMessage,$ as isRemoteWorkerJsonValue,I as REMOTE_WORKER_SUPPORTED_PROTOCOL_VERSIONS,x as REMOTE_WORKER_PROTOCOL_VERSION,g as REMOTE_WORKER_PROTOCOL_JSON_SCHEMA,h as REMOTE_WORKER_MIN_PROTOCOL_VERSION,N as REMOTE_WORKER_MESSAGE_SCHEMAS,M as REMOTE_WORKER_MAX_PROTOCOL_VERSION};
|
|
@@ -116,13 +116,8 @@ export interface InFlightTask {
|
|
|
116
116
|
visibilityTimeout: number;
|
|
117
117
|
/** Optional fair-share partition key the task was assigned under. */
|
|
118
118
|
fairShareKey?: string;
|
|
119
|
-
/**
|
|
120
|
-
|
|
121
|
-
* handler compares the worker's echoed token against this in-memory value (after
|
|
122
|
-
* the workerId ownership guard) to reject a stale completion from an earlier
|
|
123
|
-
* attempt reassigned to the same worker.
|
|
124
|
-
*/
|
|
125
|
-
attemptToken?: string;
|
|
119
|
+
/** Unique, unguessable token for this dispatch attempt. */
|
|
120
|
+
attemptToken: string;
|
|
126
121
|
}
|
|
127
122
|
export interface WorkerRegistryOptions {
|
|
128
123
|
/** Routing policy used by {@link WorkerRegistry.findWorker}. Default: `'least-loaded'`. */
|
|
@@ -45,7 +45,7 @@ export declare class WorkerRegistry {
|
|
|
45
45
|
*/
|
|
46
46
|
findWorker(activityName: string, options?: RoutingOptions): WorkerInfo | undefined;
|
|
47
47
|
/** Track a task assignment with a visibility timeout deadline. */
|
|
48
|
-
assignTask(workerId: string, operationId: string, visibilityTimeout: number, fairShareKey
|
|
48
|
+
assignTask(workerId: string, operationId: string, visibilityTimeout: number, fairShareKey: string | undefined, attemptToken: string): void;
|
|
49
49
|
/** Return tasks whose deadline has passed and remove them from tracking. */
|
|
50
50
|
checkExpiredTasks(now: number): InFlightTask[];
|
|
51
51
|
/**
|
|
@@ -63,15 +63,9 @@ export declare class WorkerRegistry {
|
|
|
63
63
|
* to reject a stale completion from an EARLIER attempt that was reassigned to the
|
|
64
64
|
* same worker — the only case the workerId guard alone cannot catch.
|
|
65
65
|
*
|
|
66
|
-
* The
|
|
67
|
-
* never refused (no protocol version bump): it fires only when the tracked
|
|
68
|
-
* task has a stored token AND the completion echoes one AND they differ. A
|
|
69
|
-
* token-less task matches any echo, and an absent echo falls back to the
|
|
70
|
-
* workerId-only guard that already passed. The defended case — a stale earlier
|
|
71
|
-
* attempt — always echoes the OLD token it was dispatched with (present, wrong),
|
|
72
|
-
* so it is still rejected.
|
|
66
|
+
* The workerId and token must both match the current assignment exactly.
|
|
73
67
|
*/
|
|
74
|
-
isAssignedToAttempt(operationId: string, workerId: string, attemptToken: string
|
|
68
|
+
isAssignedToAttempt(operationId: string, workerId: string, attemptToken: string): boolean;
|
|
75
69
|
/** Check whether an operation is currently assigned to a worker. */
|
|
76
70
|
isAssigned(operationId: string): boolean;
|
|
77
71
|
/** Look up an in-flight task by operationId in O(1). */
|
package/dist/worker/registry.js
CHANGED
|
@@ -114,10 +114,9 @@ export class WorkerRegistry {
|
|
|
114
114
|
operationId,
|
|
115
115
|
workerId,
|
|
116
116
|
deadline,
|
|
117
|
-
visibilityTimeout
|
|
117
|
+
visibilityTimeout,
|
|
118
|
+
attemptToken
|
|
118
119
|
};
|
|
119
|
-
if (attemptToken !== void 0)
|
|
120
|
-
task.attemptToken = attemptToken;
|
|
121
120
|
if (fairShareKey !== void 0) {
|
|
122
121
|
task.fairShareKey = fairShareKey;
|
|
123
122
|
this.#fairShareCounts.increment(workerId, fairShareKey);
|
|
@@ -157,8 +156,6 @@ export class WorkerRegistry {
|
|
|
157
156
|
const task = this.#inFlightTasks.get(operationId);
|
|
158
157
|
if (task === void 0 || task.workerId !== workerId)
|
|
159
158
|
return !1;
|
|
160
|
-
if (task.attemptToken === void 0 || attemptToken === void 0)
|
|
161
|
-
return !0;
|
|
162
159
|
return task.attemptToken === attemptToken;
|
|
163
160
|
}
|
|
164
161
|
isAssigned(operationId) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lostgradient/weft",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "A Bun-native durable execution engine with pluggable key-value storage.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bun",
|
|
@@ -294,6 +294,7 @@
|
|
|
294
294
|
},
|
|
295
295
|
"peerDependencies": {
|
|
296
296
|
"@libsql/client": "^0.17.2",
|
|
297
|
+
"@lostgradient/weft-console": "^0.1.0",
|
|
297
298
|
"@neondatabase/serverless": "^1.1.0",
|
|
298
299
|
"@opentelemetry/api": "^1.0.0",
|
|
299
300
|
"better-sqlite3": "^12.8.0",
|
|
@@ -304,6 +305,9 @@
|
|
|
304
305
|
"@libsql/client": {
|
|
305
306
|
"optional": true
|
|
306
307
|
},
|
|
308
|
+
"@lostgradient/weft-console": {
|
|
309
|
+
"optional": true
|
|
310
|
+
},
|
|
307
311
|
"@neondatabase/serverless": {
|
|
308
312
|
"optional": true
|
|
309
313
|
},
|