{"version":3,"file":"ngxtension-inject-lazy.mjs","sources":["../../../../libs/ngxtension/inject-lazy/src/inject-lazy-impl.ts","../../../../libs/ngxtension/inject-lazy/src/inject-lazy.ts","../../../../libs/ngxtension/inject-lazy/src/ngxtension-inject-lazy.ts"],"sourcesContent":["import {\n\tDestroyRef,\n\tEnvironmentInjector,\n\tInjectable,\n\tInjector,\n\tType,\n\tcreateEnvironmentInjector,\n\tinject,\n\tprovideEnvironmentInitializer,\n\ttype Provider,\n\ttype ProviderToken,\n} from '@angular/core';\nimport type { Observable } from 'rxjs';\nimport { defer } from 'rxjs';\n\n/**\n * Lazy import type that includes default and normal imports\n */\nexport type LazyImportLoaderFn<T> = () =>\n\t| Promise<ProviderToken<T>>\n\t| Promise<{ default: ProviderToken<T> }>;\n\n@Injectable({ providedIn: 'root' })\nexport class InjectLazyImpl<T> {\n\tprivate overrides = new WeakMap(); // no need to clean up\n\toverride<T>(type: Type<T>, mock: Type<unknown>) {\n\t\tthis.overrides.set(type, mock);\n\t}\n\n\tget(injector: Injector, loader: LazyImportLoaderFn<T>): Observable<T> {\n\t\treturn defer(() =>\n\t\t\tloader().then((serviceOrDefault) => {\n\t\t\t\tconst type =\n\t\t\t\t\t'default' in serviceOrDefault\n\t\t\t\t\t\t? serviceOrDefault.default\n\t\t\t\t\t\t: serviceOrDefault;\n\n\t\t\t\t// Check if we have overrides, O(1), low overhead\n\t\t\t\tif (this.overrides.has(type)) {\n\t\t\t\t\tconst module = this.overrides.get(type);\n\t\t\t\t\treturn new module();\n\t\t\t\t}\n\n\t\t\t\t// If the service uses DestroyRef.onDestroy() it will never be called.\n\t\t\t\t// Even if injector is a NodeInjector, this works only with providedIn: root.\n\t\t\t\t// So it's the root injector that will provide the DestroyRef (and thus never call OnDestroy).\n\t\t\t\t// The solution would be to create an EnvironmentInjector that provides the class we just lazy-loaded.\n\t\t\t\tif (!(injector instanceof EnvironmentInjector)) {\n\t\t\t\t\t// We're passing a node injector to the function\n\n\t\t\t\t\t// This is the DestroyRef of the component\n\t\t\t\t\tconst destroyRef = injector.get(DestroyRef);\n\n\t\t\t\t\t// This is the parent injector of the environmentInjector we're creating\n\t\t\t\t\tconst environmentInjector = injector.get(EnvironmentInjector);\n\n\t\t\t\t\t// Creating an environment injector to destroy it afterward\n\t\t\t\t\tconst newInjector = createEnvironmentInjector(\n\t\t\t\t\t\t[type as Provider],\n\t\t\t\t\t\tenvironmentInjector,\n\t\t\t\t\t);\n\n\t\t\t\t\t// Destroy the injector to trigger DestroyRef.onDestroy on our service\n\t\t\t\t\tdestroyRef.onDestroy(() => newInjector.destroy());\n\n\t\t\t\t\t// We want to create the new instance of our service with our new injector\n\t\t\t\t\tinjector = newInjector;\n\t\t\t\t}\n\n\t\t\t\treturn injector.get(type)!;\n\t\t\t}),\n\t\t);\n\t}\n}\n\n/**\n * Helper function to mock the lazy-loaded module in `injectAsync`\n *\n * @usage\n * TestBed.configureTestingModule({\n *   providers: [\n *     mockLazyProvider(SandboxService, fakeSandboxService)\n *   ]\n * });\n */\nexport function mockLazyProvider<T>(type: Type<T>, mock: Type<unknown>) {\n\treturn [\n\t\tprovideEnvironmentInitializer(() => {\n\t\t\tinject(InjectLazyImpl).override(type, mock);\n\t\t}),\n\t];\n}\n","import { Injector } from '@angular/core';\nimport { assertInjector } from 'ngxtension/assert-injector';\nimport { Observable } from 'rxjs';\nimport type { LazyImportLoaderFn } from './inject-lazy-impl';\nimport { InjectLazyImpl } from './inject-lazy-impl';\n\n/**\n * Loads a service lazily. The service is loaded when the observable is subscribed to.\n *\n * @param loader A function that returns a promise of the service to load.\n * @param injector The injector to use to load the service. If not provided, the current injector is used.\n * @returns An observable of the service.\n *\n * @example\n * ```ts\n * const dataService$ = injectLazy(() => import('./data-service').then((m) => m.MyService));\n * or\n * const dataService$ = injectLazy(() => import('./data-service'));\n * ```\n */\nexport function injectLazy<T>(\n\tloader: LazyImportLoaderFn<T>,\n\tinjector?: Injector,\n): Observable<T> {\n\tinjector = assertInjector(injectLazy, injector);\n\tconst injectImpl = injector.get<InjectLazyImpl<T>>(InjectLazyImpl);\n\treturn injectImpl.get(injector, loader);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;MAuBa,cAAc,CAAA;AAD3B,IAAA,WAAA,GAAA;AAES,QAAA,IAAA,CAAA,SAAS,GAAG,IAAI,OAAO,EAAE,CAAC;AAiDlC,KAAA;IAhDA,QAAQ,CAAI,IAAa,EAAE,IAAmB,EAAA;QAC7C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;KAC/B;IAED,GAAG,CAAC,QAAkB,EAAE,MAA6B,EAAA;AACpD,QAAA,OAAO,KAAK,CAAC,MACZ,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,gBAAgB,KAAI;AAClC,YAAA,MAAM,IAAI,GACT,SAAS,IAAI,gBAAgB;kBAC1B,gBAAgB,CAAC,OAAO;kBACxB,gBAAgB,CAAC;;YAGrB,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;gBAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACxC,OAAO,IAAI,MAAM,EAAE,CAAC;aACpB;;;;;AAMD,YAAA,IAAI,EAAE,QAAQ,YAAY,mBAAmB,CAAC,EAAE;;;gBAI/C,MAAM,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;;gBAG5C,MAAM,mBAAmB,GAAG,QAAQ,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;;gBAG9D,MAAM,WAAW,GAAG,yBAAyB,CAC5C,CAAC,IAAgB,CAAC,EAClB,mBAAmB,CACnB,CAAC;;gBAGF,UAAU,CAAC,SAAS,CAAC,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;;gBAGlD,QAAQ,GAAG,WAAW,CAAC;aACvB;AAED,YAAA,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;SAC3B,CAAC,CACF,CAAC;KACF;8GAjDW,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA,EAAA;AAAd,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,cAAc,cADD,MAAM,EAAA,CAAA,CAAA,EAAA;;2FACnB,cAAc,EAAA,UAAA,EAAA,CAAA;kBAD1B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAA;;AAqDlC;;;;;;;;;AASG;AACa,SAAA,gBAAgB,CAAI,IAAa,EAAE,IAAmB,EAAA;IACrE,OAAO;QACN,6BAA6B,CAAC,MAAK;YAClC,MAAM,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAC7C,SAAC,CAAC;KACF,CAAC;AACH;;ACrFA;;;;;;;;;;;;;AAaG;AACa,SAAA,UAAU,CACzB,MAA6B,EAC7B,QAAmB,EAAA;AAEnB,IAAA,QAAQ,GAAG,cAAc,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAoB,cAAc,CAAC,CAAC;IACnE,OAAO,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AACzC;;AC3BA;;AAEG;;;;"}