terse-cli 0.4.6 → 0.5.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/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +3 -2
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +43 -21
- package/dist/commands/run.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/providers/LanguageProvider.d.ts +2 -0
- package/dist/providers/LanguageProvider.d.ts.map +1 -1
- package/dist/providers/typescript/TypeScriptProvider.d.ts +2 -0
- package/dist/providers/typescript/TypeScriptProvider.d.ts.map +1 -1
- package/dist/providers/typescript/TypeScriptProvider.js +29 -5
- package/dist/providers/typescript/TypeScriptProvider.js.map +1 -1
- package/dist/providers/typescript/jobMacro.d.ts +1 -2
- package/dist/providers/typescript/jobMacro.d.ts.map +1 -1
- package/dist/providers/typescript/jobMacro.js +69 -111
- package/dist/providers/typescript/jobMacro.js.map +1 -1
- package/dist/providers/typescript/jobSources.d.ts +7 -0
- package/dist/providers/typescript/jobSources.d.ts.map +1 -0
- package/dist/providers/typescript/jobSources.js +46 -0
- package/dist/providers/typescript/jobSources.js.map +1 -0
- package/dist/providers/typescript/runtimes/JobRuntime.d.ts +3 -0
- package/dist/providers/typescript/runtimes/JobRuntime.d.ts.map +1 -1
- package/dist/providers/typescript/runtimes/JobRuntime.js.map +1 -1
- package/dist/providers/typescript/runtimes/directJobRuntime.d.ts.map +1 -1
- package/dist/providers/typescript/runtimes/directJobRuntime.js +1 -1
- package/dist/providers/typescript/runtimes/directJobRuntime.js.map +1 -1
- package/dist/providers/typescript/runtimes/durableJobRuntime.d.ts.map +1 -1
- package/dist/providers/typescript/runtimes/durableJobRuntime.js +99 -55
- package/dist/providers/typescript/runtimes/durableJobRuntime.js.map +1 -1
- package/dist/providers/typescript/runtimes/session.d.ts +3 -1
- package/dist/providers/typescript/runtimes/session.d.ts.map +1 -1
- package/dist/providers/typescript/runtimes/session.js +14 -9
- package/dist/providers/typescript/runtimes/session.js.map +1 -1
- package/dist/providers/typescript/stepMacro.d.ts +2 -29
- package/dist/providers/typescript/stepMacro.d.ts.map +1 -1
- package/dist/providers/typescript/stepMacro.js +29 -120
- package/dist/providers/typescript/stepMacro.js.map +1 -1
- package/dist/providers/typescript/terseWorkflow.d.ts +8 -0
- package/dist/providers/typescript/terseWorkflow.d.ts.map +1 -0
- package/dist/providers/typescript/terseWorkflow.js +8 -0
- package/dist/providers/typescript/terseWorkflow.js.map +1 -0
- package/package.json +6 -8
- package/templates/typescript/init/gitignore.hbs +1 -0
- package/templates/typescript/init/package.json.hbs +0 -1
- package/dist/providers/typescript/durableRuntime.d.ts +0 -21
- package/dist/providers/typescript/durableRuntime.d.ts.map +0 -1
- package/dist/providers/typescript/durableRuntime.js +0 -207
- package/dist/providers/typescript/durableRuntime.js.map +0 -1
- package/dist/providers/typescript/rewindRun.d.ts +0 -9
- package/dist/providers/typescript/rewindRun.d.ts.map +0 -1
- package/dist/providers/typescript/rewindRun.js +0 -111
- package/dist/providers/typescript/rewindRun.js.map +0 -1
- package/dist/providers/typescript/terseWorkflowBuilder.d.ts +0 -8
- package/dist/providers/typescript/terseWorkflowBuilder.d.ts.map +0 -1
- package/dist/providers/typescript/terseWorkflowBuilder.js +0 -66
- package/dist/providers/typescript/terseWorkflowBuilder.js.map +0 -1
- package/dist/providers/typescript/workflowShim.d.ts +0 -2
- package/dist/providers/typescript/workflowShim.d.ts.map +0 -1
- package/dist/providers/typescript/workflowShim.js +0 -51
- package/dist/providers/typescript/workflowShim.js.map +0 -1
- package/dist/terseWorld.d.ts +0 -4
- package/dist/terseWorld.d.ts.map +0 -1
- package/dist/terseWorld.js +0 -46
- package/dist/terseWorld.js.map +0 -1
- package/templates/typescript/workflow-shim/api.js +0 -5
- package/templates/typescript/workflow-shim/index.js +0 -2
- package/templates/typescript/workflow-shim/internal/builtins.js +0 -83
- package/templates/typescript/workflow-shim/internal/class-serialization.js +0 -1
- package/templates/typescript/workflow-shim/runtime.js +0 -1
- package/templates/typescript/workflow-shim/stdlib.js +0 -18
- package/templates/typescript/workflow-shim/workflow.js +0 -2
|
@@ -1,128 +1,86 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { StepCallKind, findStepImportName, matchStepCall, transformJobStep, transformStep } from "./stepMacro.js";
|
|
3
|
-
// MARK: Rewrite job sources
|
|
1
|
+
import { findStepImportName, matchStepCall, transformStep } from "./stepMacro.js";
|
|
4
2
|
export function transformJobSource(ts, source, fileName) {
|
|
5
|
-
const { code: withSteps, stepDefs } = extractJobSteps(ts, source, fileName);
|
|
6
|
-
const sf = ts.createSourceFile(fileName, withSteps, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
7
|
-
const jobs = [];
|
|
8
|
-
const hoisted = [];
|
|
9
|
-
const edits = [];
|
|
10
|
-
const isProp = (p, key) => ts.isPropertyAssignment(p) && ts.isIdentifier(p.name) && p.name.text === key;
|
|
11
|
-
const visit = (node) => {
|
|
12
|
-
if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === "createJob" && node.arguments.length > 0 && ts.isObjectLiteralExpression(node.arguments[0])) {
|
|
13
|
-
const obj = node.arguments[0];
|
|
14
|
-
const nameProp = obj.properties.find(p => isProp(p, "name"));
|
|
15
|
-
const onTrigger = obj.properties.find(p => isProp(p, "onTrigger"));
|
|
16
|
-
const statesProp = obj.properties.find(p => isProp(p, "states"));
|
|
17
|
-
const durable = obj.properties.find(p => isProp(p, "durable"))?.initializer.kind === ts.SyntaxKind.TrueKeyword;
|
|
18
|
-
const jobName = nameProp && ts.isStringLiteralLike(nameProp.initializer) ? nameProp.initializer.text : undefined;
|
|
19
|
-
const fn = onTrigger?.initializer;
|
|
20
|
-
if (jobName && fn && durable && (ts.isArrowFunction(fn) || ts.isFunctionExpression(fn))) {
|
|
21
|
-
const fnName = `terseWf_${Buffer.from(jobName).toString("hex")}`;
|
|
22
|
-
const param = fn.parameters.length ? fn.parameters[0].name.getText(sf) : "event";
|
|
23
|
-
const stateParam = fn.parameters.length > 1 ? fn.parameters[1].name.getText(sf) : "state";
|
|
24
|
-
const statesText = statesProp ? statesProp.initializer.getText(sf) : "[]";
|
|
25
|
-
const body = ts.isBlock(fn.body) ? fn.body.getText(sf).slice(1, -1) : `\n return ${fn.body.getText(sf)}\n`;
|
|
26
|
-
hoisted.push(`async function ${fnName}(__rawEvent) {\n` +
|
|
27
|
-
` "use workflow"\n` +
|
|
28
|
-
` const ${param} = createSDKTrigger(__rawEvent)\n` +
|
|
29
|
-
` const ${stateParam} = __buildJobStateAccessor(${statesText})\n` +
|
|
30
|
-
body +
|
|
31
|
-
`}`);
|
|
32
|
-
edits.push({ start: onTrigger.getStart(sf), end: onTrigger.getEnd(), text: `onTrigger: ${fnName}` });
|
|
33
|
-
jobs.push({ name: jobName, fnName });
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
ts.forEachChild(node, visit);
|
|
37
|
-
};
|
|
38
|
-
visit(sf);
|
|
39
|
-
if (jobs.length === 0)
|
|
40
|
-
return { code: withSteps, stepsCode: null, jobs };
|
|
41
|
-
const imports = sf.statements.filter(ts.isImportDeclaration);
|
|
42
|
-
const lastImportEnd = imports.length ? imports[imports.length - 1].getEnd() : 0;
|
|
43
|
-
edits.push({ start: lastImportEnd, end: lastImportEnd, text: `\n\n${hoisted.join("\n\n")}\n` });
|
|
44
|
-
const importEdit = sdkImportEdit(ts, sf, imports, lastImportEnd, ["createSDKTrigger", "__buildJobStateAccessor"]);
|
|
45
|
-
if (importEdit)
|
|
46
|
-
edits.push(importEdit);
|
|
47
|
-
if (stepDefs.length > 0) {
|
|
48
|
-
edits.push({ start: lastImportEnd, end: lastImportEnd, text: `\nimport { ${stepDefs.map(s => s.name).join(", ")} } from "${stepsImportSpecifier(fileName)}"` });
|
|
49
|
-
}
|
|
50
|
-
let code = withSteps;
|
|
51
|
-
for (const e of edits.sort((a, b) => b.start - a.start))
|
|
52
|
-
code = code.slice(0, e.start) + e.text + code.slice(e.end);
|
|
53
|
-
const stepsCode = stepDefs.length > 0 ? buildStepsModule(ts, sf, stepDefs) : null;
|
|
54
|
-
return { code, stepsCode, jobs };
|
|
55
|
-
}
|
|
56
|
-
// MARK: Extract job steps
|
|
57
|
-
function extractJobSteps(ts, source, fileName) {
|
|
58
3
|
const sf = ts.createSourceFile(fileName, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
59
|
-
const stepDefs = [];
|
|
60
|
-
const edits = [];
|
|
61
4
|
const stepName = findStepImportName(ts, sf);
|
|
62
|
-
|
|
5
|
+
const stepEdits = [];
|
|
6
|
+
let stepIndex = 0;
|
|
63
7
|
const visit = (node) => {
|
|
64
8
|
const step = matchStepCall(ts, node, stepName);
|
|
65
9
|
if (step) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const { stepDef, edit } = transformStep(ts, sf, step, fileName, counter++, stepName);
|
|
69
|
-
stepDefs.push(stepDef);
|
|
70
|
-
edits.push(edit);
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
case StepCallKind.JobStep: {
|
|
74
|
-
const transformed = transformJobStep(ts, sf, step, fileName, counter, stepName);
|
|
75
|
-
if (transformed) {
|
|
76
|
-
counter++;
|
|
77
|
-
stepDefs.push(transformed.stepDef);
|
|
78
|
-
edits.push(transformed.edit);
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
10
|
+
stepEdits.push(transformStep(ts, sf, step, fileName, stepIndex++));
|
|
11
|
+
return;
|
|
84
12
|
}
|
|
85
13
|
ts.forEachChild(node, visit);
|
|
86
14
|
};
|
|
87
15
|
visit(sf);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
return { code,
|
|
16
|
+
let code = applyEdits(source, stepEdits);
|
|
17
|
+
const hoisted = hoistDurableJobs(ts, code, fileName);
|
|
18
|
+
code = hoisted.code;
|
|
19
|
+
const sdkImports = [...(stepIndex > 0 ? ["__runDurableStep"] : []), ...(hoisted.jobs.length > 0 ? ["__defineTerseWorkflow", "__registerDurableWorkflow"] : [])];
|
|
20
|
+
code = addSdkImports(ts, code, fileName, sdkImports);
|
|
21
|
+
return { code, stepsCode: null, jobs: hoisted.jobs };
|
|
94
22
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
23
|
+
function hoistDurableJobs(ts, source, fileName) {
|
|
24
|
+
const sf = ts.createSourceFile(fileName, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
25
|
+
const edits = [];
|
|
26
|
+
const jobs = [];
|
|
27
|
+
for (const statement of sf.statements) {
|
|
28
|
+
if (!ts.isExpressionStatement(statement) || !ts.isCallExpression(statement.expression))
|
|
29
|
+
continue;
|
|
30
|
+
const name = durableJobName(ts, statement.expression);
|
|
31
|
+
if (!name)
|
|
32
|
+
continue;
|
|
33
|
+
const index = jobs.length;
|
|
34
|
+
const jobName = `__terseJob${index}`;
|
|
35
|
+
const workflowName = `__terseWorkflow${index}`;
|
|
36
|
+
edits.push({
|
|
37
|
+
start: statement.getStart(sf),
|
|
38
|
+
end: statement.getEnd(),
|
|
39
|
+
text: `const ${jobName} = ${statement.expression.getText(sf)}\nconst ${workflowName} = __defineTerseWorkflow(${jobName})\n__registerDurableWorkflow(${workflowName})`
|
|
40
|
+
});
|
|
41
|
+
jobs.push({ name });
|
|
42
|
+
}
|
|
43
|
+
return { code: applyEdits(source, edits), jobs };
|
|
104
44
|
}
|
|
105
|
-
function
|
|
106
|
-
|
|
107
|
-
|
|
45
|
+
function durableJobName(ts, node) {
|
|
46
|
+
if (!ts.isCallExpression(node) || !ts.isIdentifier(node.expression) || node.expression.text !== "createJob")
|
|
47
|
+
return undefined;
|
|
48
|
+
const [config] = node.arguments;
|
|
49
|
+
if (!config || !ts.isObjectLiteralExpression(config))
|
|
50
|
+
return undefined;
|
|
51
|
+
const name = property(ts, config, "name")?.initializer;
|
|
52
|
+
const durable = property(ts, config, "durable")?.initializer;
|
|
53
|
+
if (!name || !ts.isStringLiteralLike(name) || durable?.kind !== ts.SyntaxKind.TrueKeyword)
|
|
54
|
+
return undefined;
|
|
55
|
+
return name.text;
|
|
108
56
|
}
|
|
109
|
-
function
|
|
110
|
-
return
|
|
57
|
+
function property(ts, object, name) {
|
|
58
|
+
return object.properties.find((candidate) => ts.isPropertyAssignment(candidate) && ts.isIdentifier(candidate.name) && candidate.name.text === name);
|
|
111
59
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return
|
|
124
|
-
|
|
60
|
+
function addSdkImports(ts, source, fileName, names) {
|
|
61
|
+
if (names.length === 0)
|
|
62
|
+
return source;
|
|
63
|
+
const sf = ts.createSourceFile(fileName, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
64
|
+
const imports = sf.statements.filter(ts.isImportDeclaration);
|
|
65
|
+
const sdkImport = imports.find(statement => ts.isStringLiteralLike(statement.moduleSpecifier) && statement.moduleSpecifier.text === "terse-sdk");
|
|
66
|
+
const bindings = sdkImport?.importClause?.namedBindings;
|
|
67
|
+
if (bindings && ts.isNamedImports(bindings)) {
|
|
68
|
+
const importedNames = new Set(bindings.elements.map(element => (element.propertyName ?? element.name).text));
|
|
69
|
+
const missingNames = names.filter(name => !importedNames.has(name));
|
|
70
|
+
if (missingNames.length === 0)
|
|
71
|
+
return source;
|
|
72
|
+
const lastElement = bindings.elements[bindings.elements.length - 1];
|
|
73
|
+
if (lastElement)
|
|
74
|
+
return applyEdits(source, [{ start: lastElement.getEnd(), end: lastElement.getEnd(), text: `, ${missingNames.join(", ")}` }]);
|
|
75
|
+
}
|
|
76
|
+
const lastImportEnd = imports.length > 0 ? imports[imports.length - 1].getEnd() : 0;
|
|
77
|
+
return applyEdits(source, [{ start: lastImportEnd, end: lastImportEnd, text: `\nimport { ${names.join(", ")} } from "terse-sdk"` }]);
|
|
78
|
+
}
|
|
79
|
+
function applyEdits(source, edits) {
|
|
80
|
+
let code = source;
|
|
81
|
+
for (const edit of [...edits].sort((a, b) => b.start - a.start)) {
|
|
82
|
+
code = code.slice(0, edit.start) + edit.text + code.slice(edit.end);
|
|
125
83
|
}
|
|
126
|
-
return
|
|
84
|
+
return code;
|
|
127
85
|
}
|
|
128
86
|
//# sourceMappingURL=jobMacro.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jobMacro.js","sourceRoot":"","sources":["../../../src/providers/typescript/jobMacro.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"jobMacro.js","sourceRoot":"","sources":["../../../src/providers/typescript/jobMacro.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type PrepareJobSourcesParams = {
|
|
2
|
+
readonly cwd: string;
|
|
3
|
+
readonly entryFile: string;
|
|
4
|
+
};
|
|
5
|
+
/** Copies and macro-transforms project sources for direct loading through tsx. */
|
|
6
|
+
export declare function prepareJobSources({ cwd, entryFile }: PrepareJobSourcesParams): string;
|
|
7
|
+
//# sourceMappingURL=jobSources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobSources.d.ts","sourceRoot":"","sources":["../../../src/providers/typescript/jobSources.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,uBAAuB,GAAG;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC7B,CAAA;AAED,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,uBAAuB,GAAG,MAAM,CAiBrF"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { transformJobSource } from "./jobMacro.js";
|
|
5
|
+
/** Copies and macro-transforms project sources for direct loading through tsx. */
|
|
6
|
+
export function prepareJobSources({ cwd, entryFile }) {
|
|
7
|
+
const sourceDirectory = path.join(cwd, "src");
|
|
8
|
+
const runtimeDirectory = path.join(cwd, ".terse", "runtime");
|
|
9
|
+
const preparedSourceDirectory = path.join(runtimeDirectory, "src");
|
|
10
|
+
fs.rmSync(runtimeDirectory, { recursive: true, force: true });
|
|
11
|
+
fs.mkdirSync(runtimeDirectory, { recursive: true });
|
|
12
|
+
fs.cpSync(sourceDirectory, preparedSourceDirectory, { recursive: true });
|
|
13
|
+
const ts = loadTypescript(cwd);
|
|
14
|
+
for (const file of findSourceFiles(preparedSourceDirectory)) {
|
|
15
|
+
const source = fs.readFileSync(file, "utf8");
|
|
16
|
+
const transformed = transformJobSource(ts, source, path.relative(cwd, file));
|
|
17
|
+
if (transformed.code !== source)
|
|
18
|
+
fs.writeFileSync(file, transformed.code);
|
|
19
|
+
}
|
|
20
|
+
return path.join(runtimeDirectory, entryFile);
|
|
21
|
+
}
|
|
22
|
+
function findSourceFiles(directory) {
|
|
23
|
+
const files = [];
|
|
24
|
+
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
|
|
25
|
+
const file = path.join(directory, entry.name);
|
|
26
|
+
if (entry.isDirectory())
|
|
27
|
+
files.push(...findSourceFiles(file));
|
|
28
|
+
else if (/\.(?:ts|tsx|mts|cts)$/.test(entry.name))
|
|
29
|
+
files.push(file);
|
|
30
|
+
}
|
|
31
|
+
return files;
|
|
32
|
+
}
|
|
33
|
+
function loadTypescript(cwd) {
|
|
34
|
+
try {
|
|
35
|
+
return createRequire(path.join(cwd, "package.json"))("typescript");
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
try {
|
|
39
|
+
return createRequire(import.meta.url)("typescript");
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
throw new Error("Durable execution needs TypeScript in your project. Run: npm install --save-dev typescript");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=jobSources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobSources.js","sourceRoot":"","sources":["../../../src/providers/typescript/jobSources.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAOlD,kFAAkF;AAClF,MAAM,UAAU,iBAAiB,CAAC,EAAE,GAAG,EAAE,SAAS,EAA2B;IACzE,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IAC7C,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAA;IAC5D,MAAM,uBAAuB,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAA;IAElE,EAAE,CAAC,MAAM,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IAC7D,EAAE,CAAC,SAAS,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACnD,EAAE,CAAC,MAAM,CAAC,eAAe,EAAE,uBAAuB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAExE,MAAM,EAAE,GAAG,cAAc,CAAC,GAAG,CAAC,CAAA;IAC9B,KAAK,MAAM,IAAI,IAAI,eAAe,CAAC,uBAAuB,CAAC,EAAE,CAAC;QAC1D,MAAM,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QAC5C,MAAM,WAAW,GAAG,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAA;QAC5E,IAAI,WAAW,CAAC,IAAI,KAAK,MAAM;YAAE,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,CAAA;IAC7E,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAA;AACjD,CAAC;AAED,SAAS,eAAe,CAAC,SAAiB;IACtC,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;QAC7C,IAAI,KAAK,CAAC,WAAW,EAAE;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,CAAA;aACxD,IAAI,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACvE,CAAC;IACD,OAAO,KAAK,CAAA;AAChB,CAAC;AAED,SAAS,cAAc,CAAC,GAAW;IAC/B,IAAI,CAAC;QACD,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC,YAAY,CAAC,CAAA;IACtE,CAAC;IAAC,MAAM,CAAC;QACL,IAAI,CAAC;YACD,OAAO,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,CAAA;QACvD,CAAC;QAAC,MAAM,CAAC;YACL,MAAM,IAAI,KAAK,CAAC,4FAA4F,CAAC,CAAA;QACjH,CAAC;IACL,CAAC;AACL,CAAC"}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import type { CreateJobParameters, SessionStreamEvent } from "terse-sdk";
|
|
2
2
|
import type { SerializedEvent } from "terse-types";
|
|
3
|
+
import type { SessionHandle } from "../../shared/sessionStream.js";
|
|
3
4
|
export type RunJobOptions = {
|
|
4
5
|
verbose?: boolean;
|
|
5
6
|
entryFile?: string;
|
|
6
7
|
projectId?: string;
|
|
7
8
|
onSessionEvent?: (event: SessionStreamEvent) => void;
|
|
8
9
|
pauseUiAround?: <T>(fn: () => Promise<T>) => Promise<T>;
|
|
10
|
+
/** A session stream the caller already opened, so its round trip overlaps loading the job. */
|
|
11
|
+
session?: Promise<SessionHandle>;
|
|
9
12
|
};
|
|
10
13
|
export type ResumeRunOptions = {
|
|
11
14
|
verbose?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JobRuntime.d.ts","sourceRoot":"","sources":["../../../../src/providers/typescript/runtimes/JobRuntime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD,MAAM,MAAM,aAAa,GAAG;IACxB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAA;IACpD,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"JobRuntime.d.ts","sourceRoot":"","sources":["../../../../src/providers/typescript/runtimes/JobRuntime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAElE,MAAM,MAAM,aAAa,GAAG;IACxB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAA;IACpD,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;IACvD,8FAA8F;IAC9F,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;CACnC,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;CAC1D,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,MAAM,WAAW,UAAU;IACvB,UAAU,CAAC,GAAG,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEvH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEhE,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACpG;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOxD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JobRuntime.js","sourceRoot":"","sources":["../../../../src/providers/typescript/runtimes/JobRuntime.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"JobRuntime.js","sourceRoot":"","sources":["../../../../src/providers/typescript/runtimes/JobRuntime.ts"],"names":[],"mappings":"AAiCA,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC5C,IAAI,KAAK,YAAY,KAAK;QAAE,OAAO,KAAK,CAAC,OAAO,CAAA;IAChD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACrC,OAAO,oBAAoB,CAAC,KAAK,CAAC,CAAA;IACtC,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;AACxB,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAa;IACvC,IAAI,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAChC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;IACxB,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"directJobRuntime.d.ts","sourceRoot":"","sources":["../../../../src/providers/typescript/runtimes/directJobRuntime.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,UAAU,EAAqB,MAAM,iBAAiB,CAAA;AAGpE,eAAO,MAAM,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"directJobRuntime.d.ts","sourceRoot":"","sources":["../../../../src/providers/typescript/runtimes/directJobRuntime.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,UAAU,EAAqB,MAAM,iBAAiB,CAAA;AAGpE,eAAO,MAAM,gBAAgB,EAAE,UA8C9B,CAAA"}
|
|
@@ -25,7 +25,7 @@ export const directJobRuntime = {
|
|
|
25
25
|
console.log(chalk.cyan(` Job "${job.name}" started`));
|
|
26
26
|
await job.onTrigger(inputEvent, state);
|
|
27
27
|
});
|
|
28
|
-
}, opts?.onSessionEvent);
|
|
28
|
+
}, opts?.onSessionEvent, opts?.session);
|
|
29
29
|
}
|
|
30
30
|
catch (error) {
|
|
31
31
|
if (error instanceof CliError)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"directJobRuntime.js","sourceRoot":"","sources":["../../../../src/providers/typescript/runtimes/directJobRuntime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAA;AAEjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAEhD,OAAO,EAAmB,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1C,MAAM,CAAC,MAAM,gBAAgB,GAAe;IACxC,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI;QACpC,MAAM,SAAS,GAAG,IAAI,EAAE,OAAO,IAAI,IAAI,CAAA;QACvC,MAAM,aAAa,GAAG,IAAI,EAAE,aAAa,IAAI,CAAC,KAAK,EAAC,EAAE,EAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAA;QAC/D,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAA;QACrC,MAAM,UAAU,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAA;QAE1C,IAAI,CAAC;YACD,MAAM,WAAW,CACb,MAAM,EACN,SAAS,EACT,aAAa,EACb,KAAK,EAAC,SAAS,EAAC,EAAE;gBACd,MAAM,iBAAiB,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,KAAK,IAAI,EAAE;oBAC7H,MAAM,KAAK,GAAG,uBAAuB,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAA;oBACvD,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;wBACvD,IAAI,SAAS;4BAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,GAAG,CAAC,IAAI,sCAAsC,CAAC,CAAC,CAAA;wBACjG,OAAM;oBACV,CAAC;oBACD,IAAI,SAAS;wBAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,IAAI,WAAW,CAAC,CAAC,CAAA;oBACrE,MAAM,GAAG,CAAC,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC,CAAA;gBAC1C,CAAC,CAAC,CAAA;YACN,CAAC,EACD,IAAI,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"directJobRuntime.js","sourceRoot":"","sources":["../../../../src/providers/typescript/runtimes/directJobRuntime.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"durableJobRuntime.d.ts","sourceRoot":"","sources":["../../../../src/providers/typescript/runtimes/durableJobRuntime.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"durableJobRuntime.d.ts","sourceRoot":"","sources":["../../../../src/providers/typescript/runtimes/durableJobRuntime.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,KAAK,UAAU,EAAkE,MAAM,iBAAiB,CAAA;AAGjH,eAAO,MAAM,iBAAiB,EAAE,UA0C/B,CAAA"}
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
+
import { FileJournalStore, Runtime } from "little-durable";
|
|
2
3
|
import path from "node:path";
|
|
3
|
-
import {
|
|
4
|
+
import { __fetchRegisteredDurableWorkflow, __inputRequestHook, fetchRegisteredJobs } from "terse-sdk";
|
|
5
|
+
import { runWithJobContext } from "terse-sdk/dist/runIdentity/jobContextStore.js";
|
|
6
|
+
import { ApiRoutes } from "terse-types";
|
|
7
|
+
import { fetchWithAuth, readRuntimeKeyOrBail } from "../../../api.js";
|
|
4
8
|
import { CliError } from "../../../cliError.js";
|
|
5
9
|
import { BACKEND_URL } from "../../../config.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { readRunStatus, resolveWorkflowRunId, rewindFailedRun } from "../rewindRun.js";
|
|
10
|
+
import { readProjectConfig } from "../../../projectConfig.js";
|
|
11
|
+
import { shouldRunTerseWorkflow } from "../terseWorkflow.js";
|
|
9
12
|
import { formatErrorDetail } from "./JobRuntime.js";
|
|
10
13
|
import { withSession } from "./session.js";
|
|
11
14
|
export const durableJobRuntime = {
|
|
12
15
|
async executeJob(job, runId, event, opts) {
|
|
16
|
+
if (!runId)
|
|
17
|
+
throw new CliError("durable_run_id_missing", "Durable execution requires a run ID.");
|
|
13
18
|
const isVerbose = opts?.verbose ?? true;
|
|
14
19
|
const pauseUiAround = opts?.pauseUiAround ?? (async (fn) => fn());
|
|
15
20
|
const apiKey = readRuntimeKeyOrBail();
|
|
@@ -17,23 +22,24 @@ export const durableJobRuntime = {
|
|
|
17
22
|
await withSession(apiKey, isVerbose, pauseUiAround, async (sessionId) => {
|
|
18
23
|
if (isVerbose)
|
|
19
24
|
console.log(chalk.cyan(` Job "${job.name}" started`));
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
if (!
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
const journalStore = createJournalStore();
|
|
26
|
+
const runtime = new Runtime({ journalStore });
|
|
27
|
+
const context = jobContext({ sessionId, runId, job, projectId: opts?.projectId });
|
|
28
|
+
const shouldRun = await shouldRunTerseWorkflow({ job, event, context });
|
|
29
|
+
if (!shouldRun)
|
|
30
|
+
return;
|
|
31
|
+
const workflow = __fetchRegisteredDurableWorkflow(job.name);
|
|
32
|
+
if (!workflow)
|
|
33
|
+
throw new Error(`No durable workflow was registered for job "${job.name}".`);
|
|
34
|
+
const outcome = await runWithJobContext(context, () => runtime.start(workflow, { runId, input: event }).waitForOutcome());
|
|
35
|
+
await handleOutcome({ runId, outcome, apiKey });
|
|
36
|
+
}, opts?.onSessionEvent, opts?.session);
|
|
27
37
|
}
|
|
28
38
|
catch (error) {
|
|
29
39
|
if (error instanceof CliError)
|
|
30
40
|
throw error;
|
|
31
41
|
throw new CliError("job_execution_failed", `Job "${job.name}" threw an error.`, { detail: formatErrorDetail(error) });
|
|
32
42
|
}
|
|
33
|
-
finally {
|
|
34
|
-
if (!isCliRunCommandEnabled())
|
|
35
|
-
await closeDurableRuntime();
|
|
36
|
-
}
|
|
37
43
|
},
|
|
38
44
|
async resumeRun(runId, opts) {
|
|
39
45
|
return driveResume(runId, opts);
|
|
@@ -46,31 +52,40 @@ async function driveResume(runId, opts, input) {
|
|
|
46
52
|
const isVerbose = opts?.verbose ?? true;
|
|
47
53
|
const pauseUiAround = opts?.pauseUiAround ?? (async (fn) => fn());
|
|
48
54
|
const apiKey = readRuntimeKeyOrBail();
|
|
49
|
-
const dataDir = resolveDataDir();
|
|
50
|
-
const workflowRunId = resolveWorkflowRunId(dataDir, runId);
|
|
51
|
-
const status = readRunStatus(dataDir, workflowRunId);
|
|
52
55
|
try {
|
|
53
|
-
await withSession(apiKey, isVerbose, pauseUiAround, async () => {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (input) {
|
|
64
|
-
await deliverInput(rt, input, isVerbose);
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
await rt.start();
|
|
68
|
-
}
|
|
69
|
-
if (isCliRunCommandEnabled())
|
|
70
|
-
return;
|
|
71
|
-
await rt.awaitRunResult(workflowRunId);
|
|
56
|
+
await withSession(apiKey, isVerbose, pauseUiAround, async (sessionId) => {
|
|
57
|
+
const journalStore = createJournalStore();
|
|
58
|
+
const runtime = new Runtime({ journalStore });
|
|
59
|
+
const run = await runtime.getRun({ runId });
|
|
60
|
+
const job = fetchRegisteredJobs().get(run.workflowName);
|
|
61
|
+
if (!job)
|
|
62
|
+
throw new Error(`No registered job matches durable workflow "${run.workflowName}".`);
|
|
63
|
+
const workflow = __fetchRegisteredDurableWorkflow(job.name);
|
|
64
|
+
if (!workflow)
|
|
65
|
+
throw new Error(`No durable workflow was registered for job "${job.name}".`);
|
|
72
66
|
if (isVerbose)
|
|
73
|
-
console.log(chalk.
|
|
67
|
+
console.log(chalk.cyan(` Resuming run ${runId}`));
|
|
68
|
+
const context = jobContext({ sessionId, runId, job, projectId: readProjectConfig()?.projectId });
|
|
69
|
+
const outcome = await runWithJobContext(context, async () => {
|
|
70
|
+
const suspension = await runtime.getSuspension({ runId });
|
|
71
|
+
if (input) {
|
|
72
|
+
if (!suspension || suspension.request.name !== __inputRequestHook.name) {
|
|
73
|
+
throw new Error(`No unresolved input wait with token "${input.token}" exists in run "${runId}".`);
|
|
74
|
+
}
|
|
75
|
+
const request = __inputRequestHook.request.safeParse(suspension.request.payload);
|
|
76
|
+
if (!request.success || request.data.token !== input.token) {
|
|
77
|
+
throw new Error(`No unresolved input wait with token "${input.token}" exists in run "${runId}".`);
|
|
78
|
+
}
|
|
79
|
+
const resolution = __inputRequestHook.resolution.parse(input.payload);
|
|
80
|
+
return runtime.resumeHook(__inputRequestHook, { runId, workflow, waitId: suspension.waitId, resolution }).waitForOutcome();
|
|
81
|
+
}
|
|
82
|
+
return suspension?.request.name === "timer"
|
|
83
|
+
? runtime.resumeTimer(workflow, { runId, waitId: suspension.waitId }).waitForOutcome()
|
|
84
|
+
: runtime.resume(workflow, { runId }).waitForOutcome();
|
|
85
|
+
});
|
|
86
|
+
await handleOutcome({ runId, outcome, apiKey });
|
|
87
|
+
if (isVerbose && outcome.status === "completed")
|
|
88
|
+
console.log(chalk.green(` Run ${runId} completed`));
|
|
74
89
|
});
|
|
75
90
|
}
|
|
76
91
|
catch (error) {
|
|
@@ -78,26 +93,55 @@ async function driveResume(runId, opts, input) {
|
|
|
78
93
|
throw error;
|
|
79
94
|
throw new CliError("run_resume_failed", `Run "${runId}" could not be resumed.`, { detail: formatErrorDetail(error) });
|
|
80
95
|
}
|
|
81
|
-
finally {
|
|
82
|
-
if (!isCliRunCommandEnabled())
|
|
83
|
-
await closeDurableRuntime();
|
|
84
|
-
}
|
|
85
96
|
}
|
|
86
|
-
function
|
|
87
|
-
return
|
|
97
|
+
function createJournalStore() {
|
|
98
|
+
return new FileJournalStore(resolveDataDirectory());
|
|
88
99
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
100
|
+
function resolveDataDirectory() {
|
|
101
|
+
return process.env.TERSE_JOURNAL_ROOT ?? path.join(process.cwd(), ".terse", "data");
|
|
102
|
+
}
|
|
103
|
+
function jobContext({ sessionId, runId, job, projectId }) {
|
|
104
|
+
return {
|
|
105
|
+
sessionId,
|
|
106
|
+
runId,
|
|
107
|
+
apiBaseUrl: BACKEND_URL,
|
|
108
|
+
jobName: job.name,
|
|
109
|
+
projectId
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
async function handleOutcome({ runId, outcome, apiKey }) {
|
|
113
|
+
if (outcome.status === "completed")
|
|
114
|
+
return;
|
|
115
|
+
if (outcome.status === "failed") {
|
|
116
|
+
const error = new Error(outcome.error.message);
|
|
117
|
+
error.name = outcome.error.name;
|
|
118
|
+
throw error;
|
|
96
119
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
120
|
+
const body = suspendRequest({ runId, suspension: outcome.suspension });
|
|
121
|
+
await fetchWithAuth(ApiRoutes.SDK.SUSPEND, apiKey, body, "POST");
|
|
122
|
+
}
|
|
123
|
+
function suspendRequest({ runId, suspension }) {
|
|
124
|
+
const payload = suspension.request.payload;
|
|
125
|
+
if (suspension.request.name === "timer") {
|
|
126
|
+
if (typeof payload !== "object" || payload === null || Array.isArray(payload) || typeof payload.wakeAt !== "string") {
|
|
127
|
+
throw new Error("Timer suspension has an invalid wakeAt.");
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
runId,
|
|
131
|
+
kind: "timer",
|
|
132
|
+
delaySeconds: Math.max(1, Math.ceil((Date.parse(payload.wakeAt) - Date.now()) / 1_000)),
|
|
133
|
+
idempotencyKey: suspension.waitId
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
if (suspension.request.name === __inputRequestHook.name) {
|
|
137
|
+
const input = __inputRequestHook.request.parse(payload);
|
|
138
|
+
return {
|
|
139
|
+
runId,
|
|
140
|
+
kind: "input",
|
|
141
|
+
hookToken: input.token,
|
|
142
|
+
idempotencyKey: suspension.waitId
|
|
143
|
+
};
|
|
101
144
|
}
|
|
145
|
+
throw new Error(`Terse does not know how to park hook "${suspension.request.name}".`);
|
|
102
146
|
}
|
|
103
147
|
//# sourceMappingURL=durableJobRuntime.js.map
|