{"version":3,"file":"di-container.umd.cjs","sources":["../src/circular.ts","../src/classNames.ts","../src/stringifyServiceKey.ts","../src/ServiceResolutionError.ts","../src/Context.ts","../src/ServiceContainer.ts","../src/ServiceResolver.ts","../src/Container.ts","../src/constant.ts"],"sourcesContent":["import type { ServiceFactory } from \"./ServiceContainer\";\nimport type { ServicesMap } from \"./ServiceResolver\";\n\n/**\n * Helper function for service factories with circular dependencies registration.\n *\n * @param factory\n */\nexport function circular<\n  TServicesMap extends ServicesMap,\n  ServiceType extends object,\n>(\n  factory: ServiceFactory<TServicesMap, ServiceType>\n): ServiceFactory<TServicesMap, ServiceType> {\n  return ((context) => {\n    let instance: ServiceType;\n    const getService = () => {\n      if (!instance) {\n        instance = factory(context);\n      }\n      return instance;\n    };\n\n    return new Proxy(\n      {},\n      {\n        get(_: object, p: string | symbol, receiver: unknown): unknown {\n          return Reflect.get(getService(), p, receiver);\n        },\n        set(\n          _: object,\n          p: string | symbol,\n          newValue: unknown,\n          receiver: unknown\n        ): boolean {\n          return Reflect.set(getService(), p, newValue, receiver);\n        },\n        has(_: object, p: string | symbol): boolean {\n          return Reflect.has(getService(), p);\n        },\n        deleteProperty(_: object, p: string | symbol): boolean {\n          return Reflect.deleteProperty(getService(), p);\n        },\n        getPrototypeOf(): object | null {\n          return Reflect.getPrototypeOf(getService());\n        },\n        setPrototypeOf(_: object, v: object | null): boolean {\n          return Reflect.setPrototypeOf(getService(), v);\n        },\n        isExtensible(): boolean {\n          return Reflect.isExtensible(getService());\n        },\n        preventExtensions(): boolean {\n          return Reflect.preventExtensions(getService());\n        },\n        defineProperty(\n          _: object,\n          property: string | symbol,\n          attributes: PropertyDescriptor\n        ): boolean {\n          return Reflect.defineProperty(getService(), property, attributes);\n        },\n        getOwnPropertyDescriptor(\n          _: object,\n          p: string | symbol\n        ): PropertyDescriptor | undefined {\n          return Reflect.getOwnPropertyDescriptor(getService(), p);\n        },\n        ownKeys(): ArrayLike<string | symbol> {\n          return Reflect.ownKeys(getService());\n        },\n      }\n    ) as ServiceType;\n  }) as ServiceFactory<TServicesMap, ServiceType>;\n}\n","import type { Constructor } from \"./ServiceResolver\";\n\n/**\n * Class names map for keeping meaningful class names in error messages, after code minification.\n */\nexport const classNames: Map<Constructor<object>, string> = new Map();\n","import { classNames } from \"./classNames\";\nimport type { Constructor } from \"./ServiceResolver\";\n\n/**\n * Returns service name, using ServiceKey - either constructor, or string key of ServicesMap.\n *\n * @param key\n *\n * @internal\n */\nexport function stringifyServiceKey(key: unknown): string {\n  if (typeof key === \"function\") {\n    if (classNames.has(key as Constructor<object>)) {\n      return classNames.get(key as Constructor<object>) || key.name;\n    }\n    return key.name;\n  }\n\n  return String(key);\n}\n","import type { NamedServiceKey, ServicesMap } from \"./ServiceResolver\";\nimport { stringifyServiceKey } from \"./stringifyServiceKey\";\n\n/**\n * Service resolution error class.\n */\nexport class ServiceResolutionError<\n  TServicesMap extends ServicesMap,\n> extends Error {\n  /**\n   * ServiceResolutionError constructor.\n   *\n   * @param message\n   * @param resolutionStack\n   * @param cause\n   */\n  constructor(\n    message: string,\n    readonly resolutionStack: NamedServiceKey<TServicesMap>[],\n    readonly cause: Error | unknown\n  ) {\n    const resolutionStackMessage = resolutionStack\n      .slice()\n      .reverse()\n      .map(\n        (entry) =>\n          `Resolving service ${stringifyServiceKey(entry.service)}, named \"${entry.name}\"`\n      )\n      .join(\"\\n\");\n\n    const errorMessage =\n      message +\n      (cause ? `\\n${cause}` : \"\") +\n      `\\nResolution stack:\\n${resolutionStackMessage}`;\n\n    super(errorMessage);\n    this.name = \"ServiceResolutionError\";\n  }\n}\n","import type { ServiceFactory, ServiceLifecycle } from \"./ServiceContainer\";\nimport type { ServiceResolutionContext } from \"./ServiceResolutionContext\";\nimport { ServiceResolutionError } from \"./ServiceResolutionError\";\nimport type {\n  NamedServiceKey,\n  ResolvedServicesTuple,\n  ServiceTokensTuple,\n  ServicesMap,\n  ServiceKey,\n  ResolvedByKey,\n} from \"./ServiceResolver\";\nimport { stringifyServiceKey } from \"./stringifyServiceKey\";\n\n/**\n * Service registration record\n *\n * @internal\n */\nexport interface ServiceRegistration<SMap extends ServicesMap, ServiceType> {\n  /**\n   * Service name.\n   */\n  name: string;\n\n  /**\n   * Service instance, registered either using service container `registerConstant()` method, or created by service\n   * factory with \"singleton\" lifecycle.\n   */\n  instance?: ServiceType;\n\n  /**\n   * Service factory function.\n   */\n  factory?: ServiceFactory<SMap, ServiceType>;\n\n  /**\n   * Service lifecycle (only when service registered using factory).\n   */\n  lifecycle: ServiceLifecycle;\n}\n\n/**\n * Service resolution context class.\n */\nexport class Context<TServicesMap extends ServicesMap>\n  implements ServiceResolutionContext<TServicesMap>\n{\n  /**\n   * Storage of resolved service instances, registered with \"request\" lifecycle.\n   * @private\n   */\n  private readonly resolved: Map<\n    ServiceKey<TServicesMap>,\n    { name: string; service: unknown }[]\n  >;\n\n  /**\n   * Services resolution stack.\n   * @private\n   */\n  private readonly resolutionStack: NamedServiceKey<TServicesMap>[];\n\n  /**\n   * Delayed callbacks, executed after all dependencies stack resolution of current service resolution.\n   *\n   * @private\n   */\n  private readonly delayedCallbacksQueue: (() => void)[];\n\n  /**\n   * Context constructor.\n   *\n   * @param registry\n   */\n  constructor(\n    private readonly registry: Map<\n      ServiceKey<TServicesMap>,\n      ServiceRegistration<TServicesMap, unknown>[]\n    >\n  ) {\n    this.resolved = new Map();\n    this.resolutionStack = [];\n    this.delayedCallbacksQueue = [];\n  }\n\n  /**\n   * @inheritDoc\n   */\n  resolve<TServiceKey extends ServiceKey<TServicesMap>>(\n    key: TServiceKey,\n    name = \"default\"\n  ): ResolvedByKey<TServicesMap, TServiceKey> {\n    this.resolutionStack.push({ service: key, name });\n    let service: ResolvedByKey<TServicesMap, TServiceKey>;\n    try {\n      service = this.doResolve(key, name);\n      this.executeDelayed();\n      return service;\n    } finally {\n      this.resolutionStack.pop();\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  resolveAll<TServiceKey extends ServiceKey<TServicesMap>>(\n    key: TServiceKey\n  ): ResolvedByKey<TServicesMap, TServiceKey>[] {\n    const registrations = this.registry.get(key);\n    if (!registrations) {\n      return [];\n    }\n    return registrations.map(({ name }) => this.resolve(key, name));\n  }\n\n  /**\n   * @inheritDoc\n   */\n  resolveTuple<ServiceKeys extends ServiceTokensTuple<TServicesMap>>(\n    services: ServiceKeys\n  ): ResolvedServicesTuple<TServicesMap, ServiceKeys> {\n    return services.map((key) => {\n      if (typeof key === \"object\") {\n        return this.resolve(key.service, key.name);\n      }\n      return this.resolve(key);\n    }) as ResolvedServicesTuple<TServicesMap, ServiceKeys>;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  has(key: ServiceKey<TServicesMap>, name?: string): boolean {\n    const registrations = this.registry.get(key);\n    if (name === undefined) {\n      return !!registrations?.length;\n    }\n    return !!registrations && !!registrations.find((r) => r.name === name);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getStack(): NamedServiceKey<TServicesMap>[] {\n    return [...this.resolutionStack];\n  }\n\n  /**\n   * @inheritDoc\n   */\n  isResolvingFor(key: ServiceKey<TServicesMap>, name?: string): boolean {\n    return !!this.resolutionStack.find((entry) => {\n      return (\n        entry.service === key && (name === undefined || entry.name === name)\n      );\n    });\n  }\n\n  /**\n   * @inheritDoc\n   */\n  isDirectlyResolvingFor(\n    key: ServiceKey<TServicesMap>,\n    name?: string\n  ): boolean {\n    if (this.resolutionStack.length < 2) {\n      // Call made from resolution root.\n      return false;\n    }\n    const resolvingFor = this.resolutionStack[this.resolutionStack.length - 2];\n    return (\n      resolvingFor.service === key &&\n      (name === undefined || resolvingFor.name === name)\n    );\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getServiceNames(key: ServiceKey<TServicesMap>): string[] {\n    const registrations = this.registry.get(key);\n    if (!registrations) {\n      return [];\n    }\n    return registrations.map(({ name }) => name);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  delay(callback: () => void) {\n    this.delayedCallbacksQueue.push(callback);\n  }\n\n  /**\n   * Performs service resolution.\n   *\n   * @param key\n   * @param name\n   * @private\n   */\n  private doResolve<TServiceKey extends ServiceKey<TServicesMap>>(\n    key: TServiceKey,\n    name = \"default\"\n  ): ResolvedByKey<TServicesMap, TServiceKey> {\n    const alreadyResolved = this.findInResolved(key, name);\n    if (alreadyResolved) {\n      return alreadyResolved;\n    }\n\n    return this.resolveRegistered(key, name);\n  }\n\n  /**\n   * Resolves service, using container registration record.\n   *\n   * @param key\n   * @param name\n   * @private\n   */\n  private resolveRegistered<TServiceKey extends ServiceKey<TServicesMap>>(\n    key: TServiceKey,\n    name: string\n  ): ResolvedByKey<TServicesMap, TServiceKey> {\n    const registration = this.getServiceRegistration(key, name);\n\n    if (registration.instance) {\n      // Return instance, that was registered as constant or resolved earlier with \"singleton\" lifecycle.\n      return registration.instance;\n    }\n\n    if (!registration.factory) {\n      // Make sure we have service factory\n      throw new TypeError(\n        `Service \"${stringifyServiceKey(key)}\" has neither instance, nor factory.`\n      );\n    }\n\n    const instance = this.resolveWithErrorHandling(\n      key,\n      name,\n      registration.factory\n    );\n\n    if ([\"singleton\", \"request\"].includes(registration.lifecycle)) {\n      // Store resolved instance in resolution context cache for further resolutions.\n      this.saveInResolved(key, instance, name);\n\n      if (registration.lifecycle === \"singleton\") {\n        // Store resolved value in container registration.\n        registration.instance = instance;\n      }\n    }\n\n    return instance;\n  }\n\n  /**\n   * Executes service factory with errors handling and returns resolved value.\n   *\n   * @param key\n   * @param name\n   * @param factory\n   * @private\n   */\n  private resolveWithErrorHandling<\n    TServiceKey extends ServiceKey<TServicesMap>,\n  >(\n    key: TServiceKey,\n    name: string,\n    factory: ServiceFactory<\n      TServicesMap,\n      ResolvedByKey<TServicesMap, TServiceKey>\n    >\n  ): ResolvedByKey<TServicesMap, TServiceKey> {\n    try {\n      this.checkForCircularDependency();\n      return factory(this);\n    } catch (e) {\n      if (e instanceof ServiceResolutionError) {\n        throw e;\n      }\n      throw new ServiceResolutionError(\n        `An error occurred in \"${stringifyServiceKey(key)}\" service factory, named \"${name}\"`,\n        this.getStack(),\n        e\n      );\n    }\n  }\n\n  /**\n   * Searches for previously resolved service instance in context resolved services storage..\n   *\n   * @param key\n   * @param name\n   * @private\n   */\n  private findInResolved<TServiceKey extends ServiceKey<TServicesMap>>(\n    key: TServiceKey,\n    name: string\n  ): ResolvedByKey<TServicesMap, TServiceKey> | undefined {\n    const resolved = this.resolved.get(key) as\n      | { name: string; service: ResolvedByKey<TServicesMap, TServiceKey> }[]\n      | undefined;\n    if (!resolved) {\n      return;\n    }\n    const named = resolved.find((record) => record.name === name);\n    return (named && named.service) || undefined;\n  }\n\n  /**\n   * Stores resolved service with \"singleton\" or \"request\" lifecycle in context resolved services storage.\n   *\n   * @param key\n   * @param service\n   * @param name\n   * @private\n   */\n  private saveInResolved<TServiceKey extends ServiceKey<TServicesMap>>(\n    key: TServiceKey,\n    service: ResolvedByKey<TServicesMap, TServiceKey>,\n    name: string\n  ): void {\n    const existingResolved = this.resolved.get(key);\n    if (!existingResolved) {\n      this.resolved.set(key, [{ service, name }]);\n      return;\n    }\n    const existingNamed = existingResolved.find(\n      (record) => record.name === name\n    );\n    if (existingNamed) {\n      existingNamed.service = service;\n      return;\n    }\n\n    existingResolved.push({ service, name });\n  }\n\n  /**\n   * Searches for service registration using service key and name. Throws `RangeError` if registration is not found.\n   *\n   * @param key\n   * @param name\n   * @private\n   */\n  private getServiceRegistration<TServiceKey extends ServiceKey<TServicesMap>>(\n    key: TServiceKey,\n    name: string\n  ): ServiceRegistration<\n    TServicesMap,\n    ResolvedByKey<TServicesMap, TServiceKey>\n  > {\n    const registrations = this.registry.get(key) as\n      | ServiceRegistration<\n          TServicesMap,\n          ResolvedByKey<TServicesMap, TServiceKey>\n        >[]\n      | undefined;\n    if (!registrations) {\n      throw new RangeError(\n        `Service \"${stringifyServiceKey(key)}\" is not found.`\n      );\n    }\n    const registration = registrations.find((record) => record.name === name);\n    if (!registration) {\n      throw new RangeError(\n        `Service \"${stringifyServiceKey(key)}\", named \"${name}\" is not found.`\n      );\n    }\n    return registration;\n  }\n\n  /**\n   * Checks for circular dependencies and throws Error, if circular dependency was found.\n   *\n   * @private\n   */\n  private checkForCircularDependency() {\n    const resolutionStackPath = this.resolutionStack.map(\n      (entry) => `${stringifyServiceKey(entry.service)}[${entry.name}]`\n    );\n    const current = resolutionStackPath.pop();\n    if (!current) {\n      // This shouldn't happen\n      return;\n    }\n    const firstAppeared = resolutionStackPath.indexOf(current);\n    if (firstAppeared < 0) {\n      // If no previous requests for current service was made -- no circular dependency\n      return;\n    }\n\n    // Get resolutions stack from first request of current service to the previous resolution.\n    const substack = resolutionStackPath.slice(firstAppeared);\n    if (substack.length % 2) {\n      // If sub-stack length is odd, no circular dependency\n      return;\n    }\n\n    // Divide sub-stack into two equal arrays and compare - if they're equal - circular dependency detected.\n    const first = substack.splice(substack.length / 2, substack.length / 2);\n    for (let i = 0; i < first.length; i++) {\n      if (first[i] !== substack[i]) {\n        return;\n      }\n    }\n\n    // Circular dependency detected.\n    const circularPath = first.join(\" < \") + ` < (CIRCULAR) ${current}`;\n    throw new Error(\n      `Circular dependency detected: ${circularPath}.\\nRefer to the documentation for options for resolving circular dependencies.`\n    );\n  }\n\n  /**\n   * Executes delayed callbacks queue.\n   *\n   * @private\n   */\n  private executeDelayed(): void {\n    let callback = this.delayedCallbacksQueue.shift();\n    while (callback) {\n      callback();\n      callback = this.delayedCallbacksQueue.shift();\n    }\n  }\n}\n","import type { ServiceResolutionContext } from \"./ServiceResolutionContext\";\nimport type {\n  Constructor,\n  ResolvedByKey,\n  ServiceKey,\n  ServiceResolver,\n  ServicesMap,\n} from \"./ServiceResolver\";\n\n/**\n * Utility type. Infers union of keys of ServicesMap, which type is as given. Used for typing class dependencies tuple.\n */\nexport type ServiceResolvingKey<\n  TServicesMap extends ServicesMap,\n  ResolvedType,\n> =\n  | {\n      [K in keyof TServicesMap]: TServicesMap[K] extends ResolvedType\n        ? K\n        : never;\n    }[keyof TServicesMap]\n  | (ResolvedType extends object ? Constructor<ResolvedType> : never);\n\n/**\n * Utility type. Infers NamedServiceKey, resolving given ResolvedType. Used for typing class dependencies tuple.\n */\ntype ServiceResolvingToken<TServicesMap extends ServicesMap, ResolvedType> = {\n  /**\n   * ServiceKey, resolving given ResolvedType\n   */\n  service: ServiceResolvingKey<TServicesMap, ResolvedType>;\n\n  /**\n   * Service name.\n   */\n  name: string;\n};\n\n/**\n * Special object interface for providing constant class dependencies, when some class depends on primitive types.\n */\nexport interface ConstantToken<T> {\n  constant: T;\n}\n\n/**\n * Type guard for ConstantToken.\n *\n * @param obj\n */\nexport function isConstantToken(obj: unknown): obj is ConstantToken<unknown> {\n  return typeof obj === \"object\" && obj !== null && \"constant\" in obj;\n}\n\n/**\n * Type alias of class dependency token.\n */\nexport type DependencyToken<TServicesMap extends ServicesMap, ResolvedType> =\n  | ServiceResolvingKey<TServicesMap, ResolvedType>\n  | ServiceResolvingToken<TServicesMap, ResolvedType>\n  | ConstantToken<ResolvedType>\n  | (ResolvedType extends object ? Constructor<ResolvedType> : never);\n\n/**\n * Utility type. Infers tuple of DependencyToken's, which resolves tuple of class constructor arguments.\n */\nexport type DependenciesTuple<\n  TServicesMap extends ServicesMap,\n  Tuple extends [...unknown[]],\n> = {\n  [K in keyof Tuple]: DependencyToken<TServicesMap, Tuple[K]>;\n} & { length: Tuple[\"length\"] };\n\n/**\n * Utility type. Infers constructor of type, resolved using given TServiceKey. Infers `never`, when type, resolved\n * by given key, is not object type.\n */\nexport type InterfaceImplementation<\n  TServicesMap extends ServicesMap,\n  TServiceKey extends keyof TServicesMap,\n> = TServicesMap[TServiceKey] extends object\n  ? Constructor<TServicesMap[TServiceKey]>\n  : never;\n\n/**\n * Service factory function. Takes service resolution context and returns service instance.\n */\nexport interface ServiceFactory<TServicesMap extends ServicesMap, ServiceType> {\n  (context: ServiceResolutionContext<TServicesMap>): ServiceType;\n}\n\n/**\n * Service module interface.\n */\nexport interface ServiceModule<TServicesMap extends ServicesMap> {\n  /**\n   * Performs services registrations in given container.\n   *\n   * @param container\n   */\n  register(container: ServiceContainer<TServicesMap>): void;\n}\n\n/**\n * Lifecycle of services, created using factories:\n * - \"transient\": creates new service instance each time service is requested.\n * - \"singleton\": creates service instance when service is requested first time, and returns that service instance\n *    in all further service requests.\n * - \"request\": creates service instance once per root service resolution request and returns that instance in all further\n *    service requests in context of that root service resolution request.\n */\nexport type ServiceLifecycle = \"transient\" | \"singleton\" | \"request\";\n\n/**\n * Service registration options.\n */\nexport interface ServiceRegistrationOptions {\n  /**\n   * Service name. Used to distinguish between different variations of same interface.\n   * @default \"default\"\n   */\n  name?: string;\n\n  /**\n   * Used to replace service, that is already registered under given key and name. If omitted or set to false,\n   * TypeError will be thrown, if service under that key and name is already registered.\n   *\n   * @default false\n   */\n  replace?: boolean;\n}\n\n/**\n * Service factory registration options.\n */\nexport interface ServiceFactoryRegistrationOptions\n  extends ServiceRegistrationOptions {\n  /**\n   * Service lifecycle.\n   * @default \"transient\"\n   */\n  lifecycle?: ServiceLifecycle;\n}\n\n/**\n * Class config registration options.\n */\nexport interface ClassRegistrationOptions\n  extends ServiceFactoryRegistrationOptions {\n  /**\n   * Must be `true` for classes with circular dependencies.\n   * @default false\n   */\n  circular?: boolean;\n}\n\n/**\n * Interface implementation registration options.\n */\nexport interface ImplementationRegistrationOptions\n  extends ClassRegistrationOptions {}\n\n/**\n * Service container interface.\n */\nexport interface ServiceContainer<TServicesMap extends ServicesMap>\n  extends ServiceResolver<TServicesMap> {\n  /**\n   * Registers constant value under given key.\n   *\n   * @param key\n   * @param service\n   * @param options\n   */\n  registerConstant<TServiceKey extends ServiceKey<TServicesMap>>(\n    key: TServiceKey,\n    service: ResolvedByKey<TServicesMap, TServiceKey>,\n    options?: ServiceRegistrationOptions\n  ): void;\n\n  /**\n   * Registers service factory under given key.\n   *\n   * @param key\n   * @param factory\n   * @param options\n   */\n  registerFactory<TServiceKey extends ServiceKey<TServicesMap>>(\n    key: TServiceKey,\n    factory: ServiceFactory<\n      TServicesMap,\n      ResolvedByKey<TServicesMap, TServiceKey>\n    >,\n    options?: ServiceFactoryRegistrationOptions\n  ): void;\n\n  /**\n   * Registers class dependencies configuration, using class as key. Multiple configurations can be registered, using\n   * different names. If name is omitted, the name \"default\" is assigned implicitly.\n   *\n   * @param constructor\n   * @param deps\n   * @param options\n   *\n   * @example\n   *\n   * ```ts\n   * container.registerClassConfig(TextDecoder, [{constant: \"utf-8\"}]);\n   * container.registerClassConfig(TextDecoder, [{constant: \"KOI8-R\"}], {name: \"koi8-r\"});\n   * ```\n   */\n  registerClassConfig<\n    ConstructorType extends Constructor<object>,\n    DepsTuple extends DependenciesTuple<\n      TServicesMap,\n      ConstructorParameters<ConstructorType>\n    >,\n  >(\n    constructor: ConstructorType,\n    deps: DepsTuple,\n    options?: ClassRegistrationOptions\n  ): void;\n\n  /**\n   * Registers interface implementation, using key of ServicesMap, implementation constructor and DependenciesTuple.\n   *\n   * @param key\n   * @param implementation\n   * @param deps\n   * @param options\n   *\n   * @example\n   * ```ts\n   * class ConcreteApiClient implements ApiClient {\n   *    constructor(private readonly httpClient: HttpClient) {}\n   *    // ...\n   * }\n   *\n   * container.implement(\"ApiClient\", ConcreteApiClient, [\"HttpClient\"]);\n   * ```\n   */\n  implement<\n    ServiceKey extends keyof TServicesMap,\n    ConstructorType extends InterfaceImplementation<TServicesMap, ServiceKey>,\n    DepsTuple extends DependenciesTuple<\n      TServicesMap,\n      ConstructorParameters<ConstructorType>\n    >,\n  >(\n    key: ServiceKey,\n    implementation: ConstructorType,\n    deps: DepsTuple,\n    options?: ImplementationRegistrationOptions\n  ): void;\n\n  /**\n   * Loads ServiceModule.\n   *\n   * @param module\n   */\n  loadModule(module: ServiceModule<TServicesMap>): void;\n\n  /**\n   * Removes service registration. When name is omitted or is `undefined`, removes all registrations of that\n   * service. If name is passed, removes only service registration, that has given name.\n   * When 'cascade' argument is set to true, also removes that registration from all parent containers.\n   *\n   * @param key\n   * @param name\n   * @param cascade\n   */\n  unregister(\n    key: ServiceKey<TServicesMap>,\n    name?: string,\n    cascade?: boolean\n  ): void;\n\n  /**\n   * Creates child container. Child container can override any service registration, that exists in parent container,\n   * without changing parent container registrations. All parent container registrations are still available in child\n   * container.\n   */\n  createChild(): ServiceContainer<TServicesMap>;\n\n  /**\n   * Checks if container has own service registration of given key and optional name. Unlike `has()` method, it doesn't\n   * check registrations in parent container.\n   *\n   * @param key\n   * @param name\n   */\n  hasOwn(key: ServiceKey<TServicesMap>, name?: string): boolean;\n\n  /**\n   * Returns parent container, if it exists.\n   */\n  getParent(): ServiceContainer<TServicesMap> | undefined;\n\n  /**\n   * Creates snapshot of current container registrations and stores it in internal storage. Registrations can be restored\n   * later, using `restore()` method. Backups are stackable. When 'cascade' argument is set to true, then `backup()`\n   * method is called through all ancestor containers hierarchy.\n   *\n   * @param cascade\n   */\n  backup(cascade?: boolean): void;\n\n  /**\n   * Restores service registrations state to previous snapshot, made using `backup()` method. If there is no snapshots,\n   * does nothing. When 'cascade' argument is set to true, then `restore()` method is called through all ancestor\n   * containers hierarchy.\n   *\n   * @param cascade\n   */\n  restore(cascade?: boolean): void;\n\n  /**\n   * Creates instance of given class. Constructor dependencies are resolved, using DependenciesTuple.\n   *\n   * @param constructor\n   * @param deps\n   */\n  instantiate<\n    ConstructorType extends Constructor<object>,\n    DepsTuple extends DependenciesTuple<\n      TServicesMap,\n      ConstructorParameters<ConstructorType>\n    >,\n  >(\n    constructor: ConstructorType,\n    deps: DepsTuple\n  ): InstanceType<ConstructorType>;\n\n  /**\n   * Generates ServiceFactory of array of given services under `arrayKey`.\n   *\n   * @param key\n   * @param arrayKey\n   * @param options\n   *\n   * @example\n   * ```ts\n   * interface TypesMap extends ServicesMap {\n   *  DatabaseConnection: DatabaseConnection;\n   *  \"DatabaseConnection[]\": DatabaseConnection[];\n   * }\n   *\n   * // ...\n   *\n   * container.createArrayResolver(\"DatabaseConnection\", \"DatabaseConnection[]\");\n   * ```\n   */\n  createArrayResolver<TServiceKey extends ServiceKey<TServicesMap>>(\n    key: TServiceKey,\n    arrayKey: ServiceResolvingKey<\n      TServicesMap,\n      ResolvedByKey<TServicesMap, TServiceKey>[]\n    >,\n    options?: ServiceFactoryRegistrationOptions\n  ): void;\n}\n","/**\n * Services map. Defines service types, available in container. This base empty interface should be extended in\n * consuming application.\n * Interface property keys are strings, which are service keys, and values are service types.\n *\n * @exapmle\n *\n * ```ts\n * interface AppTypesMap extends ServicesMap {\n *   HttpClient: HttpClient;\n *   BackendApiClient: BackendApiClient;\n *   applicationKey: string;\n * }\n * ```\n */\nexport interface ServicesMap {}\n\n/**\n * Generic constructor.\n */\nexport type Constructor<ConstructedType extends object> = {\n  new (\n    ...args: any[] // eslint-disable-line @typescript-eslint/no-explicit-any\n  ): ConstructedType;\n  name: string;\n  length: number;\n};\n\n/**\n * Service key, used for service registration, resolution etc. This is either keyof ServicesMap, or class Constructor.\n */\nexport type ServiceKey<TServicesMap extends ServicesMap> =\n  | keyof TServicesMap\n  | Constructor<object>;\n\n/**\n * Utility type. Infers service type by ServiceKey.\n */\nexport type ResolvedByKey<\n  TServicesMap extends ServicesMap,\n  TServiceKey extends ServiceKey<TServicesMap>,\n> =\n  TServiceKey extends Constructor<infer ConstructedType>\n    ? ConstructedType\n    : TServiceKey extends keyof TServicesMap\n      ? TServicesMap[TServiceKey]\n      : never;\n\n/**\n * Object containing service key and name.\n */\nexport interface NamedServiceKey<TServicesMap extends ServicesMap> {\n  service: ServiceKey<TServicesMap>;\n  name: string;\n}\n\n/**\n * Type guard for NamedServiceKey.\n *\n * @param obj\n */\nexport function isNamedServiceKey(\n  obj: unknown\n): obj is NamedServiceKey<object> {\n  return (\n    typeof obj === \"object\" &&\n    obj !== null &&\n    \"service\" in obj &&\n    [\"string\", \"function\"].includes(typeof obj.service) &&\n    \"name\" in obj &&\n    typeof obj.name === \"string\"\n  );\n}\n\n/**\n * ServiceKey or NamedServiceKey. Used for services tuple resolution, declaring class dependencies etc.\n */\nexport type ServiceToken<TServicesMap extends ServicesMap> =\n  | ServiceKey<TServicesMap>\n  | NamedServiceKey<TServicesMap>;\n\n/**\n * Tuple of ServiceToken's.\n */\nexport type ServiceTokensTuple<TServicesMap extends ServicesMap> = [\n  ...ServiceToken<TServicesMap>[],\n];\n\n/**\n * Utility type. Infers service type, resolved using ServiceToken.\n */\nexport type ResolvedByToken<\n  TServicesMap extends ServicesMap,\n  TServiceToken extends ServiceToken<TServicesMap>,\n> =\n  TServiceToken extends NamedServiceKey<TServicesMap>\n    ? ResolvedByKey<TServicesMap, TServiceToken[\"service\"]>\n    : TServiceToken extends keyof TServicesMap\n      ? ResolvedByKey<TServicesMap, TServiceToken>\n      : never;\n\n/**\n * Utility type. Maps ServiceTokensTuple to resolved services tuple.\n */\nexport type ResolvedServicesTuple<\n  TServiceMap extends ServicesMap,\n  Tuple extends ServiceTokensTuple<TServiceMap>,\n> = {\n  [K in keyof Tuple]: ResolvedByToken<TServiceMap, Tuple[K]>;\n} & { length: Tuple[\"length\"] };\n\n/**\n * Service resolver interface.\n */\nexport interface ServiceResolver<TServicesMap extends ServicesMap> {\n  /**\n   * Resolves single service by its ServiceKey and optional name. If name is omitted or is `undefined`,\n   * \"default\" is used as name.\n   *\n   * @param key\n   * @param name\n   */\n  resolve<TServiceKey extends ServiceKey<TServicesMap>>(\n    key: TServiceKey,\n    name?: string\n  ): ResolvedByKey<TServicesMap, TServiceKey>;\n\n  /**\n   * Resolves array of services, registered under given key with different names. Returns empty array, when there is\n   * no services, registered under given key.\n   *\n   * @param key\n   */\n  resolveAll<TServiceKey extends ServiceKey<TServicesMap>>(\n    key: TServiceKey\n  ): ResolvedByKey<TServicesMap, TServiceKey>[];\n\n  /**\n   * Resolves tuple of services, using given ServiceTokensTuple. Used to get independent\n   * services in single resolution context, which means that same instance of services, having 'request' lifecycle\n   * will be resolved. There is no need to call this method inside service factories, since they're already resolves\n   * services in same context.\n   *\n   * @param services\n   */\n  resolveTuple<ServiceTokens extends ServiceTokensTuple<TServicesMap>>(\n    services: ServiceTokens\n  ): ResolvedServicesTuple<TServicesMap, ServiceTokens>;\n\n  /**\n   * Checks if given service exists. When name is omitted, returns true, when at least one registration of given service\n   * exists, ignoring registration name. When name is passed, returns true if there exists registration of given service\n   * with given name.\n   *\n   * @param key\n   * @param name\n   */\n  has(key: ServiceKey<TServicesMap>, name?: string): boolean;\n\n  /**\n   * Returns array of service names, registered under given key. If service was registered without explicit name,\n   * it will have name \"default\".\n   * @param key\n   */\n  getServiceNames(key: ServiceKey<TServicesMap>): string[];\n}\n","import { circular } from \"./circular\";\nimport { Context, type ServiceRegistration } from \"./Context\";\nimport {\n  type ClassRegistrationOptions,\n  type ConstantToken,\n  type DependenciesTuple,\n  type ImplementationRegistrationOptions,\n  type InterfaceImplementation,\n  isConstantToken,\n  type ServiceContainer,\n  type ServiceFactory,\n  type ServiceFactoryRegistrationOptions,\n  type ServiceModule,\n  type ServiceRegistrationOptions,\n  type ServiceResolvingKey,\n} from \"./ServiceContainer\";\nimport {\n  type ResolvedServicesTuple,\n  type ServiceTokensTuple,\n  type ServicesMap,\n  type ServiceKey,\n  type ResolvedByKey,\n  type Constructor,\n  isNamedServiceKey,\n  type NamedServiceKey,\n} from \"./ServiceResolver\";\nimport { stringifyServiceKey } from \"./stringifyServiceKey\";\n\n/**\n * Service container.\n */\nexport class Container<TServicesMap extends ServicesMap>\n  implements ServiceContainer<TServicesMap>\n{\n  /**\n   * Services registrations storage.\n   *\n   * @private\n   */\n  private registry: Map<\n    ServiceKey<TServicesMap>,\n    ServiceRegistration<TServicesMap, unknown>[]\n  >;\n\n  /**\n   * Backup snapshots stack.\n   *\n   * @private\n   */\n  private readonly snapshots: Map<\n    ServiceKey<TServicesMap>,\n    ServiceRegistration<TServicesMap, unknown>[]\n  >[];\n\n  /**\n   * Container constructor.\n   *\n   * @param parent\n   */\n  constructor(private readonly parent?: Container<TServicesMap>) {\n    this.registry = new Map();\n    this.snapshots = [];\n  }\n\n  /**\n   * @inheritDoc\n   */\n  resolve<TServiceKey extends ServiceKey<TServicesMap>>(\n    key: TServiceKey,\n    name?: string\n  ): ResolvedByKey<TServicesMap, TServiceKey> {\n    return new Context(this.getMergedRegistry()).resolve(key, name);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  resolveAll<TServiceKey extends ServiceKey<TServicesMap>>(\n    key: TServiceKey\n  ): ResolvedByKey<TServicesMap, TServiceKey>[] {\n    return new Context(this.getMergedRegistry()).resolveAll(key);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  resolveTuple<ServiceKeys extends ServiceTokensTuple<TServicesMap>>(\n    services: ServiceKeys\n  ): ResolvedServicesTuple<TServicesMap, ServiceKeys> {\n    return new Context(this.getMergedRegistry()).resolveTuple(services);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  registerConstant<TServiceKey extends ServiceKey<TServicesMap>>(\n    key: TServiceKey,\n    service: ResolvedByKey<TServicesMap, TServiceKey>,\n    options?: ServiceRegistrationOptions\n  ) {\n    this.registerConstantOrFactory(key, service, false, options);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  registerFactory<TServiceKey extends ServiceKey<TServicesMap>>(\n    key: TServiceKey,\n    factory: ServiceFactory<\n      TServicesMap,\n      ResolvedByKey<TServicesMap, TServiceKey>\n    >,\n    options?: ServiceFactoryRegistrationOptions\n  ) {\n    this.registerConstantOrFactory(key, factory, true, options);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  registerClassConfig<\n    ConstructorType extends Constructor<object>,\n    DepsTuple extends DependenciesTuple<\n      TServicesMap,\n      ConstructorParameters<ConstructorType>\n    >,\n  >(\n    constructor: ConstructorType,\n    deps: DepsTuple,\n    options: ClassRegistrationOptions = {}\n  ) {\n    const factory = this.createFactoryForConstructor(\n      constructor,\n      deps,\n      options.circular\n    );\n\n    this.registerFactory(\n      constructor,\n      factory as ServiceFactory<\n        TServicesMap,\n        ResolvedByKey<TServicesMap, ConstructorType>\n      >,\n      options\n    );\n  }\n\n  /**\n   * @inheritdoc\n   */\n  implement<\n    TServiceKey extends keyof TServicesMap,\n    ConstructorType extends InterfaceImplementation<TServicesMap, TServiceKey>,\n    DepsTuple extends DependenciesTuple<\n      TServicesMap,\n      ConstructorParameters<ConstructorType>\n    >,\n  >(\n    key: TServiceKey,\n    implementation: ConstructorType,\n    deps: DepsTuple,\n    options: ImplementationRegistrationOptions = {}\n  ) {\n    const factory = this.createFactoryForConstructor(\n      implementation,\n      deps,\n      options.circular\n    );\n\n    this.registerFactory(\n      key,\n      factory as ServiceFactory<\n        TServicesMap,\n        ResolvedByKey<TServicesMap, TServiceKey>\n      >,\n      options\n    );\n  }\n\n  /**\n   * @inheritDoc\n   */\n  loadModule(module: ServiceModule<TServicesMap>): void {\n    return module.register(this);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  unregister(key: ServiceKey<TServicesMap>, name?: string, cascade = false) {\n    this.unregisterOwn(key, name);\n    if (cascade && this.parent) {\n      this.parent.unregister(key, name, true);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  has(key: ServiceKey<TServicesMap>, name?: string): boolean {\n    if (this.hasOwn(key, name)) {\n      return true;\n    }\n    if (this.parent) {\n      return this.parent.has(key, name);\n    }\n    return false;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  hasOwn(key: ServiceKey<TServicesMap>, name?: string): boolean {\n    const registrations = this.registry.get(key);\n    if (name === undefined) {\n      return !!registrations?.length;\n    }\n    return !!registrations && !!registrations.find((r) => r.name === name);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  createChild(): Container<TServicesMap> {\n    return new Container(this);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getParent(): ServiceContainer<TServicesMap> | undefined {\n    return this.parent;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  backup(cascade = false) {\n    const newRegistry: Map<\n      ServiceKey<TServicesMap>,\n      ServiceRegistration<TServicesMap, unknown>[]\n    > = new Map();\n    for (const [key, registrations] of this.registry) {\n      newRegistry.set(\n        key,\n        registrations.map((registration) => ({ ...registration }))\n      );\n    }\n    this.snapshots.push(this.registry);\n    this.registry = newRegistry;\n\n    if (this.parent && cascade) {\n      this.parent.backup(true);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  restore(cascade = false) {\n    const snapshot = this.snapshots.pop();\n    if (snapshot) {\n      this.registry.clear();\n      this.registry = snapshot;\n    }\n\n    if (this.parent && cascade) {\n      this.parent.restore(true);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getServiceNames(key: ServiceKey<TServicesMap>): string[] {\n    const mergedRegistry = this.getMergedRegistry();\n    const registrations = mergedRegistry.get(key);\n    if (!registrations) {\n      return [];\n    }\n    return registrations.map(({ name }) => name);\n  }\n\n  /**\n   * @inheritdoc\n   */\n  instantiate<\n    ConstructorType extends Constructor<object>,\n    DepsTuple extends DependenciesTuple<\n      TServicesMap,\n      ConstructorParameters<ConstructorType>\n    >,\n  >(\n    constructor: ConstructorType,\n    deps: DepsTuple\n  ): InstanceType<ConstructorType> {\n    const factory = this.createFactoryForConstructor(constructor, deps);\n    const context = new Context(this.getMergedRegistry());\n    return factory(context);\n  }\n\n  /**\n   * @inheritdoc\n   */\n  createArrayResolver<TServiceKey extends ServiceKey<TServicesMap>>(\n    key: TServiceKey,\n    arrayKey: ServiceResolvingKey<\n      TServicesMap,\n      ResolvedByKey<TServicesMap, TServiceKey>[]\n    >,\n    options?: ServiceFactoryRegistrationOptions\n  ) {\n    this.registerFactory(\n      arrayKey,\n      (context) =>\n        context.resolveAll(key) as ResolvedByKey<\n          TServicesMap,\n          ServiceResolvingKey<\n            TServicesMap,\n            ResolvedByKey<TServicesMap, TServiceKey>[]\n          >\n        >,\n      options\n    );\n  }\n\n  /**\n   * Unregisters service from own registry.\n   *\n   * @param key\n   * @param name\n   * @private\n   */\n  private unregisterOwn(key: ServiceKey<TServicesMap>, name?: string) {\n    if (name === undefined) {\n      this.registry.delete(key);\n      return;\n    }\n    const registrations = this.registry.get(key);\n    if (registrations) {\n      const registration = registrations.find((r) => r.name === name);\n      if (registration) {\n        registrations.splice(registrations.indexOf(registration), 1);\n      }\n      if (!registrations.length) {\n        this.registry.delete(key);\n      }\n    }\n  }\n\n  /**\n   * Returns service registry, resulting from merging parent container registry and own registry.\n   *\n   * @protected\n   */\n  protected getMergedRegistry(): Map<\n    ServiceKey<TServicesMap>,\n    ServiceRegistration<TServicesMap, unknown>[]\n  > {\n    if (!this.parent) {\n      return this.registry;\n    }\n    const parentRegistry = this.parent.getMergedRegistry();\n    const result: Map<\n      ServiceKey<TServicesMap>,\n      ServiceRegistration<TServicesMap, unknown>[]\n    > = new Map();\n\n    // Get unique service keys from both registries.\n    const serviceKeys = new Set([\n      ...parentRegistry.keys(),\n      ...this.registry.keys(),\n    ]);\n\n    for (const serviceKey of serviceKeys) {\n      const parentRegistrations = parentRegistry.get(serviceKey);\n      const ownRegistrations = this.registry.get(serviceKey);\n      if (!parentRegistrations && ownRegistrations) {\n        result.set(serviceKey, ownRegistrations);\n        continue;\n      }\n      if (!ownRegistrations && parentRegistrations) {\n        result.set(serviceKey, parentRegistrations);\n        continue;\n      }\n      if (parentRegistrations && ownRegistrations) {\n        result.set(\n          serviceKey,\n          this.mergeRegistrations(parentRegistrations, ownRegistrations)\n        );\n      }\n    }\n\n    return result;\n  }\n\n  /**\n   * Merges own concrete service registrations with parent registrations.\n   *\n   * @param parentRegistrations\n   * @param ownRegistrations\n   * @private\n   */\n  private mergeRegistrations<T>(\n    parentRegistrations: ServiceRegistration<TServicesMap, T>[],\n    ownRegistrations: ServiceRegistration<TServicesMap, T>[]\n  ): ServiceRegistration<TServicesMap, T>[] {\n    const mergedRegistrations = [...parentRegistrations];\n    for (const registration of ownRegistrations) {\n      const parentRegistration = mergedRegistrations.find(\n        (r) => r.name === registration.name\n      );\n      if (parentRegistration) {\n        mergedRegistrations.splice(\n          mergedRegistrations.indexOf(parentRegistration),\n          1,\n          registration\n        );\n      } else {\n        mergedRegistrations.push(registration);\n      }\n    }\n    return mergedRegistrations;\n  }\n\n  /**\n   * Registers constant or service factory.\n   *\n   * @param key\n   * @param serviceOrFactory\n   * @param isFactory\n   * @param options\n   * @private\n   */\n  private registerConstantOrFactory<\n    TServiceKey extends ServiceKey<TServicesMap>,\n  >(\n    key: TServiceKey,\n    serviceOrFactory:\n      | ResolvedByKey<TServicesMap, TServiceKey>\n      | ServiceFactory<TServicesMap, ResolvedByKey<TServicesMap, TServiceKey>>,\n    isFactory: boolean,\n    options: ServiceFactoryRegistrationOptions = {}\n  ) {\n    const registration = this.createRegistration(\n      serviceOrFactory,\n      isFactory,\n      options\n    );\n\n    const existingRegistrations = this.registry.get(key) as\n      | ServiceRegistration<\n          TServicesMap,\n          ResolvedByKey<TServicesMap, TServiceKey>\n        >[]\n      | undefined;\n    if (!existingRegistrations) {\n      this.registry.set(key, [registration]);\n      return;\n    }\n\n    const { name } = registration;\n    const existingRegistration = existingRegistrations.find(\n      (r) => r.name === name\n    );\n    if (!existingRegistration) {\n      existingRegistrations.push(registration);\n      return;\n    }\n\n    if (!options.replace) {\n      throw new TypeError(\n        `Service \"${stringifyServiceKey(key)}\", named \"${name}\", already registered. Set 'replace' option to true, if you want to replace registration.`\n      );\n    }\n\n    const index = existingRegistrations.indexOf(existingRegistration);\n    existingRegistrations.splice(index, 1, registration);\n  }\n\n  /**\n   * Creates registration object.\n   *\n   * @param serviceOrFactory\n   * @param isFactory\n   * @param options\n   * @private\n   */\n  private createRegistration<ServiceType>(\n    serviceOrFactory: ServiceType | ServiceFactory<TServicesMap, ServiceType>,\n    isFactory: boolean,\n    options: ServiceFactoryRegistrationOptions\n  ): ServiceRegistration<TServicesMap, ServiceType> {\n    return {\n      name: options.name || \"default\",\n      lifecycle: options.lifecycle || \"transient\",\n      instance: !isFactory ? (serviceOrFactory as ServiceType) : undefined,\n      factory: isFactory\n        ? (serviceOrFactory as ServiceFactory<TServicesMap, ServiceType>)\n        : undefined,\n    };\n  }\n\n  /**\n   * Creates ServiceFactory function for given class constructor.\n   *\n   * @param constructor\n   * @param deps\n   * @param hasCircularDeps\n   * @private\n   */\n  private createFactoryForConstructor<\n    ConstructorType extends Constructor<object>,\n    DepsTuple extends DependenciesTuple<\n      TServicesMap,\n      ConstructorParameters<ConstructorType>\n    >,\n  >(\n    constructor: ConstructorType,\n    deps: DepsTuple,\n    hasCircularDeps = false\n  ): ServiceFactory<TServicesMap, InstanceType<ConstructorType>> {\n    let factory: ServiceFactory<TServicesMap, InstanceType<ConstructorType>> = (\n      context\n    ) => {\n      const resolvedDeps = (\n        deps as unknown as (\n          | ServiceKey<TServicesMap>\n          | NamedServiceKey<TServicesMap>\n          | ConstantToken<unknown>\n        )[]\n      ).map((dep) => {\n        if (isConstantToken(dep)) {\n          return dep.constant;\n        }\n        if (isNamedServiceKey(dep)) {\n          return context.resolve(dep.service, dep.name);\n        }\n        return context.resolve(dep as ServiceKey<TServicesMap>);\n      }) as ConstructorParameters<ConstructorType>;\n      return new constructor(...resolvedDeps) as InstanceType<ConstructorType>;\n    };\n\n    if (hasCircularDeps) {\n      factory = circular(factory);\n    }\n\n    return factory;\n  }\n}\n","import type { ConstantToken } from \"./ServiceContainer\";\n\n/**\n * Helper function for creating ConstantToken objects.\n *\n * @param value\n */\nexport function constant<T>(value: T): ConstantToken<T> {\n  return { constant: value };\n}\n"],"names":["circular","factory","context","instance","getService","Proxy","get","_","p","receiver","Reflect","set","newValue","has","deleteProperty","getPrototypeOf","setPrototypeOf","v","isExtensible","preventExtensions","defineProperty","property","attributes","getOwnPropertyDescriptor","ownKeys","classNames","Map","stringifyServiceKey","key","name","String","ServiceResolutionError","Error","message","resolutionStack","cause","super","slice","reverse","map","entry","service","join","this","Context","registry","resolved","delayedCallbacksQueue","push","t","doResolve","executeDelayed","pop","registrations","resolve","services","length","find","r","resolvingFor","callback","findInResolved","resolveRegistered","registration","getServiceRegistration","TypeError","resolveWithErrorHandling","includes","lifecycle","saveInResolved","checkForCircularDependency","e","getStack","named","record","existingResolved","existingNamed","RangeError","resolutionStackPath","current","firstAppeared","indexOf","substack","first","splice","i","circularPath","shift","isConstantToken","obj","isNamedServiceKey","Container","parent","snapshots","getMergedRegistry","resolveAll","resolveTuple","options","registerConstantOrFactory","constructor","deps","createFactoryForConstructor","registerFactory","implementation","module","register","cascade","unregisterOwn","unregister","hasOwn","createChild","newRegistry","backup","snapshot","clear","restore","arrayKey","delete","parentRegistry","result","serviceKeys","Set","keys","serviceKey","parentRegistrations","ownRegistrations","mergeRegistrations","mergedRegistrations","parentRegistration","serviceOrFactory","isFactory","createRegistration","existingRegistrations","existingRegistration","replace","index","hasCircularDeps","resolvedDeps","dep","constant","value"],"mappings":"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"}