@openfn/ws-worker 0.2.7 → 0.2.9
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/CHANGELOG.md +16 -0
- package/README.md +1 -1
- package/dist/index.d.ts +93 -10
- package/dist/index.js +9 -0
- package/dist/start.js +62 -71
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# ws-worker
|
|
2
2
|
|
|
3
|
+
## 0.2.9
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 54d0017: Start ws-worker using node (not pnpm) by default
|
|
8
|
+
- 6f78b7a: Add env var for WORKER_REPO_DIR
|
|
9
|
+
- Updated dependencies [4a17048]
|
|
10
|
+
- @openfn/engine-multi@0.2.0
|
|
11
|
+
- @openfn/runtime@0.2.0
|
|
12
|
+
|
|
13
|
+
## 0.2.8
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Tweak typings
|
|
18
|
+
|
|
3
19
|
## 0.2.7
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ You can start a dev server (which rebuilds on save) by running:
|
|
|
48
48
|
pnpm start:watch
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
This will wrap a real runtime engine into the server
|
|
51
|
+
This will wrap a real runtime engine into the server. It will rebuild when the Worker Engine code changes (although you'll have to `pnpm build:watch` in `runtime-manager`). This will use the repo at `WORKER_REPO_DIR` (or a default path in /tmp)
|
|
52
52
|
|
|
53
53
|
### Disabling auto-fetch
|
|
54
54
|
|
package/dist/index.d.ts
CHANGED
|
@@ -17,6 +17,40 @@ type ExitReason = {
|
|
|
17
17
|
error_type: string | null;
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
+
type Node = {
|
|
21
|
+
id: string;
|
|
22
|
+
body?: string;
|
|
23
|
+
adaptor?: string;
|
|
24
|
+
credential_id?: any; // TODO tighten this up, string or object
|
|
25
|
+
type?: 'webhook' | 'cron'; // trigger only
|
|
26
|
+
state?: any; // Initial state / defaults
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
interface Edge {
|
|
30
|
+
id: string;
|
|
31
|
+
source_job_id?: string;
|
|
32
|
+
source_trigger_id?: string;
|
|
33
|
+
target_job_id: string;
|
|
34
|
+
name?: string;
|
|
35
|
+
condition?: string;
|
|
36
|
+
error_path?: boolean;
|
|
37
|
+
errors?: any;
|
|
38
|
+
enabled?: boolean;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// An attempt object returned by Lightning
|
|
42
|
+
type Attempt = {
|
|
43
|
+
id: string;
|
|
44
|
+
dataclip_id: string;
|
|
45
|
+
starting_node_id: string;
|
|
46
|
+
|
|
47
|
+
triggers: Node[];
|
|
48
|
+
jobs: Node[];
|
|
49
|
+
edges: Edge[];
|
|
50
|
+
|
|
51
|
+
options?: AttemptOptions;
|
|
52
|
+
};
|
|
53
|
+
|
|
20
54
|
type AttemptOptions = {
|
|
21
55
|
timeout?: number;
|
|
22
56
|
sanitize?: SanitizePolicies;
|
|
@@ -45,13 +79,6 @@ type ReceiveHook = {
|
|
|
45
79
|
) => ReceiveHook;
|
|
46
80
|
};
|
|
47
81
|
|
|
48
|
-
// export declare class Socket extends PhxSocket {
|
|
49
|
-
// constructor(endpoint: string, options: { params: any });
|
|
50
|
-
// onOpen(callback: () => void): void;
|
|
51
|
-
// connect(): void;
|
|
52
|
-
// channel(channelName: string, params: any): Channel;
|
|
53
|
-
// }
|
|
54
|
-
|
|
55
82
|
interface Channel extends Channel$1 {
|
|
56
83
|
// on: (event: string, fn: (evt: any) => void) => void;
|
|
57
84
|
|
|
@@ -67,10 +94,66 @@ declare type Context = {
|
|
|
67
94
|
onFinish: (result: any) => void;
|
|
68
95
|
};
|
|
69
96
|
|
|
70
|
-
declare
|
|
97
|
+
declare const CLAIM = "claim";
|
|
98
|
+
declare type ClaimPayload = {
|
|
99
|
+
demand?: number;
|
|
100
|
+
};
|
|
101
|
+
declare type ClaimReply = {
|
|
102
|
+
attempts: Array<ClaimAttempt>;
|
|
103
|
+
};
|
|
104
|
+
declare type ClaimAttempt = {
|
|
71
105
|
id: string;
|
|
72
106
|
token: string;
|
|
73
107
|
};
|
|
108
|
+
declare const GET_ATTEMPT = "fetch:attempt";
|
|
109
|
+
declare type GetAttemptPayload = void;
|
|
110
|
+
declare type GetAttemptReply = Attempt;
|
|
111
|
+
declare const GET_CREDENTIAL = "fetch:credential";
|
|
112
|
+
declare type GetCredentialPayload = {
|
|
113
|
+
id: string;
|
|
114
|
+
};
|
|
115
|
+
declare type GetCredentialReply = {};
|
|
116
|
+
declare const GET_DATACLIP = "fetch:dataclip";
|
|
117
|
+
declare type GetDataclipPayload = {
|
|
118
|
+
id: string;
|
|
119
|
+
};
|
|
120
|
+
declare type GetDataClipReply = Uint8Array;
|
|
121
|
+
declare const ATTEMPT_START = "attempt:start";
|
|
122
|
+
declare type AttemptStartPayload = void;
|
|
123
|
+
declare type AttemptStartReply = {};
|
|
124
|
+
declare const ATTEMPT_COMPLETE = "attempt:complete";
|
|
125
|
+
declare type AttemptCompletePayload = ExitReason & {
|
|
126
|
+
final_dataclip_id?: string;
|
|
127
|
+
};
|
|
128
|
+
declare type AttemptCompleteReply = undefined;
|
|
129
|
+
declare const ATTEMPT_LOG = "attempt:log";
|
|
130
|
+
declare type AttemptLogPayload = {
|
|
131
|
+
message: Array<string | object>;
|
|
132
|
+
timestamp: string;
|
|
133
|
+
attempt_id: string;
|
|
134
|
+
level?: string;
|
|
135
|
+
source?: string;
|
|
136
|
+
job_id?: string;
|
|
137
|
+
run_id?: string;
|
|
138
|
+
};
|
|
139
|
+
declare type AttemptLogReply = void;
|
|
140
|
+
declare const RUN_START = "run:start";
|
|
141
|
+
declare type RunStartPayload = {
|
|
142
|
+
job_id: string;
|
|
143
|
+
run_id: string;
|
|
144
|
+
attempt_id?: string;
|
|
145
|
+
input_dataclip_id?: string;
|
|
146
|
+
};
|
|
147
|
+
declare type RunStartReply = void;
|
|
148
|
+
declare const RUN_COMPLETE = "run:complete";
|
|
149
|
+
declare type RunCompletePayload = ExitReason & {
|
|
150
|
+
attempt_id?: string;
|
|
151
|
+
job_id: string;
|
|
152
|
+
run_id: string;
|
|
153
|
+
output_dataclip?: string;
|
|
154
|
+
output_dataclip_id?: string;
|
|
155
|
+
};
|
|
156
|
+
declare type RunCompleteReply = void;
|
|
74
157
|
|
|
75
158
|
declare type ServerOptions = {
|
|
76
159
|
maxWorkflows?: number;
|
|
@@ -89,10 +172,10 @@ interface ServerApp extends Koa {
|
|
|
89
172
|
socket: any;
|
|
90
173
|
channel: Channel;
|
|
91
174
|
workflows: Record<string, true | Context>;
|
|
92
|
-
execute: ({ id, token }:
|
|
175
|
+
execute: ({ id, token }: ClaimAttempt) => Promise<void>;
|
|
93
176
|
destroy: () => void;
|
|
94
177
|
killWorkloop?: () => void;
|
|
95
178
|
}
|
|
96
179
|
declare function createServer(engine: RuntimeEngine, options?: ServerOptions): ServerApp;
|
|
97
180
|
|
|
98
|
-
export { createServer as default };
|
|
181
|
+
export { ATTEMPT_COMPLETE, ATTEMPT_LOG, ATTEMPT_START, AttemptCompletePayload, AttemptCompleteReply, AttemptLogPayload, AttemptLogReply, AttemptStartPayload, AttemptStartReply, CLAIM, ClaimAttempt, ClaimPayload, ClaimReply, GET_ATTEMPT, GET_CREDENTIAL, GET_DATACLIP, GetAttemptPayload, GetAttemptReply, GetCredentialPayload, GetCredentialReply, GetDataClipReply, GetDataclipPayload, RUN_COMPLETE, RUN_START, RunCompletePayload, RunCompleteReply, RunStartPayload, RunStartReply, createServer as default };
|
package/dist/index.js
CHANGED
|
@@ -661,5 +661,14 @@ var server_default = createServer;
|
|
|
661
661
|
// src/index.ts
|
|
662
662
|
var src_default = server_default;
|
|
663
663
|
export {
|
|
664
|
+
ATTEMPT_COMPLETE,
|
|
665
|
+
ATTEMPT_LOG,
|
|
666
|
+
ATTEMPT_START,
|
|
667
|
+
CLAIM,
|
|
668
|
+
GET_ATTEMPT,
|
|
669
|
+
GET_CREDENTIAL,
|
|
670
|
+
GET_DATACLIP,
|
|
671
|
+
RUN_COMPLETE,
|
|
672
|
+
RUN_START,
|
|
664
673
|
src_default as default
|
|
665
674
|
};
|
package/dist/start.js
CHANGED
|
@@ -4864,8 +4864,8 @@ import createLogger from "@openfn/logger";
|
|
|
4864
4864
|
import createRTE from "@openfn/engine-multi";
|
|
4865
4865
|
|
|
4866
4866
|
// src/mock/runtime-engine.ts
|
|
4867
|
-
import crypto from "node:crypto";
|
|
4868
4867
|
import { EventEmitter } from "node:events";
|
|
4868
|
+
import run from "@openfn/runtime";
|
|
4869
4869
|
|
|
4870
4870
|
// src/mock/resolvers.ts
|
|
4871
4871
|
var mockResolveCredential = (_credId) => new Promise(
|
|
@@ -4887,6 +4887,10 @@ var resolvers_default = {
|
|
|
4887
4887
|
};
|
|
4888
4888
|
|
|
4889
4889
|
// src/mock/runtime-engine.ts
|
|
4890
|
+
var helpers = {
|
|
4891
|
+
fn: (f) => (s) => f(s),
|
|
4892
|
+
wait: (duration) => (s) => new Promise((resolve5) => setTimeout(() => resolve5(s), duration))
|
|
4893
|
+
};
|
|
4890
4894
|
async function createMock() {
|
|
4891
4895
|
const activeWorkflows = {};
|
|
4892
4896
|
const bus = new EventEmitter();
|
|
@@ -4902,73 +4906,59 @@ async function createMock() {
|
|
|
4902
4906
|
const listen = (planId, events) => {
|
|
4903
4907
|
listeners[planId] = events;
|
|
4904
4908
|
};
|
|
4905
|
-
const
|
|
4906
|
-
const { id, expression, configuration, adaptor } = job;
|
|
4907
|
-
if (!expression && !adaptor) {
|
|
4908
|
-
return initialState;
|
|
4909
|
-
}
|
|
4910
|
-
const runId = crypto.randomUUID();
|
|
4911
|
-
const jobId = id;
|
|
4912
|
-
if (typeof configuration === "string") {
|
|
4913
|
-
await resolvers.credential?.(configuration);
|
|
4914
|
-
}
|
|
4915
|
-
const info = (...message) => {
|
|
4916
|
-
dispatch("workflow-log", {
|
|
4917
|
-
workflowId,
|
|
4918
|
-
message,
|
|
4919
|
-
level: "info",
|
|
4920
|
-
time: (BigInt(Date.now()) * BigInt(1e3)).toString(),
|
|
4921
|
-
name: "mck"
|
|
4922
|
-
});
|
|
4923
|
-
};
|
|
4924
|
-
dispatch("job-start", { workflowId, jobId, runId });
|
|
4925
|
-
info("Running job " + jobId);
|
|
4926
|
-
let nextState = initialState;
|
|
4927
|
-
if (expression?.startsWith?.("wait@")) {
|
|
4928
|
-
const [_, delay] = expression.split("@");
|
|
4929
|
-
nextState = initialState;
|
|
4930
|
-
await new Promise((resolve5) => {
|
|
4931
|
-
setTimeout(() => resolve5(), parseInt(delay));
|
|
4932
|
-
});
|
|
4933
|
-
} else {
|
|
4934
|
-
try {
|
|
4935
|
-
nextState = JSON.parse(expression);
|
|
4936
|
-
info("Parsing expression as JSON state");
|
|
4937
|
-
info(nextState);
|
|
4938
|
-
} catch (e) {
|
|
4939
|
-
nextState = initialState;
|
|
4940
|
-
}
|
|
4941
|
-
}
|
|
4942
|
-
dispatch("job-complete", {
|
|
4943
|
-
workflowId,
|
|
4944
|
-
jobId,
|
|
4945
|
-
state: nextState,
|
|
4946
|
-
runId,
|
|
4947
|
-
next: []
|
|
4948
|
-
});
|
|
4949
|
-
return nextState;
|
|
4950
|
-
};
|
|
4951
|
-
const execute2 = (xplan, options = {
|
|
4909
|
+
const execute2 = async (xplan, options = {
|
|
4952
4910
|
resolvers: resolvers_default
|
|
4953
4911
|
}) => {
|
|
4954
|
-
|
|
4955
|
-
throw new Error("test error");
|
|
4956
|
-
}
|
|
4957
|
-
const { id, jobs, initialState } = xplan;
|
|
4958
|
-
const workflowId = id;
|
|
4912
|
+
const { id, jobs } = xplan;
|
|
4959
4913
|
activeWorkflows[id] = true;
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
|
|
4914
|
+
for (const job of jobs) {
|
|
4915
|
+
if (typeof job.configuration === "string") {
|
|
4916
|
+
job.configuration = await options.resolvers?.credential?.(
|
|
4917
|
+
job.configuration
|
|
4918
|
+
);
|
|
4919
|
+
}
|
|
4920
|
+
if (typeof job.expression === "string" && !job.expression.match(/export default \[/)) {
|
|
4921
|
+
job.expression = `export default [${job.expression}];`;
|
|
4922
|
+
}
|
|
4923
|
+
}
|
|
4924
|
+
const jobLogger = {
|
|
4925
|
+
log: (...args2) => {
|
|
4926
|
+
dispatch("workflow-log", {
|
|
4927
|
+
workflowId: id,
|
|
4928
|
+
level: "info",
|
|
4929
|
+
json: true,
|
|
4930
|
+
message: args2,
|
|
4931
|
+
time: Date.now()
|
|
4932
|
+
});
|
|
4933
|
+
}
|
|
4934
|
+
};
|
|
4935
|
+
const opts = {
|
|
4936
|
+
strict: false,
|
|
4937
|
+
jobLogger,
|
|
4938
|
+
...options,
|
|
4939
|
+
globals: helpers,
|
|
4940
|
+
callbacks: {
|
|
4941
|
+
notify: (name, payload) => {
|
|
4942
|
+
dispatch(name, {
|
|
4943
|
+
workflowId: id,
|
|
4944
|
+
...payload
|
|
4945
|
+
});
|
|
4966
4946
|
}
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
4947
|
+
}
|
|
4948
|
+
};
|
|
4949
|
+
setTimeout(async () => {
|
|
4950
|
+
dispatch("workflow-start", { workflowId: id });
|
|
4951
|
+
try {
|
|
4952
|
+
await run(xplan, void 0, opts);
|
|
4953
|
+
} catch (e) {
|
|
4954
|
+
dispatch("workflow-error", {
|
|
4955
|
+
workflowId: id,
|
|
4956
|
+
type: e.name,
|
|
4957
|
+
message: e.message
|
|
4958
|
+
});
|
|
4959
|
+
}
|
|
4960
|
+
delete activeWorkflows[id];
|
|
4961
|
+
dispatch("workflow-complete", { workflowId: id });
|
|
4972
4962
|
}, 1);
|
|
4973
4963
|
};
|
|
4974
4964
|
const getStatus = () => {
|
|
@@ -5105,10 +5095,10 @@ var startWorkloop = (app, logger2, minBackoff2, maxBackoff2, maxWorkers) => {
|
|
|
5105
5095
|
var workloop_default = startWorkloop;
|
|
5106
5096
|
|
|
5107
5097
|
// src/api/execute.ts
|
|
5108
|
-
import
|
|
5098
|
+
import crypto2 from "node:crypto";
|
|
5109
5099
|
|
|
5110
5100
|
// src/util/convert-attempt.ts
|
|
5111
|
-
import
|
|
5101
|
+
import crypto from "node:crypto";
|
|
5112
5102
|
var conditions = {
|
|
5113
5103
|
on_job_success: "!state.errors",
|
|
5114
5104
|
on_job_failure: "state.errors",
|
|
@@ -5153,7 +5143,7 @@ var convert_attempt_default = (attempt) => {
|
|
|
5153
5143
|
}
|
|
5154
5144
|
if (attempt.jobs?.length) {
|
|
5155
5145
|
attempt.jobs.forEach((job) => {
|
|
5156
|
-
const id = job.id ||
|
|
5146
|
+
const id = job.id || crypto.randomUUID();
|
|
5157
5147
|
nodes[id] = {
|
|
5158
5148
|
id,
|
|
5159
5149
|
configuration: job.credential_id,
|
|
@@ -5336,7 +5326,7 @@ var sendEvent = (channel, event, payload) => new Promise((resolve5, reject) => {
|
|
|
5336
5326
|
channel.push(event, payload).receive("error", reject).receive("timeout", () => reject(new Error("timeout"))).receive("ok", resolve5);
|
|
5337
5327
|
});
|
|
5338
5328
|
function onJobStart({ channel, state }, event) {
|
|
5339
|
-
state.activeRun =
|
|
5329
|
+
state.activeRun = crypto2.randomUUID();
|
|
5340
5330
|
state.activeJob = event.jobId;
|
|
5341
5331
|
const input_dataclip_id = state.inputDataclips[event.jobId];
|
|
5342
5332
|
return sendEvent(channel, RUN_START, {
|
|
@@ -5354,7 +5344,7 @@ function onJobError(context, event) {
|
|
|
5354
5344
|
}
|
|
5355
5345
|
}
|
|
5356
5346
|
function onJobComplete({ channel, state }, event, error) {
|
|
5357
|
-
const dataclipId =
|
|
5347
|
+
const dataclipId = crypto2.randomUUID();
|
|
5358
5348
|
const run_id = state.activeRun;
|
|
5359
5349
|
const job_id = state.activeJob;
|
|
5360
5350
|
if (!state.dataclips) {
|
|
@@ -5647,6 +5637,7 @@ function createServer(engine, options = {}) {
|
|
|
5647
5637
|
var server_default = createServer;
|
|
5648
5638
|
|
|
5649
5639
|
// src/start.ts
|
|
5640
|
+
var { WORKER_REPO_DIR, WORKER_SECRET } = process.env;
|
|
5650
5641
|
var args = yargs_default(hideBin(process.argv)).command("server", "Start a ws-worker server").option("port", {
|
|
5651
5642
|
alias: "p",
|
|
5652
5643
|
description: "Port to run the server on",
|
|
@@ -5658,7 +5649,8 @@ var args = yargs_default(hideBin(process.argv)).command("server", "Start a ws-wo
|
|
|
5658
5649
|
default: "ws://localhost:4000/worker"
|
|
5659
5650
|
}).option("repo-dir", {
|
|
5660
5651
|
alias: "d",
|
|
5661
|
-
description: "Path to the runtime repo (where modules will be installed)"
|
|
5652
|
+
description: "Path to the runtime repo (where modules will be installed)",
|
|
5653
|
+
default: WORKER_REPO_DIR
|
|
5662
5654
|
}).option("secret", {
|
|
5663
5655
|
alias: "s",
|
|
5664
5656
|
description: "Worker secret (comes from WORKER_SECRET by default)"
|
|
@@ -5689,7 +5681,6 @@ if (args.lightning === "mock") {
|
|
|
5689
5681
|
args.secret = "abdefg";
|
|
5690
5682
|
}
|
|
5691
5683
|
} else if (!args.secret) {
|
|
5692
|
-
const { WORKER_SECRET } = process.env;
|
|
5693
5684
|
if (!WORKER_SECRET) {
|
|
5694
5685
|
logger.error("WORKER_SECRET is not set");
|
|
5695
5686
|
process.exit(1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfn/ws-worker",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.9",
|
|
4
4
|
"description": "A Websocket Worker to connect Lightning to a Runtime Engine",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
"koa-logger": "^3.2.1",
|
|
22
22
|
"phoenix": "^1.7.7",
|
|
23
23
|
"ws": "^8.14.1",
|
|
24
|
-
"@openfn/engine-multi": "0.
|
|
25
|
-
"@openfn/
|
|
26
|
-
"@openfn/
|
|
24
|
+
"@openfn/engine-multi": "0.2.0",
|
|
25
|
+
"@openfn/logger": "0.0.19",
|
|
26
|
+
"@openfn/runtime": "0.2.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/koa": "^2.13.5",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"tsup": "^6.2.3",
|
|
41
41
|
"typescript": "^4.6.4",
|
|
42
42
|
"yargs": "^17.6.2",
|
|
43
|
-
"@openfn/lightning-mock": "1.
|
|
43
|
+
"@openfn/lightning-mock": "1.1.2"
|
|
44
44
|
},
|
|
45
45
|
"files": [
|
|
46
46
|
"dist",
|