{"version":3,"file":"dioma.umd.cjs","sources":["../src/errors.ts","../src/scopes.ts","../src/token.ts","../src/container.ts"],"sourcesContent":["export class DependencyCycleError extends Error {\n  constructor() {\n    super(\"Circular dependency detected\");\n  }\n}\n\nexport class AsyncDependencyCycleError extends Error {\n  constructor() {\n    super(\"Circular dependency detected in async resolution\");\n  }\n}\n\nexport class ArgumentsError extends Error {\n  constructor(scope: string, className: string) {\n    super(`Arguments are not supported for ${scope} of ${className}`);\n  }\n}\n\nexport class TokenNotRegisteredError extends Error {\n  constructor() {\n    super(\"Token is not registered in the container\");\n  }\n}\n","import { globalContainer } from \"./container\";\nimport { ArgumentsError } from \"./errors\";\nimport type { ScopeHandler } from \"./types\";\n\nexport class Scopes {\n  public static Singleton(): ScopeHandler {\n    return function SingletonScope(descriptor, args) {\n      if (args.length > 0) {\n        throw new ArgumentsError(SingletonScope.name, descriptor.class.name);\n      }\n\n      return globalContainer.$getInstance(descriptor);\n    };\n  }\n\n  public static Transient(): ScopeHandler {\n    return function TransientScope(descriptor, args, container) {\n      return container.$getInstance(descriptor, args, false);\n    };\n  }\n\n  public static Container(): ScopeHandler {\n    return function ContainerScope(descriptor, args, container) {\n      if (args.length > 0) {\n        throw new ArgumentsError(ContainerScope.name, descriptor.class.name);\n      }\n\n      return container.$getInstance(descriptor);\n    };\n  }\n\n  public static Resolution(): ScopeHandler {\n    return function ResolutionScope(descriptor, args, _, resolutionContainer) {\n      return resolutionContainer.$getInstance(descriptor, args);\n    };\n  }\n\n  public static Scoped = Scopes.Container;\n}\n","export class Token<T> {\n  constructor(public readonly name?: string) {}\n}\n","import {\n  AsyncDependencyCycleError,\n  DependencyCycleError,\n  TokenNotRegisteredError,\n} from \"./errors\";\nimport { Scopes } from \"./scopes\";\nimport { Token } from \"./token\";\nimport type {\n  AnyDescriptor,\n  ArgsOf,\n  InstanceOf,\n  ScopeHandler,\n  ScopedClass,\n  TokenClassDescriptor,\n  TokenFactoryDescriptor,\n  TokenOrClass,\n  TokenValueDescriptor,\n} from \"./types\";\n\ntype DescriptorWithContainer = AnyDescriptor & {\n  container: Container;\n};\n\nconst MAX_LOOP_COUNT = 100;\n\nexport class Container {\n  private instances = new WeakMap();\n\n  private resolutionContainer: Container | null = null;\n\n  private resolutionSet = new Set<TokenOrClass>();\n\n  private pendingPromiseMap = new Map<TokenOrClass, Promise<InstanceType<any>>>();\n\n  private tokenDescriptorMap = new Map<TokenOrClass, DescriptorWithContainer>();\n\n  private resolutionsLoopCounter = 0;\n\n  constructor(private parentContainer: Container | null = null, public name?: string) {\n    this.register = this.register.bind(this);\n  }\n\n  childContainer = (name?: string) => {\n    return new Container(this, name);\n  };\n\n  public $getInstance(\n    descriptor: TokenClassDescriptor<any>,\n    args: any[] = [],\n    cache = true\n  ) {\n    let instance = null;\n    let container: Container | null = this;\n\n    const cls = descriptor.class;\n\n    while (!instance && container) {\n      instance = container.instances.get(cls);\n      container = container.parentContainer;\n    }\n\n    if (!instance) {\n      if (descriptor.beforeCreate) {\n        descriptor.beforeCreate(this, descriptor, args);\n      }\n\n      instance = new cls(...args);\n\n      if (cache) {\n        this.instances.set(cls, instance);\n      }\n    }\n\n    return instance;\n  }\n\n  private getTokenDescriptor(\n    clsOrToken: TokenOrClass\n  ): DescriptorWithContainer | undefined {\n    let tokenDescriptor;\n    let container: Container | null = this;\n\n    while (!tokenDescriptor && container) {\n      tokenDescriptor = container.tokenDescriptorMap.get(clsOrToken);\n      container = container.parentContainer;\n    }\n\n    return tokenDescriptor;\n  }\n\n  private injectImpl<T extends TokenOrClass, Args extends ArgsOf<T>>(\n    clsOrToken: T,\n    args: Args,\n    resolutionContainer = this.resolutionContainer\n  ): InstanceOf<T> {\n    this.resolutionContainer = resolutionContainer || new Container();\n\n    try {\n      if (this.resolutionSet.has(clsOrToken)) {\n        throw new DependencyCycleError();\n      }\n\n      let cls = clsOrToken as TokenOrClass;\n\n      let scope: ScopeHandler;\n\n      let container: Container = this;\n\n      let descriptor = this.getTokenDescriptor(clsOrToken);\n\n      this.resolutionSet.add(clsOrToken);\n\n      if (!descriptor) {\n        if (clsOrToken instanceof Token) {\n          throw new TokenNotRegisteredError();\n        }\n\n        cls = clsOrToken;\n        scope = cls.scope || Scopes.Transient();\n        container = this;\n        descriptor = { class: cls, container: this };\n      } else {\n        if (descriptor.beforeInject) {\n          descriptor.beforeInject(container, descriptor, args);\n        }\n\n        if (\"class\" in descriptor) {\n          cls = descriptor.class as ScopedClass;\n          scope = descriptor.scope || cls.scope || Scopes.Transient();\n          container = descriptor.container;\n        } else if (\"value\" in descriptor) {\n          return descriptor.value;\n        } else if (\"factory\" in descriptor) {\n          // @ts-ignore\n          return descriptor.factory(container, ...args);\n        } else {\n          throw new Error(\"Invalid descriptor\");\n        }\n      }\n\n      return scope(descriptor, args, container, this.resolutionContainer);\n    } finally {\n      this.resolutionSet.delete(clsOrToken);\n      this.resolutionContainer = resolutionContainer;\n\n      if (!resolutionContainer) {\n        this.resolutionsLoopCounter = 0;\n      }\n    }\n  }\n\n  inject = <T extends TokenOrClass, Args extends ArgsOf<T>>(\n    cls: T,\n    ...args: Args\n  ): InstanceOf<T> => {\n    return this.injectImpl(cls, args, undefined);\n  };\n\n  injectAsync = <T extends TokenOrClass, Args extends ArgsOf<T>>(\n    cls: T,\n    ...args: Args\n  ): Promise<InstanceOf<T>> => {\n    const resolutionContainer = this.resolutionContainer;\n\n    this.resolutionsLoopCounter += 1;\n\n    if (this.resolutionsLoopCounter > MAX_LOOP_COUNT) {\n      throw new AsyncDependencyCycleError();\n    }\n\n    if (this.pendingPromiseMap.has(cls)) {\n      return this.pendingPromiseMap.get(cls) as Promise<InstanceOf<T>>;\n    }\n\n    if (this.instances.has(cls)) {\n      return Promise.resolve(this.instances.get(cls));\n    }\n\n    const promise = Promise.resolve().then(() => {\n      try {\n        return this.injectImpl(cls, args, resolutionContainer);\n      } finally {\n        this.pendingPromiseMap.delete(cls);\n      }\n    });\n\n    this.pendingPromiseMap.set(cls, promise);\n\n    return promise;\n  };\n\n  waitAsync = async () => {\n    // // The solution doesn't work correctly in all cases\n    // // because at the moment of the call not all promises are in the map\n    // await Promise.all(this.pendingPromiseMap.values());\n    return new Promise<void>((resolve) => setTimeout(resolve, 0));\n  };\n\n  register<T extends Token<any>>(descriptor: TokenValueDescriptor<T>): void;\n\n  register<T extends Token<any>>(descriptor: TokenFactoryDescriptor<T>): void;\n\n  register<T extends Token<any>>(descriptor: TokenClassDescriptor<T>): void;\n\n  register(tokenDescriptor: any): void {\n    const token = tokenDescriptor.token || tokenDescriptor.class;\n\n    const descriptorWithContainer = { ...tokenDescriptor, container: this };\n\n    this.tokenDescriptorMap.set(token, descriptorWithContainer);\n\n    if (tokenDescriptor.class) {\n      this.tokenDescriptorMap.set(token.class, descriptorWithContainer);\n    }\n  }\n\n  unregister = (token: TokenOrClass): void => {\n    const descriptor = this.getTokenDescriptor(token);\n\n    this.tokenDescriptorMap.delete(token);\n    this.instances.delete(token);\n\n    if (descriptor && \"class\" in descriptor) {\n      this.tokenDescriptorMap.delete(descriptor.class as ScopedClass);\n      this.instances.delete(descriptor.class);\n    }\n  };\n\n  reset = (): void => {\n    this.instances = new WeakMap();\n    this.resolutionSet.clear();\n    this.pendingPromiseMap.clear();\n    this.tokenDescriptorMap.clear();\n    this.resolutionContainer = null;\n    this.resolutionsLoopCounter = 0;\n  };\n}\n\nexport const globalContainer = new Container(null, \"Global container\");\n\nexport const inject = globalContainer.inject;\n\nexport const injectAsync = globalContainer.injectAsync;\n\nexport const childContainer = globalContainer.childContainer;\n"],"names":["name"],"mappings":"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"}