All files / src/internal/context async-local-storage.mts

50% Statements 8/16
50% Branches 2/4
33.33% Functions 3/9
50% Lines 8/16

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70                                        17x           17x     10x       10x                                     10x 10x         10x       10x              
import type { IAsyncLocalStorage } from './async-local-storage.types.mjs'
 
import { AsyncLocalStorage } from 'node:async_hooks'
 
/**
 * Cross-platform AsyncLocalStorage switcher.
 *
 * Provides the appropriate implementation based on environment:
 * - Production: No-op implementation (circular detection disabled)
 * - Development: Native AsyncLocalStorage from node:async_hooks
 *
 * Browser environments use a separate entry point via package.json exports
 * that directly uses SyncLocalStorage.
 *
 * Uses lazy initialization to avoid import overhead until first use,
 * and works with both ESM and CJS builds.
 */
 
export type { IAsyncLocalStorage }
 
const isProduction = process.env.NODE_ENV === 'production'
 
// Lazy-loaded module cache
let loadedModule: {
  createAsyncLocalStorage: <T>() => IAsyncLocalStorage<T>
  isUsingNativeAsyncLocalStorage: () => boolean
} | null = null
 
function getModule() {
  Iif (loadedModule) {
    return loadedModule
  }
 
  Iif (isProduction) {
    // In production, use the noop implementation
    // Inline to avoid any import overhead
    class NoopLocalStorage<T> implements IAsyncLocalStorage<T> {
      run<R>(_store: T, fn: () => R): R {
        return fn()
      }
      getStore(): T | undefined {
        return undefined
      }
    }
 
    loadedModule = {
      createAsyncLocalStorage: <T,>() => new NoopLocalStorage<T>(),
      isUsingNativeAsyncLocalStorage: () => false,
    }
  } else {
    // In development, use native AsyncLocalStorage
 
    loadedModule = {
      createAsyncLocalStorage: <T,>() => new AsyncLocalStorage<T>(),
      isUsingNativeAsyncLocalStorage: () => true,
    }
  }
 
  return loadedModule
}
 
export function createAsyncLocalStorage<T>(): IAsyncLocalStorage<T> {
  return getModule().createAsyncLocalStorage<T>()
}
 
export function isUsingNativeAsyncLocalStorage(): boolean {
  return getModule().isUsingNativeAsyncLocalStorage()
}