{"version":3,"file":"index.mjs","sources":["../src/async-context-id.js","../src/lru-map.js","../src/timed-map.js"],"sourcesContent":["import asyncHooks from 'async_hooks'\n\nlet instance = null\n\n/**\n * A singleton class that tracks correlation IDs across asynchronous operations in Node.js.\n * Uses async_hooks to automatically propagate correlation context across async boundaries.\n *\n * @class\n * @description This class provides context propagation across async operations in Node.js\n * applications. It maintains correlation IDs and metadata throughout the async execution chain.\n *\n * @property {Map} contextStore - Storage for async context data\n * @property {AsyncHook} hook - The async_hooks instance for tracking async operations\n * @property {Function} cleanUpFn - Cleanup function registered for process exit\n *\n * @tutorial initializing-async-context-id-in-a-controller\n * @tutorial monkey-patch-logs\n * @tutorial down-stream-http-hand-off\n * @tutorial winston\n */\nclass AsyncContextId {\n  contextStore\n  correlationIdFn\n  hook\n  cleanUpFn\n\n  /**\n   * Creates a new AsyncContextId instance or returns the existing singleton.\n   * Initializes async hooks and sets up process cleanup.\n   *\n   * @param {Object} [options={}] - Configuration options\n   * @param {Map} [options.store=new Map()] - Optional Map instance for context storage, this package includes both a LRU ( Least Recently Used ) Map and a Timed Map.\n   * @param {fn} [options.correlationIdFn] -Optional function to override default UUID generation. Should return a string\n   * @returns {AsyncContextId} The singleton instance\n   * @example\n   * // Using default Map and UUID generation\n   * const tracker = new AsyncContextId();\n   *\n   * @example\n   * // Using custom LRU Map and correlation ID generator\n   * const tracker = new AsyncContextId({\n   *   store: new LruMap(1000),\n   *   correlationIdFn: () => `custom-${Date.now()}`\n   * });\n   */\n  constructor({store, correlationIdFn} = {\n    store: new Map(), correlationIdFn: null\n  }) {\n    if (instance) {\n      return instance\n    }\n    this.contextStore = store\n    this.correlationIdFn = correlationIdFn\n    this.hook = asyncHooks.createHook({\n      init: (asyncId, type, triggerAsyncId) => {\n        // Copy parent context for new async operations to maintain same correlation ID\n        if (this.contextStore.has(triggerAsyncId)) {\n          const parentContext = this.contextStore.get(triggerAsyncId)\n          const newContext = JSON.parse(JSON.stringify(parentContext))\n          this.contextStore.set(asyncId, newContext)\n        }\n      },\n      promiseResolve: (asyncId) => {\n        const context = this.contextStore.get(asyncId)\n        if (context) {\n          const currentAsyncId = asyncHooks.executionAsyncId()\n          this.contextStore.set(\n            currentAsyncId,\n            JSON.parse(JSON.stringify(context)),\n          )\n        }\n      },\n      destroy: (asyncId) => {\n        this.contextStore.delete(asyncId)\n      },\n    })\n\n    /**\n     * remove the listener of itself to prevent memory leaks\n     */\n    this.cleanUpFn = () => {\n      process.removeListener('beforeExit', this.cleanUpFn)\n      this.hook.disable()\n      this.contextStore.clear()\n    }\n    this.hook.enable()\n    process.on('beforeExit', this.cleanUpFn)\n    instance = this\n    return this\n  }\n\n  /**\n   * Generates a correlation ID for tracking.\n   * Uses custom correlation ID generator if provided, otherwise generates UUID v4.\n   *\n   * @private\n   * @returns {string} A correlation ID string\n   * @throws {Error} If custom correlationIdFn throws or returns non-string\n   *\n   * @example\n   * // Using default UUID v4 generator\n   * const id = this.generateCorrelationId();\n   * // Returns: \"123e4567-e89b-12d3-a456-426614174000\"\n   *\n   * @example\n   * // Using custom generator\n   * const tracker = new AsyncContextId({\n   *   correlationIdFn: () => `custom-${Date.now()}`\n   * });\n   * const id = tracker.generateCorrelationId();\n   * // Returns: \"custom-1708704000000\"\n   */\n  generateCorrelationId() {\n    if (this.correlationIdFn) {\n      return this.correlationIdFn()\n    }\n    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n      const r = (Math.random() * 16) | 0\n      const v = c === 'x' ? r : (r & 0x3) | 0x8\n      return v.toString(16)\n    })\n  }\n\n  /**\n   * Retrieves the correlation ID for the current async context.\n   * Creates a new context with generated ID if none exists.\n   *\n   * @returns {string} The current correlation ID\n   * @throws {Error} If async hooks are not enabled\n   *\n   * @example\n   * const correlationId = tracker.getCorrelationId();\n   * res.setHeader('x-correlation-id', correlationId);\n   */\n  getCorrelationId() {\n    const asyncId = asyncHooks.executionAsyncId()\n    if (!this.contextStore.has(asyncId)) {\n      this.contextStore.set(asyncId, {\n        correlationId: this.generateCorrelationId(),\n        startTime: Date.now(),\n        metadata: {},\n      })\n    }\n    return this.contextStore.get(asyncId).correlationId\n  }\n\n  /**\n   * Sets the correlation ID for the current async context.\n   * Creates a new context if none exists.\n   *\n   * @param {string} correlationId - The correlation ID to set\n   * @throws {Error} If the correlationId is not a string\n   * @throws {Error} If async hooks are not enabled\n   *\n   * @example\n   * const upstreamId = req.headers['x-correlation-id'];\n   * if (upstreamId) {\n   *   tracker.setCorrelationId(upstreamId);\n   * }\n   */\n  setCorrelationId(correlationId = this.generateCorrelationId()) {\n    const asyncId = asyncHooks.executionAsyncId()\n    if (!this.contextStore.has(asyncId)) {\n      this.contextStore.set(asyncId, {\n        correlationId,\n        startTime: Date.now(),\n        metadata: {},\n      })\n    } else {\n      const existingContext = this.contextStore.get(asyncId)\n      const newContext = JSON.parse(JSON.stringify(existingContext))\n      newContext.correlationId = correlationId\n      this.contextStore.set(asyncId, newContext)\n    }\n    return correlationId\n  }\n\n  /**\n   * Retrieves the complete context object for the current async operation.\n   * Creates a new context if none exists.\n   *\n   * @returns {Object} The correlation context\n   * @returns {string} context.correlationId - The correlation ID\n   * @returns {number} context.startTime - Unix timestamp of context creation\n   * @returns {Object} context.metadata - Custom metadata object\n   * @throws {Error} If async hooks are not enabled\n   *\n   * @example\n   * const context = tracker.getContext();\n   * console.log({\n   *   correlationId: context.correlationId,\n   *   duration: Date.now() - context.startTime,\n   *   metadata: context.metadata\n   * });\n   */\n  getContext() {\n    const asyncId = asyncHooks.executionAsyncId()\n    if (!this.contextStore.has(asyncId)) {\n      this.contextStore.set(asyncId, {\n        correlationId: this.generateCorrelationId(),\n        startTime: Date.now(),\n        metadata: {},\n      })\n    }\n    return JSON.parse(JSON.stringify(this.contextStore.get(asyncId)))\n  }\n\n  /**\n   * Updates the context for the current async operation.\n   * Creates a new context if none exists. Preserves existing correlationId\n   * and startTime unless explicitly overridden.\n   *\n   * @param {Object} [context={}] - The context object to merge\n   * @param {string} [context.correlationId] - Optional correlation ID override\n   * @param {Object} [context.metadata] - Optional metadata to merge\n   * @throws {Error} If async hooks are not enabled\n   * @throws {Error} If context is not an object\n   *\n   * @example\n   * // Add request context\n   * tracker.setContext({\n   *   metadata: {\n   *     operation: 'processData',\n   *     requestId: req.id,\n   *     userId: req.user.id\n   *   }\n   * });\n   */\n  setContext(context = {}) {\n    const asyncId = asyncHooks.executionAsyncId()\n    const existingContext = this.contextStore.get(asyncId) || {\n      correlationId: this.generateCorrelationId(),\n      startTime: Date.now(),\n      metadata: {},\n    }\n    const clonedExisting = JSON.parse(JSON.stringify(existingContext))\n    const clonedNew = JSON.parse(JSON.stringify(context))\n    Object.assign(clonedExisting, clonedNew)\n    clonedExisting.correlationId =\n      clonedNew.correlationId || clonedExisting.correlationId\n    clonedExisting.startTime = existingContext.startTime\n    this.contextStore.set(asyncId, clonedExisting)\n  }\n\n  /**\n   * Removes the correlation context for the current async operation.\n   *\n   * @throws {Error} If async hooks are not enabled\n   *\n   * @example\n   * try {\n   *   await processRequest(data);\n   * } finally {\n   *   tracker.clear();\n   * }\n   */\n  clear() {\n    const asyncId = asyncHooks.executionAsyncId()\n    this.contextStore.delete(asyncId)\n  }\n}\n\nexport default AsyncContextId\nexport {instance}\n","/**\n * A Map extension implementing Least Recently Used (LRU) caching strategy.\n * Automatically removes oldest entries when size limit is reached.\n * @extends {Map}\n *\n * @example\n * const cache = new LruMap(3);\n * cache.set('a', 1).set('b', 2).set('c', 3);\n * cache.set('d', 4); // Removes 'a', now contains b,c,d\n */\nclass LruMap extends Map {\n  /**\n   * Creates an LRU cache with specified maximum size.\n   * @param {number} maxSize - Maximum number of entries\n   *\n   * @example\n   * const cache = new LruMap(1000);\n   */\n  constructor(maxSize) {\n    super()\n    this.maxSize = maxSize\n  }\n\n  /**\n   * Sets a value, removing oldest entry if size limit reached.\n   * @param {*} key - The key to set\n   * @param {*} value - The value to store\n   * @returns {this} The LruMap instance for chaining\n   *\n   * @example\n   * const cache = new LruMap(2);\n   * cache.set('key1', 'value1')\n   *      .set('key2', 'value2')\n   *      .set('key3', 'value3'); // Removes key1\n   */\n  set(key, value) {\n    if (!this.has(key) && this.size >= this.maxSize) {\n      const firstKey = this.keys().next().value\n      this.delete(firstKey)\n    }\n    return super.set(key, value)\n  }\n}\nexport default LruMap\n","/**\n * A Map extension that automatically deletes entries after a specified time-to-live (TTL).\n * @extends {Map}\n *\n * @example\n * const cache = new TimedMap(5000); // 5 second TTL\n * cache.set('key1', 'value1');\n * console.log(cache.get('key1')); // 'value1'\n * // After 5 seconds:\n * console.log(cache.get('key1')); // undefined\n *\n * @example\n * // Resetting TTL on value update\n * const cache = new TimedMap(2000);\n * cache.set('user', { name: 'Alice' });\n * // 1 second later:\n * cache.set('user', { name: 'Alice', age: 30 }); // Resets the 2-second timer\n */\nclass TimedMap extends Map {\n  /**\n   * Creates a new TimedMap instance.\n   * @param {number} ttl - Time-to-live in milliseconds for each key-value pair\n   *\n   * @example\n   * const sessionCache = new TimedMap(1800000); // 30 minute TTL\n   */\n  constructor(ttl) {\n    super()\n    this.ttl = ttl\n    this.timeouts = new Map()\n  }\n\n  /**\n   * Sets a value in the map with an automatic deletion timer.\n   * If the key already exists, its timer is reset.\n   * @param {*} key - The key to set\n   * @param {*} value - The value to store\n   * @returns {this} The TimedMap instance for chaining\n   *\n   * @example\n   * const cache = new TimedMap(10000);\n   * cache.set('apiKey', 'xyz123')\n   *      .set('timestamp', Date.now());\n   */\n  set(key, value) {\n    if (this.timeouts.has(key)) clearTimeout(this.timeouts.get(key))\n    this.timeouts.set(\n      key,\n      setTimeout(() => this.delete(key), this.ttl),\n    )\n    return super.set(key, value)\n  }\n\n  /**\n   * Deletes a key-value pair and its associated timer.\n   * @param {*} key - The key to delete\n   * @returns {boolean} True if the element was deleted, false if it didn't exist\n   *\n   * @example\n   * const cache = new TimedMap(5000);\n   * cache.set('temp', 'data');\n   * cache.delete('temp'); // Manually delete before TTL expires\n   */\n  delete(key) {\n    if (this.timeouts.has(key)) {\n      clearTimeout(this.timeouts.get(key))\n      this.timeouts.delete(key)\n    }\n    return super.delete(key)\n  }\n}\nexport default TimedMap\n"],"names":[],"mappings":"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"}