@mastra/inngest 0.11.0 → 0.11.1
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/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +52 -0
- package/dist/_tsup-dts-rollup.d.cts +9 -13
- package/dist/_tsup-dts-rollup.d.ts +9 -13
- package/dist/index.cjs +106 -39
- package/dist/index.js +106 -39
- package/package.json +7 -7
- package/src/index.test.ts +257 -52
- package/src/index.ts +109 -39
package/dist/index.js
CHANGED
|
@@ -10,13 +10,17 @@ import { z } from 'zod';
|
|
|
10
10
|
// src/index.ts
|
|
11
11
|
function serve({ mastra, inngest }) {
|
|
12
12
|
const wfs = mastra.getWorkflows();
|
|
13
|
-
const functions =
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
const functions = Array.from(
|
|
14
|
+
new Set(
|
|
15
|
+
Object.values(wfs).flatMap((wf) => {
|
|
16
|
+
if (wf instanceof InngestWorkflow) {
|
|
17
|
+
wf.__registerMastra(mastra);
|
|
18
|
+
return wf.getFunctions();
|
|
19
|
+
}
|
|
20
|
+
return [];
|
|
21
|
+
})
|
|
22
|
+
)
|
|
23
|
+
);
|
|
20
24
|
return serve$1({
|
|
21
25
|
client: inngest,
|
|
22
26
|
functions
|
|
@@ -46,8 +50,14 @@ var InngestRun = class extends Run {
|
|
|
46
50
|
while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
|
|
47
51
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
48
52
|
runs = await this.getRuns(eventId);
|
|
49
|
-
if (runs?.[0]?.status === "Failed"
|
|
53
|
+
if (runs?.[0]?.status === "Failed") {
|
|
50
54
|
throw new Error(`Function run ${runs?.[0]?.status}`);
|
|
55
|
+
} else if (runs?.[0]?.status === "Cancelled") {
|
|
56
|
+
const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
|
|
57
|
+
workflowName: this.workflowId,
|
|
58
|
+
runId: this.runId
|
|
59
|
+
});
|
|
60
|
+
return { output: { result: { steps: snapshot?.context, status: "canceled" } } };
|
|
51
61
|
}
|
|
52
62
|
}
|
|
53
63
|
return runs?.[0];
|
|
@@ -58,6 +68,28 @@ var InngestRun = class extends Run {
|
|
|
58
68
|
data
|
|
59
69
|
});
|
|
60
70
|
}
|
|
71
|
+
async cancel() {
|
|
72
|
+
await this.inngest.send({
|
|
73
|
+
name: `cancel.workflow.${this.workflowId}`,
|
|
74
|
+
data: {
|
|
75
|
+
runId: this.runId
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
|
|
79
|
+
workflowName: this.workflowId,
|
|
80
|
+
runId: this.runId
|
|
81
|
+
});
|
|
82
|
+
if (snapshot) {
|
|
83
|
+
await this.#mastra?.storage?.persistWorkflowSnapshot({
|
|
84
|
+
workflowName: this.workflowId,
|
|
85
|
+
runId: this.runId,
|
|
86
|
+
snapshot: {
|
|
87
|
+
...snapshot,
|
|
88
|
+
status: "canceled"
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
61
93
|
async start({
|
|
62
94
|
inputData
|
|
63
95
|
}) {
|
|
@@ -91,7 +123,9 @@ var InngestRun = class extends Run {
|
|
|
91
123
|
if (result.status === "failed") {
|
|
92
124
|
result.error = new Error(result.error);
|
|
93
125
|
}
|
|
94
|
-
|
|
126
|
+
if (result.status !== "suspended") {
|
|
127
|
+
this.cleanup?.();
|
|
128
|
+
}
|
|
95
129
|
return result;
|
|
96
130
|
}
|
|
97
131
|
async resume(params) {
|
|
@@ -293,23 +327,26 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
293
327
|
this.inngest
|
|
294
328
|
);
|
|
295
329
|
this.runs.set(runIdToUse, run);
|
|
296
|
-
await this.
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
330
|
+
const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse);
|
|
331
|
+
if (!workflowSnapshotInStorage) {
|
|
332
|
+
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
333
|
+
workflowName: this.id,
|
|
300
334
|
runId: runIdToUse,
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
335
|
+
snapshot: {
|
|
336
|
+
runId: runIdToUse,
|
|
337
|
+
status: "pending",
|
|
338
|
+
value: {},
|
|
339
|
+
context: {},
|
|
340
|
+
activePaths: [],
|
|
341
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
342
|
+
suspendedPaths: {},
|
|
343
|
+
result: void 0,
|
|
344
|
+
error: void 0,
|
|
345
|
+
// @ts-ignore
|
|
346
|
+
timestamp: Date.now()
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
}
|
|
313
350
|
return run;
|
|
314
351
|
}
|
|
315
352
|
getFunction() {
|
|
@@ -317,8 +354,12 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
317
354
|
return this.function;
|
|
318
355
|
}
|
|
319
356
|
this.function = this.inngest.createFunction(
|
|
320
|
-
|
|
321
|
-
|
|
357
|
+
{
|
|
358
|
+
id: `workflow.${this.id}`,
|
|
359
|
+
// @ts-ignore
|
|
360
|
+
retries: this.retryConfig?.attempts ?? 0,
|
|
361
|
+
cancelOn: [{ event: `cancel.workflow.${this.id}` }]
|
|
362
|
+
},
|
|
322
363
|
{ event: `workflow.${this.id}` },
|
|
323
364
|
async ({ event, step, attempt, publish }) => {
|
|
324
365
|
let { inputData, runId, resume } = event.data;
|
|
@@ -360,7 +401,8 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
360
401
|
retryConfig: this.retryConfig,
|
|
361
402
|
runtimeContext: new RuntimeContext(),
|
|
362
403
|
// TODO
|
|
363
|
-
resume
|
|
404
|
+
resume,
|
|
405
|
+
abortController: new AbortController()
|
|
364
406
|
});
|
|
365
407
|
return { result, runId };
|
|
366
408
|
}
|
|
@@ -404,7 +446,7 @@ function createStep(params) {
|
|
|
404
446
|
outputSchema: z.object({
|
|
405
447
|
text: z.string()
|
|
406
448
|
}),
|
|
407
|
-
execute: async ({ inputData, [EMITTER_SYMBOL]: emitter, runtimeContext }) => {
|
|
449
|
+
execute: async ({ inputData, [EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort }) => {
|
|
408
450
|
let streamPromise = {};
|
|
409
451
|
streamPromise.promise = new Promise((resolve, reject) => {
|
|
410
452
|
streamPromise.resolve = resolve;
|
|
@@ -424,8 +466,12 @@ function createStep(params) {
|
|
|
424
466
|
runtimeContext,
|
|
425
467
|
onFinish: (result) => {
|
|
426
468
|
streamPromise.resolve(result.text);
|
|
427
|
-
}
|
|
469
|
+
},
|
|
470
|
+
abortSignal
|
|
428
471
|
});
|
|
472
|
+
if (abortSignal.aborted) {
|
|
473
|
+
return abort();
|
|
474
|
+
}
|
|
429
475
|
for await (const chunk of fullStream) {
|
|
430
476
|
switch (chunk.type) {
|
|
431
477
|
case "text-delta":
|
|
@@ -600,6 +646,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
600
646
|
resume,
|
|
601
647
|
prevOutput,
|
|
602
648
|
emitter,
|
|
649
|
+
abortController,
|
|
603
650
|
runtimeContext
|
|
604
651
|
}) {
|
|
605
652
|
return super.executeStep({
|
|
@@ -611,6 +658,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
611
658
|
resume,
|
|
612
659
|
prevOutput,
|
|
613
660
|
emitter,
|
|
661
|
+
abortController,
|
|
614
662
|
runtimeContext
|
|
615
663
|
});
|
|
616
664
|
}
|
|
@@ -634,6 +682,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
634
682
|
resume,
|
|
635
683
|
prevOutput,
|
|
636
684
|
emitter,
|
|
685
|
+
abortController,
|
|
637
686
|
runtimeContext
|
|
638
687
|
}) {
|
|
639
688
|
const startedAt = await this.inngestStep.run(
|
|
@@ -664,7 +713,8 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
664
713
|
await emitter.emit("watch-v2", {
|
|
665
714
|
type: "step-start",
|
|
666
715
|
payload: {
|
|
667
|
-
id: step.id
|
|
716
|
+
id: step.id,
|
|
717
|
+
status: "running"
|
|
668
718
|
}
|
|
669
719
|
});
|
|
670
720
|
return startedAt2;
|
|
@@ -732,7 +782,9 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
732
782
|
type: "step-result",
|
|
733
783
|
payload: {
|
|
734
784
|
id: step.id,
|
|
735
|
-
status: "failed"
|
|
785
|
+
status: "failed",
|
|
786
|
+
error: result?.error,
|
|
787
|
+
payload: prevOutput
|
|
736
788
|
}
|
|
737
789
|
});
|
|
738
790
|
return { executionContext, result: { status: "failed", error: result?.error } };
|
|
@@ -764,7 +816,8 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
764
816
|
await emitter.emit("watch-v2", {
|
|
765
817
|
type: "step-suspended",
|
|
766
818
|
payload: {
|
|
767
|
-
id: step.id
|
|
819
|
+
id: step.id,
|
|
820
|
+
status: "suspended"
|
|
768
821
|
}
|
|
769
822
|
});
|
|
770
823
|
return {
|
|
@@ -817,6 +870,14 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
817
870
|
},
|
|
818
871
|
eventTimestamp: Date.now()
|
|
819
872
|
});
|
|
873
|
+
await emitter.emit("watch-v2", {
|
|
874
|
+
type: "step-result",
|
|
875
|
+
payload: {
|
|
876
|
+
id: step.id,
|
|
877
|
+
status: "success",
|
|
878
|
+
output: result?.result
|
|
879
|
+
}
|
|
880
|
+
});
|
|
820
881
|
await emitter.emit("watch-v2", {
|
|
821
882
|
type: "step-finish",
|
|
822
883
|
payload: {
|
|
@@ -865,7 +926,8 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
865
926
|
[EMITTER_SYMBOL]: emitter,
|
|
866
927
|
engine: {
|
|
867
928
|
step: this.inngestStep
|
|
868
|
-
}
|
|
929
|
+
},
|
|
930
|
+
abortSignal: abortController.signal
|
|
869
931
|
});
|
|
870
932
|
const endedAt = Date.now();
|
|
871
933
|
execResults = {
|
|
@@ -927,8 +989,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
927
989
|
type: "step-suspended",
|
|
928
990
|
payload: {
|
|
929
991
|
id: step.id,
|
|
930
|
-
|
|
931
|
-
output: execResults.status === "success" ? execResults?.output : void 0
|
|
992
|
+
...execResults
|
|
932
993
|
}
|
|
933
994
|
});
|
|
934
995
|
} else {
|
|
@@ -936,8 +997,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
936
997
|
type: "step-result",
|
|
937
998
|
payload: {
|
|
938
999
|
id: step.id,
|
|
939
|
-
|
|
940
|
-
output: execResults.status === "success" ? execResults?.output : void 0
|
|
1000
|
+
...execResults
|
|
941
1001
|
}
|
|
942
1002
|
});
|
|
943
1003
|
await emitter.emit("watch-v2", {
|
|
@@ -998,6 +1058,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
998
1058
|
resume,
|
|
999
1059
|
executionContext,
|
|
1000
1060
|
emitter,
|
|
1061
|
+
abortController,
|
|
1001
1062
|
runtimeContext
|
|
1002
1063
|
}) {
|
|
1003
1064
|
let execResults;
|
|
@@ -1009,6 +1070,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1009
1070
|
runId,
|
|
1010
1071
|
mastra: this.mastra,
|
|
1011
1072
|
runtimeContext,
|
|
1073
|
+
runCount: -1,
|
|
1012
1074
|
inputData: prevOutput,
|
|
1013
1075
|
getInitData: () => stepResults?.input,
|
|
1014
1076
|
getStepResult: (step) => {
|
|
@@ -1026,10 +1088,14 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1026
1088
|
},
|
|
1027
1089
|
bail: () => {
|
|
1028
1090
|
},
|
|
1091
|
+
abort: () => {
|
|
1092
|
+
abortController.abort();
|
|
1093
|
+
},
|
|
1029
1094
|
[EMITTER_SYMBOL]: emitter,
|
|
1030
1095
|
engine: {
|
|
1031
1096
|
step: this.inngestStep
|
|
1032
|
-
}
|
|
1097
|
+
},
|
|
1098
|
+
abortSignal: abortController.signal
|
|
1033
1099
|
});
|
|
1034
1100
|
return result ? index : null;
|
|
1035
1101
|
} catch (e) {
|
|
@@ -1058,6 +1124,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1058
1124
|
executionSpan: executionContext.executionSpan
|
|
1059
1125
|
},
|
|
1060
1126
|
emitter,
|
|
1127
|
+
abortController,
|
|
1061
1128
|
runtimeContext
|
|
1062
1129
|
})
|
|
1063
1130
|
)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/inngest",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"description": "Mastra Inngest integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -33,17 +33,17 @@
|
|
|
33
33
|
"eslint": "^9.29.0",
|
|
34
34
|
"execa": "^9.6.0",
|
|
35
35
|
"get-port": "7.1.0",
|
|
36
|
-
"hono": "^4.
|
|
36
|
+
"hono": "^4.8.3",
|
|
37
37
|
"tsup": "^8.5.0",
|
|
38
38
|
"typescript": "^5.8.3",
|
|
39
|
-
"vitest": "^2.
|
|
40
|
-
"@internal/lint": "0.0.
|
|
41
|
-
"@mastra/core": "0.10.7",
|
|
39
|
+
"vitest": "^3.2.4",
|
|
40
|
+
"@internal/lint": "0.0.16",
|
|
42
41
|
"@mastra/libsql": "0.11.0",
|
|
43
|
-
"@mastra/deployer": "0.10.
|
|
42
|
+
"@mastra/deployer": "0.10.9",
|
|
43
|
+
"@mastra/core": "0.10.9"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
|
-
"@mastra/core": ">=0.10.
|
|
46
|
+
"@mastra/core": ">=0.10.9-0 <0.11.0-0"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
49
49
|
"build": "tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting",
|
package/src/index.test.ts
CHANGED
|
@@ -732,6 +732,203 @@ describe('MastraInngestWorkflow', () => {
|
|
|
732
732
|
});
|
|
733
733
|
});
|
|
734
734
|
|
|
735
|
+
describe('abort', () => {
|
|
736
|
+
it('should be able to abort workflow execution in between steps', async ctx => {
|
|
737
|
+
const inngest = new Inngest({
|
|
738
|
+
id: 'mastra',
|
|
739
|
+
baseUrl: `http://localhost:${(ctx as any).inngestPort}`,
|
|
740
|
+
middleware: [realtimeMiddleware()],
|
|
741
|
+
});
|
|
742
|
+
|
|
743
|
+
const { createWorkflow, createStep } = init(inngest);
|
|
744
|
+
|
|
745
|
+
const step1 = createStep({
|
|
746
|
+
id: 'step1',
|
|
747
|
+
execute: async ({ inputData }) => {
|
|
748
|
+
return { result: 'step1: ' + inputData.value };
|
|
749
|
+
},
|
|
750
|
+
inputSchema: z.object({ value: z.string() }),
|
|
751
|
+
outputSchema: z.object({ result: z.string() }),
|
|
752
|
+
});
|
|
753
|
+
const step2 = createStep({
|
|
754
|
+
id: 'step2',
|
|
755
|
+
execute: async ({ inputData }) => {
|
|
756
|
+
return { result: 'step2: ' + inputData.result };
|
|
757
|
+
},
|
|
758
|
+
inputSchema: z.object({ result: z.string() }),
|
|
759
|
+
outputSchema: z.object({ result: z.string() }),
|
|
760
|
+
});
|
|
761
|
+
|
|
762
|
+
const workflow = createWorkflow({
|
|
763
|
+
id: 'test-workflow',
|
|
764
|
+
inputSchema: z.object({}),
|
|
765
|
+
outputSchema: z.object({
|
|
766
|
+
result: z.string(),
|
|
767
|
+
}),
|
|
768
|
+
steps: [step1, step2],
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
workflow.then(step1).sleep(2000).then(step2).commit();
|
|
772
|
+
|
|
773
|
+
const mastra = new Mastra({
|
|
774
|
+
storage: new DefaultStorage({
|
|
775
|
+
url: ':memory:',
|
|
776
|
+
}),
|
|
777
|
+
workflows: {
|
|
778
|
+
'test-workflow': workflow,
|
|
779
|
+
},
|
|
780
|
+
server: {
|
|
781
|
+
apiRoutes: [
|
|
782
|
+
{
|
|
783
|
+
path: '/inngest/api',
|
|
784
|
+
method: 'ALL',
|
|
785
|
+
createHandler: async ({ mastra }) => inngestServe({ mastra, inngest }),
|
|
786
|
+
},
|
|
787
|
+
],
|
|
788
|
+
},
|
|
789
|
+
});
|
|
790
|
+
|
|
791
|
+
const app = await createHonoServer(mastra);
|
|
792
|
+
|
|
793
|
+
const srv = serve({
|
|
794
|
+
fetch: app.fetch,
|
|
795
|
+
port: (ctx as any).handlerPort,
|
|
796
|
+
});
|
|
797
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
798
|
+
|
|
799
|
+
const run = await workflow.createRunAsync();
|
|
800
|
+
const p = run.start({ inputData: { value: 'test' } });
|
|
801
|
+
|
|
802
|
+
setTimeout(() => {
|
|
803
|
+
run.cancel();
|
|
804
|
+
}, 1000);
|
|
805
|
+
|
|
806
|
+
const result = await p;
|
|
807
|
+
|
|
808
|
+
srv.close();
|
|
809
|
+
|
|
810
|
+
expect(result.status).toBe('canceled');
|
|
811
|
+
expect(result.steps['step1']).toEqual({
|
|
812
|
+
status: 'success',
|
|
813
|
+
output: { result: 'step1: test' },
|
|
814
|
+
payload: { value: 'test' },
|
|
815
|
+
startedAt: expect.any(Number),
|
|
816
|
+
endedAt: expect.any(Number),
|
|
817
|
+
});
|
|
818
|
+
|
|
819
|
+
expect(result.steps['step2']).toBeUndefined();
|
|
820
|
+
});
|
|
821
|
+
|
|
822
|
+
it('should be able to abort workflow execution during a step', async ctx => {
|
|
823
|
+
const inngest = new Inngest({
|
|
824
|
+
id: 'mastra',
|
|
825
|
+
baseUrl: `http://localhost:${(ctx as any).inngestPort}`,
|
|
826
|
+
middleware: [realtimeMiddleware()],
|
|
827
|
+
});
|
|
828
|
+
|
|
829
|
+
const { createWorkflow, createStep } = init(inngest);
|
|
830
|
+
|
|
831
|
+
const step1 = createStep({
|
|
832
|
+
id: 'step1',
|
|
833
|
+
execute: async ({ inputData }) => {
|
|
834
|
+
return { result: 'step1: ' + inputData.value };
|
|
835
|
+
},
|
|
836
|
+
inputSchema: z.object({ value: z.string() }),
|
|
837
|
+
outputSchema: z.object({ result: z.string() }),
|
|
838
|
+
});
|
|
839
|
+
const step2 = createStep({
|
|
840
|
+
id: 'step2',
|
|
841
|
+
execute: async ({ inputData, abortSignal, abort }) => {
|
|
842
|
+
console.log('abort signal', abortSignal);
|
|
843
|
+
const timeout: Promise<string> = new Promise((resolve, _reject) => {
|
|
844
|
+
const ref = setTimeout(() => {
|
|
845
|
+
resolve('step2: ' + inputData.result);
|
|
846
|
+
}, 5000);
|
|
847
|
+
|
|
848
|
+
abortSignal.addEventListener('abort', () => {
|
|
849
|
+
resolve('');
|
|
850
|
+
clearTimeout(ref);
|
|
851
|
+
});
|
|
852
|
+
});
|
|
853
|
+
|
|
854
|
+
const result = await timeout;
|
|
855
|
+
if (abortSignal.aborted) {
|
|
856
|
+
return abort();
|
|
857
|
+
}
|
|
858
|
+
return { result };
|
|
859
|
+
},
|
|
860
|
+
inputSchema: z.object({ result: z.string() }),
|
|
861
|
+
outputSchema: z.object({ result: z.string() }),
|
|
862
|
+
});
|
|
863
|
+
|
|
864
|
+
const workflow = createWorkflow({
|
|
865
|
+
id: 'test-workflow',
|
|
866
|
+
inputSchema: z.object({}),
|
|
867
|
+
outputSchema: z.object({
|
|
868
|
+
result: z.string(),
|
|
869
|
+
}),
|
|
870
|
+
steps: [step1, step2],
|
|
871
|
+
});
|
|
872
|
+
|
|
873
|
+
workflow.then(step1).then(step2).commit();
|
|
874
|
+
|
|
875
|
+
const mastra = new Mastra({
|
|
876
|
+
storage: new DefaultStorage({
|
|
877
|
+
url: ':memory:',
|
|
878
|
+
}),
|
|
879
|
+
workflows: {
|
|
880
|
+
'test-workflow': workflow,
|
|
881
|
+
},
|
|
882
|
+
server: {
|
|
883
|
+
apiRoutes: [
|
|
884
|
+
{
|
|
885
|
+
path: '/inngest/api',
|
|
886
|
+
method: 'ALL',
|
|
887
|
+
createHandler: async ({ mastra }) => inngestServe({ mastra, inngest }),
|
|
888
|
+
},
|
|
889
|
+
],
|
|
890
|
+
},
|
|
891
|
+
});
|
|
892
|
+
|
|
893
|
+
const app = await createHonoServer(mastra);
|
|
894
|
+
|
|
895
|
+
const srv = serve({
|
|
896
|
+
fetch: app.fetch,
|
|
897
|
+
port: (ctx as any).handlerPort,
|
|
898
|
+
});
|
|
899
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
900
|
+
|
|
901
|
+
const run = await workflow.createRunAsync();
|
|
902
|
+
const p = run.start({ inputData: { value: 'test' } });
|
|
903
|
+
|
|
904
|
+
setTimeout(() => {
|
|
905
|
+
run.cancel();
|
|
906
|
+
}, 1000);
|
|
907
|
+
|
|
908
|
+
const result = await p;
|
|
909
|
+
console.log('result', result);
|
|
910
|
+
|
|
911
|
+
srv.close();
|
|
912
|
+
|
|
913
|
+
expect(result.status).toBe('canceled');
|
|
914
|
+
expect(result.steps['step1']).toEqual({
|
|
915
|
+
status: 'success',
|
|
916
|
+
output: { result: 'step1: test' },
|
|
917
|
+
payload: { value: 'test' },
|
|
918
|
+
startedAt: expect.any(Number),
|
|
919
|
+
endedAt: expect.any(Number),
|
|
920
|
+
});
|
|
921
|
+
|
|
922
|
+
// expect(result.steps['step2']).toEqual({
|
|
923
|
+
// status: 'canceled',
|
|
924
|
+
// payload: { result: 'step1: test' },
|
|
925
|
+
// output: undefined,
|
|
926
|
+
// startedAt: expect.any(Number),
|
|
927
|
+
// endedAt: expect.any(Number),
|
|
928
|
+
// });
|
|
929
|
+
});
|
|
930
|
+
});
|
|
931
|
+
|
|
735
932
|
describe('Variable Resolution', () => {
|
|
736
933
|
it('should resolve trigger data', async ctx => {
|
|
737
934
|
const inngest = new Inngest({
|
|
@@ -5965,68 +6162,76 @@ describe('MastraInngestWorkflow', () => {
|
|
|
5965
6162
|
srv.close();
|
|
5966
6163
|
|
|
5967
6164
|
expect(watchData.length).toBe(8);
|
|
5968
|
-
expect(watchData).
|
|
5969
|
-
|
|
5970
|
-
{
|
|
5971
|
-
|
|
5972
|
-
"runId": "test-run-id",
|
|
5973
|
-
},
|
|
5974
|
-
"type": "start",
|
|
6165
|
+
expect(watchData).toMatchObject([
|
|
6166
|
+
{
|
|
6167
|
+
payload: {
|
|
6168
|
+
runId: 'test-run-id',
|
|
5975
6169
|
},
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
6170
|
+
type: 'start',
|
|
6171
|
+
},
|
|
6172
|
+
{
|
|
6173
|
+
payload: {
|
|
6174
|
+
id: 'step1',
|
|
6175
|
+
status: 'running',
|
|
5981
6176
|
},
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
|
|
6177
|
+
type: 'step-start',
|
|
6178
|
+
},
|
|
6179
|
+
{
|
|
6180
|
+
payload: {
|
|
6181
|
+
id: 'step1',
|
|
6182
|
+
endedAt: expect.any(Number),
|
|
6183
|
+
startedAt: expect.any(Number),
|
|
6184
|
+
payload: {},
|
|
6185
|
+
output: {
|
|
6186
|
+
result: 'success1',
|
|
5989
6187
|
},
|
|
5990
|
-
|
|
6188
|
+
status: 'success',
|
|
5991
6189
|
},
|
|
5992
|
-
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
6190
|
+
type: 'step-result',
|
|
6191
|
+
},
|
|
6192
|
+
{
|
|
6193
|
+
payload: {
|
|
6194
|
+
id: 'step1',
|
|
6195
|
+
metadata: {},
|
|
5998
6196
|
},
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6197
|
+
type: 'step-finish',
|
|
6198
|
+
},
|
|
6199
|
+
{
|
|
6200
|
+
payload: {
|
|
6201
|
+
id: 'step2',
|
|
6202
|
+
status: 'running',
|
|
6004
6203
|
},
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
|
|
6204
|
+
type: 'step-start',
|
|
6205
|
+
},
|
|
6206
|
+
{
|
|
6207
|
+
payload: {
|
|
6208
|
+
id: 'step2',
|
|
6209
|
+
endedAt: expect.any(Number),
|
|
6210
|
+
startedAt: expect.any(Number),
|
|
6211
|
+
payload: {
|
|
6212
|
+
result: 'success1',
|
|
6012
6213
|
},
|
|
6013
|
-
|
|
6014
|
-
|
|
6015
|
-
{
|
|
6016
|
-
"payload": {
|
|
6017
|
-
"id": "step2",
|
|
6018
|
-
"metadata": {},
|
|
6214
|
+
output: {
|
|
6215
|
+
result: 'success2',
|
|
6019
6216
|
},
|
|
6020
|
-
|
|
6217
|
+
status: 'success',
|
|
6021
6218
|
},
|
|
6022
|
-
|
|
6023
|
-
|
|
6024
|
-
|
|
6025
|
-
|
|
6026
|
-
|
|
6219
|
+
type: 'step-result',
|
|
6220
|
+
},
|
|
6221
|
+
{
|
|
6222
|
+
payload: {
|
|
6223
|
+
id: 'step2',
|
|
6224
|
+
metadata: {},
|
|
6027
6225
|
},
|
|
6028
|
-
|
|
6029
|
-
|
|
6226
|
+
type: 'step-finish',
|
|
6227
|
+
},
|
|
6228
|
+
{
|
|
6229
|
+
payload: {
|
|
6230
|
+
runId: 'test-run-id',
|
|
6231
|
+
},
|
|
6232
|
+
type: 'finish',
|
|
6233
|
+
},
|
|
6234
|
+
]);
|
|
6030
6235
|
// Verify execution completed successfully
|
|
6031
6236
|
expect(executionResult.steps.step1).toMatchObject({
|
|
6032
6237
|
status: 'success',
|