@ai.ntellect/core 0.7.7 → 1.0.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.
Files changed (111) hide show
  1. package/README.md +158 -81
  2. package/index.ts +462 -22
  3. package/package copy.json +21 -0
  4. package/package.json +9 -44
  5. package/tsconfig.json +108 -22
  6. package/types.ts +62 -0
  7. package/utils/executor.ts +42 -0
  8. package/.mocharc.json +0 -5
  9. package/dist/graph/controller.d.ts +0 -31
  10. package/dist/graph/controller.d.ts.map +0 -1
  11. package/dist/graph/controller.js +0 -71
  12. package/dist/graph/controller.js.map +0 -1
  13. package/dist/graph/event-manager.d.ts +0 -92
  14. package/dist/graph/event-manager.d.ts.map +0 -1
  15. package/dist/graph/event-manager.js +0 -244
  16. package/dist/graph/event-manager.js.map +0 -1
  17. package/dist/graph/index.d.ts +0 -159
  18. package/dist/graph/index.d.ts.map +0 -1
  19. package/dist/graph/index.js +0 -303
  20. package/dist/graph/index.js.map +0 -1
  21. package/dist/graph/logger.d.ts +0 -46
  22. package/dist/graph/logger.d.ts.map +0 -1
  23. package/dist/graph/logger.js +0 -69
  24. package/dist/graph/logger.js.map +0 -1
  25. package/dist/graph/node.d.ts +0 -92
  26. package/dist/graph/node.d.ts.map +0 -1
  27. package/dist/graph/node.js +0 -249
  28. package/dist/graph/node.js.map +0 -1
  29. package/dist/graph/observer.d.ts +0 -113
  30. package/dist/graph/observer.d.ts.map +0 -1
  31. package/dist/graph/observer.js +0 -198
  32. package/dist/graph/observer.js.map +0 -1
  33. package/dist/index.d.ts +0 -26
  34. package/dist/index.d.ts.map +0 -1
  35. package/dist/index.js +0 -42
  36. package/dist/index.js.map +0 -1
  37. package/dist/interfaces/index.d.ts +0 -447
  38. package/dist/interfaces/index.d.ts.map +0 -1
  39. package/dist/interfaces/index.js +0 -75
  40. package/dist/interfaces/index.js.map +0 -1
  41. package/dist/modules/agenda/adapters/node-cron/index.d.ts +0 -17
  42. package/dist/modules/agenda/adapters/node-cron/index.d.ts.map +0 -1
  43. package/dist/modules/agenda/adapters/node-cron/index.js +0 -30
  44. package/dist/modules/agenda/adapters/node-cron/index.js.map +0 -1
  45. package/dist/modules/agenda/index.d.ts +0 -63
  46. package/dist/modules/agenda/index.d.ts.map +0 -1
  47. package/dist/modules/agenda/index.js +0 -141
  48. package/dist/modules/agenda/index.js.map +0 -1
  49. package/dist/modules/embedding/adapters/ai/index.d.ts +0 -29
  50. package/dist/modules/embedding/adapters/ai/index.d.ts.map +0 -1
  51. package/dist/modules/embedding/adapters/ai/index.js +0 -58
  52. package/dist/modules/embedding/adapters/ai/index.js.map +0 -1
  53. package/dist/modules/embedding/index.d.ts +0 -36
  54. package/dist/modules/embedding/index.d.ts.map +0 -1
  55. package/dist/modules/embedding/index.js +0 -60
  56. package/dist/modules/embedding/index.js.map +0 -1
  57. package/dist/modules/memory/adapters/in-memory/index.d.ts +0 -120
  58. package/dist/modules/memory/adapters/in-memory/index.d.ts.map +0 -1
  59. package/dist/modules/memory/adapters/in-memory/index.js +0 -211
  60. package/dist/modules/memory/adapters/in-memory/index.js.map +0 -1
  61. package/dist/modules/memory/adapters/meilisearch/index.d.ts +0 -110
  62. package/dist/modules/memory/adapters/meilisearch/index.d.ts.map +0 -1
  63. package/dist/modules/memory/adapters/meilisearch/index.js +0 -321
  64. package/dist/modules/memory/adapters/meilisearch/index.js.map +0 -1
  65. package/dist/modules/memory/adapters/redis/index.d.ts +0 -82
  66. package/dist/modules/memory/adapters/redis/index.d.ts.map +0 -1
  67. package/dist/modules/memory/adapters/redis/index.js +0 -159
  68. package/dist/modules/memory/adapters/redis/index.js.map +0 -1
  69. package/dist/modules/memory/index.d.ts +0 -67
  70. package/dist/modules/memory/index.d.ts.map +0 -1
  71. package/dist/modules/memory/index.js +0 -104
  72. package/dist/modules/memory/index.js.map +0 -1
  73. package/dist/types/index.d.ts +0 -166
  74. package/dist/types/index.d.ts.map +0 -1
  75. package/dist/types/index.js +0 -3
  76. package/dist/types/index.js.map +0 -1
  77. package/dist/utils/generate-action-schema.d.ts +0 -5
  78. package/dist/utils/generate-action-schema.d.ts.map +0 -1
  79. package/dist/utils/generate-action-schema.js +0 -44
  80. package/dist/utils/generate-action-schema.js.map +0 -1
  81. package/dist/utils/header-builder.d.ts +0 -12
  82. package/dist/utils/header-builder.d.ts.map +0 -1
  83. package/dist/utils/header-builder.js +0 -35
  84. package/dist/utils/header-builder.js.map +0 -1
  85. package/graph/controller.ts +0 -74
  86. package/graph/event-manager.ts +0 -295
  87. package/graph/index.ts +0 -397
  88. package/graph/logger.ts +0 -70
  89. package/graph/node.ts +0 -305
  90. package/graph/observer.ts +0 -368
  91. package/interfaces/index.ts +0 -545
  92. package/modules/agenda/adapters/node-cron/index.ts +0 -25
  93. package/modules/agenda/index.ts +0 -146
  94. package/modules/embedding/adapters/ai/index.ts +0 -42
  95. package/modules/embedding/index.ts +0 -45
  96. package/modules/memory/adapters/in-memory/index.ts +0 -207
  97. package/modules/memory/adapters/meilisearch/index.ts +0 -361
  98. package/modules/memory/adapters/redis/index.ts +0 -164
  99. package/modules/memory/index.ts +0 -93
  100. package/test/graph/controller.test.ts +0 -187
  101. package/test/graph/event-manager.test.ts +0 -72
  102. package/test/graph/index.test.ts +0 -768
  103. package/test/graph/node.test.ts +0 -510
  104. package/test/graph/observer.test.ts +0 -398
  105. package/test/modules/agenda/node-cron.test.ts +0 -307
  106. package/test/modules/memory/adapters/in-memory.test.ts +0 -153
  107. package/test/modules/memory/adapters/meilisearch.test.ts +0 -287
  108. package/test/modules/memory/base.test.ts +0 -230
  109. package/types/index.ts +0 -184
  110. package/utils/generate-action-schema.ts +0 -46
  111. package/utils/header-builder.ts +0 -40
@@ -1,164 +0,0 @@
1
- import { createClient } from "redis";
2
- import { IMemoryAdapter } from "../../../../interfaces";
3
- import { BaseMemoryType, CreateMemoryInput } from "../../../../types";
4
-
5
- /**
6
- * @module RedisAdapter
7
- * @description Adapter implementation for Redis as a memory storage solution.
8
- * Provides integration with Redis for storing and retrieving memory entries with TTL support.
9
- * @implements {IMemoryAdapter}
10
- */
11
- export class RedisAdapter implements IMemoryAdapter {
12
- private redis;
13
- private readonly cachePrefix: string;
14
- private readonly cacheTTL: number;
15
-
16
- /**
17
- * Creates an instance of RedisAdapter
18
- * @param {string} redisUrl - Redis connection URL
19
- * @param {Object} options - Configuration options
20
- * @param {string} [options.cachePrefix="memory:"] - Prefix for Redis keys
21
- * @param {number} [options.cacheTTL=3600] - Default TTL in seconds
22
- */
23
- constructor(
24
- private readonly redisUrl: string,
25
- options: {
26
- cachePrefix?: string;
27
- cacheTTL?: number;
28
- }
29
- ) {
30
- this.cachePrefix = options.cachePrefix || "memory:";
31
- this.cacheTTL = options.cacheTTL || 3600;
32
- this.redis = createClient({
33
- url: redisUrl,
34
- socket: {
35
- tls: true,
36
- rejectUnauthorized: true,
37
- },
38
- });
39
- }
40
-
41
- /**
42
- * Initializes the Redis connection
43
- * @param {string} roomId - Room identifier
44
- * @returns {Promise<void>}
45
- */
46
- async init(roomId: string): Promise<void> {
47
- this.redis.on("error", (err) => console.error("Redis Client Error:", err));
48
- await this.redis.connect();
49
- }
50
-
51
- /**
52
- * Creates a new memory entry in Redis
53
- * @param {CreateMemoryInput & { embedding?: number[] }} input - Memory data with optional embedding
54
- * @returns {Promise<BaseMemoryType | undefined>} Created memory or undefined
55
- */
56
- async createMemory(
57
- input: CreateMemoryInput & { embedding?: number[] }
58
- ): Promise<BaseMemoryType | undefined> {
59
- const memory: BaseMemoryType = {
60
- id: input.id || crypto.randomUUID(),
61
- data: input.data,
62
- embedding: input.embedding,
63
- roomId: input.roomId,
64
- createdAt: new Date(),
65
- };
66
-
67
- const key = memory.roomId
68
- ? `${this.cachePrefix}${memory.roomId}:${memory.id}`
69
- : `${this.cachePrefix}${memory.id}`;
70
-
71
- await this.redis.set(key, JSON.stringify(memory), {
72
- EX: this.cacheTTL,
73
- });
74
-
75
- return memory;
76
- }
77
-
78
- /**
79
- * Retrieves a memory by ID and room ID from Redis
80
- * @param {string} id - Memory identifier
81
- * @param {string} roomId - Room identifier
82
- * @returns {Promise<BaseMemoryType | null>} Memory entry or null if not found
83
- */
84
- async getMemoryById(
85
- id: string,
86
- roomId: string
87
- ): Promise<BaseMemoryType | null> {
88
- const key = `${this.cachePrefix}${roomId}:${id}`;
89
- const data = await this.redis.get(key);
90
- return data ? JSON.parse(data) : null;
91
- }
92
-
93
- /**
94
- * Searches for memories in Redis based on pattern matching
95
- * @param {string} query - Search query
96
- * @param {Object} options - Search options
97
- * @param {string} options.roomId - Room identifier
98
- * @param {number} [options.limit] - Maximum number of results
99
- * @returns {Promise<BaseMemoryType[]>} Array of matching memories
100
- */
101
- async getMemoryByIndex(
102
- query: string,
103
- options: { roomId: string; limit?: number }
104
- ): Promise<BaseMemoryType[]> {
105
- const pattern = `${this.cachePrefix}${options.roomId}:*`;
106
- const keys = await this.redis.keys(pattern);
107
- const memories = await Promise.all(
108
- keys.map(async (key) => {
109
- const data = await this.redis.get(key);
110
- return data ? JSON.parse(data) : null;
111
- })
112
- );
113
- return memories.filter(Boolean).slice(0, options.limit || 10);
114
- }
115
-
116
- /**
117
- * Retrieves all memories for a room from Redis
118
- * @param {string} roomId - Room identifier
119
- * @returns {Promise<BaseMemoryType[]>} Array of all memories
120
- */
121
- async getAllMemories(roomId: string): Promise<BaseMemoryType[]> {
122
- const pattern = `${this.cachePrefix}${roomId}:*`;
123
- const keys = await this.redis.keys(pattern);
124
- const memories = await Promise.all(
125
- keys.map(async (key) => {
126
- const data = await this.redis.get(key);
127
- return data ? JSON.parse(data) : null;
128
- })
129
- );
130
- return memories.filter(Boolean);
131
- }
132
-
133
- /**
134
- * Deletes a specific memory from Redis
135
- * @param {string} id - Memory identifier
136
- * @param {string} roomId - Room identifier
137
- * @returns {Promise<void>}
138
- */
139
- async clearMemoryById(id: string, roomId: string): Promise<void> {
140
- const key = `${this.cachePrefix}${roomId}:${id}`;
141
- await this.redis.del(key);
142
- }
143
-
144
- /**
145
- * Clears all memories across all rooms from Redis
146
- * @returns {Promise<void>}
147
- */
148
- async clearAllMemories(): Promise<void> {
149
- const keys = await this.redis.keys(`${this.cachePrefix}*`);
150
- if (keys.length > 0) {
151
- await this.redis.del(keys);
152
- }
153
- }
154
-
155
- /**
156
- * Closes the Redis connection
157
- * @returns {Promise<void>}
158
- */
159
- async quit(): Promise<void> {
160
- if (this.redis) {
161
- await this.redis.quit();
162
- }
163
- }
164
- }
@@ -1,93 +0,0 @@
1
- import { BaseMemory, IMemoryAdapter } from "../../interfaces";
2
- import { BaseMemoryType, CreateMemoryInput } from "../../types";
3
-
4
- /**
5
- * @module Memory
6
- * @description A module for managing memory storage and retrieval operations.
7
- * Implements the BaseMemory abstract class and provides concrete implementations
8
- * for memory-related operations using the provided adapter.
9
- * @extends {BaseMemory}
10
- */
11
- export class Memory extends BaseMemory {
12
- /**
13
- * Creates an instance of Memory
14
- * @param {IMemoryAdapter} adapter - The memory adapter implementation to use
15
- */
16
- constructor(adapter: IMemoryAdapter) {
17
- super(adapter);
18
- }
19
-
20
- /**
21
- * Initializes the memory module with default room
22
- * @returns {Promise<void>}
23
- */
24
- async init(): Promise<void> {
25
- await this.adapter.init("default");
26
- }
27
-
28
- /**
29
- * Creates a new memory entry
30
- * @param {CreateMemoryInput & { embedding?: number[] }} input - Memory data with optional embedding
31
- * @returns {Promise<BaseMemoryType | undefined>} Created memory or undefined
32
- */
33
- async createMemory(
34
- input: CreateMemoryInput & { embedding?: number[] }
35
- ): Promise<BaseMemoryType | undefined> {
36
- return this.adapter.createMemory(input);
37
- }
38
-
39
- /**
40
- * Retrieves a memory by ID and room ID
41
- * @param {string} id - Memory identifier
42
- * @param {string} roomId - Room identifier
43
- * @returns {Promise<BaseMemoryType | null>} Memory entry or null if not found
44
- */
45
- async getMemoryById(
46
- id: string,
47
- roomId: string
48
- ): Promise<BaseMemoryType | null> {
49
- return this.adapter.getMemoryById(id, roomId);
50
- }
51
-
52
- /**
53
- * Searches for memories based on query and options
54
- * @param {string} query - Search query
55
- * @param {Object} options - Search options
56
- * @param {string} options.roomId - Room identifier
57
- * @param {number} [options.limit] - Maximum number of results to return
58
- * @returns {Promise<BaseMemoryType[]>} Array of matching memories
59
- */
60
- async getMemoryByIndex(
61
- query: string,
62
- options: { roomId: string; limit?: number }
63
- ): Promise<BaseMemoryType[]> {
64
- return this.adapter.getMemoryByIndex(query, options);
65
- }
66
-
67
- /**
68
- * Retrieves all memories for a specific room
69
- * @param {string} roomId - Room identifier
70
- * @returns {Promise<BaseMemoryType[]>} Array of all memories in the room
71
- */
72
- async getAllMemories(roomId: string): Promise<BaseMemoryType[]> {
73
- return this.adapter.getAllMemories(roomId);
74
- }
75
-
76
- /**
77
- * Deletes a specific memory
78
- * @param {string} id - Memory identifier
79
- * @param {string} roomId - Room identifier
80
- * @returns {Promise<void>}
81
- */
82
- async clearMemoryById(id: string, roomId: string): Promise<void> {
83
- await this.adapter.clearMemoryById(id, roomId);
84
- }
85
-
86
- /**
87
- * Clears all memories across all rooms
88
- * @returns {Promise<void>}
89
- */
90
- async clearAllMemories(): Promise<void> {
91
- await this.adapter.clearAllMemories();
92
- }
93
- }
@@ -1,187 +0,0 @@
1
- import { expect } from "chai";
2
- import { z } from "zod";
3
- import { GraphController } from "../../graph/controller";
4
- import { GraphFlow } from "../../graph/index";
5
- import { Node } from "../../types";
6
-
7
- describe("GraphController", () => {
8
- const TestSchema = z.object({
9
- counter: z.number(),
10
- message: z.string(),
11
- });
12
-
13
- const createTestGraph = (name: string): GraphFlow<typeof TestSchema> => {
14
- const nodes: Node<typeof TestSchema>[] = [
15
- {
16
- name: "start",
17
- execute: async (context, params) => {
18
- context.counter = params?.value ?? 0;
19
- context.message = params?.prefix ? `${params.prefix}-${name}` : name;
20
- },
21
- },
22
- {
23
- name: "increment",
24
- execute: async (context) => {
25
- context.counter += 1;
26
- },
27
- },
28
- ];
29
-
30
- return new GraphFlow(name, {
31
- name,
32
- nodes,
33
- schema: TestSchema,
34
- context: { counter: 0, message: "" },
35
- });
36
- };
37
-
38
- describe("Sequential Execution", () => {
39
- it("should execute graphs sequentially with different params and params", async () => {
40
- const graph1 = createTestGraph("graph1");
41
- const graph2 = createTestGraph("graph2");
42
- const graph3 = createTestGraph("graph3");
43
-
44
- const params = [{ value: 10 }, { value: 20 }, { value: 30 }];
45
-
46
- const params2 = [
47
- { prefix: "test1" },
48
- { prefix: "test2" },
49
- { prefix: "test3" },
50
- ];
51
-
52
- const results = await GraphController.executeSequential(
53
- [graph1, graph2, graph3],
54
- ["start", "start", "start"],
55
- params.map((value, i) => ({ ...value, prefix: params2[i].prefix }))
56
- );
57
-
58
- expect(results).to.have.length(3);
59
- expect(results[0].counter).to.equal(10);
60
- expect(results[1].counter).to.equal(20);
61
- expect(results[2].counter).to.equal(30);
62
- expect(results[0].message).to.equal("test1-graph1");
63
- expect(results[1].message).to.equal("test2-graph2");
64
- expect(results[2].message).to.equal("test3-graph3");
65
- });
66
-
67
- it("should handle missing params and params gracefully", async () => {
68
- const graph1 = createTestGraph("graph1");
69
- const graph2 = createTestGraph("graph2");
70
-
71
- const results = await GraphController.executeSequential(
72
- [graph1, graph2],
73
- ["start", "start"]
74
- );
75
-
76
- expect(results).to.have.length(2);
77
- expect(results[0].counter).to.equal(0);
78
- expect(results[1].counter).to.equal(0);
79
- expect(results[0].message).to.equal("graph1");
80
- expect(results[1].message).to.equal("graph2");
81
- });
82
- });
83
-
84
- describe("Parallel Execution", () => {
85
- it("should execute graphs in parallel with concurrency limit", async () => {
86
- const graphs = Array.from({ length: 5 }, (_, i) =>
87
- createTestGraph(`graph${i + 1}`)
88
- );
89
-
90
- const params = Array.from({ length: 5 }, (_, i) => ({
91
- value: (i + 1) * 10,
92
- prefix: `test${i + 1}`,
93
- }));
94
-
95
- // Ajouter un délai dans l'exécution
96
- const originalExecute = graphs[0].execute;
97
- graphs[0].execute = async (...args) => {
98
- await new Promise((resolve) => setTimeout(resolve, 100));
99
- return originalExecute.apply(graphs[0], args);
100
- };
101
-
102
- const startTime = Date.now();
103
- const results = await GraphController.executeParallel(
104
- graphs,
105
- Array(5).fill("start"),
106
- 2,
107
- params
108
- );
109
- const executionTime = Date.now() - startTime;
110
-
111
- expect(executionTime).to.be.greaterThan(0);
112
- expect(results).to.have.length(5);
113
- results.forEach((result, i) => {
114
- expect(result.counter).to.equal((i + 1) * 10);
115
- expect(result.message).to.equal(`test${i + 1}-graph${i + 1}`);
116
- });
117
- });
118
-
119
- it("should handle errors in parallel execution", async () => {
120
- const errorGraph = new GraphFlow("errorGraph", {
121
- name: "errorGraph",
122
- nodes: [
123
- {
124
- name: "start",
125
- execute: async () => {
126
- throw new Error("Test error");
127
- },
128
- },
129
- ],
130
- schema: TestSchema,
131
- context: { counter: 0, message: "" },
132
- });
133
-
134
- const successGraph = createTestGraph("successGraph");
135
-
136
- try {
137
- await GraphController.executeParallel(
138
- [errorGraph, successGraph],
139
- ["start", "start"],
140
- 2
141
- );
142
- expect.fail("Should have thrown an error");
143
- } catch (error: any) {
144
- expect(error.message).to.equal("Test error");
145
- }
146
- });
147
- });
148
-
149
- describe("Complex Workflows", () => {
150
- it("should handle mixed sequential and parallel execution", async () => {
151
- const graphs = Array.from({ length: 4 }, (_, i) =>
152
- createTestGraph(`graph${i + 1}`)
153
- );
154
-
155
- // Exécuter les deux premiers graphes en parallèle
156
- const parallelResults = await GraphController.executeParallel(
157
- graphs.slice(0, 2),
158
- ["start", "start"],
159
- 2,
160
- [
161
- { value: 10, prefix: "parallel1" },
162
- { value: 20, prefix: "parallel2" },
163
- ]
164
- );
165
-
166
- // Puis exécuter les deux suivants séquentiellement
167
- const sequentialResults = await GraphController.executeSequential(
168
- graphs.slice(2),
169
- ["start", "start"],
170
- [
171
- { value: 30, prefix: "seq1" },
172
- { value: 40, prefix: "seq2" },
173
- ]
174
- );
175
-
176
- const allResults = [...parallelResults, ...sequentialResults];
177
- expect(allResults).to.have.length(4);
178
- expect(allResults.map((r) => r.counter)).to.deep.equal([10, 20, 30, 40]);
179
- expect(allResults.map((r) => r.message)).to.deep.equal([
180
- "parallel1-graph1",
181
- "parallel2-graph2",
182
- "seq1-graph3",
183
- "seq2-graph4",
184
- ]);
185
- });
186
- });
187
- });
@@ -1,72 +0,0 @@
1
- import { expect } from "chai";
2
- import { EventEmitter } from "events";
3
- import { z } from "zod";
4
- import { GraphEventManager } from "../../graph/event-manager";
5
-
6
- describe("GraphEventManager", () => {
7
- const TestSchema = z.object({
8
- counter: z.number(),
9
- message: z.string(),
10
- });
11
-
12
- let eventManager: GraphEventManager<typeof TestSchema>;
13
- let eventEmitter: EventEmitter;
14
- let events: any[] = [];
15
-
16
- beforeEach(() => {
17
- events = [];
18
- eventEmitter = new EventEmitter();
19
- eventManager = new GraphEventManager(eventEmitter, new Map(), "test", {
20
- counter: 0,
21
- message: "Hello",
22
- });
23
- });
24
-
25
- it("should emit events without duplication", () => {
26
- const emittedEvents: any[] = [];
27
- eventEmitter.on("test", (event) => emittedEvents.push(event));
28
-
29
- eventManager.emitEvent("test", { data: "test" });
30
-
31
- expect(emittedEvents).to.have.lengthOf(1);
32
- expect(emittedEvents[0]).to.deep.equal({ data: "test" });
33
- });
34
-
35
- it("should handle nodeStateChanged events correctly", () => {
36
- const stateChanges: any[] = [];
37
- eventEmitter.on("nodeStateChanged", (event) => stateChanges.push(event));
38
-
39
- eventManager.emitEvent("nodeStateChanged", {
40
- nodeName: "test",
41
- property: "counter",
42
- oldValue: 0,
43
- newValue: 1,
44
- context: { counter: 1, message: "Hello" },
45
- });
46
-
47
- expect(stateChanges).to.have.lengthOf(1);
48
- expect(stateChanges[0].nodeName).to.equal("test");
49
- expect(stateChanges[0].context.counter).to.equal(1);
50
- });
51
-
52
- it("should setup and cleanup event listeners", () => {
53
- const nodes = new Map();
54
- nodes.set("test", {
55
- name: "test",
56
- events: ["customEvent"],
57
- execute: async () => {},
58
- });
59
-
60
- eventManager = new GraphEventManager(eventEmitter, nodes, "test", {
61
- counter: 0,
62
- message: "Hello",
63
- });
64
-
65
- eventManager.setupEventListeners();
66
- expect(eventEmitter.listenerCount("customEvent")).to.equal(1);
67
-
68
- // Réinitialiser les listeners
69
- eventManager.setupEventListeners();
70
- expect(eventEmitter.listenerCount("customEvent")).to.equal(1);
71
- });
72
- });