{"version":3,"file":"als.cjs","names":["fallback: AsyncLocalStorageIsh"],"sources":["../../../src/components/execution/als.ts"],"sourcesContent":["import type { Context, StepOptions } from \"../../types.ts\";\nimport type { Inngest } from \"../Inngest.ts\";\nimport type { Stream } from \"../StreamTools.ts\";\nimport type { IInngestExecution } from \"./InngestExecution.ts\";\n\n/**\n * Note - this structure can be used by other libraries, so cannot have breaking changes.\n */\nexport interface AsyncContext {\n  /**\n   * The Inngest App that is currently being used to execute the function.\n   *\n   * If this is defined, we are in the context of an Inngest function execution,\n   * or a possible one.\n   */\n  app: Inngest.Like;\n\n  /**\n   * Details of the current function execution context. If this doesn't exist,\n   * then we're not currently in a function execution context.\n   */\n  execution?: {\n    /**\n     * The execution instance that is currently running the function.\n     */\n    instance: IInngestExecution;\n\n    /**\n     * The `ctx` object that has been passed in to this function execution,\n     * including values such as `step` and `event`.\n     */\n    ctx: Context.Any;\n\n    /**\n     * If present, this indicates we are currently executing a `step.run()` step's\n     * callback. Useful to understand whether we are in the context of a step\n     * execution or within the main function body.\n     */\n    executingStep?: StepOptions & { hashedId?: string };\n\n    /**\n     * If present, indicates the parallel mode that should be applied to steps\n     * created within this context. Set by `group.parallel()`.\n     */\n    parallelMode?: \"race\";\n\n    /**\n     * The stream tools instance for this execution context. Used by the\n     * `stream` singleton to push/pipe SSE data to the client.\n     */\n    stream?: Stream;\n\n    /**\n     * If present, indicates the variant callback is executing within an\n     * experiment. Set by `group.experiment()`. Any `step.*()` call within\n     * this context will include these fields in `OutgoingOp.opts`.\n     */\n    experimentContext?: {\n      experimentStepID: string;\n      experimentName: string;\n      variant: string;\n      selectionStrategy: string;\n    };\n\n    /**\n     * A mutable tracker used to detect whether any step tool was invoked\n     * during a variant callback. Set by `group.experiment()`, flipped by\n     * `createTool` in `InngestStepTools.ts`.\n     */\n    experimentStepTracker?: { found: boolean };\n\n    /**\n     * If true, we are inside the `select()` callback of\n     * `group.experiment()`. Any `step.*()` call here would create a\n     * nested step, which is not allowed.\n     */\n    insideExperimentSelect?: boolean;\n  };\n}\n\n/**\n * A local-only symbol used as a key in global state to store the async local\n * storage instance.\n */\nconst alsSymbol = Symbol.for(\"inngest:als\");\n\n/**\n * Cache structure that stores both the promise and resolved ALS instance.\n * This allows synchronous access after initialization.\n */\ntype ALSCache = {\n  promise: Promise<AsyncLocalStorageIsh>;\n  resolved?: AsyncLocalStorageIsh;\n  isFallback?: boolean;\n};\n\n/**\n * A type that represents a partial, runtime-agnostic interface of\n * `AsyncLocalStorage`.\n */\ntype AsyncLocalStorageIsh = {\n  getStore: () => AsyncContext | undefined;\n  run: <R>(store: AsyncContext, fn: () => R) => R;\n};\n\nconst getCache = (): ALSCache => {\n  const g = globalThis as Record<symbol, ALSCache | undefined>;\n\n  if (!g[alsSymbol]) {\n    g[alsSymbol] = createCache();\n  }\n\n  return g[alsSymbol];\n};\n\nconst createCache = (): ALSCache => {\n  const cache = {} as ALSCache;\n  cache.promise = initializeALS(cache);\n  return cache;\n};\n\nconst initializeALS = async (\n  cache: ALSCache,\n): Promise<AsyncLocalStorageIsh> => {\n  try {\n    const { AsyncLocalStorage } = await import(\"node:async_hooks\");\n    const als = new AsyncLocalStorage<AsyncContext>();\n    cache.resolved = als;\n    cache.isFallback = false;\n    return als;\n  } catch {\n    const fallback: AsyncLocalStorageIsh = {\n      getStore: () => undefined,\n      run: (_, fn) => fn(),\n    };\n    cache.resolved = fallback;\n    cache.isFallback = true;\n    console.warn(\n      \"node:async_hooks is not supported in this runtime. Async context is disabled.\",\n    );\n    return fallback;\n  }\n};\n\n/**\n * Check if AsyncLocalStorage is unavailable and we're using the fallback.\n * Returns `undefined` if ALS hasn't been initialized yet.\n */\nexport const isALSFallback = (): boolean | undefined => {\n  return getCache().isFallback;\n};\n\n/**\n * Retrieve the async context for the current execution.\n */\nexport const getAsyncCtx = async (): Promise<AsyncContext | undefined> => {\n  return getAsyncLocalStorage().then((als) => als.getStore());\n};\n\n/**\n * Retrieve the async context for the current execution synchronously.\n * Returns undefined if ALS hasn't been initialized yet.\n */\nexport const getAsyncCtxSync = (): AsyncContext | undefined => {\n  return getCache().resolved?.getStore();\n};\n\n/**\n * Get a singleton instance of `AsyncLocalStorage` used to store and retrieve\n * async context for the current execution.\n */\nexport const getAsyncLocalStorage = async (): Promise<AsyncLocalStorageIsh> => {\n  return getCache().promise;\n};\n"],"mappings":";;;;;;AAoFA,MAAM,YAAY,OAAO,IAAI,cAAc;AAqB3C,MAAM,iBAA2B;CAC/B,MAAM,IAAI;AAEV,KAAI,CAAC,EAAE,WACL,GAAE,aAAa,aAAa;AAG9B,QAAO,EAAE;;AAGX,MAAM,oBAA8B;CAClC,MAAM,QAAQ,EAAE;AAChB,OAAM,UAAU,cAAc,MAAM;AACpC,QAAO;;AAGT,MAAM,gBAAgB,OACpB,UACkC;AAClC,KAAI;EACF,MAAM,EAAE,sBAAsB,MAAM,OAAO;EAC3C,MAAM,MAAM,IAAI,mBAAiC;AACjD,QAAM,WAAW;AACjB,QAAM,aAAa;AACnB,SAAO;SACD;EACN,MAAMA,WAAiC;GACrC,gBAAgB;GAChB,MAAM,GAAG,OAAO,IAAI;GACrB;AACD,QAAM,WAAW;AACjB,QAAM,aAAa;AACnB,UAAQ,KACN,gFACD;AACD,SAAO;;;;;;;AAQX,MAAa,sBAA2C;AACtD,QAAO,UAAU,CAAC;;;;;AAMpB,MAAa,cAAc,YAA+C;AACxE,QAAO,sBAAsB,CAAC,MAAM,QAAQ,IAAI,UAAU,CAAC;;;;;;AAO7D,MAAa,wBAAkD;AAC7D,QAAO,UAAU,CAAC,UAAU,UAAU;;;;;;AAOxC,MAAa,uBAAuB,YAA2C;AAC7E,QAAO,UAAU,CAAC"}