@lotto24-angular/imports-orchestrator
Version:
Orchestrate dynamically imported components in Angular applications
1 lines • 79.3 kB
Source Map (JSON)
{"version":3,"file":"lotto24-angular-imports-orchestrator.mjs","sources":["../../../../libs/imports-orchestrator/src/lib/host-directive/import-lifecycle.directive.ts","../../../../libs/imports-orchestrator/src/lib/host-directive/import-css-class.directive.ts","../../../../libs/imports-orchestrator/src/lib/host-directive/import-io.directive.ts","../../../../libs/imports-orchestrator/src/lib/host-directive/util/find-import-priority.ts","../../../../libs/imports-orchestrator/src/lib/host-directive/util/find-fn.ts","../../../../libs/imports-orchestrator/src/lib/queue/process-queue-item.ts","../../../../libs/imports-orchestrator/src/lib/internal.ts","../../../../libs/imports-orchestrator/src/lib/queue/imports-queue-processor.service.ts","../../../../libs/imports-orchestrator/src/lib/service.ts","../../../../libs/imports-orchestrator/src/lib/host-directive/import-queue.directive.ts","../../../../libs/imports-orchestrator/src/lib/features/internal.ts","../../../../libs/imports-orchestrator/src/lib/features/concurrency.ts","../../../../libs/imports-orchestrator/src/lib/features/interceptor.ts","../../../../libs/imports-orchestrator/src/lib/features/routing.ts","../../../../libs/imports-orchestrator/src/lib/features/logger.ts","../../../../libs/imports-orchestrator/src/lib/features/timeout.ts","../../../../libs/imports-orchestrator/src/lib/resolve/util/bind-component-io.ts","../../../../libs/imports-orchestrator/src/lib/resolve/util/module.ts","../../../../libs/imports-orchestrator/src/lib/resolve/util/defer-until-component-ready.ts","../../../../libs/imports-orchestrator/src/lib/resolve/util/mount-component.ts","../../../../libs/imports-orchestrator/src/lib/resolve/util/resolve-constructor.ts","../../../../libs/imports-orchestrator/src/lib/resolve/import-standalone.ts","../../../../libs/imports-orchestrator/src/lib/resolve/import-ng-module.ts","../../../../libs/imports-orchestrator/src/lib/resolve/import-promise.ts","../../../../libs/imports-orchestrator/src/lib/component.ts","../../../../libs/imports-orchestrator/src/lib/decorator.ts","../../../../libs/imports-orchestrator/src/lib/directive.ts","../../../../libs/imports-orchestrator/src/lib/queue/queue.ts","../../../../libs/imports-orchestrator/src/lib/features/queue.ts","../../../../libs/imports-orchestrator/src/lib/features/orchestration.ts","../../../../libs/imports-orchestrator/src/lib/provide.ts","../../../../libs/imports-orchestrator/src/lotto24-angular-imports-orchestrator.ts"],"sourcesContent":["import { ComponentRef, Directive, EventEmitter, Output } from '@angular/core';\nimport { ImportLifecycle } from '../interface';\n\n@Directive({\n selector: '[importLifecycle]',\n standalone: true,\n})\nexport class ImportsOrchestratorLifecycleDirective implements ImportLifecycle {\n @Output() public importQueued = new EventEmitter<void>();\n @Output() public importStarted = new EventEmitter<void>();\n @Output() public importFinished = new EventEmitter<unknown>();\n @Output() public importComponent = new EventEmitter<ComponentRef<unknown>>();\n @Output() public importErrored = new EventEmitter<unknown>();\n}\n","import {\n ComponentRef,\n Directive,\n ElementRef,\n inject,\n Input,\n OnDestroy,\n Renderer2,\n} from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { ImportsOrchestratorLifecycleDirective } from './import-lifecycle.directive';\n\n@Directive({\n selector: '[importCSSClass]',\n standalone: true,\n})\nexport class ImportsOrchestratorCSSClassDirective implements OnDestroy {\n @Input() public cssClass!: string;\n\n private readonly subscriptions = new Subscription();\n private readonly lifecycle = inject(ImportsOrchestratorLifecycleDirective, {\n self: true,\n });\n\n constructor() {\n this.subscriptions.add(\n this.lifecycle.importComponent.subscribe(\n this.onImportComponent.bind(this)\n )\n );\n }\n\n private onImportComponent(componentRef: ComponentRef<unknown>): void {\n if (!this.cssClass) return;\n\n const renderer2 = componentRef.injector.get(Renderer2);\n const elementRef = componentRef.injector.get(ElementRef);\n const htmlElement = elementRef.nativeElement as HTMLElement;\n\n const classes = this.cssClass.match(/[^\\s]+/gi);\n classes?.forEach((c) => renderer2.addClass(htmlElement, c));\n }\n\n public ngOnDestroy(): void {\n this.subscriptions.unsubscribe();\n }\n}\n","import { Directive, Input, OnDestroy } from '@angular/core';\nimport { ReplaySubject, share, Subject, takeUntil } from 'rxjs';\nimport { ImportObservableComponentIO } from '../interface';\n\nexport type ComponentIO = { [index: string]: unknown };\n\n@Directive({\n selector: '[importLifecycle]',\n standalone: true,\n})\nexport class ImportsOrchestratorIODirective\n implements ImportObservableComponentIO, OnDestroy\n{\n private readonly destroy$ = new Subject<void>();\n public readonly _inputs = new ReplaySubject<ComponentIO>(1);\n public readonly inputs$ = this._inputs.pipe(\n takeUntil(this.destroy$),\n share()\n );\n public readonly _outputs = new ReplaySubject<ComponentIO>(1);\n public readonly outputs$ = this._outputs.pipe(\n takeUntil(this.destroy$),\n share()\n );\n\n @Input()\n public set inputs(value: ComponentIO | null) {\n this._inputs.next(value ?? {});\n }\n\n @Input()\n public set outputs(value: ComponentIO | null) {\n this._outputs.next(value ?? {});\n }\n\n public ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n}\n","import {ConsoleLike} from \"../../features\";\n\nexport const IMPORT_PRIORITY_LOWEST = 9999999999;\nexport function findImportPriority(\n priorities: { [p: string]: number },\n importId: string,\n logger: ConsoleLike\n): number {\n if (typeof priorities[importId] === 'number') {\n return priorities[importId];\n }\n\n const key = Object.keys(priorities).find((key) => importId.startsWith(key));\n\n if (key) {\n return priorities[key];\n }\n\n logger.warn(\n `no priority found for import '${importId}; falling back to lowest priority'`\n );\n\n return IMPORT_PRIORITY_LOWEST;\n}\n","export function findFn<T>(\n config: { [index: string]: string | T },\n key: string,\n trail: string[] = []\n): T {\n const stringOrFn = config[key];\n\n if (trail.includes(key)) {\n throw new Error(\n `circular reference found: ${[...trail, key].join(' => ')}`\n );\n }\n\n if (typeof stringOrFn === 'string') {\n return findFn(config, stringOrFn, [...trail, key]);\n }\n\n if (typeof stringOrFn === 'function') {\n return stringOrFn;\n }\n\n throw new Error(`Missing entry for key=\"${key}\"`);\n}\n","import {ImportsOrchestratorQueueItem} from '../service';\nimport {Queue} from './queue';\nimport {ConsoleLike} from \"../features\";\n\n/**\n * recursive loading of queued features\n */\nexport async function processQueueItem(\n queue: Queue<ImportsOrchestratorQueueItem>,\n logger: ConsoleLike,\n): Promise<void> {\n // let's take the next item off the queue\n const item = queue.take();\n\n // let's stop if there are no items in the queue\n if (!item) {\n logger.debug('queue is drained');\n return;\n }\n\n logger.debug(`queue item resolve (${item})`);\n\n try {\n item.hooks.start.next(item);\n item.lifecycle?.importStarted?.emit();\n const result = await item.resolveFn(item);\n item.hooks.finish.next(item);\n item.lifecycle?.importFinished?.emit(result);\n item.callback && item.callback(result, null);\n logger.debug(`queue item resolved (${item})`);\n } catch (x) {\n item.hooks.error.next([item, x]);\n item.lifecycle?.importErrored?.emit(x);\n item.callback && item.callback(null, x);\n logger.error(`error resolving queue item (${item})`, x);\n } finally {\n item.hooks.start.complete();\n item.hooks.finish.complete();\n item.hooks.error.complete();\n }\n}\n","import { InjectionToken } from '@angular/core';\nimport { Queue } from './queue/queue';\nimport { ImportsOrchestratorQueueItem } from './service';\nimport { ImportsOrchestration, ImportsStore } from './features/internal';\nimport { Observable } from 'rxjs';\nimport { ImportsInterceptor } from './interface';\n\nexport const IMPORTS_ORCHESTRATOR_FEATURE_CONCURRENCY = new InjectionToken<\n number | (() => number)\n>('IMPORTS_ORCHESTRATOR_FEAUTURE_CONCURRENCY');\nexport const IMPORTS_ORCHESTRATOR_FEATURE_INTERCEPTOR = new InjectionToken<ImportsInterceptor>('IMPORTS_ORCHESTRATOR_FEAUTURE_INTERCEPTOR');\nexport const IMPORTS_ORCHESTRATOR_FEATURE_ROUTING = new InjectionToken<\n Observable<boolean>\n>('IMPORTS_ORCHESTRATOR_FEAUTURE_DEFER_UNTIL_FIRST_NAVIGATION');\nexport const IMPORTS_ORCHESTRATOR_FEATURE_TIMEOUT = new InjectionToken<number>(\n 'IMPORTS_ORCHESTRATOR_FEAUTURE_TIMEOUT'\n);\nexport const IMPORTS_ORCHESTRATOR_FEATURE_LOGGER = new InjectionToken<\n Pick<Console, 'info' | 'warn' | 'error' | 'debug'>\n>('IMPORTS_ORCHESTRATOR_FEAUTURE_LOGGER');\nexport const IMPORTS_ORCHESTRATOR_FEATURE_QUEUE = new InjectionToken<\n Queue<ImportsOrchestratorQueueItem>\n>('IMPORTS_ORCHESTRATOR_FEATURE_QUEUE');\nexport const IMPORTS_ORCHESTRATOR_FEATURE_ORCHESTRATION =\n new InjectionToken<ImportsOrchestration>(\n 'IMPORTS_ORCHESTRATOR_FEATURE_ORCHESTRATION'\n );\n\nexport const IMPORTS_STORE: ImportsStore = {};\nexport const IMPORTS_ORCHESTRATOR_FEATURE_IMPORTS_STORE =\n new InjectionToken<ImportsStore>(\n 'IMPORTS_ORCHESTRATOR_FEATURE_IMPORTS_STORE',\n { providedIn: 'platform', factory: () => IMPORTS_STORE }\n );\n","import { inject, Injectable } from '@angular/core';\nimport { processQueueItem } from './process-queue-item';\nimport {\n IMPORTS_ORCHESTRATOR_FEATURE_CONCURRENCY,\n IMPORTS_ORCHESTRATOR_FEATURE_LOGGER,\n IMPORTS_ORCHESTRATOR_FEATURE_QUEUE,\n IMPORTS_ORCHESTRATOR_FEATURE_ROUTING,\n} from '../internal';\nimport { filter, firstValueFrom, tap } from 'rxjs';\n\n@Injectable({ providedIn: 'root' })\nexport class ImportsQueueProcessor {\n private static processing = false;\n\n private readonly logger = inject(IMPORTS_ORCHESTRATOR_FEATURE_LOGGER);\n private readonly queue = inject(IMPORTS_ORCHESTRATOR_FEATURE_QUEUE);\n private readonly isRoutingActive$ = inject(\n IMPORTS_ORCHESTRATOR_FEATURE_ROUTING\n );\n private readonly concurrency = inject(\n IMPORTS_ORCHESTRATOR_FEATURE_CONCURRENCY\n );\n\n private running = 0;\n\n public process(): void {\n if (!ImportsQueueProcessor.processing) {\n // do not await, as it would block the lifecycle callback from completing until the queue is processed\n ImportsQueueProcessor.processing = true;\n\n this.processQueue()\n .then(() => {\n this.logger.debug('queue processing ended');\n })\n .catch(() => {\n this.logger.debug('queue processing failed');\n })\n .finally(() => {\n ImportsQueueProcessor.processing = false;\n });\n }\n }\n\n private async processQueue(): Promise<void> {\n await this.suspendForNavigation();\n\n const concurrency = this.updateConcurrency();\n const concurrentBatch = [];\n for (let i = this.running; i < concurrency; i++) {\n this.running++;\n concurrentBatch.push(this.processItem());\n }\n this.logger.debug(\n `queue starting ${concurrentBatch.length} item(s) to reach max concurrency (running=${this.running})`\n );\n await Promise.all(concurrentBatch);\n }\n\n private async processItem(): Promise<void> {\n await processQueueItem(this.queue, this.logger);\n this.running--;\n if (!this.queue.empty) {\n await this.processQueue();\n }\n }\n\n private updateConcurrency(): number {\n const value =\n typeof this.concurrency === 'function'\n ? this.concurrency()\n : this.concurrency;\n\n if (value !== this.concurrency) {\n this.logger.debug(`queue concurrency changed to ${value}`);\n }\n\n return value;\n }\n\n private async suspendForNavigation(): Promise<unknown> {\n // suspend processing while routing, as navigation takes precedence\n return firstValueFrom(\n this.isRoutingActive$.pipe(\n tap((active) => {\n if (active) {\n this.logger.debug('queue processing suspended for navigation');\n }\n }),\n filter((active) => !active)\n )\n );\n }\n}\n","import {\n inject,\n Injectable,\n Injector,\n runInInjectionContext,\n} from '@angular/core';\nimport { findFn, findImportPriority } from './host-directive/util';\nimport { ImportsQueueProcessor } from './queue/imports-queue-processor.service';\nimport { Observable, Subject } from 'rxjs';\nimport { ImportResolveFn } from './resolve';\nimport {\n ImportLifecycle,\n ImportObservableComponentIO,\n ImportsInterceptorHooks,\n} from './interface';\n\nimport {\n IMPORTS_ORCHESTRATOR_FEATURE_IMPORTS_STORE,\n IMPORTS_ORCHESTRATOR_FEATURE_INTERCEPTOR,\n IMPORTS_ORCHESTRATOR_FEATURE_LOGGER,\n IMPORTS_ORCHESTRATOR_FEATURE_ORCHESTRATION,\n IMPORTS_ORCHESTRATOR_FEATURE_QUEUE,\n IMPORTS_ORCHESTRATOR_FEATURE_TIMEOUT,\n} from './internal';\nimport { ImportsStore } from './features/internal';\nimport { ConsoleLike } from './features';\n\nexport interface ImportServiceOptions {\n lifecycle?: Partial<ImportLifecycle>;\n io?: ImportObservableComponentIO;\n injector: Injector;\n timeout: number;\n}\n\ninterface InterceptorHooksSubjects extends ImportsInterceptorHooks {\n queued: Subject<ImportsOrchestratorQueueItem>;\n finish: Subject<ImportsOrchestratorQueueItem>;\n start: Subject<ImportsOrchestratorQueueItem>;\n error: Subject<[ImportsOrchestratorQueueItem, unknown]>;\n}\n\nexport interface ImportsOrchestratorQueueItem extends ImportServiceOptions {\n identifier: string;\n resolveFn: ImportResolveFn;\n priority: number;\n logger: ConsoleLike;\n destroy$: Observable<void>;\n hooks: InterceptorHooksSubjects;\n callback?: (result: unknown, err: unknown) => void;\n toString: () => string;\n}\n\n@Injectable({\n providedIn: 'root',\n})\nexport class ImportService {\n private readonly queueProcessor = inject(ImportsQueueProcessor);\n private readonly timeout = inject(IMPORTS_ORCHESTRATOR_FEATURE_TIMEOUT);\n private readonly logger = inject(IMPORTS_ORCHESTRATOR_FEATURE_LOGGER);\n private readonly queue = inject(IMPORTS_ORCHESTRATOR_FEATURE_QUEUE);\n private readonly orchestration = inject(\n IMPORTS_ORCHESTRATOR_FEATURE_ORCHESTRATION\n );\n private readonly interceptor = inject(\n IMPORTS_ORCHESTRATOR_FEATURE_INTERCEPTOR,\n { optional: true }\n );\n private readonly injector = inject(Injector);\n\n public createQueueItem(\n identifier: string,\n destroy$: Observable<void>,\n options: Partial<ImportServiceOptions> = {}\n ): Readonly<ImportsOrchestratorQueueItem> {\n const opts: ImportServiceOptions = {\n ...options,\n injector: options.injector ?? this.injector,\n timeout: options.timeout ?? this.timeout,\n };\n\n const imports = this.importsFromDI(opts.injector);\n const resolveFn = this.resolveFnFromImports(imports, identifier);\n\n const priority = findImportPriority(\n this.orchestration,\n identifier,\n this.logger\n );\n\n const hooks: InterceptorHooksSubjects = {\n queued: new Subject(),\n start: new Subject(),\n finish: new Subject(),\n error: new Subject(),\n };\n\n runInInjectionContext(this.injector, () => {\n if (this.interceptor) {\n this.interceptor(identifier, hooks);\n }\n });\n\n return {\n ...opts,\n priority,\n identifier,\n resolveFn,\n destroy$,\n hooks,\n logger: this.logger,\n toString: () => `@identifier=\"${identifier}\", @priority=${priority}`,\n };\n }\n\n public async addItemToQueue(\n item: ImportsOrchestratorQueueItem\n ): Promise<unknown> {\n const promise = new Promise((resolve, reject) => {\n item.callback = (result, err) => {\n if (err) {\n reject(err);\n } else {\n resolve(result);\n }\n };\n });\n\n this.queue.insert(item.priority, item);\n item.lifecycle?.importQueued?.emit();\n item.hooks.queued.next(item);\n item.hooks.queued.complete();\n\n this.logger.debug(`queue insert ${item.toString()}`);\n\n this.queueProcessor.process();\n\n return promise;\n }\n\n public async bypassQueue(\n item: ImportsOrchestratorQueueItem\n ): Promise<unknown> {\n this.logger.debug(`bypass queue ${item.toString()}`);\n\n return item.resolveFn(item);\n }\n\n public removeItemFromQueue(\n item: Readonly<ImportsOrchestratorQueueItem>\n ): boolean {\n return this.queue.take(item) !== undefined;\n }\n\n private importsFromDI(injector: Injector): ImportsStore {\n try {\n const store = injector.get(IMPORTS_ORCHESTRATOR_FEATURE_IMPORTS_STORE);\n return store;\n } catch (x: unknown) {\n throw new Error(`\n Could not inject ${IMPORTS_ORCHESTRATOR_FEATURE_IMPORTS_STORE}. Did you \\`provideImports({...})\\` in a component or module? If you did, you may need to provide an Injector when calling createQueueItem.\n ${x}`);\n }\n }\n\n private resolveFnFromImports(\n imports: ImportsStore,\n identifier: string\n ): ImportResolveFn {\n try {\n return findFn(imports, identifier);\n } catch (x) {\n throw new Error(`\n Could not find ImportResolveFn. Did you \\`provideImports({...})\\` in a component or module? If you did, you may need to provide an Injector when calling createQueueItem.\n ${x}`);\n }\n }\n}\n","import {\n Directive,\n inject,\n Injector,\n Input,\n NgModuleRef,\n OnChanges,\n OnDestroy,\n SimpleChanges,\n StaticProvider,\n ViewContainerRef,\n} from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { ImportsOrchestratorIODirective } from './import-io.directive';\nimport { ImportsOrchestratorLifecycleDirective } from './import-lifecycle.directive';\nimport {\n ImportService,\n ImportServiceOptions,\n ImportsOrchestratorQueueItem,\n} from '../service';\n\ntype ImportsOrchestratorQueueDirectiveExposed = Pick<\n ImportServiceOptions,\n 'io' | 'lifecycle'\n>;\n\n@Directive({\n selector: '[importQueue]',\n standalone: true,\n})\nexport class ImportsOrchestratorQueueDirective implements OnChanges, OnDestroy {\n @Input() public import!: string;\n @Input() public providers!: StaticProvider[];\n @Input() public timeout!: number;\n\n public readonly io = inject(ImportsOrchestratorIODirective, {\n self: true,\n });\n public readonly lifecycle = inject(ImportsOrchestratorLifecycleDirective, {\n self: true,\n });\n\n public readonly destroyComponents$ = new Subject<void>();\n public viewContainerRef = inject(ViewContainerRef);\n\n private readonly moduleRef = inject(NgModuleRef);\n\n private readonly importService = inject(ImportService);\n\n private item: ImportsOrchestratorQueueItem | null = null;\n\n public ngOnChanges(changes: SimpleChanges): void {\n const importInput = changes['import'];\n if (\n importInput !== undefined &&\n importInput.currentValue !== importInput.previousValue\n ) {\n this.createAndAddItemToQueue();\n }\n }\n\n public createAndAddItemToQueue(): void {\n this.removeItemFromQueue();\n this.destroyComponents$.next(); // destroy a previously mounted component(s)\n\n const injector = Injector.create({\n providers: [\n ...(this.providers ?? []),\n { provide: ViewContainerRef, useValue: this.viewContainerRef },\n ],\n parent: this.moduleRef.injector,\n });\n\n this.item = this.importService.createQueueItem(\n this.import,\n this.destroyComponents$,\n {\n ...(this as ImportsOrchestratorQueueDirectiveExposed),\n injector,\n lifecycle: this.lifecycle,\n }\n );\n\n this.importService.addItemToQueue(this.item);\n }\n\n private removeItemFromQueue(): void {\n if (this.item) {\n this.importService.removeItemFromQueue(this.item);\n this.item = null;\n }\n }\n\n public ngOnDestroy(): void {\n this.removeItemFromQueue();\n this.destroyComponents$.next();\n this.destroyComponents$.complete();\n }\n}\n","import { Provider } from '@angular/core';\nimport { ImportResolveFn } from '../resolve';\n\nexport type ImportsOrchestratorConcurrency =\n ImportsOrchestratorFeature<ImportsOrchestratorFeatureKind.Concurrency>;\n\nexport type ImportsOrchestratorInterceptor =\n ImportsOrchestratorFeature<ImportsOrchestratorFeatureKind.Interceptor>;\n\nexport type ImportsOrchestratorRouting =\n ImportsOrchestratorFeature<ImportsOrchestratorFeatureKind.Routing>;\n\nexport type ImportsOrchestratorTimeout =\n ImportsOrchestratorFeature<ImportsOrchestratorFeatureKind.Timeout>;\n\nexport type ImportsOrchestratorLogger =\n ImportsOrchestratorFeature<ImportsOrchestratorFeatureKind.Logger>;\n\nexport type ImportsOrhestratorQueue =\n ImportsOrchestratorFeature<ImportsOrchestratorFeatureKind.Queue>;\n\nexport type ImportsOrchestratorOrchestration =\n ImportsOrchestratorFeature<ImportsOrchestratorFeatureKind.Orchestration>;\n\nexport enum ImportsOrchestratorFeatureKind {\n Logger,\n Timeout,\n Routing,\n Concurrency,\n Interceptor,\n // internal\n Orchestration,\n Queue,\n}\n\n// internal utils\n\nexport type ImportsOrchestratorFeature<\n T extends ImportsOrchestratorFeatureKind\n> = {\n kind: T;\n providers: Provider[];\n};\n\nexport function importsOrchestratorFeature<\n T extends ImportsOrchestratorFeatureKind\n>(kind: T, providers: Provider[]): ImportsOrchestratorFeature<T> {\n return { kind, providers };\n}\n\nexport type ImportsOrchestration = {\n [index: string]: number;\n};\nexport type ImportsStore = {\n [index: string]: string | ImportResolveFn;\n};\n","import { Provider } from '@angular/core';\nimport {\n ImportsOrchestratorConcurrency,\n importsOrchestratorFeature,\n ImportsOrchestratorFeatureKind,\n} from './internal';\nimport { IMPORTS_ORCHESTRATOR_FEATURE_CONCURRENCY } from '../internal';\n\nexport function withConcurrencyRelativeToDownlinkSpeed(\n max: number = 4,\n min: number = 1\n): ImportsOrchestratorConcurrency {\n const providers: Provider[] = [\n {\n provide: IMPORTS_ORCHESTRATOR_FEATURE_CONCURRENCY,\n useValue: downlinkToConcurrencyFn(max, min),\n },\n ];\n return importsOrchestratorFeature(\n ImportsOrchestratorFeatureKind.Concurrency,\n providers\n );\n}\n\n/**\n * @param onUpdateConcurrencyFn called when queue processor updates concurrency;\n */\nexport function withConcurrencyUpdateFn(\n onUpdateConcurrencyFn: () => number\n): ImportsOrchestratorConcurrency {\n const providers: Provider[] = [\n {\n provide: IMPORTS_ORCHESTRATOR_FEATURE_CONCURRENCY,\n useValue: onUpdateConcurrencyFn,\n },\n ];\n\n return importsOrchestratorFeature(\n ImportsOrchestratorFeatureKind.Concurrency,\n providers\n );\n}\n\nexport function withConcurrencyStatic(\n value: number\n): ImportsOrchestratorConcurrency {\n const providers: Provider[] = [\n {\n provide: IMPORTS_ORCHESTRATOR_FEATURE_CONCURRENCY,\n useValue: value,\n },\n ];\n return importsOrchestratorFeature(\n ImportsOrchestratorFeatureKind.Concurrency,\n providers\n );\n}\n\nfunction downlinkToConcurrencyFn(max: number, min: number = 1): () => number {\n return () => {\n\n const downlink = (navigator as any).connection?.downlink ?? 10;\n\n if (downlink < 1) {\n return min;\n } else if (downlink < 2) {\n return Math.max(min, Math.floor(min + (max - min) / 4));\n } else if (downlink < 4) {\n return Math.max(min, Math.floor(min + (max - min) / 2));\n } else if (downlink < 8) {\n return Math.max(min, Math.floor(min + (max - min) / 1.5));\n }\n\n return max;\n };\n}\n","import {\n importsOrchestratorFeature,\n ImportsOrchestratorFeatureKind,\n ImportsOrchestratorInterceptor,\n} from './internal';\nimport { Provider } from '@angular/core';\nimport { IMPORTS_ORCHESTRATOR_FEATURE_INTERCEPTOR } from '../internal';\nimport { ImportsInterceptor } from '../interface';\n\nexport function withInterceptor(\n interceptor: ImportsInterceptor\n): ImportsOrchestratorInterceptor {\n const providers: Provider[] = [\n {\n provide: IMPORTS_ORCHESTRATOR_FEATURE_INTERCEPTOR,\n useValue: interceptor,\n },\n ];\n return importsOrchestratorFeature(\n ImportsOrchestratorFeatureKind.Interceptor,\n providers\n );\n}\n","import { Provider } from '@angular/core';\nimport {\n importsOrchestratorFeature,\n ImportsOrchestratorFeatureKind,\n ImportsOrchestratorRouting,\n} from './internal';\nimport { IMPORTS_ORCHESTRATOR_FEATURE_ROUTING } from '../internal';\nimport { NavigationEnd, NavigationStart, Router } from '@angular/router';\nimport {\n asyncScheduler,\n filter,\n map,\n Observable,\n observeOn,\n of,\n shareReplay,\n startWith,\n} from 'rxjs';\n\nexport function withSuspendWhileRouting(\n suspendForInitialNavigation = true\n): ImportsOrchestratorRouting {\n const providers: Provider[] = [\n {\n provide: IMPORTS_ORCHESTRATOR_FEATURE_ROUTING,\n useFactory: (router: Router) =>\n isRoutingActive$(router, suspendForInitialNavigation),\n deps: [Router],\n },\n ];\n return importsOrchestratorFeature(\n ImportsOrchestratorFeatureKind.Routing,\n providers\n );\n}\n\nexport function withoutRouting(): ImportsOrchestratorRouting {\n const providers: Provider[] = [\n {\n provide: IMPORTS_ORCHESTRATOR_FEATURE_ROUTING,\n useValue: of(false).pipe(shareReplay(1)),\n },\n ];\n return importsOrchestratorFeature(\n ImportsOrchestratorFeatureKind.Routing,\n providers\n );\n}\n\nfunction isRoutingActive$(\n router: Router,\n suspendForInitialNavigation: boolean\n): Observable<boolean> {\n const navigationActive$ = router.events.pipe(\n filter(\n (event) =>\n event instanceof NavigationStart || event instanceof NavigationEnd\n ),\n map((event) => {\n if (event instanceof NavigationStart) {\n return true;\n }\n\n return false;\n }),\n observeOn(asyncScheduler),\n startWith(suspendForInitialNavigation)\n );\n\n return navigationActive$.pipe(shareReplay(1));\n}\n","import { Provider } from '@angular/core';\nimport {\n importsOrchestratorFeature,\n ImportsOrchestratorFeatureKind,\n ImportsOrchestratorLogger,\n} from './internal';\nimport { IMPORTS_ORCHESTRATOR_FEATURE_LOGGER } from '../internal';\n\nexport type ConsoleLike = Pick<Console, 'info' | 'warn' | 'error' | 'debug'>;\n\nexport function withLogger(logger: ConsoleLike): ImportsOrchestratorLogger {\n const providers: Provider[] = [\n {\n provide: IMPORTS_ORCHESTRATOR_FEATURE_LOGGER,\n useValue: logger,\n },\n ];\n return importsOrchestratorFeature(\n ImportsOrchestratorFeatureKind.Logger,\n providers\n );\n}\n","import {\n importsOrchestratorFeature,\n ImportsOrchestratorFeatureKind,\n ImportsOrchestratorTimeout,\n} from './internal';\nimport { Provider } from '@angular/core';\nimport {IMPORTS_ORCHESTRATOR_FEATURE_TIMEOUT} from \"../internal\";\n\nexport function withTimeout(timeout: number = 10000): ImportsOrchestratorTimeout {\n const providers: Provider[] = [\n {\n provide: IMPORTS_ORCHESTRATOR_FEATURE_TIMEOUT,\n useValue: timeout,\n },\n ];\n return importsOrchestratorFeature(\n ImportsOrchestratorFeatureKind.Timeout,\n providers\n );\n}\n","import type { ComponentRef } from '@angular/core';\nimport {\n filter,\n mergeMap,\n pairwise,\n share,\n skip,\n startWith,\n takeUntil,\n} from 'rxjs';\nimport { ImportsOrchestratorQueueItem } from '../../service';\nimport { ComponentIO } from '../../host-directive';\n\nexport function bindComponentInputs(\n componentRef: ComponentRef<any>,\n item: ImportsOrchestratorQueueItem\n): void {\n item.io?.inputs$\n .pipe(\n takeUntil(item.destroy$),\n startWith({} as ComponentIO),\n pairwise(),\n filter(([_, current]) => Object.keys(current).length > 0),\n mergeMap(([previous, current]) =>\n Object.entries(current).filter(\n ([key, value]) => previous[key] !== value\n )\n )\n )\n .subscribe(([key, value]) => componentRef.setInput(key, value));\n}\n\nexport function bindComponentOutputs(\n componentRef: ComponentRef<any>,\n item: ImportsOrchestratorQueueItem\n): void {\n const outputs$ = item.io?.outputs$.pipe(share());\n if (!outputs$) return;\n\n const output$ = outputs$.pipe(\n takeUntil(item.destroy$),\n startWith({} as ComponentIO),\n pairwise(),\n filter(([_, current]) => Object.keys(current).length > 0),\n mergeMap(([previous, current]) =>\n Object.entries(current).filter(([key, value]) => !previous[key])\n )\n // tap(([key, value]) => console.log(key, value))\n );\n\n output$.subscribe(([key, value]) => {\n if (typeof value !== 'function') {\n throw new Error(\n `outputs.${key} must be a function, got '${typeof value}'`\n );\n }\n\n componentRef.instance[key]\n .pipe(\n takeUntil(item.destroy$),\n takeUntil(\n output$.pipe(\n filter(([k]) => k === key),\n skip(1) // skip the first value emitted from replay\n // tap(() => console.log('unsubscribe componentRef, key=' + key))\n )\n )\n )\n .subscribe((data: any) => {\n value(data);\n });\n });\n}\n","import { Type } from '@angular/core';\n\nexport interface ESModule {\n __esModule: boolean;\n}\n\nexport interface NgModuleDef<T> {\n bootstrap: Type<any>[] | (() => Type<any>[]);\n}\n\nexport const NG_MOD_DEF = getClosureSafeProperty({\n ɵmod: getClosureSafeProperty,\n});\nexport const ES_MODULE = getClosureSafeProperty({\n __esModule: getClosureSafeProperty,\n});\n\nexport function isESModule(type: any): type is ESModule {\n return type[Symbol.toStringTag] === 'Module' || type[ES_MODULE];\n}\n\nexport function isNgModuleDef<T>(\n type: any\n): type is Type<T> & { ɵmod: NgModuleDef<T> } {\n return !!type[NG_MOD_DEF];\n}\n\nfunction getClosureSafeProperty<T>(objWithPropertyToExtract: T): string {\n for (const key in objWithPropertyToExtract) {\n if (objWithPropertyToExtract[key] === (getClosureSafeProperty as any)) {\n return key;\n }\n }\n throw Error('Could not find renamed property on target object.');\n}\n","import { ImportedComponentReady } from '../imported-component-ready.interface';\nimport {\n catchError,\n filter,\n from,\n map,\n Observable,\n of,\n race,\n take,\n timeout,\n TimeoutError,\n} from 'rxjs';\nimport { ChangeDetectorRef, ComponentRef, Signal } from '@angular/core';\n\nimport { ImportsOrchestratorQueueItem } from '../../service';\nimport { assertPromise, assertSignal } from '@lotto24-angular/util';\nimport { toObservable } from '@angular/core/rxjs-interop';\n\nexport function deferUntilComponentReady$<T>(\n componentRef: ComponentRef<any>,\n item: ImportsOrchestratorQueueItem\n): Observable<void> {\n const instance = componentRef.instance;\n if (!assertImportedComponentReadyEmitter(instance)) {\n return of(undefined);\n }\n\n item.logger.debug(\n `deferring until component w/ import=${item.identifier} emits ready`\n );\n componentRef.injector.get(ChangeDetectorRef).markForCheck(); // ensure Lifecycle hooks are called\n\n return race(resolveReady(instance), item.destroy$).pipe(\n timeout(item.timeout),\n catchError((err) => {\n if (err instanceof TimeoutError) {\n item.logger.warn(\n `deferred component w/ import=${item.identifier} timed out after ${item.timeout}ms`\n );\n } else {\n item.logger.error(\n `deferred component w/ import=${item.identifier} errored: ${err}`\n );\n }\n return of(undefined);\n })\n );\n}\n\nexport function assertImportedComponentReadyEmitter(\n type: any\n): type is ImportedComponentReady {\n return (type as ImportedComponentReady).importedComponentReady !== undefined;\n}\n\nfunction resolveReady(instance: ImportedComponentReady): Observable<void> {\n const callback = instance.importedComponentReady.call(instance);\n if (assertPromise(callback)) {\n return from(callback);\n }\n\n return (\n assertSignal(callback)\n ? toObservable(callback as unknown as Signal<boolean>)\n : (callback as unknown as Observable<boolean>)\n ).pipe(\n filter((value) => value),\n map(() => undefined),\n take(1)\n );\n}\n","import { ChangeDetectorRef, ComponentRef } from '@angular/core';\nimport { bindComponentInputs, bindComponentOutputs } from './bind-component-io';\nimport { firstValueFrom } from 'rxjs';\nimport { deferUntilComponentReady$ } from './defer-until-component-ready';\nimport { ImportsOrchestratorQueueItem } from '../../service';\n\nexport async function mountComponent(\n componentRef: ComponentRef<unknown>,\n item: ImportsOrchestratorQueueItem\n): Promise<void> {\n item.destroy$.subscribe(() => componentRef.destroy());\n if (item.io) {\n bindComponentInputs(componentRef, item);\n bindComponentOutputs(componentRef, item);\n }\n try {\n await firstValueFrom(deferUntilComponentReady$(componentRef, item));\n } catch (x) {\n // no-op\n }\n\n // This will trigger Angular lifecycle on componentRef's entire component tree\n // * Bindings will be resolved\n // * Projected content will be processed\n // * Usages of ImportsOrchestratorQueueDirective in the tree will then insert items to the queue\n // * It is of vital importance that items are queued before triggering processQueue again\n // IMPORTANT: markForCheck is not enough, as it would not cause an immediate change detection cycle\n componentRef.injector.get(ChangeDetectorRef).detectChanges();\n}\n","import { Type } from '@angular/core';\nimport { ESModule, isESModule } from './module';\n\nexport type Constructor = Type<unknown>;\n\nexport function isAssumedESModuleContainingAngularComponentsOrModules(type: any) {\n return typeof type === 'object' && Object.keys(type).some(key => key.includes('Module') || key.includes('Component'));\n}\n\nexport function resolveConstructorsFromESModule(\n esm: ESModule | Constructor\n): Constructor[] {\n if (isESModule(esm) || isAssumedESModuleContainingAngularComponentsOrModules(esm)) {\n const constructors = Object.values<Constructor>(\n esm as unknown as { [index: string]: Constructor }\n ).filter((v) => typeof v === 'function');\n\n if (!constructors) {\n throw new Error('Class not found');\n }\n\n return constructors;\n }\n\n return [esm];\n}\n\n","import {\n Constructor,\n ESModule,\n mountComponent,\n resolveConstructorsFromESModule,\n} from './util';\nimport { ImportsOrchestratorQueueItem } from '../service';\nimport { ViewContainerRef } from '@angular/core';\nimport { ImportResolveFn } from './import-resolve-fn.interface';\nimport {\n assertStandalone,\n resolvePromiseWithRetries,\n} from '@lotto24-angular/util';\n\nexport function importStandalone(\n promise: () => Promise<unknown>\n): ImportResolveFn {\n return async (item: ImportsOrchestratorQueueItem) => {\n const resolvedImport = (await resolvePromiseWithRetries(promise)) as\n | Constructor\n | ESModule;\n const constructor = resolveConstructorsFromESModule(resolvedImport).shift();\n\n if (!constructor) {\n throw new Error('class not found');\n }\n\n assertStandalone(constructor);\n\n const viewContainerRef = item.injector.get(ViewContainerRef);\n\n const componentRef = viewContainerRef.createComponent(constructor, {\n injector: item.injector,\n });\n\n await mountComponent(componentRef, item);\n item.lifecycle?.importComponent?.emit(componentRef);\n return componentRef;\n };\n}\n","import {createEnvironmentInjector, createNgModule, Type, ViewContainerRef} from '@angular/core';\nimport {\n Constructor,\n ESModule,\n isNgModuleDef,\n mountComponent,\n resolveConstructorsFromESModule,\n} from './util';\nimport { ImportsOrchestratorQueueItem } from '../service';\nimport { ImportResolveFn } from './import-resolve-fn.interface';\nimport { resolvePromiseWithRetries } from '@lotto24-angular/util';\n\nexport function importNgModule(\n promise: () => Promise<unknown>\n): ImportResolveFn {\n return async (item: ImportsOrchestratorQueueItem) => {\n const resolvedImport = (await resolvePromiseWithRetries(promise)) as\n | Constructor\n | ESModule;\n const ngModuleConstructors = resolveConstructorsFromESModule(\n resolvedImport\n )?.filter((type) => isNgModuleDef(type));\n\n if (ngModuleConstructors?.length > 1) {\n item.logger.warn(\n `ES module should return a single NgModule definition, found ${ngModuleConstructors?.length}. Please append \\`.then(m => m.{DesiredModule})\\` to your dynamic import.`\n );\n }\n\n const ngModuleConstructor = ngModuleConstructors?.shift();\n\n if (!ngModuleConstructor) {\n throw new Error('no ngModuleRef constructor found');\n }\n\n\n const ngModuleRef = createNgModule(ngModuleConstructor, item.injector);\n\n const componentConstructors = (\n ngModuleRef as unknown as {\n _bootstrapComponents: Array<Type<unknown>> | null;\n }\n )._bootstrapComponents;\n\n if (!componentConstructors?.length) {\n item.logger.debug('no bootstrap components found in ngModuleRef');\n item.lifecycle?.importFinished?.emit(undefined);\n return;\n }\n\n const viewContainerRef = ngModuleRef.injector.get(ViewContainerRef);\n\n const mountComponentPromises = componentConstructors.map(\n (componentConstructor) => {\n const componentRef = viewContainerRef.createComponent(\n componentConstructor,\n { injector: ngModuleRef.injector, ngModuleRef }\n );\n\n return mountComponent(componentRef, item).then(() => componentRef);\n }\n );\n\n const componentRefs = await Promise.all(mountComponentPromises);\n componentRefs.forEach((componentRef) =>\n item.lifecycle?.importComponent?.emit(componentRef)\n );\n return componentRefs;\n };\n}\n","import { ImportResolveFn } from './import-resolve-fn.interface';\nimport { resolvePromiseWithRetries } from '@lotto24-angular/util';\n\nexport function importPromise(\n promise: () => Promise<unknown>\n): ImportResolveFn {\n return async () => resolvePromiseWithRetries(promise);\n}\n","import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n inject,\n Input,\n OnChanges,\n SimpleChanges,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport {\n ImportsOrchestratorCSSClassDirective,\n ImportsOrchestratorIODirective,\n ImportsOrchestratorLifecycleDirective,\n ImportsOrchestratorQueueDirective,\n} from './host-directive';\n\n@Component({\n selector: 'import',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n hostDirectives: [\n {\n directive: ImportsOrchestratorQueueDirective,\n // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property\n inputs: ['providers', 'timeout'],\n },\n {\n directive: ImportsOrchestratorIODirective,\n // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property\n inputs: ['inputs', 'outputs'],\n },\n {\n directive: ImportsOrchestratorLifecycleDirective,\n // eslint-disable-next-line @angular-eslint/no-outputs-metadata-property\n outputs: [\n 'importQueued',\n 'importStarted',\n 'importFinished',\n 'importComponent',\n 'importErrored',\n ],\n },\n {\n directive: ImportsOrchestratorCSSClassDirective,\n // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property\n inputs: ['cssClass'],\n },\n ],\n template: `<ng-container #container></ng-container>`,\n})\nexport class ImportsOrchestratorComponent implements OnChanges, AfterViewInit {\n @Input()\n public identifier!: string;\n\n private readonly queue = inject(ImportsOrchestratorQueueDirective, {\n self: true,\n });\n\n @ViewChild('container', { read: ViewContainerRef })\n container!: ViewContainerRef;\n\n public ngOnChanges(changes: SimpleChanges): void {\n const importInput = changes['import'];\n if (\n importInput !== undefined &&\n importInput.currentValue !== importInput.previousValue\n ) {\n this.createAndAddItemToQueue();\n }\n }\n\n public ngAfterViewInit(): void {\n this.createAndAddItemToQueue();\n }\n\n private createAndAddItemToQueue(): void {\n if (!this.identifier || !this.container) {\n return;\n }\n\n this.queue.viewContainerRef = this.container;\n this.queue.import = this.identifier;\n this.queue.createAndAddItemToQueue();\n }\n}\n","import { ImportsOrchestration } from './features/internal';\nimport { IMPORTS_STORE } from './internal';\nimport { ImportResolveFn } from './resolve';\n\nexport const Imports = <T extends ImportsOrchestration>(\n imports: Partial<{\n [key in keyof T]: keyof T | ImportResolveFn;\n }>\n) => {\n Object.entries(imports).forEach(([key, value]) => {\n IMPORTS_STORE[key] = value as ImportResolveFn | string;\n });\n\n return function (target: unknown) {\n // noop\n };\n};\n","import { Directive } from '@angular/core';\n\nimport {\n ImportsOrchestratorCSSClassDirective,\n ImportsOrchestratorIODirective,\n ImportsOrchestratorLifecycleDirective,\n ImportsOrchestratorQueueDirective,\n} from './host-directive';\n\n@Directive({\n selector: '[import]',\n standalone: true,\n hostDirectives: [\n {\n directive: ImportsOrchestratorQueueDirective,\n // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property\n inputs: ['import', 'providers', 'timeout'],\n },\n {\n directive: ImportsOrchestratorIODirective,\n // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property\n inputs: ['inputs', 'outputs'],\n },\n {\n directive: ImportsOrchestratorLifecycleDirective,\n // eslint-disable-next-line @angular-eslint/no-outputs-metadata-property\n outputs: [\n 'importQueued',\n 'importStarted',\n 'importFinished',\n 'importComponent',\n 'importErrored',\n ],\n },\n {\n directive: ImportsOrchestratorCSSClassDirective,\n // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property\n inputs: ['cssClass'],\n },\n ],\n})\nexport class ImportsOrchestratorDirective {}\n","interface Item<T> {\n priority: number;\n payload: T;\n}\n\nexport class Queue<T> {\n protected data: Item<T>[] = [];\n\n public insert(priority: number, payload: T): void {\n this.data = [...this.data, { priority, payload }].sort(comparePriority);\n }\n\n public take(payload: T | null = null): T | null {\n if (!payload) {\n return this.data.shift()?.payload || null;\n }\n\n return this.takeSpecific(payload);\n }\n\n public peek(): T | undefined {\n return this.data[0]?.payload;\n }\n\n public get length(): number {\n return this.data.length;\n }\n\n public get empty(): boolean {\n return this.length < 1;\n }\n\n private takeSpecific(payload: T): T | null {\n const index = this.data.findIndex((s) => s.payload === payload);\n if (index < 0) {\n return null;\n }\n\n payload = this.data[index].payload;\n const updated = this.data.slice();\n updated.splice(index, 1);\n this.data = updated;\n return payload;\n }\n}\n\nfunction comparePriority<T>(a: Item<T>, b: Item<T>) {\n return a.priority - b.priority;\n}\n","import {\n importsOrchestratorFeature,\n ImportsOrchestratorFeatureKind,\n ImportsOrhestratorQueue,\n} from './internal';\nimport { Provider } from '@angular/core';\nimport { Queue } from '../queue/queue';\nimport { ImportsOrchestratorQueueItem } from '../service';\nimport { IMPORTS_ORCHESTRATOR_FEATURE_QUEUE } from '../internal';\n\nexport function withQueue(\n queue: Queue<ImportsOrchestratorQueueItem>\n): ImportsOrhestratorQueue {\n const providers: Provider[] = [\n {\n provide: IMPORTS_ORCHESTRATOR_FEATURE_QUEUE,\n useValue: queue,\n },\n ];\n return importsOrchestratorFeature(\n ImportsOrchestratorFeatureKind.Queue,\n providers\n );\n}\n","import {\n ImportsOrchestration,\n importsOrchestratorFeature,\n ImportsOrchestratorFeatureKind,\n ImportsOrchestratorOrchestration,\n} from './internal';\nimport { Provider } from '@angular/core';\nimport {IMPORTS_ORCHESTRATOR_FEATURE_ORCHESTRATION, IMPORTS_ORCHESTRATOR_FEATURE_LOGGER} from \"../internal\";\nimport {ConsoleLike} from \"./logger\";\n\nexport function withOrchestration(\n orchestration: ImportsOrchestration\n): ImportsOrchestratorOrchestration {\n const providers: Provider[] = [\n {\n provide: IMPORTS_ORCHESTRATOR_FEATURE_ORCHESTRATION,\n useFactory: (logger: ConsoleLike) =>\n validateOrchestration(orchestration, logger),\n deps: [IMPORTS_ORCHESTRATOR_FEATURE_LOGGER],\n },\n ];\n return importsOrchestratorFeature(\n ImportsOrchestratorFeatureKind.Orchestration,\n providers\n );\n}\n\nfunction validateOrchestration(\n orchestration: ImportsOrchestration,\n logger: ConsoleLike\n) {\n const conflicts = findConflictingPriorities(orchestration).map(\n ([priority, imports]) =>\n `conflicting priority=${priority} for @imports=\"${imports.join('\", \"')}\"`\n );\n\n if (conflicts.length > 0) {\n logger.warn(conflicts.join('\\n'));\n }\n\n return orchestration;\n}\n\nfunction findConflictingPriorities(orchestration: ImportsOrchestration) {\n const byPriority = Object.entries(orchestration).reduce<{\n [key: number]: string[];\n }>((acc, [key, value]) => {\n acc[value] = [...(acc[value] || []), key];\n return acc;\n }, {});\n\n return Object.entries(byPriority).filter(\n ([order, imports]) => imports.length > 1\n );\n}\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport {\n ImportsOrchestration,\n ImportsOrchestratorConcurrency, ImportsOrchestratorInterceptor,\n ImportsOrchestratorLogger,\n ImportsOrchestratorRouting,\n ImportsOrchestratorTimeout,\n} from './features/internal';\nimport {\n withConcurrencyStatic,\n withLogger,\n withoutRouting,\n withTimeout,\n} from './features';\nimport { Queue } from './queue/queue';\nimport { ImportsOrchestratorQueueItem } from './service';\nimport { withQueue } from './features/queue';\nimport { withOrchestration } from './features/orchestration';\n\nexport type ImportsOrchestratorFeatures =\n | ImportsOrchestratorRouting\n | ImportsOrchestratorConcurrency\n | ImportsOrchestratorInterceptor\n | ImportsOrchestratorTimeout\n | ImportsOrchestratorLogger;\n\nexport const provideImportsOrchestration = <T>(\n orchestration: T & ImportsOrchestration,\n ...features: ImportsOrchestratorFeatures[]\n): EnvironmentProviders =>\n makeEnvironmentProviders([\n // default values:\n ...[\n withoutRouting(),\n withConcurrencyStatic(2),\n withLogger(console),\n withTimeout(10000),\n withQueue(new Queue<ImportsOrchestratorQueueItem>()),\n ].map((feature) => feature.providers),\n // configured values from features\n ...(features || []).map((feature) => feature.providers),\n ...withOrchestration(orchestration).providers,\n ]);\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.ImportsOrchestratorQueueDirective","i2.ImportsOrchestratorIODirective","i3.ImportsOrchestratorLifecycleDirective","i4.ImportsOrchestratorCSSClassDirective"],"mappings":"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