{"version":3,"file":"Jimple.cjs","sources":["../src/Jimple.ts"],"sourcesContent":["/**\n * Factory function type that creates a service instance.\n * @template T - The type of service being created\n * @template TContainer - The type of the container being injected\n */\nexport type ServiceFactory<T, TContainer> = (container: TContainer) => T;\n\n/**\n * Extender function type that modifies an existing service.\n * @template T - The type of service being extended\n * @template TContainer - The type of the container being injected\n */\nexport type ServiceExtender<T, TContainer> = (\n  original: T,\n  container: TContainer,\n) => T;\n\n/**\n * Interface for service providers that can register services with a container.\n * @template TMap - The service map type extending ServiceMap\n */\nexport interface ServiceProvider<TMap extends ServiceMap = ServiceMap> {\n  /**\n   * Registers services with the provided container.\n   * @param container - The container to register services with\n   */\n  register(container: JimpleWithProxy<TMap>): void;\n}\n\n/**\n * Interface for async service providers that can register services with a container.\n * @template TMap - The service map type extending ServiceMap\n */\nexport interface AsyncServiceProvider<TMap extends ServiceMap = ServiceMap> {\n  /**\n   * Registers services asynchronously with the provided container.\n   * @param container - The container to register services with\n   */\n  registerAsync(container: JimpleWithProxy<TMap>): Promise<void>;\n}\n\n/**\n * Base interface for service mapping. Extend this interface to define your service types.\n * @example\n * ```typescript\n * interface MyServiceMap extends ServiceMap {\n *   userService: UserService;\n *   logger: Logger;\n * }\n * ```\n */\nexport interface ServiceMap {}\n\n/**\n * Utility type to extract the service type from a service map.\n * @template TMap - The service map\n * @template TKey - The key in the service map\n */\nexport type ServiceType<TMap, TKey extends keyof TMap> = TMap[TKey];\n\n/**\n * Type for initial service registration, allowing either concrete instances or factory functions.\n * @template TMap - The service map\n * @template TContainer - The container type\n */\nexport type InitialServiceMap<TMap, TContainer> = {\n  [TKey in keyof TMap]:\n    | ServiceType<TMap, TKey>\n    | ServiceFactory<ServiceType<TMap, TKey>, TContainer>;\n};\n\n/**\n * Proxy-enhanced Jimple container with direct property access to services.\n * @template TMap - The service map extending ServiceMap\n */\nexport type JimpleWithProxy<TMap extends ServiceMap> = Jimple<TMap> & {\n  readonly [TKey in keyof TMap]: ServiceType<TMap, TKey>;\n};\n\n/**\n * Assertion function that throws an error if the condition is false.\n * @param ok - The condition to assert\n * @param message - Error message to throw if condition is false\n * @throws {Error} When the assertion fails\n * @internal\n */\nfunction assert(ok: boolean, message: string): asserts ok {\n  if (!ok) {\n    throw new Error(message);\n  }\n}\n\n/**\n * Type guard to check if a value is a regular function.\n * @param fn - The value to check\n * @returns True if the value is a function\n * @internal\n */\nfunction isFunction(fn: unknown): fn is Function {\n  return (\n    Object.prototype.toString.call(fn) === \"[object Function]\" &&\n    (fn as any).constructor.name === \"Function\"\n  );\n}\n\n/**\n * Type guard to check if a value is an async function.\n * @param fn - The value to check\n * @returns True if the value is an async function\n * @internal\n */\nfunction isAsyncFunction(fn: unknown): fn is Function {\n  return (\n    Object.prototype.toString.call(fn) === \"[object AsyncFunction]\" &&\n    (fn as any).constructor.name === \"AsyncFunction\"\n  );\n}\n\n/**\n * Type guard to check if a value is a plain object (not an array, function, etc.).\n * @param value - The value to check\n * @returns True if the value is a plain object\n * @internal\n */\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n  if (Object.prototype.toString.call(value) !== \"[object Object]\") {\n    return false;\n  }\n  const prototype = Object.getPrototypeOf(value);\n  return prototype === null || prototype === Object.prototype;\n}\n\n/**\n * Checks if a value is a valid service definition (function or async function).\n * This is used to ensure that only valid service definitions are added to the container.\n *\n * @param fn - The value to check\n * @returns True if the value is an async function\n * @internal\n */\nfunction isServiceDefinition(fn: unknown): fn is Function {\n  return isFunction(fn) || isAsyncFunction(fn);\n}\n\n/**\n * Adds a function to a set after validating it's a proper function.\n * @template T - The function type\n * @param set - The set to add the function to\n * @param fn - The function to add\n * @throws {Error} When the value is not a function\n * @internal\n */\nfunction addFunctionTo<T extends Function>(set: Set<T>, fn: T): void {\n  assert(isServiceDefinition(fn), \"Expected a function or async function.\");\n  set.add(fn);\n}\n\n/**\n * The Jimple Container class with TypeScript support.\n * A dependency injection container that manages services and parameters.\n *\n * @template TMap - The service map extending ServiceMap\n *\n * @example\n * ```typescript\n * interface MyServices extends ServiceMap {\n *   logger: Logger;\n *   userService: UserService;\n * }\n *\n * const container = Jimple.create<MyServices>();\n * container.set('logger', () => new ConsoleLogger());\n * container.set('userService', (c) => new UserService(c.logger));\n *\n * const userService = container.userService; // Typed as UserService\n * ```\n */\nexport default class Jimple<TMap extends ServiceMap = ServiceMap> {\n  /** Internal storage for service definitions and parameters */\n  private readonly _items: Record<string, unknown> = {};\n\n  /** Cache for instantiated services */\n  private readonly _instances = new Map<Function, unknown>();\n\n  /** Set of functions marked as factories (always return new instances) */\n  private readonly _factories = new Set<Function>();\n\n  /** Set of functions marked as protected (returned as-is, not called) */\n  private readonly _protected = new Set<Function>();\n\n  /** Proxy-enhanced version of this container for property access */\n  private readonly _bind: JimpleWithProxy<TMap>;\n\n  /**\n   * Creates a service provider object.\n   * @template TMap - The service map\n   * @param register - Function that registers services with a container\n   * @returns A service provider object\n   *\n   * @example\n   * ```typescript\n   * const myProvider = Jimple.provider<MyServices>((container) => {\n   *   container.set('logger', () => new Logger());\n   * });\n   * ```\n   */\n  static provider<TMap extends ServiceMap = ServiceMap>(\n    register: ServiceProvider<TMap>[\"register\"],\n  ): ServiceProvider<TMap> {\n    return { register };\n  }\n\n  /**\n   * Creates an asynchronous service provider object.\n   * @template TMap - The service map\n   * @param registerAsync - Function that registers services with a container asynchronously\n   * @returns A service provider object\n   *\n   * @example\n   * ```typescript\n   * const myProvider = Jimple.providerAsync<MyServices>(async (container) => {\n   *   container.set('config', await initLogger());\n   * });\n   * ```\n   */\n  static providerAsync<TMap extends ServiceMap = ServiceMap>(\n    registerAsync: AsyncServiceProvider<TMap>[\"registerAsync\"],\n  ): AsyncServiceProvider<TMap> {\n    return { registerAsync };\n  }\n\n  /**\n   * Creates a new Jimple container instance with proxy support.\n   * @template TMap - The service map\n   * @param values - Initial services and parameters to register\n   * @returns A proxy-enhanced container\n   *\n   * @example\n   * ```typescript\n   * const container = Jimple.create<MyServices>({\n   *   logger: () => new ConsoleLogger(),\n   *   apiUrl: 'https://api.example.com'\n   * });\n   * ```\n   */\n  static create<TMap extends ServiceMap = ServiceMap>(\n    values?: InitialServiceMap<TMap, JimpleWithProxy<TMap>>,\n  ): JimpleWithProxy<TMap> {\n    return new this<TMap>(values) as JimpleWithProxy<TMap>;\n  }\n\n  /**\n   * Create a Jimple Container.\n   * @param values - Initial services and parameters to register\n   *\n   * @example\n   * ```typescript\n   * const container = new Jimple<MyServices>({\n   *   config: { apiUrl: 'https://api.example.com' },\n   *   logger: (c) => new Logger(c.config)\n   * });\n   * ```\n   */\n  constructor(\n    values?: Partial<InitialServiceMap<TMap, JimpleWithProxy<TMap>>>,\n  ) {\n    if (isPlainObject(values)) {\n      Object.keys(values).forEach((key) => {\n        const value = values[key as keyof TMap];\n        if (typeof value !== \"undefined\") {\n          this.set(key as keyof TMap, value as any);\n        }\n      });\n    }\n\n    this._bind = new Proxy(this, {\n      get(target: Jimple<TMap>, prop: string | symbol): any {\n        if (prop in target && typeof prop === \"string\") {\n          const value = (target as any)[prop];\n          if (isFunction(value) || isAsyncFunction(value)) {\n            return value.bind(target);\n          }\n        }\n        return target.get(prop as keyof TMap);\n      },\n\n      set(target: Jimple<TMap>, prop: string | symbol, value: any): boolean {\n        assert(\n          !(prop in target) || typeof prop !== \"string\",\n          `Cannot override method '${prop as string}'. Use set() instead.`,\n        );\n        target.set(prop as keyof TMap, value);\n        return true;\n      },\n\n      has(target: Jimple<TMap>, prop: string | symbol): boolean {\n        if (prop in target) {\n          return true;\n        }\n\n        return target.has(prop as keyof TMap);\n      },\n\n      deleteProperty(target: Jimple<TMap>, prop: string | symbol): boolean {\n        assert(\n          !(prop in target) || typeof prop !== \"string\",\n          `Cannot delete method '${prop as string}'. Use unset() instead.`,\n        );\n        target.unset(prop as keyof TMap);\n        return true;\n      },\n\n      ownKeys(target: Jimple<TMap>): ArrayLike<string | symbol> {\n        const classKeys = Object.getOwnPropertyNames(target);\n        const serviceKeys = target.keys() as string[];\n        return [...new Set([...classKeys, ...serviceKeys])];\n      },\n\n      getOwnPropertyDescriptor(target: Jimple<TMap>, prop: string | symbol) {\n        if (prop in target) {\n          return Object.getOwnPropertyDescriptor(target, prop);\n        }\n\n        if (typeof prop === \"string\" && target.has(prop as keyof TMap)) {\n          return {\n            enumerable: true,\n            configurable: true,\n            get: () => target.get(prop as keyof TMap),\n            set: (value: any) => target.set(prop as keyof TMap, value),\n          };\n        }\n\n        return undefined;\n      },\n    }) as JimpleWithProxy<TMap>;\n    return this._bind;\n  }\n\n  /**\n   * Return the specified parameter or service with correct typing.\n   * Services defined as functions are instantiated when first accessed (singleton pattern).\n   * Services marked as factories are instantiated on every access.\n   * Services marked as protected are returned as-is without being called.\n   *\n   * @template TKey - The service key type\n   * @param key - The service key to retrieve\n   * @returns The service instance or parameter value\n   * @throws {Error} When the service is not defined\n   *\n   * @example\n   * ```typescript\n   * const logger = container.get('logger');\n   * const apiUrl = container.get('apiUrl');\n   * ```\n   */\n  get<TKey extends keyof TMap>(key: TKey): ServiceType<TMap, TKey> {\n    const item = this.raw(key);\n\n    if (isServiceDefinition(item)) {\n      if (this._protected.has(item)) {\n        return item as ServiceType<TMap, TKey>;\n      } else if (this._instances.has(item)) {\n        return this._instances.get(item) as ServiceType<TMap, TKey>;\n      }\n      const obj = item(this._bind);\n      if (!this._factories.has(item)) {\n        this._instances.set(item, obj);\n      }\n      return obj;\n    }\n    return item;\n  }\n\n  /**\n   * Defines a new parameter or service.\n   * Functions are treated as service factories unless marked as protected.\n   *\n   * @template TKey - The service key type\n   * @param key - The service key\n   * @param value - The service value, instance, or factory function\n   * @throws {Error} When trying to redefine an already instantiated service\n   *\n   * @example\n   * ```typescript\n   * // Parameter\n   * container.set('apiUrl', 'https://api.example.com');\n   *\n   * // Service factory\n   * container.set('logger', (c) => new Logger(c.apiUrl));\n   *\n   * // Service instance\n   * container.set('cache', new MemoryCache());\n   * ```\n   */\n  set<TKey extends keyof TMap>(\n    key: TKey,\n    value: ServiceFactory<ServiceType<TMap, TKey>, JimpleWithProxy<TMap>>,\n  ): void;\n  set<TKey extends keyof TMap>(key: TKey, value: ServiceType<TMap, TKey>): void;\n  set<TKey extends keyof TMap>(\n    key: TKey,\n    value:\n      | ServiceType<TMap, TKey>\n      | ServiceFactory<ServiceType<TMap, TKey>, JimpleWithProxy<TMap>>,\n  ): void {\n    const originalItem = this._items[key as string];\n    assert(\n      !isServiceDefinition(originalItem) || !this._instances.has(originalItem),\n      `Service '${key as string}' already instantiated and cannot be redefined.`,\n    );\n    this._items[key as string] = value;\n  }\n\n  /**\n   * Unsets a parameter or service, removing it from the container.\n   * Also clears any cached instances and metadata for the service.\n   *\n   * @template TKey - The service key type\n   * @param key - The service key to remove\n   *\n   * @example\n   * ```typescript\n   * container.unset('logger');\n   * console.log(container.has('logger')); // false\n   * ```\n   */\n  unset<TKey extends keyof TMap>(key: TKey): void {\n    const item = this._items[key as string];\n    if (isServiceDefinition(item)) {\n      this._instances.delete(item);\n      this._factories.delete(item);\n      this._protected.delete(item);\n    }\n    delete this._items[key as string];\n  }\n\n  /**\n   * Returns if a service or parameter is defined in the container.\n   *\n   * @template TKey - The service key type\n   * @param key - The service key to check\n   * @returns True if the service is defined\n   *\n   * @example\n   * ```typescript\n   * if (container.has('logger')) {\n   *   const logger = container.get('logger');\n   * }\n   * ```\n   */\n  has<TKey extends keyof TMap>(key: TKey): boolean {\n    return Object.prototype.hasOwnProperty.call(this._items, key as string);\n  }\n\n  /**\n   * Defines a service as a factory that creates new instances on every access.\n   * Unlike regular services (which are singletons), factories always call the function.\n   *\n   * @template TKey - The service key type\n   * @template T - The factory function type\n   * @param fn - The factory function to mark\n   * @returns The same function (for chaining)\n   * @throws {Error} When the value is not a function\n   *\n   * @example\n   * ```typescript\n   * container.set('requestId', container.factory(() => Math.random().toString()));\n   *\n   * const id1 = container.get('requestId'); // Different value each time\n   * const id2 = container.get('requestId'); // Different value each time\n   * ```\n   */\n  factory<\n    TKey extends keyof TMap,\n    T extends ServiceFactory<ServiceType<TMap, TKey>, JimpleWithProxy<TMap>>,\n  >(fn: T): T {\n    addFunctionTo(this._factories, fn);\n    return fn;\n  }\n\n  /**\n   * Defines a function as a parameter (protected from being called as a service factory).\n   * The function will be returned as-is when accessed, not executed.\n   *\n   * @template T - The function type\n   * @param fn - The function to protect\n   * @returns The same function (for chaining)\n   * @throws {Error} When the value is not a function\n   *\n   * @example\n   * ```typescript\n   * const callback = (data: any) => console.log(data);\n   * container.set('onComplete', container.protect(callback));\n   *\n   * const fn = container.get('onComplete'); // Returns the function itself\n   * fn('Hello'); // Can be called later\n   * ```\n   */\n  protect<TKey extends keyof TMap, T extends ServiceType<TMap, TKey>>(\n    fn: T extends (...args: any[]) => any ? T : never,\n  ): T {\n    addFunctionTo(this._protected, fn);\n    return fn;\n  }\n\n  /**\n   * Return all the keys registered in the container.\n   *\n   * @returns Array of all service keys\n   *\n   * @example\n   * ```typescript\n   * const keys = container.keys();\n   * console.log('Registered services:', keys);\n   * ```\n   */\n  keys(): (keyof TMap)[] {\n    return Object.keys(this._items) as (keyof TMap)[];\n  }\n\n  /**\n   * Extends a service already registered in the container.\n   * Allows decorating or modifying an existing service definition.\n   *\n   * @template TKey - The service key type\n   * @template TResult - The extended service type\n   * @param key - The service key to extend\n   * @param fn - Function that receives the original service and returns the extended version\n   * @throws {Error} When the service is not defined, not a function, protected, or already instantiated\n   *\n   * @example\n   * ```typescript\n   * container.set('logger', () => new Logger());\n   *\n   * container.extend('logger', (logger, c) => {\n   *   return new LoggerDecorator(logger, c.config);\n   * });\n   * ```\n   */\n  extend<TKey extends keyof TMap>(\n    key: TKey,\n    fn: ServiceExtender<ServiceType<TMap, TKey>, JimpleWithProxy<TMap>>,\n  ): void {\n    const originalItem = this.raw(key);\n\n    assert(\n      isServiceDefinition(originalItem) && !this._protected.has(originalItem),\n      `Service '${key as string}' is not extendable.`,\n    );\n    assert(\n      isServiceDefinition(fn),\n      `Extension for '${key as string}' must be a function.`,\n    );\n    assert(\n      !this._instances.has(originalItem),\n      `Service '${key as string}' already instantiated and cannot be extended.`,\n    );\n\n    type ServiceExtenderWrapper = typeof originalItem & { _: (typeof fn)[] };\n    const maybeList = (originalItem as ServiceExtenderWrapper)._;\n    if (maybeList) {\n      maybeList.push(fn);\n      return;\n    }\n\n    const wrapper = (this._items[key as string] = (\n      app: JimpleWithProxy<TMap>,\n    ) =>\n      wrapper._.reduce(\n        (result, extend) => extend(result, app),\n        originalItem(app),\n      )) as ServiceExtenderWrapper;\n    wrapper._ = [fn];\n\n    const { _factories } = this;\n\n    if (_factories.delete(originalItem)) {\n      _factories.add(wrapper);\n    }\n  }\n\n  /**\n   * Uses a provider to extend the service container.\n   * Providers are objects with a register method that can add multiple services.\n   *\n   * @template K - The subset of service keys the provider manages\n   * @param provider - The service provider to register\n   *\n   * @example\n   * ```typescript\n   * const databaseProvider = Jimple.provider<MyServices>((container) => {\n   *   container.set('db', () => new Database(container.config));\n   *   container.set('userRepo', (c) => new UserRepository(c.db));\n   * });\n   *\n   * container.register(databaseProvider);\n   * ```\n   */\n  register<K extends keyof TMap>(\n    provider: ServiceProvider<Pick<TMap, K>>,\n  ): void {\n    return provider.register(\n      this._bind as unknown as JimpleWithProxy<Pick<TMap, K>>,\n    );\n  }\n\n  /**\n   * Uses an async provider to extend the service container.\n   * Providers are objects with a register method that can add multiple services and returns a Promise.\n   *\n   * @template K - The subset of service keys the provider manages\n   * @param provider - The asynchronous service provider to register\n   *\n   * @example\n   * ```typescript\n   * const databaseProvider = Jimple.providerAsync<MyServices>(async (container) => {\n   *   container.set(\"config\", await initDb());\n   *   container.set('db', () => new Database(container.config));\n   *   container.set('userRepo', (c) => new UserRepository(c.db));\n   * });\n   *\n   * container.registerAsync(databaseProvider);\n   * ```\n   */\n  registerAsync<K extends keyof TMap>(\n    provider: AsyncServiceProvider<Pick<TMap, K>>,\n  ): Promise<void> {\n    return new Promise((resolve, reject) =>\n      provider\n        .registerAsync(this._bind as unknown as JimpleWithProxy<Pick<TMap, K>>)\n        .then(() => resolve(), reject),\n    );\n  }\n\n  /**\n   * Returns the raw value of a service or parameter without instantiation.\n   * For services defined as functions, returns the function itself rather than calling it.\n   *\n   * @template TKey - The service key type\n   * @param key - The service key\n   * @returns The raw service definition or parameter value\n   * @throws {Error} When the service is not defined\n   *\n   * @example\n   * ```typescript\n   * const factory = container.raw('logger'); // Returns the factory function\n   * const logger = factory(container); // Manually instantiate\n   * ```\n   */\n  raw<TKey extends keyof TMap>(\n    key: TKey,\n  ):\n    | ServiceType<TMap, TKey>\n    | ServiceFactory<ServiceType<TMap, TKey>, JimpleWithProxy<TMap>> {\n    assert(this.has(key), `Service \"${key as string}\" not found.`);\n    return this._items[key as string] as\n      | ServiceType<TMap, TKey>\n      | ServiceFactory<ServiceType<TMap, TKey>, JimpleWithProxy<TMap>>;\n  }\n}\n"],"names":["assert","ok","message","Error","isFunction","fn","Object","prototype","toString","call","constructor","name","isAsyncFunction","isServiceDefinition","addFunctionTo","set","add","provider","register","providerAsync","registerAsync","create","values","this","_items","_instances","Map","_factories","Set","_protected","_bind","value","getPrototypeOf","isPlainObject","keys","forEach","key","Proxy","get","target","prop","bind","has","deleteProperty","unset","ownKeys","classKeys","getOwnPropertyNames","serviceKeys","getOwnPropertyDescriptor","enumerable","configurable","item","raw","obj","originalItem","delete","hasOwnProperty","factory","protect","extend","maybeList","_","push","wrapper","app","reduce","result","o","Promise","resolve","reject","then"],"mappings":"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"}