@twin.org/modules 0.0.4-next.8 → 0.9.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  // Copyright 2024 IOTA Stiftung.
2
2
  // SPDX-License-Identifier: Apache-2.0.
3
3
  import { Worker } from "node:worker_threads";
4
- import { BaseError, GeneralError, Is, Mutex, SharedStore } from "@twin.org/core";
4
+ import { BaseError, GeneralError, Is, Mutex, SharedObjectBuffer, SharedStore } from "@twin.org/core";
5
5
  /**
6
6
  * Helper functions for modules.
7
7
  */
@@ -189,6 +189,9 @@ export class ModuleHelper {
189
189
  if (Mutex.handleWorkerMessage(msg)) {
190
190
  return;
191
191
  }
192
+ if (SharedObjectBuffer.handleWorkerMessage(msg)) {
193
+ return;
194
+ }
192
195
  if (!Is.stringValue(msg?.method)) {
193
196
  return;
194
197
  }
@@ -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 type { IContextIds } from \"@twin.org/context\";\nimport { BaseError, GeneralError, Is, Mutex, 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\tlet messageModule: IModuleWorker | undefined;\n\t\ttry {\n\t\t\treturn await new Promise<T>((resolve, reject) => {\n\t\t\t\tmessageModule = ModuleHelper.execModuleMethodThreadMessage(\n\t\t\t\t\tmodule,\n\t\t\t\t\t(resultMethod, result, err) => {\n\t\t\t\t\t\tif (err) {\n\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresolve(result as T);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\tmessageModule.executeMethod(method, args, contextIds);\n\t\t\t});\n\t\t} finally {\n\t\t\tawait messageModule?.terminate();\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 { BaseError } = await import('@twin.org/core');\n\tconst { module } = workerData;\n\n\tfunction rejectError(errorType, methodName, args, cause) {\n\t\tparentPort.postMessage({ errorType, method: methodName, args, cause: BaseError.fromError(cause).toJsonObject(true) });\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\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 (Mutex.handleWorkerMessage(msg)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!Is.stringValue(msg?.method)) {\n\t\t\t\treturn;\n\t\t\t}\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"]}
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 {\n\tBaseError,\n\tGeneralError,\n\tIs,\n\tMutex,\n\tSharedObjectBuffer,\n\tSharedStore\n} 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\tlet messageModule: IModuleWorker | undefined;\n\t\ttry {\n\t\t\treturn await new Promise<T>((resolve, reject) => {\n\t\t\t\tmessageModule = ModuleHelper.execModuleMethodThreadMessage(\n\t\t\t\t\tmodule,\n\t\t\t\t\t(resultMethod, result, err) => {\n\t\t\t\t\t\tif (err) {\n\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresolve(result as T);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\tmessageModule.executeMethod(method, args, contextIds);\n\t\t\t});\n\t\t} finally {\n\t\t\tawait messageModule?.terminate();\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 { BaseError } = await import('@twin.org/core');\n\tconst { module } = workerData;\n\n\tfunction rejectError(errorType, methodName, args, cause) {\n\t\tparentPort.postMessage({ errorType, method: methodName, args, cause: BaseError.fromError(cause).toJsonObject(true) });\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\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 (Mutex.handleWorkerMessage(msg)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (SharedObjectBuffer.handleWorkerMessage(msg)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!Is.stringValue(msg?.method)) {\n\t\t\t\treturn;\n\t\t\t}\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"]}
@@ -1 +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
+ {"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 */\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"]}
@@ -8,7 +8,6 @@ export interface IModuleWorker {
8
8
  * @param method The method to execute.
9
9
  * @param args The arguments for the method.
10
10
  * @param contextIds The context IDs.
11
- * @returns The result of the method.
12
11
  */
13
12
  executeMethod(method: string, args?: unknown, contextIds?: IContextIds): void;
14
13
  /**
package/docs/changelog.md CHANGED
@@ -1,5 +1,210 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.9.0-next.1](https://github.com/iotaledger/twin-framework/compare/modules-v0.9.0-next.0...modules-v0.9.0-next.1) (2026-06-22)
4
+
5
+
6
+ ### Features
7
+
8
+ * add context id features ([#206](https://github.com/iotaledger/twin-framework/issues/206)) ([ef0d4ee](https://github.com/iotaledger/twin-framework/commit/ef0d4ee11a4f5fc6cc6f52a4958ce905c04ee13b))
9
+ * add mutex ([#316](https://github.com/iotaledger/twin-framework/issues/316)) ([1027e5a](https://github.com/iotaledger/twin-framework/commit/1027e5ac77aa9804178b4253abdeefd6f1c3d521))
10
+ * automatically handle SharedObjectBuffer message in module threads ([10510ff](https://github.com/iotaledger/twin-framework/commit/10510ff4180a2cfbb51aa5a65c57362291826077))
11
+ * eslint migration to flat config ([74427d7](https://github.com/iotaledger/twin-framework/commit/74427d78d342167f7850e49ab87269326355befe))
12
+ * improve async pattern and error handling ([aaa1f68](https://github.com/iotaledger/twin-framework/commit/aaa1f6879d60adf04b78b0c1bbbec50f2873f020))
13
+ * improve Is.function and ModuleHelper.getModuleMethod signatures ([ecf968b](https://github.com/iotaledger/twin-framework/commit/ecf968b02934b3676be4bf7cd2d1e7f8e7af6ce2))
14
+ * locales validation ([#197](https://github.com/iotaledger/twin-framework/issues/197)) ([55fdadb](https://github.com/iotaledger/twin-framework/commit/55fdadb13595ce0047f787bd1d4135d429a99f12))
15
+ * module helper can now handle long running threads with messaging ([4ecbb9a](https://github.com/iotaledger/twin-framework/commit/4ecbb9a526927d462d4fb3f95ba2a44889202753))
16
+ * nodeIdentity optional in IComponent methods ([c78dc17](https://github.com/iotaledger/twin-framework/commit/c78dc17f4357d3e1ae40e415f468d3eae13e81f4))
17
+ * provide module helper override ([e998a64](https://github.com/iotaledger/twin-framework/commit/e998a64842cfd18693a14444be33b084fef2bb90))
18
+ * relocate core packages from tools ([bcab8f3](https://github.com/iotaledger/twin-framework/commit/bcab8f3160442ea4fcaf442947462504f3d6a17d))
19
+ * retain detail in Errors from background threads ([52bdeef](https://github.com/iotaledger/twin-framework/commit/52bdeef7a75fd462ed118073b9dc7612304e038d))
20
+ * typescript 6 update ([1d10f31](https://github.com/iotaledger/twin-framework/commit/1d10f31e6516ec622773f45e88af82fe749b384a))
21
+ * update dependencies ([4da77ab](https://github.com/iotaledger/twin-framework/commit/4da77ab30f499e52825ac5a76f51436ceb59c26e))
22
+ * update dependencies ([f3bd015](https://github.com/iotaledger/twin-framework/commit/f3bd015efd169196b7e0335f5cab876ba6ca1d75))
23
+ * use cause instead of inner for errors ([1f4acc4](https://github.com/iotaledger/twin-framework/commit/1f4acc4d7a6b71a134d9547da9bf40de1e1e49da))
24
+
25
+
26
+ ### Bug Fixes
27
+
28
+ * ensure __decorate is defined for decorators ([103a563](https://github.com/iotaledger/twin-framework/commit/103a563ce01ebdef6240d2e590e7b026e8692684))
29
+ * module tests ([58fd497](https://github.com/iotaledger/twin-framework/commit/58fd497876aa65062001d146727e1084be891ac4))
30
+ * module tests ([e323b7b](https://github.com/iotaledger/twin-framework/commit/e323b7b62aa430cedbeb09e83c2388cd458a6d48))
31
+
32
+
33
+ ### Dependencies
34
+
35
+ * The following workspace dependencies were updated
36
+ * dependencies
37
+ * @twin.org/core bumped from 0.9.0-next.0 to 0.9.0-next.1
38
+ * @twin.org/context bumped from 0.9.0-next.0 to 0.9.0-next.1
39
+ * @twin.org/nameof bumped from 0.9.0-next.0 to 0.9.0-next.1
40
+ * devDependencies
41
+ * @twin.org/nameof-transformer bumped from 0.9.0-next.0 to 0.9.0-next.1
42
+ * @twin.org/nameof-vitest-plugin bumped from 0.9.0-next.0 to 0.9.0-next.1
43
+ * @twin.org/validate-locales bumped from 0.9.0-next.0 to 0.9.0-next.1
44
+
45
+ ## [0.0.4-next.15](https://github.com/iotaledger/twin-framework/compare/modules-v0.0.4-next.14...modules-v0.0.4-next.15) (2026-06-19)
46
+
47
+
48
+ ### Miscellaneous Chores
49
+
50
+ * **modules:** Synchronize repo versions
51
+
52
+
53
+ ### Dependencies
54
+
55
+ * The following workspace dependencies were updated
56
+ * dependencies
57
+ * @twin.org/core bumped from 0.0.4-next.14 to 0.0.4-next.15
58
+ * @twin.org/context bumped from 0.0.4-next.14 to 0.0.4-next.15
59
+ * @twin.org/nameof bumped from 0.0.4-next.14 to 0.0.4-next.15
60
+ * devDependencies
61
+ * @twin.org/nameof-transformer bumped from 0.0.4-next.14 to 0.0.4-next.15
62
+ * @twin.org/nameof-vitest-plugin bumped from 0.0.4-next.14 to 0.0.4-next.15
63
+ * @twin.org/validate-locales bumped from 0.0.4-next.14 to 0.0.4-next.15
64
+
65
+ ## [0.0.4-next.14](https://github.com/iotaledger/twin-framework/compare/modules-v0.0.4-next.13...modules-v0.0.4-next.14) (2026-06-18)
66
+
67
+
68
+ ### Miscellaneous Chores
69
+
70
+ * **modules:** Synchronize repo versions
71
+
72
+
73
+ ### Dependencies
74
+
75
+ * The following workspace dependencies were updated
76
+ * dependencies
77
+ * @twin.org/core bumped from 0.0.4-next.13 to 0.0.4-next.14
78
+ * @twin.org/context bumped from 0.0.4-next.13 to 0.0.4-next.14
79
+ * @twin.org/nameof bumped from 0.0.4-next.13 to 0.0.4-next.14
80
+ * devDependencies
81
+ * @twin.org/nameof-transformer bumped from 0.0.4-next.13 to 0.0.4-next.14
82
+ * @twin.org/nameof-vitest-plugin bumped from 0.0.4-next.13 to 0.0.4-next.14
83
+ * @twin.org/validate-locales bumped from 0.0.4-next.13 to 0.0.4-next.14
84
+
85
+ ## [0.0.4-next.13](https://github.com/iotaledger/twin-framework/compare/modules-v0.0.4-next.12...modules-v0.0.4-next.13) (2026-06-18)
86
+
87
+
88
+ ### Miscellaneous Chores
89
+
90
+ * **modules:** Synchronize repo versions
91
+
92
+
93
+ ### Dependencies
94
+
95
+ * The following workspace dependencies were updated
96
+ * dependencies
97
+ * @twin.org/core bumped from 0.0.4-next.12 to 0.0.4-next.13
98
+ * @twin.org/context bumped from 0.0.4-next.12 to 0.0.4-next.13
99
+ * @twin.org/nameof bumped from 0.0.4-next.12 to 0.0.4-next.13
100
+ * devDependencies
101
+ * @twin.org/nameof-transformer bumped from 0.0.4-next.12 to 0.0.4-next.13
102
+ * @twin.org/nameof-vitest-plugin bumped from 0.0.4-next.12 to 0.0.4-next.13
103
+ * @twin.org/validate-locales bumped from 0.0.4-next.12 to 0.0.4-next.13
104
+
105
+ ## [0.0.4-next.12](https://github.com/iotaledger/twin-framework/compare/modules-v0.0.4-next.11...modules-v0.0.4-next.12) (2026-06-18)
106
+
107
+
108
+ ### Miscellaneous Chores
109
+
110
+ * **modules:** Synchronize repo versions
111
+
112
+
113
+ ### Dependencies
114
+
115
+ * The following workspace dependencies were updated
116
+ * dependencies
117
+ * @twin.org/core bumped from 0.0.4-next.11 to 0.0.4-next.12
118
+ * @twin.org/context bumped from 0.0.4-next.11 to 0.0.4-next.12
119
+ * @twin.org/nameof bumped from 0.0.4-next.11 to 0.0.4-next.12
120
+ * devDependencies
121
+ * @twin.org/nameof-transformer bumped from 0.0.4-next.11 to 0.0.4-next.12
122
+ * @twin.org/nameof-vitest-plugin bumped from 0.0.4-next.11 to 0.0.4-next.12
123
+ * @twin.org/validate-locales bumped from 0.0.4-next.11 to 0.0.4-next.12
124
+
125
+ ## [0.0.4-next.11](https://github.com/iotaledger/twin-framework/compare/modules-v0.0.4-next.10...modules-v0.0.4-next.11) (2026-06-15)
126
+
127
+
128
+ ### Miscellaneous Chores
129
+
130
+ * **modules:** Synchronize repo versions
131
+
132
+
133
+ ### Dependencies
134
+
135
+ * The following workspace dependencies were updated
136
+ * dependencies
137
+ * @twin.org/core bumped from 0.0.4-next.10 to 0.0.4-next.11
138
+ * @twin.org/context bumped from 0.0.4-next.10 to 0.0.4-next.11
139
+ * @twin.org/nameof bumped from 0.0.4-next.10 to 0.0.4-next.11
140
+ * devDependencies
141
+ * @twin.org/nameof-transformer bumped from 0.0.4-next.10 to 0.0.4-next.11
142
+ * @twin.org/nameof-vitest-plugin bumped from 0.0.4-next.10 to 0.0.4-next.11
143
+ * @twin.org/validate-locales bumped from 0.0.4-next.10 to 0.0.4-next.11
144
+
145
+ ## [0.0.4-next.10](https://github.com/iotaledger/twin-framework/compare/modules-v0.0.4-next.9...modules-v0.0.4-next.10) (2026-06-15)
146
+
147
+
148
+ ### Features
149
+
150
+ * add context id features ([#206](https://github.com/iotaledger/twin-framework/issues/206)) ([ef0d4ee](https://github.com/iotaledger/twin-framework/commit/ef0d4ee11a4f5fc6cc6f52a4958ce905c04ee13b))
151
+ * add guards arrayEndsWith and arrayStartsWith ([95d875e](https://github.com/iotaledger/twin-framework/commit/95d875ec8ccb4713c145fdde941d4cfedcec2ed3))
152
+ * add mutex ([#316](https://github.com/iotaledger/twin-framework/issues/316)) ([1027e5a](https://github.com/iotaledger/twin-framework/commit/1027e5ac77aa9804178b4253abdeefd6f1c3d521))
153
+ * automatically handle SharedObjectBuffer message in module threads ([10510ff](https://github.com/iotaledger/twin-framework/commit/10510ff4180a2cfbb51aa5a65c57362291826077))
154
+ * eslint migration to flat config ([74427d7](https://github.com/iotaledger/twin-framework/commit/74427d78d342167f7850e49ab87269326355befe))
155
+ * improve async pattern and error handling ([aaa1f68](https://github.com/iotaledger/twin-framework/commit/aaa1f6879d60adf04b78b0c1bbbec50f2873f020))
156
+ * improve Is.function and ModuleHelper.getModuleMethod signatures ([ecf968b](https://github.com/iotaledger/twin-framework/commit/ecf968b02934b3676be4bf7cd2d1e7f8e7af6ce2))
157
+ * locales validation ([#197](https://github.com/iotaledger/twin-framework/issues/197)) ([55fdadb](https://github.com/iotaledger/twin-framework/commit/55fdadb13595ce0047f787bd1d4135d429a99f12))
158
+ * module helper can now handle long running threads with messaging ([4ecbb9a](https://github.com/iotaledger/twin-framework/commit/4ecbb9a526927d462d4fb3f95ba2a44889202753))
159
+ * nodeIdentity optional in IComponent methods ([c78dc17](https://github.com/iotaledger/twin-framework/commit/c78dc17f4357d3e1ae40e415f468d3eae13e81f4))
160
+ * provide module helper override ([e998a64](https://github.com/iotaledger/twin-framework/commit/e998a64842cfd18693a14444be33b084fef2bb90))
161
+ * relocate core packages from tools ([bcab8f3](https://github.com/iotaledger/twin-framework/commit/bcab8f3160442ea4fcaf442947462504f3d6a17d))
162
+ * retain detail in Errors from background threads ([52bdeef](https://github.com/iotaledger/twin-framework/commit/52bdeef7a75fd462ed118073b9dc7612304e038d))
163
+ * typescript 6 update ([1d10f31](https://github.com/iotaledger/twin-framework/commit/1d10f31e6516ec622773f45e88af82fe749b384a))
164
+ * update dependencies ([4da77ab](https://github.com/iotaledger/twin-framework/commit/4da77ab30f499e52825ac5a76f51436ceb59c26e))
165
+ * update dependencies ([f3bd015](https://github.com/iotaledger/twin-framework/commit/f3bd015efd169196b7e0335f5cab876ba6ca1d75))
166
+ * use cause instead of inner for errors ([1f4acc4](https://github.com/iotaledger/twin-framework/commit/1f4acc4d7a6b71a134d9547da9bf40de1e1e49da))
167
+
168
+
169
+ ### Bug Fixes
170
+
171
+ * ensure __decorate is defined for decorators ([103a563](https://github.com/iotaledger/twin-framework/commit/103a563ce01ebdef6240d2e590e7b026e8692684))
172
+ * module tests ([58fd497](https://github.com/iotaledger/twin-framework/commit/58fd497876aa65062001d146727e1084be891ac4))
173
+ * module tests ([e323b7b](https://github.com/iotaledger/twin-framework/commit/e323b7b62aa430cedbeb09e83c2388cd458a6d48))
174
+
175
+
176
+ ### Dependencies
177
+
178
+ * The following workspace dependencies were updated
179
+ * dependencies
180
+ * @twin.org/core bumped from 0.0.4-next.9 to 0.0.4-next.10
181
+ * @twin.org/context bumped from 0.0.4-next.9 to 0.0.4-next.10
182
+ * @twin.org/nameof bumped from 0.0.4-next.9 to 0.0.4-next.10
183
+ * devDependencies
184
+ * @twin.org/nameof-transformer bumped from 0.0.4-next.9 to 0.0.4-next.10
185
+ * @twin.org/nameof-vitest-plugin bumped from 0.0.4-next.9 to 0.0.4-next.10
186
+ * @twin.org/validate-locales bumped from 0.0.4-next.9 to 0.0.4-next.10
187
+
188
+ ## [0.0.4-next.9](https://github.com/iotaledger/twin-framework/compare/modules-v0.0.4-next.8...modules-v0.0.4-next.9) (2026-06-15)
189
+
190
+
191
+ ### Miscellaneous Chores
192
+
193
+ * **modules:** Synchronize repo versions
194
+
195
+
196
+ ### Dependencies
197
+
198
+ * The following workspace dependencies were updated
199
+ * dependencies
200
+ * @twin.org/core bumped from 0.0.4-next.8 to 0.0.4-next.9
201
+ * @twin.org/context bumped from 0.0.4-next.8 to 0.0.4-next.9
202
+ * @twin.org/nameof bumped from 0.0.4-next.8 to 0.0.4-next.9
203
+ * devDependencies
204
+ * @twin.org/nameof-transformer bumped from 0.0.4-next.8 to 0.0.4-next.9
205
+ * @twin.org/nameof-vitest-plugin bumped from 0.0.4-next.8 to 0.0.4-next.9
206
+ * @twin.org/validate-locales bumped from 0.0.4-next.8 to 0.0.4-next.9
207
+
3
208
  ## [0.0.4-next.8](https://github.com/iotaledger/twin-framework/compare/modules-v0.0.4-next.7...modules-v0.0.4-next.8) (2026-06-10)
4
209
 
5
210
 
@@ -34,8 +34,6 @@ The context IDs.
34
34
 
35
35
  `void`
36
36
 
37
- The result of the method.
38
-
39
37
  ***
40
38
 
41
39
  ### terminate() {#terminate}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/modules",
3
- "version": "0.0.4-next.8",
3
+ "version": "0.9.0-next.1",
4
4
  "description": "Helper classes for loading and executing from modules",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,9 +14,9 @@
14
14
  "node": ">=20.0.0"
15
15
  },
16
16
  "dependencies": {
17
- "@twin.org/context": "0.0.4-next.8",
18
- "@twin.org/core": "0.0.4-next.8",
19
- "@twin.org/nameof": "0.0.4-next.8"
17
+ "@twin.org/context": "0.9.0-next.1",
18
+ "@twin.org/core": "0.9.0-next.1",
19
+ "@twin.org/nameof": "0.9.0-next.1"
20
20
  },
21
21
  "main": "./dist/es/index.js",
22
22
  "types": "./dist/types/index.d.ts",