@twin.org/modules 0.0.3-next.5 → 0.0.3-next.7
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/es/helpers/moduleHelper.js +85 -58
- package/dist/es/helpers/moduleHelper.js.map +1 -1
- package/dist/es/index.js +1 -0
- package/dist/es/index.js.map +1 -1
- package/dist/es/models/IModuleWorker.js +2 -0
- package/dist/es/models/IModuleWorker.js.map +1 -0
- package/dist/types/helpers/moduleHelper.d.ts +16 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/models/IModuleWorker.d.ts +19 -0
- package/docs/changelog.md +52 -0
- package/docs/reference/classes/ModuleHelper.md +49 -1
- package/docs/reference/index.md +4 -0
- package/docs/reference/interfaces/IModuleWorker.md +51 -0
- package/locales/en.json +2 -3
- package/package.json +4 -3
|
@@ -70,7 +70,7 @@ export class ModuleHelper {
|
|
|
70
70
|
}
|
|
71
71
|
throw new GeneralError(ModuleHelper.CLASS_NAME, "notFunction", {
|
|
72
72
|
module,
|
|
73
|
-
|
|
73
|
+
method
|
|
74
74
|
});
|
|
75
75
|
}
|
|
76
76
|
const moduleEntry = await ModuleHelper.getModuleEntry(module, methodParts[0]);
|
|
@@ -79,7 +79,7 @@ export class ModuleHelper {
|
|
|
79
79
|
}
|
|
80
80
|
throw new GeneralError(ModuleHelper.CLASS_NAME, "notFunction", {
|
|
81
81
|
module,
|
|
82
|
-
|
|
82
|
+
method
|
|
83
83
|
});
|
|
84
84
|
}
|
|
85
85
|
/**
|
|
@@ -99,78 +99,105 @@ export class ModuleHelper {
|
|
|
99
99
|
* @param module The module.
|
|
100
100
|
* @param method The method to execute from the module.
|
|
101
101
|
* @param args The arguments to pass to the method.
|
|
102
|
+
* @param contextIds The context IDs.
|
|
102
103
|
* @returns The result of the method execution.
|
|
103
104
|
* @throws GeneralError if executing the module entry failed.
|
|
104
105
|
*/
|
|
105
|
-
static async execModuleMethodThread(module, method, args) {
|
|
106
|
+
static async execModuleMethodThread(module, method, args, contextIds) {
|
|
106
107
|
return new Promise((resolve, reject) => {
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
const messageModule = ModuleHelper.execModuleMethodThreadMessage(module, (resultMethod, result, err) => {
|
|
109
|
+
if (err) {
|
|
110
|
+
reject(err);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
resolve(result);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
messageModule.executeMethod(method, args, contextIds);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Load the module and provide a messaging interface.
|
|
121
|
+
* @param module The module.
|
|
122
|
+
* @param completed Callback called when the worker thread processes a completion.
|
|
123
|
+
* @param options Optional settings.
|
|
124
|
+
* @param options.threadName The name of the thread.
|
|
125
|
+
* @returns The messaging interface.
|
|
126
|
+
* @throws GeneralError if executing the module entry failed.
|
|
127
|
+
*/
|
|
128
|
+
static execModuleMethodThreadMessage(module, completed, options) {
|
|
129
|
+
const worker = new Worker(`(async () => {
|
|
130
|
+
const { workerData, parentPort } = await import('node:worker_threads');
|
|
131
|
+
const { ContextIdStore } = await import('@twin.org/context');
|
|
132
|
+
const { module } = workerData;
|
|
110
133
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
134
|
+
function rejectError(errorType, methodName, args, cause) {
|
|
135
|
+
parentPort.postMessage({ errorType, method: methodName, args, cause });
|
|
136
|
+
}
|
|
114
137
|
|
|
115
|
-
|
|
116
|
-
|
|
138
|
+
async function executeMethod(method, methodName, args, contextIds) {
|
|
139
|
+
try {
|
|
140
|
+
await ContextIdStore.run(contextIds ?? {}, async () => {
|
|
117
141
|
const result = await method(...(args ?? []));
|
|
118
142
|
|
|
119
|
-
parentPort.postMessage({ result });
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
|
|
143
|
+
parentPort.postMessage({ method: methodName, result });
|
|
144
|
+
});
|
|
145
|
+
} catch (err) {
|
|
146
|
+
rejectError('resultError', methodName, args, err);
|
|
123
147
|
}
|
|
148
|
+
}
|
|
124
149
|
|
|
125
|
-
|
|
150
|
+
const modules = {};
|
|
126
151
|
|
|
127
|
-
|
|
128
|
-
const
|
|
129
|
-
const moduleEntry = moduleInstance[methodParts[0]];
|
|
152
|
+
parentPort.on('message', async msg => {
|
|
153
|
+
const { method, args, contextIds } = msg;
|
|
130
154
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
155
|
+
try {
|
|
156
|
+
const moduleInstance = modules[module] ?? (await import(module));
|
|
157
|
+
modules[module] = moduleInstance;
|
|
158
|
+
|
|
159
|
+
const methodParts = method.split('.');
|
|
160
|
+
const moduleEntry = moduleInstance[methodParts[0]];
|
|
161
|
+
|
|
162
|
+
if (moduleEntry === undefined) {
|
|
163
|
+
rejectError('entryNotFound', method, args);
|
|
164
|
+
} else if (methodParts.length === 2) {
|
|
165
|
+
const moduleMethod = moduleEntry[methodParts[1]];
|
|
166
|
+
if (typeof moduleMethod === 'function') {
|
|
167
|
+
await executeMethod(moduleMethod, method, args, contextIds);
|
|
168
|
+
} else {
|
|
169
|
+
rejectError('notFunction', method, args);
|
|
170
|
+
}
|
|
171
|
+
} else if (typeof moduleEntry === 'function') {
|
|
172
|
+
await executeMethod(moduleEntry, method, args, contextIds);
|
|
137
173
|
} else {
|
|
138
|
-
rejectError('notFunction');
|
|
174
|
+
rejectError('notFunction', method, args);
|
|
139
175
|
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
} else {
|
|
143
|
-
rejectError('notFunction');
|
|
176
|
+
} catch (errInner) {
|
|
177
|
+
rejectError('moduleNotFound', method, args, errInner);
|
|
144
178
|
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}, err));
|
|
163
|
-
});
|
|
164
|
-
worker.on("exit", code => {
|
|
165
|
-
if (code === 1) {
|
|
166
|
-
reject(new GeneralError(ModuleHelper.CLASS_NAME, "workerFailed", {
|
|
167
|
-
module,
|
|
168
|
-
entry: method,
|
|
169
|
-
exitCode: code
|
|
170
|
-
}));
|
|
171
|
-
}
|
|
172
|
-
});
|
|
179
|
+
});
|
|
180
|
+
})();`, { eval: true, workerData: { module }, name: options?.threadName });
|
|
181
|
+
worker.on("message", msg => {
|
|
182
|
+
if (Is.stringValue(msg.errorType)) {
|
|
183
|
+
completed(msg.method, undefined, new GeneralError(ModuleHelper.CLASS_NAME, msg.errorType, { module, method: msg.method, args: msg.args }, msg.cause));
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
completed(msg.method, msg.result);
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
worker.on("error", err => {
|
|
190
|
+
completed("error", undefined, new GeneralError(ModuleHelper.CLASS_NAME, "workerException", {
|
|
191
|
+
module
|
|
192
|
+
}, err));
|
|
193
|
+
});
|
|
194
|
+
worker.on("exit", code => {
|
|
195
|
+
completed("terminate", code);
|
|
173
196
|
});
|
|
197
|
+
return {
|
|
198
|
+
executeMethod: (method, args, contextIds) => worker.postMessage({ method, args, contextIds }),
|
|
199
|
+
terminate: async () => worker.terminate()
|
|
200
|
+
};
|
|
174
201
|
}
|
|
175
202
|
/**
|
|
176
203
|
* Check if a module is a local module.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"moduleHelper.js","sourceRoot":"","sources":["../../../src/helpers/moduleHelper.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { Worker } from \"node:worker_threads\";\nimport { BaseError, GeneralError, Is, SharedStore } from \"@twin.org/core\";\nimport { nameof } from \"@twin.org/nameof\";\n\n/**\n * Helper functions for modules.\n */\nexport class ModuleHelper {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<ModuleHelper>();\n\n\t/**\n\t * Override the import function for modules.\n\t * @param overrideImport The override import function.\n\t */\n\tpublic static overrideImport(\n\t\toverrideImport: (moduleName: string) => Promise<{ module?: unknown; useDefault: boolean }>\n\t): void {\n\t\tSharedStore.set(\"overrideImport\", overrideImport);\n\t}\n\n\t/**\n\t * Get the module entry.\n\t * @param module The module.\n\t * @param entry The entry to get from the module.\n\t * @returns The entry from the module.\n\t * @throws GeneralError if getting the module entry failed.\n\t */\n\tpublic static async getModuleEntry<T>(module: string, entry: string): Promise<T> {\n\t\tlet moduleInstance;\n\n\t\ttry {\n\t\t\tlet useDefault = true;\n\n\t\t\tconst overrideImport =\n\t\t\t\tSharedStore.get<(moduleName: string) => Promise<{ module?: unknown; useDefault: boolean }>>(\n\t\t\t\t\t\"overrideImport\"\n\t\t\t\t);\n\n\t\t\tif (Is.function(overrideImport)) {\n\t\t\t\tconst overrideResult = await overrideImport(module);\n\n\t\t\t\tmoduleInstance = overrideResult.module;\n\t\t\t\tuseDefault = overrideResult.useDefault;\n\t\t\t}\n\n\t\t\tif (useDefault) {\n\t\t\t\tmoduleInstance = await import(module);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tModuleHelper.CLASS_NAME,\n\t\t\t\t\"moduleNotFound\",\n\t\t\t\t{\n\t\t\t\t\tmodule,\n\t\t\t\t\tentry\n\t\t\t\t},\n\t\t\t\tBaseError.fromError(err)\n\t\t\t);\n\t\t}\n\n\t\tconst moduleEntry = moduleInstance?.[entry];\n\n\t\tif (Is.empty(moduleEntry)) {\n\t\t\tthrow new GeneralError(ModuleHelper.CLASS_NAME, \"entryNotFound\", {\n\t\t\t\tmodule,\n\t\t\t\tentry\n\t\t\t});\n\t\t}\n\n\t\treturn moduleEntry as T;\n\t}\n\n\t/**\n\t * Get the method from a module.\n\t * @param module The module.\n\t * @param method The method to execute from the module, use dot notation to get a static class method.\n\t * @returns The result of the method execution.\n\t * @throws GeneralError if executing the module entry failed.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic static async getModuleMethod<T extends (...args: any[]) => any = (...args: any[]) => any>(\n\t\tmodule: string,\n\t\tmethod: string\n\t): Promise<T> {\n\t\tconst methodParts = method.split(\".\");\n\n\t\tif (methodParts.length === 2) {\n\t\t\tconst moduleEntry = await ModuleHelper.getModuleEntry<{\n\t\t\t\t[id: string]: T;\n\t\t\t}>(module, methodParts[0]);\n\n\t\t\tif (Is.function<T>(moduleEntry[methodParts[1]])) {\n\t\t\t\treturn moduleEntry[methodParts[1]];\n\t\t\t}\n\t\t\tthrow new GeneralError(ModuleHelper.CLASS_NAME, \"notFunction\", {\n\t\t\t\tmodule,\n\t\t\t\tentry: method\n\t\t\t});\n\t\t}\n\n\t\tconst moduleEntry = await ModuleHelper.getModuleEntry<T>(module, methodParts[0]);\n\n\t\tif (Is.function<T>(moduleEntry)) {\n\t\t\treturn moduleEntry;\n\t\t}\n\n\t\tthrow new GeneralError(ModuleHelper.CLASS_NAME, \"notFunction\", {\n\t\t\tmodule,\n\t\t\tentry: method\n\t\t});\n\t}\n\n\t/**\n\t * Execute the method in the module.\n\t * @param module The module.\n\t * @param method The method to execute from the module.\n\t * @param args The arguments to pass to the method.\n\t * @returns The result of the method execution.\n\t * @throws GeneralError if executing the module entry failed.\n\t */\n\tpublic static async execModuleMethod<T>(\n\t\tmodule: string,\n\t\tmethod: string,\n\t\targs?: unknown[]\n\t): Promise<T> {\n\t\tconst moduleMethod = await ModuleHelper.getModuleMethod<(...args: unknown[]) => T>(\n\t\t\tmodule,\n\t\t\tmethod\n\t\t);\n\n\t\treturn moduleMethod(...(args ?? []));\n\t}\n\n\t/**\n\t * Execute the method in the module in a thread.\n\t * @param module The module.\n\t * @param method The method to execute from the module.\n\t * @param args The arguments to pass to the method.\n\t * @returns The result of the method execution.\n\t * @throws GeneralError if executing the module entry failed.\n\t */\n\tpublic static async execModuleMethodThread<T>(\n\t\tmodule: string,\n\t\tmethod: string,\n\t\targs?: unknown[]\n\t): Promise<T> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst worker = new Worker(\n\t\t\t\t`(async () => {\n\ttry {\n\t\tconst { workerData, parentPort } = await import('node:worker_threads');\n\n\t\tfunction rejectError(errorType, cause) {\n\t\t\tparentPort.postMessage({ errorType, cause });\n\t\t}\n\n\t\tasync function executeMethod(method) {\n\t\t\ttry {\n\t\t\t\tconst result = await method(...(args ?? []));\n\n\t\t\t\tparentPort.postMessage({ result });\n\t\t\t} catch (err) {\n\t\t\t\trejectError('resultError', err);\n\t\t\t}\n\t\t}\n\n\t\tconst { module, method, args } = workerData;\n\n\t\tconst moduleInstance = await import(module);\n\t\tconst methodParts = method.split('.');\n\t\tconst moduleEntry = moduleInstance[methodParts[0]];\n\n\t\tif (moduleEntry === undefined) {\n\t\t\trejectError('entryNotFound');\n\t\t} else if (methodParts.length === 2) {\n\t\t\tconst moduleMethod = moduleEntry[methodParts[1]];\n\t\t\tif (typeof moduleMethod === 'function') {\n\t\t\t\tawait executeMethod(moduleMethod, args);\n\t\t\t} else {\n\t\t\t\trejectError('notFunction');\n\t\t\t}\n\t\t} else if (typeof moduleEntry === 'function') {\n\t\t\tawait executeMethod(moduleEntry, args);\n\t\t} else {\n\t\t\trejectError('notFunction');\n\t\t}\n\t} catch (err) {\n\t\trejectError('moduleNotFound', err);\n\t}\n})();\n\t\t\t`,\n\t\t\t\t{ eval: true, workerData: { module, method, args: args ?? [] } }\n\t\t\t);\n\n\t\t\tworker.on(\"message\", msg => {\n\t\t\t\tif (Is.stringValue(msg.errorType)) {\n\t\t\t\t\treject(\n\t\t\t\t\t\tnew GeneralError(\n\t\t\t\t\t\t\tModuleHelper.CLASS_NAME,\n\t\t\t\t\t\t\tmsg.errorType,\n\t\t\t\t\t\t\t{ module, entry: method },\n\t\t\t\t\t\t\tmsg.cause\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tresolve(msg.result);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tworker.on(\"error\", err => {\n\t\t\t\treject(\n\t\t\t\t\tnew GeneralError(\n\t\t\t\t\t\tModuleHelper.CLASS_NAME,\n\t\t\t\t\t\t\"workerException\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmodule,\n\t\t\t\t\t\t\tentry: method\n\t\t\t\t\t\t},\n\t\t\t\t\t\terr\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tworker.on(\"exit\", code => {\n\t\t\t\tif (code === 1) {\n\t\t\t\t\treject(\n\t\t\t\t\t\tnew GeneralError(ModuleHelper.CLASS_NAME, \"workerFailed\", {\n\t\t\t\t\t\t\tmodule,\n\t\t\t\t\t\t\tentry: method,\n\t\t\t\t\t\t\texitCode: code\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Check if a module is a local module.\n\t * @param name The name of the module.\n\t * @returns True if the module is local, false otherwise.\n\t */\n\tpublic static isLocalModule(name: string): boolean {\n\t\treturn name.startsWith(\".\") || name.startsWith(\"/\");\n\t}\n\n\t/**\n\t * Check if a module is a relative module.\n\t * @param name The name of the module.\n\t * @returns True if the module is relative, false otherwise.\n\t */\n\tpublic static isRelativeModule(name: string): boolean {\n\t\treturn name.startsWith(\".\");\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"moduleHelper.js","sourceRoot":"","sources":["../../../src/helpers/moduleHelper.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { Worker } from \"node:worker_threads\";\nimport type { IContextIds } from \"@twin.org/context\";\nimport { BaseError, GeneralError, Is, SharedStore } from \"@twin.org/core\";\nimport { nameof } from \"@twin.org/nameof\";\nimport type { IModuleWorker } from \"../models/IModuleWorker.js\";\n\n/**\n * Helper functions for modules.\n */\nexport class ModuleHelper {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<ModuleHelper>();\n\n\t/**\n\t * Override the import function for modules.\n\t * @param overrideImport The override import function.\n\t */\n\tpublic static overrideImport(\n\t\toverrideImport: (moduleName: string) => Promise<{ module?: unknown; useDefault: boolean }>\n\t): void {\n\t\tSharedStore.set(\"overrideImport\", overrideImport);\n\t}\n\n\t/**\n\t * Get the module entry.\n\t * @param module The module.\n\t * @param entry The entry to get from the module.\n\t * @returns The entry from the module.\n\t * @throws GeneralError if getting the module entry failed.\n\t */\n\tpublic static async getModuleEntry<T>(module: string, entry: string): Promise<T> {\n\t\tlet moduleInstance;\n\n\t\ttry {\n\t\t\tlet useDefault = true;\n\n\t\t\tconst overrideImport =\n\t\t\t\tSharedStore.get<(moduleName: string) => Promise<{ module?: unknown; useDefault: boolean }>>(\n\t\t\t\t\t\"overrideImport\"\n\t\t\t\t);\n\n\t\t\tif (Is.function(overrideImport)) {\n\t\t\t\tconst overrideResult = await overrideImport(module);\n\n\t\t\t\tmoduleInstance = overrideResult.module;\n\t\t\t\tuseDefault = overrideResult.useDefault;\n\t\t\t}\n\n\t\t\tif (useDefault) {\n\t\t\t\tmoduleInstance = await import(module);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tModuleHelper.CLASS_NAME,\n\t\t\t\t\"moduleNotFound\",\n\t\t\t\t{\n\t\t\t\t\tmodule,\n\t\t\t\t\tentry\n\t\t\t\t},\n\t\t\t\tBaseError.fromError(err)\n\t\t\t);\n\t\t}\n\n\t\tconst moduleEntry = moduleInstance?.[entry];\n\n\t\tif (Is.empty(moduleEntry)) {\n\t\t\tthrow new GeneralError(ModuleHelper.CLASS_NAME, \"entryNotFound\", {\n\t\t\t\tmodule,\n\t\t\t\tentry\n\t\t\t});\n\t\t}\n\n\t\treturn moduleEntry as T;\n\t}\n\n\t/**\n\t * Get the method from a module.\n\t * @param module The module.\n\t * @param method The method to execute from the module, use dot notation to get a static class method.\n\t * @returns The result of the method execution.\n\t * @throws GeneralError if executing the module entry failed.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic static async getModuleMethod<T extends (...args: any[]) => any = (...args: any[]) => any>(\n\t\tmodule: string,\n\t\tmethod: string\n\t): Promise<T> {\n\t\tconst methodParts = method.split(\".\");\n\n\t\tif (methodParts.length === 2) {\n\t\t\tconst moduleEntry = await ModuleHelper.getModuleEntry<{\n\t\t\t\t[id: string]: T;\n\t\t\t}>(module, methodParts[0]);\n\n\t\t\tif (Is.function<T>(moduleEntry[methodParts[1]])) {\n\t\t\t\treturn moduleEntry[methodParts[1]];\n\t\t\t}\n\t\t\tthrow new GeneralError(ModuleHelper.CLASS_NAME, \"notFunction\", {\n\t\t\t\tmodule,\n\t\t\t\tmethod\n\t\t\t});\n\t\t}\n\n\t\tconst moduleEntry = await ModuleHelper.getModuleEntry<T>(module, methodParts[0]);\n\n\t\tif (Is.function<T>(moduleEntry)) {\n\t\t\treturn moduleEntry;\n\t\t}\n\n\t\tthrow new GeneralError(ModuleHelper.CLASS_NAME, \"notFunction\", {\n\t\t\tmodule,\n\t\t\tmethod\n\t\t});\n\t}\n\n\t/**\n\t * Execute the method in the module.\n\t * @param module The module.\n\t * @param method The method to execute from the module.\n\t * @param args The arguments to pass to the method.\n\t * @returns The result of the method execution.\n\t * @throws GeneralError if executing the module entry failed.\n\t */\n\tpublic static async execModuleMethod<T>(\n\t\tmodule: string,\n\t\tmethod: string,\n\t\targs?: unknown[]\n\t): Promise<T> {\n\t\tconst moduleMethod = await ModuleHelper.getModuleMethod<(...args: unknown[]) => T>(\n\t\t\tmodule,\n\t\t\tmethod\n\t\t);\n\n\t\treturn moduleMethod(...(args ?? []));\n\t}\n\n\t/**\n\t * Execute the method in the module in a thread.\n\t * @param module The module.\n\t * @param method The method to execute from the module.\n\t * @param args The arguments to pass to the method.\n\t * @param contextIds The context IDs.\n\t * @returns The result of the method execution.\n\t * @throws GeneralError if executing the module entry failed.\n\t */\n\tpublic static async execModuleMethodThread<T>(\n\t\tmodule: string,\n\t\tmethod: string,\n\t\targs?: unknown[],\n\t\tcontextIds?: IContextIds\n\t): Promise<T> {\n\t\treturn new Promise<T>((resolve, reject) => {\n\t\t\tconst messageModule = ModuleHelper.execModuleMethodThreadMessage(\n\t\t\t\tmodule,\n\t\t\t\t(resultMethod, result, err) => {\n\t\t\t\t\tif (err) {\n\t\t\t\t\t\treject(err);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresolve(result as T);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tmessageModule.executeMethod(method, args, contextIds);\n\t\t});\n\t}\n\n\t/**\n\t * Load the module and provide a messaging interface.\n\t * @param module The module.\n\t * @param completed Callback called when the worker thread processes a completion.\n\t * @param options Optional settings.\n\t * @param options.threadName The name of the thread.\n\t * @returns The messaging interface.\n\t * @throws GeneralError if executing the module entry failed.\n\t */\n\tpublic static execModuleMethodThreadMessage(\n\t\tmodule: string,\n\t\tcompleted: (operation: string, result?: unknown, err?: Error) => void,\n\t\toptions?: {\n\t\t\tthreadName?: string;\n\t\t}\n\t): IModuleWorker {\n\t\tconst worker = new Worker(\n\t\t\t`(async () => {\n\tconst { workerData, parentPort } = await import('node:worker_threads');\n\tconst { ContextIdStore } = await import('@twin.org/context');\n\tconst { module } = workerData;\n\n\tfunction rejectError(errorType, methodName, args, cause) {\n\t\tparentPort.postMessage({ errorType, method: methodName, args, cause });\n\t}\n\n\tasync function executeMethod(method, methodName, args, contextIds) {\n\t\ttry {\n\t\t\tawait ContextIdStore.run(contextIds ?? {}, async () => {\n\t\t\t\tconst result = await method(...(args ?? []));\n\n\t\t\t\tparentPort.postMessage({ method: methodName, result });\n\t\t\t});\n\t\t} catch (err) {\n\t\t\trejectError('resultError', methodName, args, err);\n\t\t}\n\t}\n\n\tconst modules = {};\n\n\tparentPort.on('message', async msg => {\n\t\tconst { method, args, contextIds } = msg;\n\n\t\ttry {\n\t\t\tconst moduleInstance = modules[module] ?? (await import(module));\n\t\t\tmodules[module] = moduleInstance;\n\n\t\t\tconst methodParts = method.split('.');\n\t\t\tconst moduleEntry = moduleInstance[methodParts[0]];\n\n\t\t\tif (moduleEntry === undefined) {\n\t\t\t\trejectError('entryNotFound', method, args);\n\t\t\t} else if (methodParts.length === 2) {\n\t\t\t\tconst moduleMethod = moduleEntry[methodParts[1]];\n\t\t\t\tif (typeof moduleMethod === 'function') {\n\t\t\t\t\tawait executeMethod(moduleMethod, method, args, contextIds);\n\t\t\t\t} else {\n\t\t\t\t\trejectError('notFunction', method, args);\n\t\t\t\t}\n\t\t\t} else if (typeof moduleEntry === 'function') {\n\t\t\t\tawait executeMethod(moduleEntry, method, args, contextIds);\n\t\t\t} else {\n\t\t\t\trejectError('notFunction', method, args);\n\t\t\t}\n\t\t} catch (errInner) {\n\t\t\t\trejectError('moduleNotFound', method, args, errInner);\n\t\t}\n\t});\n})();`,\n\t\t\t{ eval: true, workerData: { module }, name: options?.threadName }\n\t\t);\n\n\t\tworker.on(\"message\", msg => {\n\t\t\tif (Is.stringValue(msg.errorType)) {\n\t\t\t\tcompleted(\n\t\t\t\t\tmsg.method,\n\t\t\t\t\tundefined,\n\t\t\t\t\tnew GeneralError(\n\t\t\t\t\t\tModuleHelper.CLASS_NAME,\n\t\t\t\t\t\tmsg.errorType,\n\t\t\t\t\t\t{ module, method: msg.method, args: msg.args },\n\t\t\t\t\t\tmsg.cause\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tcompleted(msg.method, msg.result);\n\t\t\t}\n\t\t});\n\n\t\tworker.on(\"error\", err => {\n\t\t\tcompleted(\n\t\t\t\t\"error\",\n\t\t\t\tundefined,\n\t\t\t\tnew GeneralError(\n\t\t\t\t\tModuleHelper.CLASS_NAME,\n\t\t\t\t\t\"workerException\",\n\t\t\t\t\t{\n\t\t\t\t\t\tmodule\n\t\t\t\t\t},\n\t\t\t\t\terr\n\t\t\t\t)\n\t\t\t);\n\t\t});\n\n\t\tworker.on(\"exit\", code => {\n\t\t\tcompleted(\"terminate\", code);\n\t\t});\n\n\t\treturn {\n\t\t\texecuteMethod: (method: string, args?: unknown, contextIds?: IContextIds) =>\n\t\t\t\tworker.postMessage({ method, args, contextIds }),\n\t\t\tterminate: async () => worker.terminate()\n\t\t};\n\t}\n\n\t/**\n\t * Check if a module is a local module.\n\t * @param name The name of the module.\n\t * @returns True if the module is local, false otherwise.\n\t */\n\tpublic static isLocalModule(name: string): boolean {\n\t\treturn name.startsWith(\".\") || name.startsWith(\"/\");\n\t}\n\n\t/**\n\t * Check if a module is a relative module.\n\t * @param name The name of the module.\n\t * @returns True if the module is relative, false otherwise.\n\t */\n\tpublic static isRelativeModule(name: string): boolean {\n\t\treturn name.startsWith(\".\");\n\t}\n}\n"]}
|
package/dist/es/index.js
CHANGED
package/dist/es/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,cAAc,2BAA2B,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nexport * from \"./helpers/moduleHelper.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nexport * from \"./helpers/moduleHelper.js\";\nexport * from \"./models/IModuleWorker.js\";\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IModuleWorker.js","sourceRoot":"","sources":["../../../src/models/IModuleWorker.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IContextIds } from \"@twin.org/context\";\n\n/**\n * Worker definition for modules.\n */\nexport interface IModuleWorker {\n\t/**\n\t * Execute a method in the module.\n\t * @param method The method to execute.\n\t * @param args The arguments for the method.\n\t * @param contextIds The context IDs.\n\t * @returns The result of the method.\n\t */\n\texecuteMethod(method: string, args?: unknown, contextIds?: IContextIds): void;\n\n\t/**\n\t * Terminate the worker.\n\t * @returns A promise that resolves when the worker is terminated including the exit code.\n\t */\n\tterminate(): Promise<number>;\n}\n"]}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { IContextIds } from "@twin.org/context";
|
|
2
|
+
import type { IModuleWorker } from "../models/IModuleWorker.js";
|
|
1
3
|
/**
|
|
2
4
|
* Helper functions for modules.
|
|
3
5
|
*/
|
|
@@ -44,10 +46,23 @@ export declare class ModuleHelper {
|
|
|
44
46
|
* @param module The module.
|
|
45
47
|
* @param method The method to execute from the module.
|
|
46
48
|
* @param args The arguments to pass to the method.
|
|
49
|
+
* @param contextIds The context IDs.
|
|
47
50
|
* @returns The result of the method execution.
|
|
48
51
|
* @throws GeneralError if executing the module entry failed.
|
|
49
52
|
*/
|
|
50
|
-
static execModuleMethodThread<T>(module: string, method: string, args?: unknown[]): Promise<T>;
|
|
53
|
+
static execModuleMethodThread<T>(module: string, method: string, args?: unknown[], contextIds?: IContextIds): Promise<T>;
|
|
54
|
+
/**
|
|
55
|
+
* Load the module and provide a messaging interface.
|
|
56
|
+
* @param module The module.
|
|
57
|
+
* @param completed Callback called when the worker thread processes a completion.
|
|
58
|
+
* @param options Optional settings.
|
|
59
|
+
* @param options.threadName The name of the thread.
|
|
60
|
+
* @returns The messaging interface.
|
|
61
|
+
* @throws GeneralError if executing the module entry failed.
|
|
62
|
+
*/
|
|
63
|
+
static execModuleMethodThreadMessage(module: string, completed: (operation: string, result?: unknown, err?: Error) => void, options?: {
|
|
64
|
+
threadName?: string;
|
|
65
|
+
}): IModuleWorker;
|
|
51
66
|
/**
|
|
52
67
|
* Check if a module is a local module.
|
|
53
68
|
* @param name The name of the module.
|
package/dist/types/index.d.ts
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { IContextIds } from "@twin.org/context";
|
|
2
|
+
/**
|
|
3
|
+
* Worker definition for modules.
|
|
4
|
+
*/
|
|
5
|
+
export interface IModuleWorker {
|
|
6
|
+
/**
|
|
7
|
+
* Execute a method in the module.
|
|
8
|
+
* @param method The method to execute.
|
|
9
|
+
* @param args The arguments for the method.
|
|
10
|
+
* @param contextIds The context IDs.
|
|
11
|
+
* @returns The result of the method.
|
|
12
|
+
*/
|
|
13
|
+
executeMethod(method: string, args?: unknown, contextIds?: IContextIds): void;
|
|
14
|
+
/**
|
|
15
|
+
* Terminate the worker.
|
|
16
|
+
* @returns A promise that resolves when the worker is terminated including the exit code.
|
|
17
|
+
*/
|
|
18
|
+
terminate(): Promise<number>;
|
|
19
|
+
}
|
package/docs/changelog.md
CHANGED
|
@@ -1,5 +1,57 @@
|
|
|
1
1
|
# @twin.org/modules - Changelog
|
|
2
2
|
|
|
3
|
+
## [0.0.3-next.7](https://github.com/twinfoundation/framework/compare/modules-v0.0.3-next.6...modules-v0.0.3-next.7) (2025-11-25)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add context id features ([#206](https://github.com/twinfoundation/framework/issues/206)) ([ef0d4ee](https://github.com/twinfoundation/framework/commit/ef0d4ee11a4f5fc6cc6f52a4958ce905c04ee13b))
|
|
9
|
+
* add guards arrayEndsWith and arrayStartsWith ([95d875e](https://github.com/twinfoundation/framework/commit/95d875ec8ccb4713c145fdde941d4cfedcec2ed3))
|
|
10
|
+
* eslint migration to flat config ([74427d7](https://github.com/twinfoundation/framework/commit/74427d78d342167f7850e49ab87269326355befe))
|
|
11
|
+
* improve async pattern and error handling ([aaa1f68](https://github.com/twinfoundation/framework/commit/aaa1f6879d60adf04b78b0c1bbbec50f2873f020))
|
|
12
|
+
* improve Is.function and ModuleHelper.getModuleMethod signatures ([ecf968b](https://github.com/twinfoundation/framework/commit/ecf968b02934b3676be4bf7cd2d1e7f8e7af6ce2))
|
|
13
|
+
* locales validation ([#197](https://github.com/twinfoundation/framework/issues/197)) ([55fdadb](https://github.com/twinfoundation/framework/commit/55fdadb13595ce0047f787bd1d4135d429a99f12))
|
|
14
|
+
* module helper can now handle long running threads with messaging ([4ecbb9a](https://github.com/twinfoundation/framework/commit/4ecbb9a526927d462d4fb3f95ba2a44889202753))
|
|
15
|
+
* nodeIdentity optional in IComponent methods ([c78dc17](https://github.com/twinfoundation/framework/commit/c78dc17f4357d3e1ae40e415f468d3eae13e81f4))
|
|
16
|
+
* provide module helper override ([e998a64](https://github.com/twinfoundation/framework/commit/e998a64842cfd18693a14444be33b084fef2bb90))
|
|
17
|
+
* relocate core packages from tools ([bcab8f3](https://github.com/twinfoundation/framework/commit/bcab8f3160442ea4fcaf442947462504f3d6a17d))
|
|
18
|
+
* update dependencies ([f3bd015](https://github.com/twinfoundation/framework/commit/f3bd015efd169196b7e0335f5cab876ba6ca1d75))
|
|
19
|
+
* use cause instead of inner for errors ([1f4acc4](https://github.com/twinfoundation/framework/commit/1f4acc4d7a6b71a134d9547da9bf40de1e1e49da))
|
|
20
|
+
* use new shared store mechanism ([#131](https://github.com/twinfoundation/framework/issues/131)) ([934385b](https://github.com/twinfoundation/framework/commit/934385b2fbaf9f5c00a505ebf9d093bd5a425f55))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Dependencies
|
|
24
|
+
|
|
25
|
+
* The following workspace dependencies were updated
|
|
26
|
+
* dependencies
|
|
27
|
+
* @twin.org/core bumped from 0.0.3-next.6 to 0.0.3-next.7
|
|
28
|
+
* @twin.org/context bumped from 0.0.3-next.6 to 0.0.3-next.7
|
|
29
|
+
* @twin.org/nameof bumped from 0.0.3-next.6 to 0.0.3-next.7
|
|
30
|
+
* devDependencies
|
|
31
|
+
* @twin.org/nameof-transformer bumped from 0.0.3-next.6 to 0.0.3-next.7
|
|
32
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.0.3-next.6 to 0.0.3-next.7
|
|
33
|
+
* @twin.org/validate-locales bumped from 0.0.3-next.6 to 0.0.3-next.7
|
|
34
|
+
|
|
35
|
+
## [0.0.3-next.6](https://github.com/twinfoundation/framework/compare/modules-v0.0.3-next.5...modules-v0.0.3-next.6) (2025-11-25)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
### Features
|
|
39
|
+
|
|
40
|
+
* module helper can now handle long running threads with messaging ([4ecbb9a](https://github.com/twinfoundation/framework/commit/4ecbb9a526927d462d4fb3f95ba2a44889202753))
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
### Dependencies
|
|
44
|
+
|
|
45
|
+
* The following workspace dependencies were updated
|
|
46
|
+
* dependencies
|
|
47
|
+
* @twin.org/core bumped from 0.0.3-next.5 to 0.0.3-next.6
|
|
48
|
+
* @twin.org/context bumped from 0.0.3-next.5 to 0.0.3-next.6
|
|
49
|
+
* @twin.org/nameof bumped from 0.0.3-next.5 to 0.0.3-next.6
|
|
50
|
+
* devDependencies
|
|
51
|
+
* @twin.org/nameof-transformer bumped from 0.0.3-next.5 to 0.0.3-next.6
|
|
52
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.0.3-next.5 to 0.0.3-next.6
|
|
53
|
+
* @twin.org/validate-locales bumped from 0.0.3-next.5 to 0.0.3-next.6
|
|
54
|
+
|
|
3
55
|
## [0.0.3-next.5](https://github.com/twinfoundation/framework/compare/modules-v0.0.3-next.4...modules-v0.0.3-next.5) (2025-11-20)
|
|
4
56
|
|
|
5
57
|
|
|
@@ -164,7 +164,7 @@ GeneralError if executing the module entry failed.
|
|
|
164
164
|
|
|
165
165
|
### execModuleMethodThread()
|
|
166
166
|
|
|
167
|
-
> `static` **execModuleMethodThread**\<`T`\>(`module`, `method`, `args?`): `Promise`\<`T`\>
|
|
167
|
+
> `static` **execModuleMethodThread**\<`T`\>(`module`, `method`, `args?`, `contextIds?`): `Promise`\<`T`\>
|
|
168
168
|
|
|
169
169
|
Execute the method in the module in a thread.
|
|
170
170
|
|
|
@@ -194,6 +194,12 @@ The method to execute from the module.
|
|
|
194
194
|
|
|
195
195
|
The arguments to pass to the method.
|
|
196
196
|
|
|
197
|
+
##### contextIds?
|
|
198
|
+
|
|
199
|
+
`IContextIds`
|
|
200
|
+
|
|
201
|
+
The context IDs.
|
|
202
|
+
|
|
197
203
|
#### Returns
|
|
198
204
|
|
|
199
205
|
`Promise`\<`T`\>
|
|
@@ -206,6 +212,48 @@ GeneralError if executing the module entry failed.
|
|
|
206
212
|
|
|
207
213
|
***
|
|
208
214
|
|
|
215
|
+
### execModuleMethodThreadMessage()
|
|
216
|
+
|
|
217
|
+
> `static` **execModuleMethodThreadMessage**(`module`, `completed`, `options?`): [`IModuleWorker`](../interfaces/IModuleWorker.md)
|
|
218
|
+
|
|
219
|
+
Load the module and provide a messaging interface.
|
|
220
|
+
|
|
221
|
+
#### Parameters
|
|
222
|
+
|
|
223
|
+
##### module
|
|
224
|
+
|
|
225
|
+
`string`
|
|
226
|
+
|
|
227
|
+
The module.
|
|
228
|
+
|
|
229
|
+
##### completed
|
|
230
|
+
|
|
231
|
+
(`operation`, `result?`, `err?`) => `void`
|
|
232
|
+
|
|
233
|
+
Callback called when the worker thread processes a completion.
|
|
234
|
+
|
|
235
|
+
##### options?
|
|
236
|
+
|
|
237
|
+
Optional settings.
|
|
238
|
+
|
|
239
|
+
###### threadName?
|
|
240
|
+
|
|
241
|
+
`string`
|
|
242
|
+
|
|
243
|
+
The name of the thread.
|
|
244
|
+
|
|
245
|
+
#### Returns
|
|
246
|
+
|
|
247
|
+
[`IModuleWorker`](../interfaces/IModuleWorker.md)
|
|
248
|
+
|
|
249
|
+
The messaging interface.
|
|
250
|
+
|
|
251
|
+
#### Throws
|
|
252
|
+
|
|
253
|
+
GeneralError if executing the module entry failed.
|
|
254
|
+
|
|
255
|
+
***
|
|
256
|
+
|
|
209
257
|
### isLocalModule()
|
|
210
258
|
|
|
211
259
|
> `static` **isLocalModule**(`name`): `boolean`
|
package/docs/reference/index.md
CHANGED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Interface: IModuleWorker
|
|
2
|
+
|
|
3
|
+
Worker definition for modules.
|
|
4
|
+
|
|
5
|
+
## Methods
|
|
6
|
+
|
|
7
|
+
### executeMethod()
|
|
8
|
+
|
|
9
|
+
> **executeMethod**(`method`, `args?`, `contextIds?`): `void`
|
|
10
|
+
|
|
11
|
+
Execute a method in the module.
|
|
12
|
+
|
|
13
|
+
#### Parameters
|
|
14
|
+
|
|
15
|
+
##### method
|
|
16
|
+
|
|
17
|
+
`string`
|
|
18
|
+
|
|
19
|
+
The method to execute.
|
|
20
|
+
|
|
21
|
+
##### args?
|
|
22
|
+
|
|
23
|
+
`unknown`
|
|
24
|
+
|
|
25
|
+
The arguments for the method.
|
|
26
|
+
|
|
27
|
+
##### contextIds?
|
|
28
|
+
|
|
29
|
+
`IContextIds`
|
|
30
|
+
|
|
31
|
+
The context IDs.
|
|
32
|
+
|
|
33
|
+
#### Returns
|
|
34
|
+
|
|
35
|
+
`void`
|
|
36
|
+
|
|
37
|
+
The result of the method.
|
|
38
|
+
|
|
39
|
+
***
|
|
40
|
+
|
|
41
|
+
### terminate()
|
|
42
|
+
|
|
43
|
+
> **terminate**(): `Promise`\<`number`\>
|
|
44
|
+
|
|
45
|
+
Terminate the worker.
|
|
46
|
+
|
|
47
|
+
#### Returns
|
|
48
|
+
|
|
49
|
+
`Promise`\<`number`\>
|
|
50
|
+
|
|
51
|
+
A promise that resolves when the worker is terminated including the exit code.
|
package/locales/en.json
CHANGED
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
"moduleHelper": {
|
|
4
4
|
"moduleNotFound": "Failed to load module \"{module}\"",
|
|
5
5
|
"entryNotFound": "Failed to load entry \"{entry}\" from module \"{module}\"",
|
|
6
|
-
"notFunction": "The entry \"{
|
|
7
|
-
"
|
|
8
|
-
"workerException": "The thread worker failed with an exception \"{entry}\" in module \"{module}\""
|
|
6
|
+
"notFunction": "The entry \"{method}\" in module \"{module}\" is not a function",
|
|
7
|
+
"workerException": "The thread worker failed with an exception in module \"{module}\""
|
|
9
8
|
}
|
|
10
9
|
}
|
|
11
10
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@twin.org/modules",
|
|
3
|
-
"version": "0.0.3-next.
|
|
3
|
+
"version": "0.0.3-next.7",
|
|
4
4
|
"description": "Helper classes for loading and executing from modules",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -14,8 +14,9 @@
|
|
|
14
14
|
"node": ">=20.0.0"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@twin.org/
|
|
18
|
-
"@twin.org/
|
|
17
|
+
"@twin.org/context": "0.0.3-next.7",
|
|
18
|
+
"@twin.org/core": "0.0.3-next.7",
|
|
19
|
+
"@twin.org/nameof": "0.0.3-next.7"
|
|
19
20
|
},
|
|
20
21
|
"main": "./dist/es/index.js",
|
|
21
22
|
"types": "./dist/types/index.d.ts",
|