data-primals-engine 1.5.1 → 1.5.2
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/README.md +2 -0
- package/client/src/App.scss +1 -1
- package/client/src/DataLayout.jsx +2 -0
- package/client/src/HistoryDialog.jsx +24 -2
- package/client/src/ModelList.jsx +280 -275
- package/client/src/filter.js +1 -0
- package/package.json +6 -6
- package/src/core.js +8 -1
- package/src/engine.js +85 -43
- package/src/events.js +137 -113
- package/src/index.js +3 -0
- package/src/modules/assistant/assistant.js +123 -134
- package/src/modules/assistant/constants.js +2 -1
- package/src/modules/data/data.history.js +32 -8
- package/src/modules/data/data.operations.js +3381 -3282
- package/src/modules/data/data.relations.js +1 -1
- package/src/modules/data/data.routes.js +3 -3
- package/src/modules/user.js +1 -0
- package/src/modules/workflow.js +2 -2
- package/src/openai.jobs.js +3 -2
- package/src/sso.js +2 -2
- package/src/workers/import-export-worker.js +1 -1
- package/test/data.history.integration.test.js +264 -192
- package/test/data.integration.test.js +1206 -1115
package/src/engine.js
CHANGED
|
@@ -20,7 +20,7 @@ import sirv from "sirv";
|
|
|
20
20
|
import * as tls from "node:tls";
|
|
21
21
|
import {Event} from "./events.js";
|
|
22
22
|
import path from "node:path";
|
|
23
|
-
import { fileURLToPath } from 'node:url';
|
|
23
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
24
24
|
import {validateModelStructure} from "./modules/data/data.validation.js";
|
|
25
25
|
import { setSafeRegex } from "./filter.js";
|
|
26
26
|
import safeRegexCallback from "safe-regex";
|
|
@@ -106,6 +106,9 @@ export const Engine = {
|
|
|
106
106
|
console.log("Creating engine", Config.Get('modules'));
|
|
107
107
|
const logger = engine.addComponent(Logger);
|
|
108
108
|
|
|
109
|
+
// Expose the Event bus on the engine instance for dependency injection
|
|
110
|
+
engine.Event = Event;
|
|
111
|
+
|
|
109
112
|
engine.userProvider = new DefaultUserProvider(engine);
|
|
110
113
|
|
|
111
114
|
engine.setUserProvider = (providerInstance) => {
|
|
@@ -157,56 +160,93 @@ export const Engine = {
|
|
|
157
160
|
return engine._modules.find(m => m.module === module);
|
|
158
161
|
};
|
|
159
162
|
|
|
160
|
-
const
|
|
161
|
-
const moduleA = await import(
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
163
|
+
const importAndPrepareModule = async (moduleEntryPoint, moduleName) => {
|
|
164
|
+
const moduleA = await import(moduleEntryPoint);
|
|
165
|
+
|
|
166
|
+
let moduleInstance = null;
|
|
167
|
+
let onInitFunction = null;
|
|
168
|
+
|
|
169
|
+
// Cas 1: `export default { onInit }`
|
|
170
|
+
if (moduleA.default && typeof moduleA.default.onInit === 'function') {
|
|
171
|
+
moduleInstance = moduleA.default;
|
|
172
|
+
onInitFunction = moduleA.default.onInit;
|
|
169
173
|
}
|
|
174
|
+
// Cas 2: `export async function onInit() {}`
|
|
175
|
+
else if (typeof moduleA.onInit === 'function') {
|
|
176
|
+
moduleInstance = moduleA;
|
|
177
|
+
onInitFunction = moduleA.onInit;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (moduleInstance) {
|
|
181
|
+
// On stocke la fonction onInit pour plus tard et on retourne l'instance
|
|
182
|
+
// avec le nom court du module.
|
|
183
|
+
return { ...moduleInstance, onInit: onInitFunction, module: moduleName };
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
logger.warn(`Module loaded from ${moduleEntryPoint} does not export an onInit function or a default object with onInit.`);
|
|
187
|
+
return null;
|
|
170
188
|
};
|
|
171
189
|
|
|
172
190
|
engine._modules = [];
|
|
173
|
-
for (const moduleIdentifier of Config.Get('modules', [])) {
|
|
174
|
-
try {
|
|
175
|
-
let moduleDir;
|
|
176
|
-
const moduleName = path.basename(moduleIdentifier);
|
|
177
|
-
|
|
178
|
-
const directPath = path.resolve(moduleIdentifier);
|
|
179
|
-
let isDir = fs.existsSync(directPath) && fs.statSync(directPath).isDirectory();
|
|
180
191
|
|
|
181
|
-
|
|
182
|
-
|
|
192
|
+
// On charge uniquement les modules spécifiés dans la configuration.
|
|
193
|
+
const allModules = Config.Get('modules', []);
|
|
194
|
+
const loadedModules = []; // Liste temporaire pour la phase 1
|
|
195
|
+
for (const moduleIdentifier of allModules) {
|
|
196
|
+
let moduleEntryPoint = null;
|
|
197
|
+
const moduleName = path.basename(moduleIdentifier, '.js');
|
|
198
|
+
try {
|
|
199
|
+
// 1. Tenter de résoudre comme un chemin (relatif au projet ou absolu)
|
|
200
|
+
const externalPath = path.resolve(process.cwd(), moduleIdentifier);
|
|
201
|
+
if (fs.existsSync(externalPath)) {
|
|
202
|
+
const stats = fs.statSync(externalPath);
|
|
203
|
+
if (stats.isDirectory()) {
|
|
204
|
+
// C'est un répertoire, on cherche le point d'entrée
|
|
205
|
+
const indexJsPath = path.join(externalPath, 'index.js');
|
|
206
|
+
const moduleJsPath = path.join(externalPath, `${moduleName}.js`);
|
|
207
|
+
if (fs.existsSync(indexJsPath)) moduleEntryPoint = pathToFileURL(indexJsPath).href;
|
|
208
|
+
else if (fs.existsSync(moduleJsPath)) moduleEntryPoint = pathToFileURL(moduleJsPath).href;
|
|
209
|
+
} else {
|
|
210
|
+
// C'est un fichier
|
|
211
|
+
moduleEntryPoint = pathToFileURL(externalPath).href;
|
|
212
|
+
}
|
|
183
213
|
} else {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
214
|
+
// 2. Si ce n'est pas un chemin, tenter de résoudre comme un module interne
|
|
215
|
+
const internalDir = path.resolve(__dirname, 'modules', moduleIdentifier);
|
|
216
|
+
const internalFile = path.resolve(__dirname, 'modules', `${moduleIdentifier}.js`);
|
|
217
|
+
|
|
218
|
+
if (fs.existsSync(internalDir) && fs.statSync(internalDir).isDirectory()) {
|
|
219
|
+
// C'est un répertoire de module interne
|
|
220
|
+
const indexJsPath = path.join(internalDir, 'index.js');
|
|
221
|
+
const moduleJsPath = path.join(internalDir, `${moduleIdentifier}.js`);
|
|
222
|
+
if (fs.existsSync(indexJsPath)) moduleEntryPoint = pathToFileURL(indexJsPath).href;
|
|
223
|
+
else if (fs.existsSync(moduleJsPath)) moduleEntryPoint = pathToFileURL(moduleJsPath).href;
|
|
224
|
+
} else if (fs.existsSync(internalFile)) {
|
|
225
|
+
// C'est un fichier de module interne
|
|
226
|
+
moduleEntryPoint = pathToFileURL(internalFile).href;
|
|
227
|
+
}
|
|
198
228
|
}
|
|
199
229
|
|
|
200
230
|
if (moduleEntryPoint) {
|
|
201
|
-
const loadedModule = await
|
|
231
|
+
const loadedModule = await importAndPrepareModule(moduleEntryPoint, moduleName);
|
|
202
232
|
if (loadedModule) {
|
|
203
|
-
|
|
233
|
+
loadedModules.push(loadedModule);
|
|
204
234
|
}
|
|
205
235
|
} else {
|
|
206
|
-
logger.warn(`
|
|
236
|
+
logger.warn(`Could not resolve or find an entry point for module '${moduleIdentifier}'.`);
|
|
207
237
|
}
|
|
208
238
|
} catch (e) {
|
|
209
|
-
logger.error(`Could not load module '${moduleIdentifier}
|
|
239
|
+
logger.error(`Could not load module '${moduleName}' (${moduleIdentifier}):`, e.stack);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Phase 2: Enregistrer et Initialiser tous les modules chargés
|
|
244
|
+
engine._modules = loadedModules; // On enregistre tous les modules dans le moteur
|
|
245
|
+
for (const moduleInstance of engine._modules) {
|
|
246
|
+
if (typeof moduleInstance.onInit === 'function') {
|
|
247
|
+
logger.info(`Initializing module '${moduleInstance.module}'...`);
|
|
248
|
+
await moduleInstance.onInit(engine);
|
|
249
|
+
logger.info(`Module '${moduleInstance.module}' loaded and initialized.`);
|
|
210
250
|
}
|
|
211
251
|
}
|
|
212
252
|
|
|
@@ -239,10 +279,12 @@ export const Engine = {
|
|
|
239
279
|
});
|
|
240
280
|
});
|
|
241
281
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
282
|
+
if( fs.existsSync('client/dist') ){
|
|
283
|
+
app.use(sirv('client/dist', {
|
|
284
|
+
single: true,
|
|
285
|
+
dev: process.env.NODE_ENV === 'development'
|
|
286
|
+
}));
|
|
287
|
+
}
|
|
246
288
|
|
|
247
289
|
process.on('uncaughtException', function (exception) {
|
|
248
290
|
console.error(exception);
|
|
@@ -277,9 +319,9 @@ export const Engine = {
|
|
|
277
319
|
model.locked = true;
|
|
278
320
|
const r = await createModel(model);
|
|
279
321
|
dbModels.push({...model, _id: r.insertedId });
|
|
280
|
-
logger.info(
|
|
322
|
+
logger.info(`Model ${model.name} inserted.`);
|
|
281
323
|
}else
|
|
282
|
-
logger.info(
|
|
324
|
+
logger.info(`Model ${model.name} loaded`);
|
|
283
325
|
}
|
|
284
326
|
logger.info("All models loaded.");
|
|
285
327
|
await Event.Trigger("OnModelsLoaded", "event", "system", engine, dbModels);
|
package/src/events.js
CHANGED
|
@@ -1,113 +1,137 @@
|
|
|
1
|
-
import {safeAssignObject} from "./core.js";
|
|
2
|
-
|
|
3
|
-
const events = {};
|
|
4
|
-
|
|
5
|
-
const eventLayerSystems = {
|
|
6
|
-
"priority": ["high", "medium", "low"],
|
|
7
|
-
"log": ["info", "debug", "warn", "error", "critical"],
|
|
8
|
-
"system": ["calls", "users"],
|
|
9
|
-
"event": ["system","user"],
|
|
10
|
-
"custom": ["data"]
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export const Event = {
|
|
16
|
-
Trigger: async (name, system = "priority", layer = "medium", ...args) => { // Ajout des arguments system et layer
|
|
17
|
-
if (!name || typeof name !== 'string') {
|
|
18
|
-
throw new Error('Event name must be a non-empty string');
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (!events[system] || !events[system][name] || (layer && !events[system][name][layer])) {
|
|
22
|
-
//console.warn(`No trigger found for ${name} in system ${system} layer ${layer}`);
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const systemsToProcess = system ? [system] : Object.keys(events); // Si system est spécifié, on cible ce système uniquement, sinon tous les systèmes
|
|
27
|
-
console.log(`[Event] Triggering ${system}.${layer}.${name}`, {
|
|
28
|
-
callbacks: events[system]?.[name]?.[layer]?.length || 0
|
|
29
|
-
});
|
|
30
|
-
let ret = null;
|
|
31
|
-
for (const currentSystem of systemsToProcess) {
|
|
32
|
-
if (events[currentSystem] && events[currentSystem][name]) {
|
|
33
|
-
const layersToProcess = layer ? [layer] : eventLayerSystems[currentSystem] || Object.keys(events[currentSystem][name]); // Si layer est spécifié, on cible cette couche, sinon toutes les couches ou celles définies dans eventLayerSystems
|
|
34
|
-
|
|
35
|
-
if (layersToProcess) {
|
|
36
|
-
for (const currentLayer of layersToProcess) {
|
|
37
|
-
if (events[currentSystem][name][currentLayer]) {
|
|
38
|
-
for (const callback of events[currentSystem][name][currentLayer]) {
|
|
39
|
-
try {
|
|
40
|
-
const res = await callback(...args);
|
|
41
|
-
if (typeof res === "object" && !Array.isArray(res)) {
|
|
42
|
-
if (typeof ret !== "object") ret = {};
|
|
43
|
-
ret = {...ret, ...res};
|
|
44
|
-
} else if (Array.isArray(res)) {
|
|
45
|
-
if (!ret || !Array.isArray(ret)) ret = [];
|
|
46
|
-
ret = ret.concat(res);
|
|
47
|
-
} else if (typeof res === "string") {
|
|
48
|
-
if (typeof ret !== "string") ret = "";
|
|
49
|
-
ret += res;
|
|
50
|
-
} else if (typeof res === "number") {
|
|
51
|
-
if (typeof ret !== "number") ret = 0;
|
|
52
|
-
ret += res;
|
|
53
|
-
} else if (typeof res === "boolean") {
|
|
54
|
-
if (typeof ret !== "boolean") ret = true;
|
|
55
|
-
ret = res && ret;
|
|
56
|
-
} else {
|
|
57
|
-
ret = res || ret;
|
|
58
|
-
}
|
|
59
|
-
} catch (error) {
|
|
60
|
-
const errorMsg = `Error in callback for event ${name} in system ${currentSystem} layer ${currentLayer}: ${error.message}`;
|
|
61
|
-
const newError = new Error(errorMsg);
|
|
62
|
-
newError.originalError = error; // Conserve l'erreur originale
|
|
63
|
-
newError.eventDetails = { name, system: currentSystem, layer: currentLayer };
|
|
64
|
-
throw newError;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return ret;
|
|
73
|
-
},
|
|
74
|
-
Listen: (name = "", callback, system = "priority", layer = "medium") => {
|
|
75
|
-
const validSystems = Object.keys(eventLayerSystems); // Récupération des clés pour une vérification plus performante
|
|
76
|
-
if (!validSystems.includes(system)) {
|
|
77
|
-
throw new Error(`System '${system}' does not exist. Valid systems are: ${validSystems.join(', ')}`); // Message d'erreur plus informatif
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const validLayers = eventLayerSystems[system]; // Récupération des couches valides pour le système
|
|
81
|
-
if (!validLayers.includes(layer)) {
|
|
82
|
-
throw new Error(`Layer '${layer}' does not exist in system '${system}'. Valid layers are: ${validLayers.join(', ')}`); // Message d'erreur plus informatif
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
safeAssignObject(events, system, events[system] || {}); // Simplification de la création des objets
|
|
86
|
-
safeAssignObject(events[system], name, events[system][name] || {});
|
|
87
|
-
safeAssignObject(events[system][name], layer, events[system][name][layer] || []);
|
|
88
|
-
events[system][name][layer].push(callback);
|
|
89
|
-
},
|
|
90
|
-
|
|
91
|
-
if (
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
1
|
+
import {safeAssignObject} from "./core.js";
|
|
2
|
+
|
|
3
|
+
const events = {};
|
|
4
|
+
|
|
5
|
+
const eventLayerSystems = {
|
|
6
|
+
"priority": ["high", "medium", "low"],
|
|
7
|
+
"log": ["info", "debug", "warn", "error", "critical"],
|
|
8
|
+
"system": ["calls", "users"],
|
|
9
|
+
"event": ["system","user"],
|
|
10
|
+
"custom": ["data"]
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
export const Event = {
|
|
16
|
+
Trigger: async (name, system = "priority", layer = "medium", ...args) => { // Ajout des arguments system et layer
|
|
17
|
+
if (!name || typeof name !== 'string') {
|
|
18
|
+
throw new Error('Event name must be a non-empty string');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (!events[system] || !events[system][name] || (layer && !events[system][name][layer])) {
|
|
22
|
+
//console.warn(`No trigger found for ${name} in system ${system} layer ${layer}`);
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const systemsToProcess = system ? [system] : Object.keys(events); // Si system est spécifié, on cible ce système uniquement, sinon tous les systèmes
|
|
27
|
+
console.log(`[Event] Triggering ${system}.${layer}.${name}`, {
|
|
28
|
+
callbacks: events[system]?.[name]?.[layer]?.length || 0
|
|
29
|
+
});
|
|
30
|
+
let ret = null;
|
|
31
|
+
for (const currentSystem of systemsToProcess) {
|
|
32
|
+
if (events[currentSystem] && events[currentSystem][name]) {
|
|
33
|
+
const layersToProcess = layer ? [layer] : eventLayerSystems[currentSystem] || Object.keys(events[currentSystem][name]); // Si layer est spécifié, on cible cette couche, sinon toutes les couches ou celles définies dans eventLayerSystems
|
|
34
|
+
|
|
35
|
+
if (layersToProcess) {
|
|
36
|
+
for (const currentLayer of layersToProcess) {
|
|
37
|
+
if (events[currentSystem][name][currentLayer]) {
|
|
38
|
+
for (const callback of events[currentSystem][name][currentLayer]) {
|
|
39
|
+
try {
|
|
40
|
+
const res = await callback(...args);
|
|
41
|
+
if (typeof res === "object" && !Array.isArray(res)) {
|
|
42
|
+
if (typeof ret !== "object") ret = {};
|
|
43
|
+
ret = {...ret, ...res};
|
|
44
|
+
} else if (Array.isArray(res)) {
|
|
45
|
+
if (!ret || !Array.isArray(ret)) ret = [];
|
|
46
|
+
ret = ret.concat(res);
|
|
47
|
+
} else if (typeof res === "string") {
|
|
48
|
+
if (typeof ret !== "string") ret = "";
|
|
49
|
+
ret += res;
|
|
50
|
+
} else if (typeof res === "number") {
|
|
51
|
+
if (typeof ret !== "number") ret = 0;
|
|
52
|
+
ret += res;
|
|
53
|
+
} else if (typeof res === "boolean") {
|
|
54
|
+
if (typeof ret !== "boolean") ret = true;
|
|
55
|
+
ret = res && ret;
|
|
56
|
+
} else {
|
|
57
|
+
ret = res || ret;
|
|
58
|
+
}
|
|
59
|
+
} catch (error) {
|
|
60
|
+
const errorMsg = `Error in callback for event ${name} in system ${currentSystem} layer ${currentLayer}: ${error.message}`;
|
|
61
|
+
const newError = new Error(errorMsg);
|
|
62
|
+
newError.originalError = error; // Conserve l'erreur originale
|
|
63
|
+
newError.eventDetails = { name, system: currentSystem, layer: currentLayer };
|
|
64
|
+
throw newError;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return ret;
|
|
73
|
+
},
|
|
74
|
+
Listen: (name = "", callback, system = "priority", layer = "medium") => {
|
|
75
|
+
const validSystems = Object.keys(eventLayerSystems); // Récupération des clés pour une vérification plus performante
|
|
76
|
+
if (!validSystems.includes(system)) {
|
|
77
|
+
throw new Error(`System '${system}' does not exist. Valid systems are: ${validSystems.join(', ')}`); // Message d'erreur plus informatif
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const validLayers = eventLayerSystems[system]; // Récupération des couches valides pour le système
|
|
81
|
+
if (!validLayers.includes(layer)) {
|
|
82
|
+
throw new Error(`Layer '${layer}' does not exist in system '${system}'. Valid layers are: ${validLayers.join(', ')}`); // Message d'erreur plus informatif
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
safeAssignObject(events, system, events[system] || {}); // Simplification de la création des objets
|
|
86
|
+
safeAssignObject(events[system], name, events[system][name] || {});
|
|
87
|
+
safeAssignObject(events[system][name], layer, events[system][name][layer] || []);
|
|
88
|
+
events[system][name][layer].push(callback);
|
|
89
|
+
},
|
|
90
|
+
addSystem: (system) => {
|
|
91
|
+
if (typeof system !== 'string' || system.trim() === '') {
|
|
92
|
+
throw new Error('Le nom du système doit être une chaîne de caractères non vide.');
|
|
93
|
+
}
|
|
94
|
+
if (!eventLayerSystems.hasOwnProperty(system)) {
|
|
95
|
+
eventLayerSystems[system] = [];
|
|
96
|
+
} else {
|
|
97
|
+
console.warn(`[Event] Le système '${system}' existe déjà.`);
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
addLayer: (system, layer) => {
|
|
101
|
+
if (typeof system !== 'string' || system.trim() === '') {
|
|
102
|
+
throw new Error('Le nom du système doit être une chaîne de caractères non vide.');
|
|
103
|
+
}
|
|
104
|
+
if (typeof layer !== 'string' || layer.trim() === '') {
|
|
105
|
+
throw new Error('Le nom de la couche doit être une chaîne de caractères non vide.');
|
|
106
|
+
}
|
|
107
|
+
if (!eventLayerSystems.hasOwnProperty(system)) {
|
|
108
|
+
throw new Error(`Le système '${system}' n'existe pas. Veuillez l'ajouter avec addSystem('${system}').`);
|
|
109
|
+
}
|
|
110
|
+
if (!eventLayerSystems[system].includes(layer)) {
|
|
111
|
+
eventLayerSystems[system].push(layer);
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
RemoveCallback: (name, callback, layer="medium", system='priority') => {
|
|
115
|
+
if (!events[system] || !events[system][name] || !events[system][name][layer]) {
|
|
116
|
+
return; // Si l'événement, le système ou la couche n'existent pas, on ne fait rien
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const index = events[system][name][layer].indexOf(callback);
|
|
120
|
+
if (index > -1) {
|
|
121
|
+
events[system][name][layer].splice(index, 1);
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
// Ajout d'une méthode pour supprimer tous les callbacks d'un événement (optionnel)
|
|
125
|
+
RemoveAllCallbacks: (name, system = 'priority') => {
|
|
126
|
+
if (events[system] && events[system][name]) {
|
|
127
|
+
delete events[system][name]; // Supprime l'objet contenant les couches et les callbacks
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
// Ajout d'une méthode pour supprimer tous les callbacks d'un système (optionnel)
|
|
132
|
+
RemoveSystemCallbacks: (system) => {
|
|
133
|
+
if (events[system]) {
|
|
134
|
+
delete events[system];
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
package/src/index.js
CHANGED
|
@@ -5,6 +5,9 @@ export { Engine } from './engine.js';
|
|
|
5
5
|
export { GameObject, Logger, BenchmarkTool } from './gameObject.js';
|
|
6
6
|
export { Config } from './config.js';
|
|
7
7
|
export { event_on, event_trigger, event_off } from './core.js';
|
|
8
|
+
export { Event } from './events.js';
|
|
9
|
+
|
|
10
|
+
export { sendSseToUser } from './modules/data/data.routes.js';
|
|
8
11
|
|
|
9
12
|
export { UserProvider } from './providers.js';
|
|
10
13
|
|