{"version":3,"file":"context-manager.mjs","names":[],"sources":["../../../../../../@warlock.js/context/src/context-manager.ts"],"sourcesContent":["import type { Context } from \"./base-context\";\n\n/**\n * Context Manager - Orchestrates multiple contexts together\n *\n * Allows running multiple AsyncLocalStorage contexts in a single operation,\n * making it easy to link request, storage, database, and other contexts.\n *\n * @example\n * ```typescript\n * // Register contexts\n * contextManager\n *   .register('request', requestContext)\n *   .register('storage', storageDriverContext)\n *   .register('database', databaseDataSourceContext);\n *\n * // Run all contexts together\n * await contextManager.runAll({\n *   request: { request, response, user },\n *   storage: { driver, metadata: { tenantId: '123' } },\n *   database: { dataSource: 'primary' },\n * }, async () => {\n *   // All contexts active!\n *   await handleRequest();\n * });\n * ```\n */\nexport class ContextManager {\n  private contexts = new Map<string, Context<any>>();\n\n  /**\n   * Register a context\n   *\n   * @param name - Unique context name\n   * @param context - Context instance\n   * @returns This instance for chaining\n   */\n  public register(name: string, context: Context<any>): this {\n    this.contexts.set(name, context);\n    return this;\n  }\n\n  /**\n   * Run all registered contexts together\n   *\n   * Nests all context.run() calls, ensuring all contexts are active\n   * for the duration of the callback.\n   *\n   * @param stores - Context stores keyed by context name\n   * @param callback - Async function to execute\n   * @returns Result of the callback\n   */\n  public async runAll<T>(stores: Record<string, any>, callback: () => Promise<T>): Promise<T> {\n    const entries = Array.from(this.contexts.entries());\n\n    // Build nested context runners\n    const runner = entries.reduceRight((next, [name, context]) => {\n      return () => context.run(stores[name] || {}, next);\n    }, callback);\n\n    return runner();\n  }\n\n  /**\n   * Enter all contexts at once (for middleware)\n   *\n   * @param stores - Context stores keyed by context name\n   */\n  public enterAll(stores: Record<string, any>): void {\n    for (const [name, context] of this.contexts.entries()) {\n      if (stores[name]) {\n        context.enter(stores[name]);\n      }\n    }\n  }\n\n  /**\n   * Clear all contexts\n   */\n  public clearAll(): void {\n    for (const context of this.contexts.values()) {\n      context.clear();\n    }\n  }\n\n  /**\n   * Get a specific registered context\n   *\n   * @param name - Context name\n   * @returns Context instance or undefined\n   */\n  public getContext<T extends Context<any>>(name: string): T | undefined {\n    return this.contexts.get(name) as T | undefined;\n  }\n\n  /**\n   * Check if a context is registered\n   *\n   * @param name - Context name\n   * @returns True if context is registered\n   */\n  public hasContext(name: string): boolean {\n    return this.contexts.has(name);\n  }\n\n  /**\n   * Build all context stores by calling each context's buildStore() method\n   *\n   * This is the immutable pattern - returns a new record of stores.\n   * Each context defines its own initialization logic.\n   *\n   * @param payload - Payload passed to each buildStore() (e.g., { request, response })\n   * @returns Record of context name -> store data\n   *\n   * @example\n   * ```typescript\n   * const httpContextStore = contextManager.buildStores({ request, response });\n   * await contextManager.runAll(httpContextStore, async () => { ... });\n   * ```\n   */\n  public buildStores(payload?: Record<string, any>): Record<string, any> {\n    const stores: Record<string, any> = {};\n\n    for (const [name, context] of this.contexts.entries()) {\n      stores[name] = context.buildStore(payload) ?? {};\n    }\n\n    return stores;\n  }\n\n  /**\n   * Unregister a context\n   *\n   * @param name - Context name to remove\n   * @returns True if context was removed\n   */\n  public unregister(name: string): boolean {\n    return this.contexts.delete(name);\n  }\n}\n\n/**\n * Global context manager instance\n *\n * Use this singleton to register and manage all framework contexts.\n */\nexport const contextManager = new ContextManager();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,IAAa,iBAAb,MAA4B;;kCACP,IAAI,IAA0B;;;;;;;;;CASjD,AAAO,SAAS,MAAc,SAA6B;EACzD,KAAK,SAAS,IAAI,MAAM,OAAO;EAC/B,OAAO;CACT;;;;;;;;;;;CAYA,MAAa,OAAU,QAA6B,UAAwC;EAQ1F,OAPgB,MAAM,KAAK,KAAK,SAAS,QAAQ,CAG5B,CAAC,CAAC,aAAa,MAAM,CAAC,MAAM,aAAa;GAC5D,aAAa,QAAQ,IAAI,OAAO,SAAS,CAAC,GAAG,IAAI;EACnD,GAAG,QAES,CAAC,CAAC;CAChB;;;;;;CAOA,AAAO,SAAS,QAAmC;EACjD,KAAK,MAAM,CAAC,MAAM,YAAY,KAAK,SAAS,QAAQ,GAClD,IAAI,OAAO,OACT,QAAQ,MAAM,OAAO,KAAK;CAGhC;;;;CAKA,AAAO,WAAiB;EACtB,KAAK,MAAM,WAAW,KAAK,SAAS,OAAO,GACzC,QAAQ,MAAM;CAElB;;;;;;;CAQA,AAAO,WAAmC,MAA6B;EACrE,OAAO,KAAK,SAAS,IAAI,IAAI;CAC/B;;;;;;;CAQA,AAAO,WAAW,MAAuB;EACvC,OAAO,KAAK,SAAS,IAAI,IAAI;CAC/B;;;;;;;;;;;;;;;;CAiBA,AAAO,YAAY,SAAoD;EACrE,MAAM,SAA8B,CAAC;EAErC,KAAK,MAAM,CAAC,MAAM,YAAY,KAAK,SAAS,QAAQ,GAClD,OAAO,QAAQ,QAAQ,WAAW,OAAO,KAAK,CAAC;EAGjD,OAAO;CACT;;;;;;;CAQA,AAAO,WAAW,MAAuB;EACvC,OAAO,KAAK,SAAS,OAAO,IAAI;CAClC;AACF;;;;;;AAOA,MAAa,iBAAiB,IAAI,eAAe"}