@ai.ntellect/core 0.6.21 → 0.7.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/.mocharc.json +2 -1
- package/README.md +61 -85
- package/graph/controller.ts +1 -1
- package/graph/event-manager.ts +288 -0
- package/graph/index.ts +153 -367
- package/graph/logger.ts +70 -0
- package/graph/node.ts +398 -0
- package/graph/observer.ts +361 -0
- package/interfaces/index.ts +102 -1
- package/modules/agenda/index.ts +3 -16
- package/package.json +10 -5
- package/test/graph/index.test.ts +244 -113
- package/test/graph/observer.test.ts +398 -0
- package/test/modules/agenda/node-cron.test.ts +37 -16
- package/test/modules/memory/adapters/in-memory.test.ts +2 -2
- package/test/modules/memory/adapters/meilisearch.test.ts +28 -24
- package/test/modules/memory/base.test.ts +3 -3
- package/tsconfig.json +4 -2
- package/types/index.ts +23 -2
- package/dist/graph/controller.js +0 -72
- package/dist/graph/index.js +0 -501
- package/dist/index.js +0 -41
- package/dist/interfaces/index.js +0 -17
- package/dist/modules/agenda/adapters/node-cron/index.js +0 -29
- package/dist/modules/agenda/index.js +0 -140
- package/dist/modules/embedding/adapters/ai/index.js +0 -57
- package/dist/modules/embedding/index.js +0 -59
- package/dist/modules/memory/adapters/in-memory/index.js +0 -210
- package/dist/modules/memory/adapters/meilisearch/index.js +0 -320
- package/dist/modules/memory/adapters/redis/index.js +0 -158
- package/dist/modules/memory/index.js +0 -103
- package/dist/types/index.js +0 -2
- package/dist/utils/generate-action-schema.js +0 -43
- package/dist/utils/header-builder.js +0 -34
- package/test/modules/embedding/ai.test.ts +0 -78
- package/test/modules/memory/adapters/redis.test.ts +0 -169
- package/test/services/agenda.test.ts +0 -279
package/test/graph/index.test.ts
CHANGED
@@ -2,43 +2,63 @@ import { expect } from "chai";
|
|
2
2
|
import EventEmitter from "events";
|
3
3
|
import sinon from "sinon";
|
4
4
|
import { z } from "zod";
|
5
|
-
import {
|
5
|
+
import { GraphFlowController } from "../../graph/controller";
|
6
6
|
import { GraphFlow } from "../../graph/index";
|
7
|
-
import { GraphDefinition, Node } from "../../types";
|
7
|
+
import { GraphContext, GraphDefinition, Node } from "../../types";
|
8
8
|
|
9
9
|
/**
|
10
|
-
*
|
10
|
+
* Test schema definition using Zod for graph context validation
|
11
|
+
* Defines a schema with:
|
12
|
+
* - value: numeric value for tracking state changes
|
13
|
+
* - eventPayload: optional object containing transaction metadata
|
11
14
|
*/
|
12
15
|
const TestSchema = z.object({
|
13
16
|
value: z.number().default(0),
|
17
|
+
eventPayload: z
|
18
|
+
.object({
|
19
|
+
transactionId: z.string().optional(),
|
20
|
+
status: z.string().optional(),
|
21
|
+
})
|
22
|
+
.optional(),
|
14
23
|
});
|
15
24
|
|
16
|
-
/**
|
17
|
-
* ✅ Define the schema type for TypeScript inference.
|
18
|
-
*/
|
19
25
|
type TestSchema = typeof TestSchema;
|
20
26
|
|
27
|
+
/**
|
28
|
+
* Test suite for the Graph Flow implementation
|
29
|
+
* This suite validates the core functionality of the graph-based workflow system:
|
30
|
+
* - Node execution and state management through context
|
31
|
+
* - Event handling (emission, correlation, waiting)
|
32
|
+
* - Error handling and retry mechanisms
|
33
|
+
* - Input/Output validation using Zod schemas
|
34
|
+
* - Complex workflows with multiple branches and conditions
|
35
|
+
* - Parallel and sequential execution patterns
|
36
|
+
*
|
37
|
+
* The tests use a simple numeric value-based context to demonstrate state changes
|
38
|
+
* and a transaction-based event payload for testing event correlation.
|
39
|
+
*/
|
21
40
|
describe("Graph", function () {
|
22
41
|
let graph: GraphFlow<TestSchema>;
|
23
42
|
let eventEmitter: EventEmitter;
|
24
43
|
|
25
44
|
beforeEach(() => {
|
26
45
|
eventEmitter = new EventEmitter();
|
27
|
-
graph = new GraphFlow(
|
28
|
-
"TestGraph",
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
eventEmitter: eventEmitter,
|
35
|
-
},
|
36
|
-
{ verbose: true }
|
37
|
-
);
|
46
|
+
graph = new GraphFlow("TestGraph", {
|
47
|
+
name: "TestGraph",
|
48
|
+
nodes: [],
|
49
|
+
context: { value: 0 },
|
50
|
+
schema: TestSchema,
|
51
|
+
eventEmitter: eventEmitter,
|
52
|
+
});
|
38
53
|
});
|
39
54
|
|
40
55
|
/**
|
41
|
-
*
|
56
|
+
* Tests basic node execution and context update functionality
|
57
|
+
* Validates that:
|
58
|
+
* - A node can be added to the graph
|
59
|
+
* - The node's execute function is called
|
60
|
+
* - The context is properly updated
|
61
|
+
* - The updated context is accessible after execution
|
42
62
|
*/
|
43
63
|
it("should execute a simple node and update the context", async function () {
|
44
64
|
const simpleNode: Node<TestSchema> = {
|
@@ -57,7 +77,11 @@ describe("Graph", function () {
|
|
57
77
|
});
|
58
78
|
|
59
79
|
/**
|
60
|
-
*
|
80
|
+
* Tests event emission for node lifecycle events
|
81
|
+
* Validates that the graph properly emits events for:
|
82
|
+
* - Node execution start (nodeStarted)
|
83
|
+
* - Node execution completion (nodeCompleted)
|
84
|
+
* This is crucial for monitoring and debugging workflow execution
|
61
85
|
*/
|
62
86
|
it("should trigger `nodeStarted` and `nodeCompleted` events", async function () {
|
63
87
|
const nodeStartedSpy = sinon.spy();
|
@@ -82,7 +106,12 @@ describe("Graph", function () {
|
|
82
106
|
});
|
83
107
|
|
84
108
|
/**
|
85
|
-
*
|
109
|
+
* Tests error handling and error event emission
|
110
|
+
* Validates that:
|
111
|
+
* - Errors in node execution are properly caught
|
112
|
+
* - The nodeError event is emitted
|
113
|
+
* - The error message is preserved
|
114
|
+
* This ensures robust error handling in the workflow
|
86
115
|
*/
|
87
116
|
it("should handle errors and trigger `nodeError` event", async function () {
|
88
117
|
const errorNode: Node<TestSchema> = {
|
@@ -107,7 +136,12 @@ describe("Graph", function () {
|
|
107
136
|
});
|
108
137
|
|
109
138
|
/**
|
110
|
-
*
|
139
|
+
* Tests context validation using Zod schema
|
140
|
+
* Validates that:
|
141
|
+
* - Invalid context values are rejected
|
142
|
+
* - Proper error messages are generated
|
143
|
+
* - Type safety is maintained during execution
|
144
|
+
* This ensures data integrity throughout the workflow
|
111
145
|
*/
|
112
146
|
it("should validate context with Zod", async function () {
|
113
147
|
const invalidContext = { value: "invalid_string" };
|
@@ -131,7 +165,12 @@ describe("Graph", function () {
|
|
131
165
|
});
|
132
166
|
|
133
167
|
/**
|
134
|
-
*
|
168
|
+
* Tests node execution with input/output validation
|
169
|
+
* Demonstrates:
|
170
|
+
* - Input parameter validation
|
171
|
+
* - Output state validation
|
172
|
+
* - Integration between node execution and validation
|
173
|
+
* Ensures type safety and data consistency in node interactions
|
135
174
|
*/
|
136
175
|
it("should execute a node with validated inputs and outputs", async function () {
|
137
176
|
const paramNode: Node<TestSchema, { increment: number }> = {
|
@@ -156,7 +195,12 @@ describe("Graph", function () {
|
|
156
195
|
});
|
157
196
|
|
158
197
|
/**
|
159
|
-
*
|
198
|
+
* Tests conditional node execution
|
199
|
+
* Validates that:
|
200
|
+
* - Nodes can have conditional execution logic
|
201
|
+
* - Conditions are evaluated against current context
|
202
|
+
* - Nodes are skipped when conditions are not met
|
203
|
+
* This enables dynamic workflow paths based on state
|
160
204
|
*/
|
161
205
|
it("should not execute a node when condition is false", async function () {
|
162
206
|
const conditionalNode: Node<TestSchema> = {
|
@@ -176,7 +220,13 @@ describe("Graph", function () {
|
|
176
220
|
});
|
177
221
|
|
178
222
|
/**
|
179
|
-
*
|
223
|
+
* Tests node retry functionality
|
224
|
+
* Validates the retry mechanism:
|
225
|
+
* - Maximum attempt limits
|
226
|
+
* - Retry delays
|
227
|
+
* - Success after retry
|
228
|
+
* - Context preservation between attempts
|
229
|
+
* Essential for handling transient failures in workflows
|
180
230
|
*/
|
181
231
|
it("should retry a node execution when it fails", async function () {
|
182
232
|
let attemptCount = 0;
|
@@ -202,45 +252,7 @@ describe("Graph", function () {
|
|
202
252
|
});
|
203
253
|
|
204
254
|
/**
|
205
|
-
*
|
206
|
-
*/
|
207
|
-
it("should trigger a node execution from an event", async function () {
|
208
|
-
this.timeout(5000); // Ensure we have enough time to complete the test
|
209
|
-
|
210
|
-
const eventNode: Node<TestSchema> = {
|
211
|
-
name: "eventNode",
|
212
|
-
events: ["customEvent"],
|
213
|
-
execute: async (context) => {
|
214
|
-
context.value = (context.value ?? 0) + 1;
|
215
|
-
},
|
216
|
-
next: [],
|
217
|
-
};
|
218
|
-
|
219
|
-
graph.addNode(eventNode);
|
220
|
-
|
221
|
-
// Use a promise to ensure the event is properly handled
|
222
|
-
await new Promise<void>((resolve, reject) => {
|
223
|
-
const timeout = setTimeout(
|
224
|
-
() => reject(new Error("Event did not trigger")),
|
225
|
-
1500
|
226
|
-
);
|
227
|
-
|
228
|
-
graph.on("nodeCompleted", ({ name }) => {
|
229
|
-
if (name === "eventNode") {
|
230
|
-
clearTimeout(timeout);
|
231
|
-
resolve();
|
232
|
-
}
|
233
|
-
});
|
234
|
-
|
235
|
-
graph.emit("customEvent").catch(reject);
|
236
|
-
});
|
237
|
-
|
238
|
-
const context = graph.getContext();
|
239
|
-
expect(context.value).to.equal(1);
|
240
|
-
});
|
241
|
-
|
242
|
-
/**
|
243
|
-
* ✅ Ensure that removing a node works correctly.
|
255
|
+
* Tests node removal functionality
|
244
256
|
*/
|
245
257
|
it("should remove a node from the graph", function () {
|
246
258
|
const testNode: Node<TestSchema> = {
|
@@ -253,6 +265,9 @@ describe("Graph", function () {
|
|
253
265
|
expect(graph.getNodes().length).to.equal(0);
|
254
266
|
});
|
255
267
|
|
268
|
+
/**
|
269
|
+
* Tests graph reloading functionality
|
270
|
+
*/
|
256
271
|
it("should clear and reload the graph using `load`", function () {
|
257
272
|
const nodeA: Node<TestSchema> = {
|
258
273
|
name: "A",
|
@@ -277,7 +292,7 @@ describe("Graph", function () {
|
|
277
292
|
});
|
278
293
|
|
279
294
|
/**
|
280
|
-
*
|
295
|
+
* Tests input validation error handling
|
281
296
|
*/
|
282
297
|
it("should throw error when node input validation fails", async function () {
|
283
298
|
const nodeWithInput: Node<TestSchema, { amount: number }> = {
|
@@ -304,7 +319,7 @@ describe("Graph", function () {
|
|
304
319
|
});
|
305
320
|
|
306
321
|
/**
|
307
|
-
*
|
322
|
+
* Tests output validation error handling
|
308
323
|
*/
|
309
324
|
it("should throw error when node output validation fails", async function () {
|
310
325
|
const nodeWithOutput: Node<TestSchema> = {
|
@@ -331,7 +346,7 @@ describe("Graph", function () {
|
|
331
346
|
});
|
332
347
|
|
333
348
|
/**
|
334
|
-
*
|
349
|
+
* Tests successful input/output validation flow
|
335
350
|
*/
|
336
351
|
it("should successfully validate both inputs and outputs", async function () {
|
337
352
|
const validatedNode: Node<TestSchema, { increment: number }> = {
|
@@ -366,7 +381,7 @@ describe("Graph", function () {
|
|
366
381
|
});
|
367
382
|
|
368
383
|
/**
|
369
|
-
*
|
384
|
+
* Tests handling of missing required inputs
|
370
385
|
*/
|
371
386
|
it("should throw error when required inputs are missing", async function () {
|
372
387
|
const nodeWithRequiredInput: Node<TestSchema, { required: string }> = {
|
@@ -389,7 +404,13 @@ describe("Graph", function () {
|
|
389
404
|
});
|
390
405
|
|
391
406
|
/**
|
392
|
-
*
|
407
|
+
* Tests complex workflow execution with multiple branches
|
408
|
+
* Demonstrates:
|
409
|
+
* - Multiple execution paths
|
410
|
+
* - Node chaining
|
411
|
+
* - Parallel branch execution
|
412
|
+
* - Context accumulation across branches
|
413
|
+
* This validates the graph's ability to handle complex business processes
|
393
414
|
*/
|
394
415
|
it("should execute a complex workflow with multiple nodes and accumulate the value", async function () {
|
395
416
|
const nodeA: Node<TestSchema> = {
|
@@ -430,7 +451,7 @@ describe("Graph", function () {
|
|
430
451
|
});
|
431
452
|
|
432
453
|
/**
|
433
|
-
*
|
454
|
+
* Tests conditional branching in workflows
|
434
455
|
*/
|
435
456
|
it("should execute different branches based on conditions", async function () {
|
436
457
|
const startNode: Node<TestSchema> = {
|
@@ -459,20 +480,22 @@ describe("Graph", function () {
|
|
459
480
|
});
|
460
481
|
|
461
482
|
/**
|
462
|
-
*
|
483
|
+
* Tests parallel workflow execution using GraphController
|
484
|
+
* Validates:
|
485
|
+
* - Multiple graph execution in parallel
|
486
|
+
* - Independent context maintenance
|
487
|
+
* - Proper result aggregation
|
488
|
+
* - Concurrency control
|
489
|
+
* Essential for scaling workflow processing
|
463
490
|
*/
|
464
491
|
it("should handle parallel workflows using GraphController", async function () {
|
465
492
|
// Graph 1
|
466
|
-
const graph1 = new GraphFlow(
|
467
|
-
"Graph1",
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
schema: TestSchema,
|
473
|
-
},
|
474
|
-
{ verbose: true }
|
475
|
-
);
|
493
|
+
const graph1 = new GraphFlow("Graph1", {
|
494
|
+
name: "Graph1",
|
495
|
+
nodes: [],
|
496
|
+
context: { value: 0 },
|
497
|
+
schema: TestSchema,
|
498
|
+
});
|
476
499
|
|
477
500
|
const processNode1: Node<TestSchema> = {
|
478
501
|
name: "process1",
|
@@ -490,16 +513,12 @@ describe("Graph", function () {
|
|
490
513
|
};
|
491
514
|
|
492
515
|
// Graph 2
|
493
|
-
const graph2 = new GraphFlow(
|
494
|
-
"Graph2",
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
schema: TestSchema,
|
500
|
-
},
|
501
|
-
{ verbose: true }
|
502
|
-
);
|
516
|
+
const graph2 = new GraphFlow("Graph2", {
|
517
|
+
name: "Graph2",
|
518
|
+
nodes: [],
|
519
|
+
context: { value: 0 },
|
520
|
+
schema: TestSchema,
|
521
|
+
});
|
503
522
|
|
504
523
|
const processNode2: Node<TestSchema> = {
|
505
524
|
name: "process2",
|
@@ -521,7 +540,7 @@ describe("Graph", function () {
|
|
521
540
|
graph2.addNode(processNode2);
|
522
541
|
graph2.addNode(finalizeNode2);
|
523
542
|
|
524
|
-
const results = await
|
543
|
+
const results = await GraphFlowController.executeParallel(
|
525
544
|
[graph1, graph2],
|
526
545
|
["process1", "process2"],
|
527
546
|
2,
|
@@ -533,20 +552,16 @@ describe("Graph", function () {
|
|
533
552
|
});
|
534
553
|
|
535
554
|
/**
|
536
|
-
*
|
555
|
+
* Tests sequential workflow execution using GraphController
|
537
556
|
*/
|
538
557
|
it("should handle sequential workflows using GraphController", async function () {
|
539
558
|
// Graph 1
|
540
|
-
const graph1 = new GraphFlow(
|
541
|
-
"Graph1",
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
schema: TestSchema,
|
547
|
-
},
|
548
|
-
{ verbose: true }
|
549
|
-
);
|
559
|
+
const graph1 = new GraphFlow("Graph1", {
|
560
|
+
name: "Graph1",
|
561
|
+
nodes: [],
|
562
|
+
context: { value: 1 },
|
563
|
+
schema: TestSchema,
|
564
|
+
});
|
550
565
|
|
551
566
|
const startNode1: Node<TestSchema> = {
|
552
567
|
name: "start1",
|
@@ -556,16 +571,12 @@ describe("Graph", function () {
|
|
556
571
|
};
|
557
572
|
|
558
573
|
// Graph 2
|
559
|
-
const graph2 = new GraphFlow(
|
560
|
-
"Graph2",
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
schema: TestSchema,
|
566
|
-
},
|
567
|
-
{ verbose: true }
|
568
|
-
);
|
574
|
+
const graph2 = new GraphFlow("Graph2", {
|
575
|
+
name: "Graph2",
|
576
|
+
nodes: [],
|
577
|
+
context: { value: 3 },
|
578
|
+
schema: TestSchema,
|
579
|
+
});
|
569
580
|
|
570
581
|
const startNode2: Node<TestSchema> = {
|
571
582
|
name: "start2",
|
@@ -577,7 +588,7 @@ describe("Graph", function () {
|
|
577
588
|
graph1.addNode(startNode1);
|
578
589
|
graph2.addNode(startNode2);
|
579
590
|
|
580
|
-
const results = await
|
591
|
+
const results = await GraphFlowController.executeSequential(
|
581
592
|
[graph1, graph2],
|
582
593
|
["start1", "start2"],
|
583
594
|
[{}, {}]
|
@@ -586,4 +597,124 @@ describe("Graph", function () {
|
|
586
597
|
expect(results[0].value).to.equal(2); // Graph1: 1 * 2
|
587
598
|
expect(results[1].value).to.equal(5); // Graph2: 3 + 2
|
588
599
|
});
|
600
|
+
|
601
|
+
/**
|
602
|
+
* Tests event correlation functionality
|
603
|
+
* Demonstrates:
|
604
|
+
* - Event correlation based on transaction ID
|
605
|
+
* - Timeout handling
|
606
|
+
* - Multiple event synchronization
|
607
|
+
* - Context updates after correlation
|
608
|
+
* Critical for integrating with external event sources
|
609
|
+
*/
|
610
|
+
it("should handle correlated events correctly", async function () {
|
611
|
+
this.timeout(10000);
|
612
|
+
const graph = new GraphFlow("test", {
|
613
|
+
name: "test",
|
614
|
+
nodes: [],
|
615
|
+
context: { value: 0 },
|
616
|
+
schema: TestSchema,
|
617
|
+
eventEmitter: new EventEmitter(),
|
618
|
+
});
|
619
|
+
|
620
|
+
let eventsReceived = 0;
|
621
|
+
const node = {
|
622
|
+
name: "testNode",
|
623
|
+
waitForEvents: {
|
624
|
+
events: ["eventA", "eventB"],
|
625
|
+
timeout: 5000,
|
626
|
+
strategy: "all" as const,
|
627
|
+
},
|
628
|
+
execute: async (context: GraphContext<typeof TestSchema>) => {
|
629
|
+
eventsReceived = 2;
|
630
|
+
context.value = 42;
|
631
|
+
},
|
632
|
+
};
|
633
|
+
|
634
|
+
graph.addNode(node);
|
635
|
+
|
636
|
+
graph.execute("testNode");
|
637
|
+
|
638
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
639
|
+
|
640
|
+
await graph.emit("eventA", { eventPayload: { status: "A" } });
|
641
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
642
|
+
await graph.emit("eventB", { eventPayload: { status: "B" } });
|
643
|
+
|
644
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
645
|
+
|
646
|
+
expect(eventsReceived).to.equal(2);
|
647
|
+
expect(graph.getContext().value).to.equal(42);
|
648
|
+
});
|
649
|
+
|
650
|
+
/**
|
651
|
+
* Tests multiple event waiting functionality
|
652
|
+
*/
|
653
|
+
it("should wait for multiple events before continuing", async function () {
|
654
|
+
this.timeout(10000);
|
655
|
+
const graph = new GraphFlow("test", {
|
656
|
+
name: "test",
|
657
|
+
nodes: [],
|
658
|
+
context: { value: 0 },
|
659
|
+
schema: TestSchema,
|
660
|
+
eventEmitter: new EventEmitter(),
|
661
|
+
});
|
662
|
+
|
663
|
+
const node = {
|
664
|
+
name: "testNode",
|
665
|
+
waitForEvents: {
|
666
|
+
events: ["event1", "event2"],
|
667
|
+
timeout: 5000,
|
668
|
+
strategy: "all" as const,
|
669
|
+
},
|
670
|
+
execute: async (context: GraphContext<typeof TestSchema>) => {
|
671
|
+
context.value = 42; // Ajouter une modification du contexte
|
672
|
+
},
|
673
|
+
};
|
674
|
+
|
675
|
+
graph.addNode(node);
|
676
|
+
graph.execute("testNode");
|
677
|
+
|
678
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
679
|
+
await graph.emit("event1", { eventPayload: { status: "1" } });
|
680
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
681
|
+
await graph.emit("event2", { eventPayload: { status: "2" } });
|
682
|
+
expect(graph.getContext().value).to.equal(42);
|
683
|
+
});
|
684
|
+
|
685
|
+
/**
|
686
|
+
* Tests single event waiting functionality
|
687
|
+
*/
|
688
|
+
it("should wait for a single event before continuing", async function () {
|
689
|
+
this.timeout(5000);
|
690
|
+
|
691
|
+
const waitingNode: Node<TestSchema> = {
|
692
|
+
name: "waitingNode",
|
693
|
+
execute: async (context: GraphContext<typeof TestSchema>) => {
|
694
|
+
context.value = 1;
|
695
|
+
},
|
696
|
+
waitForEvent: true,
|
697
|
+
next: ["finalNode"],
|
698
|
+
};
|
699
|
+
|
700
|
+
const finalNode: Node<TestSchema> = {
|
701
|
+
name: "finalNode",
|
702
|
+
execute: async (context: GraphContext<typeof TestSchema>) => {
|
703
|
+
context.value = (context.value ?? 0) + 5;
|
704
|
+
},
|
705
|
+
};
|
706
|
+
|
707
|
+
[waitingNode, finalNode].forEach((node) => graph.addNode(node));
|
708
|
+
|
709
|
+
const resultPromise = graph.execute("waitingNode");
|
710
|
+
|
711
|
+
// Wait a bit to ensure the node is ready
|
712
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
713
|
+
|
714
|
+
// Emit the event
|
715
|
+
await graph.emit("someEvent");
|
716
|
+
|
717
|
+
const result = await resultPromise;
|
718
|
+
expect(result.value).to.equal(6); // 1 (waitingNode) + 5 (finalNode)
|
719
|
+
});
|
589
720
|
});
|