diff --git a/.changeset/tough-ears-laugh.md b/.changeset/tough-ears-laugh.md new file mode 100644 index 0000000000..81a09aa800 --- /dev/null +++ b/.changeset/tough-ears-laugh.md @@ -0,0 +1,5 @@ +--- +"@medusajs/modules-sdk": patch +--- + +chore: module as singleton instances diff --git a/packages/modules-sdk/src/loaders/__tests__/medusa-module.ts b/packages/modules-sdk/src/loaders/__tests__/medusa-module.ts new file mode 100644 index 0000000000..c7eea10511 --- /dev/null +++ b/packages/modules-sdk/src/loaders/__tests__/medusa-module.ts @@ -0,0 +1,61 @@ +import { + InternalModuleDeclaration, + MODULE_RESOURCE_TYPE, + MODULE_SCOPE, +} from "@medusajs/types" +import { MedusaModule } from "../../medusa-module" + +const mockRegisterMedusaModule = jest + .fn() + .mockImplementation(() => Promise.resolve([])) +const mockModuleLoader = jest.fn().mockImplementation(() => Promise.resolve({})) + +jest.mock("./../../loaders", () => ({ + registerMedusaModule: jest + .fn() + .mockImplementation((...args) => mockRegisterMedusaModule()), + moduleLoader: jest.fn().mockImplementation((...args) => mockModuleLoader()), +})) + +describe("Medusa Module", () => { + beforeEach(() => { + jest.resetModules() + jest.clearAllMocks() + }) + + it("MedusaModule bootstrap - Singleton instances", async () => { + await MedusaModule.bootstrap( + "moduleKey", + "@path", + { + scope: MODULE_SCOPE.INTERNAL, + resources: MODULE_RESOURCE_TYPE.ISOLATED, + resolve: "@path", + options: { + abc: 123, + }, + } as InternalModuleDeclaration, + {} + ) + + expect(mockRegisterMedusaModule).toBeCalledTimes(1) + expect(mockModuleLoader).toBeCalledTimes(1) + + await MedusaModule.bootstrap( + "moduleKey", + "@path", + { + scope: MODULE_SCOPE.INTERNAL, + resources: MODULE_RESOURCE_TYPE.ISOLATED, + resolve: "@path", + options: { + abc: 123, + }, + } as InternalModuleDeclaration, + {} + ) + + expect(mockRegisterMedusaModule).toBeCalledTimes(1) + expect(mockModuleLoader).toBeCalledTimes(1) + }) +}) diff --git a/packages/modules-sdk/src/loaders/__tests__/module-loader.ts b/packages/modules-sdk/src/loaders/__tests__/module-loader.ts index 400fddd3ae..5a419785e0 100644 --- a/packages/modules-sdk/src/loaders/__tests__/module-loader.ts +++ b/packages/modules-sdk/src/loaders/__tests__/module-loader.ts @@ -1,22 +1,12 @@ import { - ModuleResolution, MODULE_RESOURCE_TYPE, MODULE_SCOPE, + ModuleResolution, } from "@medusajs/types" -import { AwilixContainer, ClassOrFunctionReturning, Resolver } from "awilix" import { createMedusaContainer } from "medusa-core-utils" import { EOL } from "os" -import { moduleLoader } from "../module-loader" import { trackInstallation } from "../__mocks__/medusa-telemetry" - -function asArray( - resolvers: (ClassOrFunctionReturning | Resolver)[] -): { resolve: (container: AwilixContainer) => unknown[] } { - return { - resolve: (container: AwilixContainer): unknown[] => - resolvers.map((resolver) => container.build(resolver)), - } -} +import { moduleLoader } from "../module-loader" const logger = { warn: jest.fn(), diff --git a/packages/modules-sdk/src/loaders/register-modules.ts b/packages/modules-sdk/src/loaders/register-modules.ts index fd197c6519..a33bc8eed0 100644 --- a/packages/modules-sdk/src/loaders/register-modules.ts +++ b/packages/modules-sdk/src/loaders/register-modules.ts @@ -1,9 +1,9 @@ import { ExternalModuleDeclaration, InternalModuleDeclaration, + MODULE_SCOPE, ModuleDefinition, ModuleResolution, - MODULE_SCOPE, } from "@medusajs/types" import resolveCwd from "resolve-cwd" import MODULE_DEFINITIONS from "../definitions" @@ -49,7 +49,7 @@ export const registerMedusaModule = ( } if (moduleDeclaration.scope === MODULE_SCOPE.EXTERNAL) { - // TODO: getExternalModuleResolution(...)a + // TODO: getExternalModuleResolution(...) throw new Error("External Modules are not supported yet.") } diff --git a/packages/modules-sdk/src/medusa-module.ts b/packages/modules-sdk/src/medusa-module.ts index 693682aa12..5f86a62a0c 100644 --- a/packages/modules-sdk/src/medusa-module.ts +++ b/packages/modules-sdk/src/medusa-module.ts @@ -17,6 +17,7 @@ const logger: any = { } export class MedusaModule { + private static instances_: Map = new Map() public static async bootstrap( moduleKey: string, defaultPath: string, @@ -25,6 +26,10 @@ export class MedusaModule { ): Promise<{ [key: string]: any }> { + if (MedusaModule.instances_.has(moduleKey)) { + return MedusaModule.instances_.get(moduleKey) + } + let modDeclaration = declaration if (declaration?.scope !== MODULE_SCOPE.EXTERNAL) { modDeclaration = { @@ -56,6 +61,8 @@ export class MedusaModule { services[keyName] = container.resolve(registrationName) } + MedusaModule.instances_.set(moduleKey, services) + return services }