{"version":3,"sources":["../src/decorators/application.ts","../src/collections/weak-map.ts","../src/container.ts","../src/metadata.ts","../src/context.ts","../src/decorators/contexts.ts","../src/decorators/contextualize.ts","../src/decorators/isolated.ts","../src/decorators/origin.ts","../src/decorators/transient.ts","../src/decorators/provide.ts","../src/provider.ts","../src/decorators/provider.ts","../src/index.ts"],"names":["application","target","_","__name","AspectraWeakMap","key","fallback","current","value","Container","provider","context","classType","DuplicateProviderError","providerClass","providers","Context","Metadata","_Metadata","name","metadata","_Context","id","AspectraMap","contextId","contexts","contextualize","args","arg","isolated","MultipleScopeModifierError","origin","transient","provide","resolved","ProviderNotFoundError","Provider","SingletonProvider","TransientProvider","IsolatedProvider","instance"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Class } from '../types'\n\n/**\n * # @application\n *\n * The `@application` decorator marks the entry point of your aspectra-based\n * application. It instantiates the class it decorates and calls its `start`\n * method automatically.\n *\n * <Callout type='info'>\n *   Lack of `start` method will result in a compile-time error.\n * </Callout>\n *\n * #### Example\n *\n * ```typescript filename='src/index.ts'\n * import { application } from 'aspectra'\n *\n * @application\n * class Application {\n *   public start() {\n *     console.log('Hello, world!')\n *   }\n * }\n * ```\n *\n * This is functionally equivalent to:\n *\n * ```javascript\n * const app = new Application()\n * app.start()\n * ```\n *\n * #### Running the Application\n *\n * ```bash\n * tsx src/index.ts\n * ```\n */\nexport function application<\n  T extends {\n    start(): void\n  },\n>(target: Class<T, []>, _: ClassDecoratorContext<typeof target>): void {\n  queueMicrotask(() => {\n    Reflect.construct(target, []).start()\n  })\n}\n","export class AspectraWeakMap<K extends object, V> extends WeakMap<K, V> {\n  public getOrPut(key: K, fallback: () => V): V {\n    const current = this.get(key)\n    if (current) {\n      return current\n    }\n    const value = fallback()\n    this.set(key, value)\n    return value\n  }\n}\n","import { AspectraWeakMap } from './collections/weak-map'\nimport { Context } from './context'\nimport { DuplicateProviderError } from './lib/error'\nimport type { Provider, ProviderClassType } from './provider'\n\nexport class Container {\n  private readonly providers = new AspectraWeakMap<\n    ProviderClassType,\n    Provider\n  >()\n\n  public register(provider: Provider, context: Context): Provider {\n    const { classType } = provider\n    if (this.providers.has(classType)) {\n      throw new DuplicateProviderError(classType.name, context.id)\n    }\n    this.providers.set(classType, provider)\n    return provider\n  }\n\n  public resolve<T>(\n    providerClass: ProviderClassType,\n    context: Context,\n  ): T | undefined {\n    for (const providers of [\n      this.providers,\n      Context.global.container.providers,\n    ]) {\n      const provider = providers.get(providerClass)\n      if (provider) {\n        return provider.provide<T>(context)\n      }\n    }\n    return\n  }\n}\n","import { name } from '../package.json'\nimport { Context } from './context'\nimport { Scope } from './lib/scope'\nimport type { Class, UnknownArgs } from './types'\n\ninterface InjectionKeys {\n  origin?: PropertyKey\n}\n\nexport class Metadata {\n  private static readonly namespace = Symbol(`${name}.metadata`)\n\n  public readonly contexts = new Set<Context>([Context.global])\n  public scope = Scope.DEFAULT\n  public readonly injectionKeys: InjectionKeys = {}\n\n  public static fromClass<T>(target: Class<T, UnknownArgs>): Metadata {\n    // biome-ignore lint/suspicious/noAssignInExpressions: handled properly\n    const metadata = (target[Symbol.metadata] ??= {\n      value: {} as DecoratorMetadataObject,\n      writable: false,\n      configurable: true,\n    })\n    // biome-ignore lint/suspicious/noAssignInExpressions: handled properly\n    return (metadata[Metadata.namespace] ??= new Metadata()) as Metadata\n  }\n\n  public static fromContext(context: DecoratorContext): Metadata {\n    context.metadata[Metadata.namespace] ??= new Metadata()\n    return context.metadata[Metadata.namespace] as Metadata\n  }\n}\n","import { name } from '../package.json'\nimport { AspectraMap } from './collections/map'\nimport { Container } from './container'\nimport { Metadata } from './metadata'\nimport type { UnknownClass } from './types'\n\nexport type ContextId = PropertyKey\n\nexport class Context {\n  public static readonly global = new Context(Symbol(`${name}.global_context`))\n\n  private static readonly contexts = new AspectraMap<ContextId, Context>([\n    [Context.global.id, Context.global],\n  ])\n\n  public readonly container = new Container()\n\n  private constructor(public readonly id: ContextId) {}\n\n  public static of(classType: UnknownClass): ReadonlySet<Context> {\n    return Metadata.fromClass(classType).contexts\n  }\n\n  public static getOrRegister(contextId: ContextId): Context {\n    return Context.contexts.getOrPut(contextId, () => {\n      return new Context(contextId)\n    })\n  }\n}\n","import type { Context } from '../context'\nimport { Metadata } from '../metadata'\nimport type { UnknownClass } from '../types'\n\n/**\n * Injects the current set of registered contexts into the decorated class field.\n *\n * @example\n * ```typescript\n * class Global {\n *   @contexts\n *   public readonly contexts!: ReadonlySet<Context> // Global context\n * }\n *\n * @contextualize('a', 'b')\n * class Contextualized {\n *   @contexts\n *   public readonly contexts!: ReadonlySet<Context> // 'a' and 'b'\n * }\n * ```\n */\nexport function contexts<T extends object>(\n  _: unknown,\n  context: ClassFieldDecoratorContext<T, ReadonlySet<Context>>,\n): void {\n  context.addInitializer(function () {\n    this[context.name as keyof T] = Metadata.fromClass(\n      this.constructor as UnknownClass,\n    ).contexts as T[keyof T]\n  })\n}\n","import { Context, type ContextId } from '../context'\nimport { Metadata } from '../metadata'\nimport type { Class, UnknownArgs } from '../types'\nimport type { NonEmptyArray } from '../types'\n\n/**\n * # @contextualize\n *\n * Contexts serve as containers for managing providers. By default, providers\n * are stored in the global context (`Context.global`) and can be injected\n * anywhere using `@provide`. To limit provider availability to specific areas,\n * use the `@contextualize` decorator.\n *\n * This decorator enables precise control over dependency injection, supporting\n * modularity, security, and organized management by keeping certain providers\n * accessible only within designated contexts.\n *\n * #### Example\n *\n * In this example, we define two contexts: `DATABASE` and `ORDER`.\n *\n * ```typescript\n * import { application, contextualize, provide, provider } from 'aspectra'\n *\n * enum ContextId {\n *   DATABASE = 'database',\n *   ORDER = 'order',\n * }\n *\n * @contextualize(ContextId.DATABASE)\n * @provider\n * class DatabaseProvider {\n *   public getById(id: number) {\n *     // run sql query\n *   }\n * }\n *\n * @contextualize(ContextId.DATABASE, ContextId.ORDER)\n * @provider\n * class OrderProvider {\n *   @provide(DatabaseProvider)\n *   private readonly database!: DatabaseProvider\n *\n *   public process(id: number) {\n *     const product = this.database.getById(id)\n *     // process order\n *   }\n * }\n *\n * @contextualize(ContextId.ORDER)\n * @application\n * class CommerceApplication {\n *   @provide(OrderProvider)\n *   private readonly order!: OrderProvider\n *\n *   // This will fail as `CommerceApplication` and `DatabaseProvider` have no shared contexts\n *   // @provide(DatabaseProvider)\n *   // private readonly database!: DatabaseProvider\n *\n *   public start() {\n *     this.order.process(1)\n *   }\n * }\n * ```\n *\n * ```mermaid\n * flowchart LR\n *     A[DatabaseProvider] <--> C0{DATABASE}\n *     C0 <--> B[OrderProvider]\n *     B <--> C1{ORDER}\n *     C1 <--> C[CommerceApplication]\n * ```\n *\n * <Callout>\n *   By assigning `DatabaseProvider` and `CommerceApplication` to different\n *   contexts, only `OrderProvider` can access `DatabaseProvider`, preserving\n *   strict boundaries between providers.\n * </Callout>\n */\nexport function contextualize<T>(...args: NonEmptyArray<Context | ContextId>) {\n  return (\n    target: Class<T, UnknownArgs>,\n    context: ClassDecoratorContext<typeof target>,\n  ): void => {\n    const metadata = Metadata.fromContext(context)\n    metadata.contexts.clear()\n    for (const arg of args) {\n      if (arg instanceof Context) {\n        metadata.contexts.add(arg)\n      } else {\n        const context = Context.getOrRegister(arg)\n        metadata.contexts.add(context)\n      }\n    }\n  }\n}\n","import { MultipleScopeModifierError } from '../lib/error'\nimport { Scope } from '../lib/scope'\nimport { Metadata } from '../metadata'\nimport type { ProviderClassType } from '../provider'\n\n/**\n * # Isolated\n *\n * Scope-modifier decorator. Marks a provider as `isolated`, ensuring a unique\n * instance of the provider is created for each associated context.\n *\n * Useful for scenarios where the same provider class must yield distinct\n * instances based on different contexts.\n *\n * <Callout type=\"warning\">\n *   Only one scope-modifier can be applied to a provider class. Multiple\n *   scope-modifier will result in a `MultipleScopeModifierError`.\n * </Callout>\n *\n * ```typescript\n * import {\n *   application,\n *   Context,\n *   contextualize,\n *   isolated,\n *   provide,\n *   provider\n * } from 'aspectra'\n * import { randomUUID } from 'node:crypto'\n *\n * @isolated\n * @provider\n * class Logger {\n *   public readonly id = randomUUID()\n * }\n *\n * @contextualize('database', Context.global)\n * @provider\n * class Database {\n *   @provide(Logger)\n *   public readonly logger!: Logger // First instance\n * }\n *\n * @contextualize('printer', Context.global)\n * @provider\n * class Printer {\n *   @provide(Logger)\n *   public readonly logger!: Logger // New instance\n * }\n *\n * @contextualize('printer', Context.global)\n * @provider\n * class OtherPrinter {\n *   @provide(Logger)\n *   public readonly logger!: Logger // Same instance as `Printer`\n * }\n *\n * @application\n * class Application {\n *   @provide(Database)\n *   private readonly database!: Database\n *\n *   @provide(Printer)\n *   private readonly printer!: Printer\n *\n *   @provide(OtherPrinter)\n *   private readonly otherPrinter!: OtherPrinter\n *\n *   public start() {\n *     console.table({\n *       database: this.database.logger.id,\n *       printer: this.printer.logger.id,\n *       otherPrinter: this.otherPrinter.logger.id\n *     })\n *   }\n * }\n * ```\n */\nexport function isolated(\n  target: ProviderClassType,\n  context: ClassDecoratorContext<typeof target>,\n): void {\n  const metadata = Metadata.fromContext(context)\n  if (metadata.scope !== Scope.DEFAULT) {\n    throw new MultipleScopeModifierError(\n      target.name,\n      metadata.scope,\n      isolated.name,\n    )\n  }\n  metadata.scope = Scope.ISOALTED\n}\n","import type { Context } from '../context'\nimport { Metadata } from '../metadata'\n\n/**\n * # Origin\n *\n * Injects the context where it was instantiated. Powerful when combined with\n * `@isolated`.\n *\n * ```typescript\n * import { application, contextualize, origin, provide, provider } from 'aspectra'\n * import { type Context, isolated } from 'aspectra'\n *\n * enum ContextId {\n *   DATABASE = 'database',\n *   APPLICATION = 'application',\n * }\n *\n * @isolated\n * @provider\n * class LoggerProvider {\n *   @origin\n *   private readonly origin!: Context\n *\n *   public log(message: string) {\n *     console.log(`[${this.origin.id.toString()}]:`, message)\n *   }\n * }\n *\n * @contextualize(ContextId.DATABASE)\n * @provider\n * class DatabaseProvider {\n *   @provide(LoggerProvider)\n *   private readonly logger!: LoggerProvider\n *\n *   public connect() {\n *     this.logger.log('Connected to database')\n *   }\n * }\n *\n * @contextualize(ContextId.APPLICATION, ContextId.DATABASE)\n * @application\n * class Application {\n *   @provide(LoggerProvider)\n *   private readonly logger!: LoggerProvider\n *\n *   @provide(DatabaseProvider)\n *   private readonly database!: DatabaseProvider\n *\n *   public start() {\n *     this.logger.log('Starting application')\n *     this.database.connect()\n *   }\n * }\n * ```\n */\nexport function origin<T>(\n  _: unknown,\n  context: ClassFieldDecoratorContext<T, Context>,\n): void {\n  const metadata = Metadata.fromContext(context)\n  metadata.injectionKeys.origin = context.name\n}\n","import { MultipleScopeModifierError } from '../lib/error'\nimport { Scope } from '../lib/scope'\nimport { Metadata } from '../metadata'\nimport type { ProviderClassType } from '../provider'\n\n/**\n * # Transient\n *\n * Scope-modifier decorator. Defines a provider as `@transient`, ensuring a new\n * instance each time the provider is injected.\n *\n * By default, providers are singletons, meaning a single instance is reused.\n * With `@transient`, a new instance is created upon each injection, which is\n * useful for stateless or temporary dependencies.\n *\n * Comparing `@transient` vs `@isolated`:\n *  - `@transient` creates a new instance each time it's requested.\n *  - `@isolated` creates one instance per context (\"different context,\n *    different instance\").\n *\n * ```typescript\n * import {\n *   application,\n *   Context,\n *   contextualize,\n *   provide,\n *   provider,\n *   transient,\n * } from 'aspectra'\n * import { randomUUID } from 'node:crypto'\n *\n * @transient\n * @provider\n * class Logger {\n *   public readonly id = randomUUID()\n * }\n *\n * @application\n * class Application {\n *   @provide(Logger)\n *   private readonly first!: Logger\n *\n *   @provide(Logger)\n *   private readonly second!: Logger\n *\n *   @provide(Logger)\n *   private readonly third!: Logger\n *\n *   public start() {\n *     console.table({\n *       first: this.first.id,\n *       second: this.second.id,\n *       third: this.third.id,\n *     })\n *   }\n * }\n * ```\n */\nexport function transient(\n  target: ProviderClassType,\n  context: ClassDecoratorContext<typeof target>,\n): void {\n  const metadata = Metadata.fromContext(context)\n  if (metadata.scope !== Scope.DEFAULT) {\n    throw new MultipleScopeModifierError(\n      target.name,\n      metadata.scope,\n      transient.name,\n    )\n  }\n  metadata.scope = Scope.TRANSIENT\n}\n","import { Context } from '../context'\nimport { ProviderNotFoundError } from '../lib/error'\nimport type { ProviderClassType } from '../provider'\nimport type { UnknownClass } from '../types'\n\n/**\n * # @provide\n *\n * The `@provide` decorator injects providers into the class field as a\n * \"singleton\", meaning the same instance is shared across all injections. This\n * allows you to inject the provider wherever needed, without having to worry\n * about creating multiple instances.\n *\n * <Callout type='info'>\n *   You can customize this behavior using scope-modifier decorators, such as\n *   `@transient` and `@isolated`, which allow more granular control over the\n *   lifecycle and scope of injected instances. These will be covered in a\n *   later section.\n * </Callout>\n *\n * #### Example\n *\n * ```typescript filename='src/index.ts'\n * import { application, provide, provider } from 'aspectra'\n *\n * @provider\n * export class Database {\n *   private constructor() {\n *     console.log(`I'm only called once!`)\n *   }\n *\n *   public getAll() {\n *     return ['item1', 'item2']\n *   }\n * }\n *\n * @application\n * class Application {\n *   @provide(Database)\n *   private readonly database!: Database\n *\n *   @provide(Database)\n *   private readonly other!: Database // same instance as `database`\n *\n *   public start() {\n *     console.log(this.database.getAll())\n *   }\n * }\n * ```\n */\nexport function provide<T extends object, P>(provider: ProviderClassType<P>) {\n  return (_: unknown, context: ClassFieldDecoratorContext<T, P>): void => {\n    const name = context.name as keyof T\n    context.addInitializer(function () {\n      const contexts = Context.of(this.constructor as UnknownClass)\n      for (const context of contexts) {\n        const resolved = context.container.resolve(provider, context)\n        if (resolved) {\n          this[name] = resolved as T[keyof T]\n          return\n        }\n      }\n      throw new ProviderNotFoundError(provider.name, contexts)\n    })\n  }\n}\n","import { AspectraWeakMap } from './collections/weak-map'\nimport type { Context } from './context'\nimport { Scope } from './lib/scope'\nimport { Metadata } from './metadata'\nimport type { Class } from './types'\n\nexport type ProviderClassType<T = unknown> = Class<T, []>\n\nexport abstract class Provider {\n  protected readonly metadata: Metadata\n\n  protected constructor(public readonly classType: ProviderClassType) {\n    this.metadata = Metadata.fromClass(classType)\n  }\n\n  public static fromClassType(classType: ProviderClassType): Provider {\n    const metadata = Metadata.fromClass(classType)\n    switch (metadata.scope) {\n      case Scope.SINGLETON: {\n        return new SingletonProvider(classType)\n      }\n      case Scope.TRANSIENT: {\n        return new TransientProvider(classType)\n      }\n      case Scope.ISOALTED: {\n        return new IsolatedProvider(classType)\n      }\n    }\n  }\n\n  abstract provide<T>(context: Context): T\n\n  protected createInstance<T>(context: Context): T {\n    const instance = Reflect.construct(this.classType, []) as T\n    if (this.metadata.injectionKeys.origin) {\n      instance[this.metadata.injectionKeys.origin as keyof T] =\n        context as T[keyof T]\n    }\n    return instance\n  }\n}\n\nexport class SingletonProvider extends Provider {\n  private instance: unknown\n\n  public override provide<T>(context: Context): T {\n    if (!this.instance) {\n      this.instance = this.createInstance(context)\n    }\n    return this.instance as T\n  }\n}\n\nexport class TransientProvider extends Provider {\n  public override provide<T>(context: Context): T {\n    return this.createInstance<T>(context)\n  }\n}\n\nexport class IsolatedProvider extends Provider {\n  private readonly providers = new AspectraWeakMap<Context, unknown>()\n\n  public override provide<T>(context: Context): T {\n    return this.providers.getOrPut(context, () => {\n      return this.createInstance<T>(context)\n    }) as T\n  }\n}\n","import { Context } from '../context'\nimport { Provider } from '../provider'\nimport type { Class } from '../types'\n\n/**\n * # @provider\n *\n * The `@provider` decorator registers a class as a service provider within the\n * application. Providers encapsulate functionality, such as a database\n * connection, which can be injected wherever needed using the `@provide`\n * decorator.\n *\n * #### Example\n *\n * ```typescript filename=\"src/providers/database.ts\"\n * import { provider } from 'aspectra'\n *\n * @provider\n * export class Database {\n *   public connect() {\n *     console.log('Connecting to the database')\n *   }\n *\n *   public getAll() {\n *     return ['item1', 'item2']\n *   }\n *\n *   public close() {\n *     console.log('Closing the database connection')\n *   }\n * }\n * ```\n */\nexport function provider<T>(\n  target: Class<T, []>,\n  context: ClassDecoratorContext<typeof target>,\n): void {\n  context.addInitializer(function () {\n    const provider = Provider.fromClassType(target)\n    for (const context of Context.of(this)) {\n      context.container.register(provider, context)\n    }\n  })\n}\n","export { application } from './decorators/application'\nexport { Context } from './context'\nexport { contexts } from './decorators/contexts'\nexport { contextualize } from './decorators/contextualize'\nexport { isolated } from './decorators/isolated'\nexport { origin } from './decorators/origin'\nexport { transient } from './decorators/transient'\nexport { provide } from './decorators/provide'\nexport { provider } from './decorators/provider'\n\n/**\n * [Symbol.metadata] polyfill\n */\ndeclare global {\n  interface SymbolConstructor {\n    readonly metadata: unique symbol\n  }\n}\n// biome-ignore lint/suspicious/noExplicitAny: Polyfill\n;(Symbol as any).metadata ??= Symbol.for('Symbol.metadata')\n"]}