inngest 4.3.0 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/api/schema.d.cts +2 -2
  3. package/api/schema.d.cts.map +1 -1
  4. package/api/schema.d.ts +2 -2
  5. package/api/schema.d.ts.map +1 -1
  6. package/components/DeferredFunction.cjs +66 -0
  7. package/components/DeferredFunction.cjs.map +1 -0
  8. package/components/DeferredFunction.d.cts +99 -0
  9. package/components/DeferredFunction.d.cts.map +1 -0
  10. package/components/DeferredFunction.d.ts +99 -0
  11. package/components/DeferredFunction.d.ts.map +1 -0
  12. package/components/DeferredFunction.js +65 -0
  13. package/components/DeferredFunction.js.map +1 -0
  14. package/components/Inngest.cjs +5 -2
  15. package/components/Inngest.cjs.map +1 -1
  16. package/components/Inngest.d.cts +4 -3
  17. package/components/Inngest.d.cts.map +1 -1
  18. package/components/Inngest.d.ts +4 -3
  19. package/components/Inngest.d.ts.map +1 -1
  20. package/components/Inngest.js +5 -2
  21. package/components/Inngest.js.map +1 -1
  22. package/components/InngestCommHandler.cjs +28 -23
  23. package/components/InngestCommHandler.cjs.map +1 -1
  24. package/components/InngestCommHandler.d.cts +9 -4
  25. package/components/InngestCommHandler.d.cts.map +1 -1
  26. package/components/InngestCommHandler.d.ts +9 -4
  27. package/components/InngestCommHandler.d.ts.map +1 -1
  28. package/components/InngestCommHandler.js +28 -23
  29. package/components/InngestCommHandler.js.map +1 -1
  30. package/components/InngestFunction.cjs +27 -19
  31. package/components/InngestFunction.cjs.map +1 -1
  32. package/components/InngestFunction.d.cts +6 -1
  33. package/components/InngestFunction.d.cts.map +1 -1
  34. package/components/InngestFunction.d.ts +6 -1
  35. package/components/InngestFunction.d.ts.map +1 -1
  36. package/components/InngestFunction.js +27 -19
  37. package/components/InngestFunction.js.map +1 -1
  38. package/components/InngestGroupTools.cjs +1 -1
  39. package/components/InngestGroupTools.cjs.map +1 -1
  40. package/components/InngestGroupTools.js +1 -1
  41. package/components/InngestGroupTools.js.map +1 -1
  42. package/components/connect/config.cjs +2 -0
  43. package/components/connect/config.cjs.map +1 -1
  44. package/components/connect/config.js +2 -0
  45. package/components/connect/config.js.map +1 -1
  46. package/components/execution/InngestExecution.cjs.map +1 -1
  47. package/components/execution/InngestExecution.d.cts +19 -2
  48. package/components/execution/InngestExecution.d.cts.map +1 -1
  49. package/components/execution/InngestExecution.d.ts +19 -2
  50. package/components/execution/InngestExecution.d.ts.map +1 -1
  51. package/components/execution/InngestExecution.js.map +1 -1
  52. package/components/execution/engine.cjs +232 -27
  53. package/components/execution/engine.cjs.map +1 -1
  54. package/components/execution/engine.d.cts +14 -0
  55. package/components/execution/engine.d.cts.map +1 -1
  56. package/components/execution/engine.d.ts +14 -0
  57. package/components/execution/engine.d.ts.map +1 -1
  58. package/components/execution/engine.js +232 -27
  59. package/components/execution/engine.js.map +1 -1
  60. package/components/execution/lazyOps.cjs +64 -0
  61. package/components/execution/lazyOps.cjs.map +1 -0
  62. package/components/execution/lazyOps.d.cts +42 -0
  63. package/components/execution/lazyOps.d.cts.map +1 -0
  64. package/components/execution/lazyOps.d.ts +42 -0
  65. package/components/execution/lazyOps.d.ts.map +1 -0
  66. package/components/execution/lazyOps.js +63 -0
  67. package/components/execution/lazyOps.js.map +1 -0
  68. package/components/execution/otel/middleware.d.cts +6 -3
  69. package/components/execution/otel/middleware.d.cts.map +1 -1
  70. package/components/execution/otel/middleware.d.ts +6 -3
  71. package/components/execution/otel/middleware.d.ts.map +1 -1
  72. package/components/middleware/middleware.cjs.map +1 -1
  73. package/components/middleware/middleware.d.cts +1 -1
  74. package/components/middleware/middleware.d.cts.map +1 -1
  75. package/components/middleware/middleware.d.ts +1 -1
  76. package/components/middleware/middleware.d.ts.map +1 -1
  77. package/components/middleware/middleware.js.map +1 -1
  78. package/components/middleware/utils.cjs +1 -0
  79. package/components/middleware/utils.cjs.map +1 -1
  80. package/components/middleware/utils.js +1 -0
  81. package/components/middleware/utils.js.map +1 -1
  82. package/components/realtime/types.d.cts +4 -4
  83. package/components/realtime/types.d.cts.map +1 -1
  84. package/components/realtime/types.d.ts +4 -4
  85. package/components/realtime/types.d.ts.map +1 -1
  86. package/components/triggers/typeHelpers.cjs.map +1 -1
  87. package/components/triggers/typeHelpers.d.cts +11 -0
  88. package/components/triggers/typeHelpers.d.cts.map +1 -1
  89. package/components/triggers/typeHelpers.d.ts +11 -0
  90. package/components/triggers/typeHelpers.d.ts.map +1 -1
  91. package/components/triggers/typeHelpers.js.map +1 -1
  92. package/experimental.cjs +3 -0
  93. package/experimental.d.cts +2 -1
  94. package/experimental.d.ts +2 -1
  95. package/experimental.js +2 -1
  96. package/helpers/consts.cjs +6 -0
  97. package/helpers/consts.cjs.map +1 -1
  98. package/helpers/consts.d.cts +6 -0
  99. package/helpers/consts.d.cts.map +1 -1
  100. package/helpers/consts.d.ts +6 -0
  101. package/helpers/consts.d.ts.map +1 -1
  102. package/helpers/consts.js +6 -0
  103. package/helpers/consts.js.map +1 -1
  104. package/helpers/functions.cjs +1 -0
  105. package/helpers/functions.cjs.map +1 -1
  106. package/helpers/functions.js +1 -0
  107. package/helpers/functions.js.map +1 -1
  108. package/helpers/marker.cjs +21 -0
  109. package/helpers/marker.cjs.map +1 -0
  110. package/helpers/marker.d.cts +12 -0
  111. package/helpers/marker.d.cts.map +1 -0
  112. package/helpers/marker.d.ts +12 -0
  113. package/helpers/marker.d.ts.map +1 -0
  114. package/helpers/marker.js +19 -0
  115. package/helpers/marker.js.map +1 -0
  116. package/package.json +2 -2
  117. package/proto/src/components/connect/protobuf/connect.cjs +11 -2
  118. package/proto/src/components/connect/protobuf/connect.cjs.map +1 -1
  119. package/proto/src/components/connect/protobuf/connect.js +11 -2
  120. package/proto/src/components/connect/protobuf/connect.js.map +1 -1
  121. package/types.cjs +2 -0
  122. package/types.cjs.map +1 -1
  123. package/types.d.cts +52 -18
  124. package/types.d.cts.map +1 -1
  125. package/types.d.ts +52 -18
  126. package/types.d.ts.map +1 -1
  127. package/types.js +2 -0
  128. package/types.js.map +1 -1
  129. package/version.cjs +1 -1
  130. package/version.cjs.map +1 -1
  131. package/version.d.cts +1 -1
  132. package/version.d.ts +1 -1
  133. package/version.js +1 -1
  134. package/version.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"InngestGroupTools.js","names":["options: ParallelOptions","nestedCtx: AsyncContext","experiment: GroupExperiment","experimentStepHashedId: string | undefined","selectedVariant: string","currentCtx","selectCtx: AsyncContext","result","result: unknown"],"sources":["../../src/components/InngestGroupTools.ts"],"sourcesContent":["import type { IsNever } from \"../helpers/types.ts\";\nimport type { StepOptionsOrId } from \"../types.ts\";\nimport {\n type AsyncContext,\n getAsyncCtxSync,\n getAsyncLocalStorage,\n isALSFallback,\n} from \"./execution/als.ts\";\nimport { getStepOptions } from \"./InngestStepTools.ts\";\nimport { NonRetriableError } from \"./NonRetriableError.ts\";\n\n/**\n * Options for the `group.parallel()` helper.\n */\nexport interface ParallelOptions {\n /**\n * The parallel mode to apply to all steps created within the callback.\n *\n * - `\"race\"`: Steps will be executed with race semantics, meaning the first\n * step to complete will \"win\" and remaining steps may be cancelled.\n */\n mode?: \"race\";\n}\n\n/**\n * A helper that sets the parallel mode for all steps created within the\n * callback. This allows you to use native `Promise.race()` with cleaner syntax.\n *\n * @example\n * ```ts\n * // Defaults to \"race\" mode\n * const winner = await group.parallel(async () => {\n * return Promise.race([\n * step.run(\"a\", () => \"a\"),\n * step.run(\"b\", () => \"b\"),\n * step.run(\"c\", () => \"c\"),\n * ]);\n * });\n *\n * // Or explicitly specify the mode\n * const winner = await group.parallel({ mode: \"race\" }, async () => {\n * return Promise.race([\n * step.run(\"a\", () => \"a\"),\n * step.run(\"b\", () => \"b\"),\n * ]);\n * });\n * ```\n */\nconst parallel = async <T>(\n optionsOrCallback: ParallelOptions | (() => Promise<T>),\n maybeCallback?: () => Promise<T>,\n): Promise<T> => {\n const options: ParallelOptions =\n typeof optionsOrCallback === \"function\" ? {} : optionsOrCallback;\n const callback =\n typeof optionsOrCallback === \"function\" ? optionsOrCallback : maybeCallback;\n\n if (!callback) {\n throw new Error(\"`group.parallel()` requires a callback function\");\n }\n\n const currentCtx = getAsyncCtxSync();\n\n if (!currentCtx?.execution) {\n throw new Error(\n \"`group.parallel()` must be called within an Inngest function execution\",\n );\n }\n\n const als = await getAsyncLocalStorage();\n\n if (isALSFallback()) {\n throw new Error(\n \"`group.parallel()` requires AsyncLocalStorage support, which is not available in this runtime. \" +\n \"Workaround: Pass `parallelMode` directly to each step:\\n\" +\n ' step.run({ id: \"my-step\", parallelMode: \"race\" }, fn)',\n );\n }\n\n // Create a new context with the parallelMode set\n const nestedCtx: AsyncContext = {\n ...currentCtx,\n execution: {\n ...currentCtx.execution,\n parallelMode: options.mode ?? \"race\",\n },\n };\n\n // Run the callback inside the nested context\n return als.run(nestedCtx, callback);\n};\n\n/**\n * Configuration for how the experiment selects a variant.\n */\nexport interface ExperimentStrategyConfig {\n strategy: string;\n weights?: Record<string, number>;\n nullishBucket?: boolean;\n}\n\n/**\n * A callable selection function that also carries strategy metadata.\n */\nexport interface ExperimentSelectFn {\n (variantNames?: string[]): Promise<string> | string;\n __experimentConfig: ExperimentStrategyConfig;\n}\n\n/**\n * Options for `group.experiment()`.\n */\nexport interface ExperimentOptions<\n TVariants extends Record<string, () => unknown>,\n> {\n /**\n * A map of variant names to callbacks. The selected variant's callback will\n * be executed at the top level so that any `step.*` calls inside it go\n * through normal step discovery.\n */\n variants: TVariants;\n\n /**\n * A selection function that returns the name of the variant to execute.\n * The result is memoized via a step so the same variant is used on retries.\n */\n select: ExperimentSelectFn;\n}\n\n/**\n * Options for `group.experiment()` when `withVariant` is true, which causes\n * the return type to include both the result and the selected variant name.\n */\nexport interface ExperimentOptionsWithVariant<\n TVariants extends Record<string, () => unknown>,\n> extends ExperimentOptions<TVariants> {\n /**\n * When true, the return value includes the variant name alongside the result.\n */\n withVariant: true;\n}\n\n/**\n * Computes the return type of an experiment based on variant callbacks.\n *\n * When `TConstraint` is `never`, the return type is inferred as the union of\n * all variant callback return types. Otherwise `TConstraint` is used directly.\n */\nexport type VariantResult<\n TConstraint,\n TVariants extends Record<string, () => unknown>,\n> = IsNever<TConstraint> extends true\n ? Awaited<ReturnType<TVariants[keyof TVariants]>>\n : TConstraint;\n\n/**\n * Metadata values stored alongside the experiment step for UI rendering.\n */\nexport interface ExperimentMetadataValues {\n experiment_name: string;\n variant_selected: string;\n selection_strategy: string;\n available_variants: string[];\n variant_weights?: Record<string, number>;\n}\n\n/**\n * Overloaded interface for `group.experiment()`.\n */\nexport interface GroupExperiment {\n /**\n * Run an A/B experiment that selects and executes a variant. Returns both\n * the result and the selected variant name.\n */\n <TVariants extends Record<string, () => unknown>>(\n idOrOptions: StepOptionsOrId,\n options: ExperimentOptionsWithVariant<TVariants>,\n ): Promise<{\n result: VariantResult<never, TVariants>;\n variant: string;\n }>;\n\n /**\n * Run an A/B experiment that selects and executes a variant. Returns only\n * the variant callback's result.\n */\n <TVariants extends Record<string, () => unknown>>(\n idOrOptions: StepOptionsOrId,\n options: ExperimentOptions<TVariants>,\n ): Promise<VariantResult<never, TVariants>>;\n}\n\n/**\n * Tools for grouping and coordinating steps.\n *\n * @public\n */\nexport interface GroupTools {\n /**\n * Run a callback where all steps automatically receive a `parallelMode`\n * option, removing the need to tag each step individually. Defaults to\n * `\"race\"` mode.\n *\n * @example\n * ```ts\n * // Defaults to \"race\" mode\n * const winner = await group.parallel(async () => {\n * return Promise.race([\n * step.run(\"a\", () => \"a\"),\n * step.run(\"b\", () => \"b\"),\n * step.run(\"c\", () => \"c\"),\n * ]);\n * });\n *\n * // Or explicitly specify the mode\n * const winner = await group.parallel({ mode: \"race\" }, async () => {\n * return Promise.race([\n * step.run(\"a\", () => \"a\"),\n * step.run(\"b\", () => \"b\"),\n * ]);\n * });\n * ```\n */\n parallel: <T>(\n optionsOrCallback: ParallelOptions | (() => Promise<T>),\n maybeCallback?: () => Promise<T>,\n ) => Promise<T>;\n\n /**\n * Run an A/B experiment within a function. Selects a variant via a memoized\n * step, then executes the selected variant's callback at the top level so\n * its `step.*` calls go through normal step discovery.\n *\n * @example\n * ```ts\n * const result = await group.experiment(\"checkout-flow\", {\n * variants: {\n * control: () => step.run(\"control-checkout\", () => oldCheckout()),\n * new_flow: () => step.run(\"new-checkout\", () => newCheckout()),\n * },\n * select: Object.assign(() => \"control\", {\n * __experimentConfig: { strategy: \"weighted\", weights: { control: 80, new_flow: 20 } },\n * }),\n * });\n * ```\n */\n experiment: GroupExperiment;\n}\n\n/**\n * Dependencies injected into `createGroupTools` from the execution engine.\n */\nexport interface GroupToolsDeps {\n /**\n * A `step.run` variant with `opts.type = \"group.experiment\"`, extracted from\n * step tools via the experiment symbol. Undefined when not available.\n */\n // biome-ignore lint/suspicious/noExplicitAny: internal plumbing\n experimentStepRun?: (...args: any[]) => Promise<any>;\n}\n\n/**\n * Create the `group` tools object provided on the function execution context.\n *\n * @public\n */\nexport const createGroupTools = (deps?: GroupToolsDeps): GroupTools => {\n const experiment: GroupExperiment = (async (\n idOrOptions: StepOptionsOrId,\n // biome-ignore lint/suspicious/noExplicitAny: implementation signature for overloaded interface\n options: any,\n ) => {\n if (!deps?.experimentStepRun) {\n throw new Error(\n \"`group.experiment()` requires step tools to be available. \" +\n \"Ensure you are calling this within an Inngest function execution.\",\n );\n }\n\n const { variants, select, withVariant } = options;\n const variantNames = Object.keys(variants);\n\n if (variantNames.length === 0) {\n throw new Error(\n \"`group.experiment()` requires at least one variant to be defined.\",\n );\n }\n\n if (isALSFallback()) {\n throw new Error(\n \"`group.experiment()` requires AsyncLocalStorage support, which is not available in this runtime.\",\n );\n }\n\n const stepOpts = getStepOptions(idOrOptions);\n\n // Use the experiment step run to memoize the variant selection.\n // This creates a StepPlanned opcode with opts.type = \"group.experiment\".\n let experimentStepHashedId: string | undefined;\n\n const selectedVariant: string = await deps.experimentStepRun(\n idOrOptions,\n async () => {\n // Capture the hashed step ID so we can propagate it to variant sub-steps.\n experimentStepHashedId =\n getAsyncCtxSync()?.execution?.executingStep?.id;\n\n const alsInstance = await getAsyncLocalStorage();\n const currentCtx = getAsyncCtxSync()!;\n const selectCtx: AsyncContext = {\n ...currentCtx,\n execution: {\n ...currentCtx.execution!,\n insideExperimentSelect: true,\n },\n };\n const result = await alsInstance.run(selectCtx, () =>\n select(variantNames),\n );\n\n if (!variantNames.includes(result)) {\n throw new NonRetriableError(\n `group.experiment(\"${stepOpts.id}\"): select() returned \"${result}\" ` +\n `which is not a known variant. Available variants: ${variantNames.join(\", \")}`,\n );\n }\n\n // Attach experiment metadata to this step's OutgoingOp.\n const ctx = getAsyncCtxSync();\n const execInstance = ctx?.execution?.instance;\n\n if (execInstance && experimentStepHashedId) {\n execInstance.addMetadata(\n experimentStepHashedId,\n \"inngest.experiment\",\n \"step\",\n \"merge\",\n {\n experiment_name: stepOpts.id,\n variant_selected: result,\n selection_strategy: select.__experimentConfig.strategy,\n available_variants: variantNames,\n ...(select.__experimentConfig.weights && {\n variant_weights: select.__experimentConfig.weights,\n }),\n } satisfies ExperimentMetadataValues,\n );\n\n if (select.__experimentConfig.nullishBucket) {\n execInstance.addMetadata(\n experimentStepHashedId,\n \"inngest.warnings\",\n \"step\",\n \"merge\",\n {\n message:\n \"experiment.bucket() received a null/undefined value; \" +\n 'hashing empty string \"\" for variant selection',\n },\n );\n }\n }\n\n return result;\n },\n );\n\n // Look up and execute the selected variant's callback at the top level\n // so its step.* calls go through normal step discovery.\n const variantFn = variants[selectedVariant];\n\n if (!variantFn) {\n throw new Error(\n `group.experiment(\"${stepOpts.id}\"): variant \"${selectedVariant}\" ` +\n `was selected but is not defined. Available variants: ${variantNames.join(\", \")}`,\n );\n }\n\n // Propagate experiment context via ALS so variant sub-steps include\n // experiment fields in their OutgoingOp.opts. The executor reads these\n // fields from opts and emits the step-scoped `inngest.experiment`\n // metadata span itself — the SDK does not need to call addMetadata()\n // for variant steps. See the companion executor change in inngest/inngest\n // for the server-side emission path.\n //\n // Also track whether any step tool is invoked to detect zero-step\n // variants.\n //\n // NOTE: experimentStepHashedId may be undefined on replay because it\n // is captured inside the selection step callback, which doesn't run\n // when memoized. We still set experimentContext (with an empty string\n // for the hashed ID fallback) so that variant sub-steps discovered on\n // replay still carry experiment fields in their opts and the executor\n // can attach metadata to their ClickHouse rows.\n const currentCtx = getAsyncCtxSync();\n const stepTracker = { found: false };\n let result: unknown;\n\n if (currentCtx?.execution && !isALSFallback()) {\n const als = await getAsyncLocalStorage();\n const nestedCtx: AsyncContext = {\n ...currentCtx,\n execution: {\n ...currentCtx.execution,\n experimentContext: {\n experimentStepID: experimentStepHashedId ?? \"\",\n experimentName: stepOpts.id,\n variant: selectedVariant,\n selectionStrategy: select.__experimentConfig.strategy,\n },\n experimentStepTracker: stepTracker,\n },\n };\n result = await als.run(nestedCtx, () => variantFn());\n } else {\n result = await variantFn();\n }\n\n // If the variant returned without invoking any step tools, it will\n // silently re-execute on every replay. Throw a non-retriable error\n // to prevent this.\n if (!stepTracker.found && !isALSFallback()) {\n throw new NonRetriableError(\n `group.experiment(\"${stepOpts.id}\"): variant \"${selectedVariant}\" ` +\n \"did not invoke any step tools. Wrap your variant logic in \" +\n \"step.run() to ensure it is memoized and not re-executed on replay.\",\n );\n }\n\n if (withVariant) {\n return { result, variant: selectedVariant };\n }\n\n return result;\n }) as GroupExperiment;\n\n return { parallel, experiment };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"InngestGroupTools.js","names":["options: ParallelOptions","nestedCtx: AsyncContext","experiment: GroupExperiment","experimentStepHashedId: string | undefined","selectedVariant: string","currentCtx","selectCtx: AsyncContext","result","result: unknown"],"sources":["../../src/components/InngestGroupTools.ts"],"sourcesContent":["import type { IsNever } from \"../helpers/types.ts\";\nimport type { StepOptionsOrId } from \"../types.ts\";\nimport {\n type AsyncContext,\n getAsyncCtxSync,\n getAsyncLocalStorage,\n isALSFallback,\n} from \"./execution/als.ts\";\nimport { getStepOptions } from \"./InngestStepTools.ts\";\nimport { NonRetriableError } from \"./NonRetriableError.ts\";\n\n/**\n * Options for the `group.parallel()` helper.\n */\nexport interface ParallelOptions {\n /**\n * The parallel mode to apply to all steps created within the callback.\n *\n * - `\"race\"`: Steps will be executed with race semantics, meaning the first\n * step to complete will \"win\" and remaining steps may be cancelled.\n */\n mode?: \"race\";\n}\n\n/**\n * A helper that sets the parallel mode for all steps created within the\n * callback. This allows you to use native `Promise.race()` with cleaner syntax.\n *\n * @example\n * ```ts\n * // Defaults to \"race\" mode\n * const winner = await group.parallel(async () => {\n * return Promise.race([\n * step.run(\"a\", () => \"a\"),\n * step.run(\"b\", () => \"b\"),\n * step.run(\"c\", () => \"c\"),\n * ]);\n * });\n *\n * // Or explicitly specify the mode\n * const winner = await group.parallel({ mode: \"race\" }, async () => {\n * return Promise.race([\n * step.run(\"a\", () => \"a\"),\n * step.run(\"b\", () => \"b\"),\n * ]);\n * });\n * ```\n */\nconst parallel = async <T>(\n optionsOrCallback: ParallelOptions | (() => Promise<T>),\n maybeCallback?: () => Promise<T>,\n): Promise<T> => {\n const options: ParallelOptions =\n typeof optionsOrCallback === \"function\" ? {} : optionsOrCallback;\n const callback =\n typeof optionsOrCallback === \"function\" ? optionsOrCallback : maybeCallback;\n\n if (!callback) {\n throw new Error(\"`group.parallel()` requires a callback function\");\n }\n\n const currentCtx = getAsyncCtxSync();\n\n if (!currentCtx?.execution) {\n throw new Error(\n \"`group.parallel()` must be called within an Inngest function execution\",\n );\n }\n\n const als = await getAsyncLocalStorage();\n\n if (isALSFallback()) {\n throw new Error(\n \"`group.parallel()` requires AsyncLocalStorage support, which is not available in this runtime. \" +\n \"Workaround: Pass `parallelMode` directly to each step:\\n\" +\n ' step.run({ id: \"my-step\", parallelMode: \"race\" }, fn)',\n );\n }\n\n // Create a new context with the parallelMode set\n const nestedCtx: AsyncContext = {\n ...currentCtx,\n execution: {\n ...currentCtx.execution,\n parallelMode: options.mode ?? \"race\",\n },\n };\n\n // Run the callback inside the nested context\n return als.run(nestedCtx, callback);\n};\n\n/**\n * Configuration for how the experiment selects a variant.\n */\nexport interface ExperimentStrategyConfig {\n strategy: string;\n weights?: Record<string, number>;\n nullishBucket?: boolean;\n}\n\n/**\n * A callable selection function that also carries strategy metadata.\n */\nexport interface ExperimentSelectFn {\n (variantNames?: string[]): Promise<string> | string;\n __experimentConfig: ExperimentStrategyConfig;\n}\n\n/**\n * Options for `group.experiment()`.\n */\nexport interface ExperimentOptions<\n TVariants extends Record<string, () => unknown>,\n> {\n /**\n * A map of variant names to callbacks. The selected variant's callback will\n * be executed at the top level so that any `step.*` calls inside it go\n * through normal step discovery.\n */\n variants: TVariants;\n\n /**\n * A selection function that returns the name of the variant to execute.\n * The result is memoized via a step so the same variant is used on retries.\n */\n select: ExperimentSelectFn;\n}\n\n/**\n * Options for `group.experiment()` when `withVariant` is true, which causes\n * the return type to include both the result and the selected variant name.\n */\nexport interface ExperimentOptionsWithVariant<\n TVariants extends Record<string, () => unknown>,\n> extends ExperimentOptions<TVariants> {\n /**\n * When true, the return value includes the variant name alongside the result.\n */\n withVariant: true;\n}\n\n/**\n * Computes the return type of an experiment based on variant callbacks.\n *\n * When `TConstraint` is `never`, the return type is inferred as the union of\n * all variant callback return types. Otherwise `TConstraint` is used directly.\n */\nexport type VariantResult<\n TConstraint,\n TVariants extends Record<string, () => unknown>,\n> = IsNever<TConstraint> extends true\n ? Awaited<ReturnType<TVariants[keyof TVariants]>>\n : TConstraint;\n\n/**\n * Metadata values stored alongside the experiment step for UI rendering.\n */\nexport interface ExperimentMetadataValues {\n experiment_name: string;\n variant: string;\n selection_strategy: string;\n available_variants: string[];\n variant_weights?: Record<string, number>;\n}\n\n/**\n * Overloaded interface for `group.experiment()`.\n */\nexport interface GroupExperiment {\n /**\n * Run an A/B experiment that selects and executes a variant. Returns both\n * the result and the selected variant name.\n */\n <TVariants extends Record<string, () => unknown>>(\n idOrOptions: StepOptionsOrId,\n options: ExperimentOptionsWithVariant<TVariants>,\n ): Promise<{\n result: VariantResult<never, TVariants>;\n variant: string;\n }>;\n\n /**\n * Run an A/B experiment that selects and executes a variant. Returns only\n * the variant callback's result.\n */\n <TVariants extends Record<string, () => unknown>>(\n idOrOptions: StepOptionsOrId,\n options: ExperimentOptions<TVariants>,\n ): Promise<VariantResult<never, TVariants>>;\n}\n\n/**\n * Tools for grouping and coordinating steps.\n *\n * @public\n */\nexport interface GroupTools {\n /**\n * Run a callback where all steps automatically receive a `parallelMode`\n * option, removing the need to tag each step individually. Defaults to\n * `\"race\"` mode.\n *\n * @example\n * ```ts\n * // Defaults to \"race\" mode\n * const winner = await group.parallel(async () => {\n * return Promise.race([\n * step.run(\"a\", () => \"a\"),\n * step.run(\"b\", () => \"b\"),\n * step.run(\"c\", () => \"c\"),\n * ]);\n * });\n *\n * // Or explicitly specify the mode\n * const winner = await group.parallel({ mode: \"race\" }, async () => {\n * return Promise.race([\n * step.run(\"a\", () => \"a\"),\n * step.run(\"b\", () => \"b\"),\n * ]);\n * });\n * ```\n */\n parallel: <T>(\n optionsOrCallback: ParallelOptions | (() => Promise<T>),\n maybeCallback?: () => Promise<T>,\n ) => Promise<T>;\n\n /**\n * Run an A/B experiment within a function. Selects a variant via a memoized\n * step, then executes the selected variant's callback at the top level so\n * its `step.*` calls go through normal step discovery.\n *\n * @example\n * ```ts\n * const result = await group.experiment(\"checkout-flow\", {\n * variants: {\n * control: () => step.run(\"control-checkout\", () => oldCheckout()),\n * new_flow: () => step.run(\"new-checkout\", () => newCheckout()),\n * },\n * select: Object.assign(() => \"control\", {\n * __experimentConfig: { strategy: \"weighted\", weights: { control: 80, new_flow: 20 } },\n * }),\n * });\n * ```\n */\n experiment: GroupExperiment;\n}\n\n/**\n * Dependencies injected into `createGroupTools` from the execution engine.\n */\nexport interface GroupToolsDeps {\n /**\n * A `step.run` variant with `opts.type = \"group.experiment\"`, extracted from\n * step tools via the experiment symbol. Undefined when not available.\n */\n // biome-ignore lint/suspicious/noExplicitAny: internal plumbing\n experimentStepRun?: (...args: any[]) => Promise<any>;\n}\n\n/**\n * Create the `group` tools object provided on the function execution context.\n *\n * @public\n */\nexport const createGroupTools = (deps?: GroupToolsDeps): GroupTools => {\n const experiment: GroupExperiment = (async (\n idOrOptions: StepOptionsOrId,\n // biome-ignore lint/suspicious/noExplicitAny: implementation signature for overloaded interface\n options: any,\n ) => {\n if (!deps?.experimentStepRun) {\n throw new Error(\n \"`group.experiment()` requires step tools to be available. \" +\n \"Ensure you are calling this within an Inngest function execution.\",\n );\n }\n\n const { variants, select, withVariant } = options;\n const variantNames = Object.keys(variants);\n\n if (variantNames.length === 0) {\n throw new Error(\n \"`group.experiment()` requires at least one variant to be defined.\",\n );\n }\n\n if (isALSFallback()) {\n throw new Error(\n \"`group.experiment()` requires AsyncLocalStorage support, which is not available in this runtime.\",\n );\n }\n\n const stepOpts = getStepOptions(idOrOptions);\n\n // Use the experiment step run to memoize the variant selection.\n // This creates a StepPlanned opcode with opts.type = \"group.experiment\".\n let experimentStepHashedId: string | undefined;\n\n const selectedVariant: string = await deps.experimentStepRun(\n idOrOptions,\n async () => {\n // Capture the hashed step ID so we can propagate it to variant sub-steps.\n experimentStepHashedId =\n getAsyncCtxSync()?.execution?.executingStep?.id;\n\n const alsInstance = await getAsyncLocalStorage();\n const currentCtx = getAsyncCtxSync()!;\n const selectCtx: AsyncContext = {\n ...currentCtx,\n execution: {\n ...currentCtx.execution!,\n insideExperimentSelect: true,\n },\n };\n const result = await alsInstance.run(selectCtx, () =>\n select(variantNames),\n );\n\n if (!variantNames.includes(result)) {\n throw new NonRetriableError(\n `group.experiment(\"${stepOpts.id}\"): select() returned \"${result}\" ` +\n `which is not a known variant. Available variants: ${variantNames.join(\", \")}`,\n );\n }\n\n // Attach experiment metadata to this step's OutgoingOp.\n const ctx = getAsyncCtxSync();\n const execInstance = ctx?.execution?.instance;\n\n if (execInstance && experimentStepHashedId) {\n execInstance.addMetadata(\n experimentStepHashedId,\n \"inngest.experiment\",\n \"step\",\n \"merge\",\n {\n experiment_name: stepOpts.id,\n variant: result,\n selection_strategy: select.__experimentConfig.strategy,\n available_variants: variantNames,\n ...(select.__experimentConfig.weights && {\n variant_weights: select.__experimentConfig.weights,\n }),\n } satisfies ExperimentMetadataValues,\n );\n\n if (select.__experimentConfig.nullishBucket) {\n execInstance.addMetadata(\n experimentStepHashedId,\n \"inngest.warnings\",\n \"step\",\n \"merge\",\n {\n message:\n \"experiment.bucket() received a null/undefined value; \" +\n 'hashing empty string \"\" for variant selection',\n },\n );\n }\n }\n\n return result;\n },\n );\n\n // Look up and execute the selected variant's callback at the top level\n // so its step.* calls go through normal step discovery.\n const variantFn = variants[selectedVariant];\n\n if (!variantFn) {\n throw new Error(\n `group.experiment(\"${stepOpts.id}\"): variant \"${selectedVariant}\" ` +\n `was selected but is not defined. Available variants: ${variantNames.join(\", \")}`,\n );\n }\n\n // Propagate experiment context via ALS so variant sub-steps include\n // experiment fields in their OutgoingOp.opts. The executor reads these\n // fields from opts and emits the step-scoped `inngest.experiment`\n // metadata span itself — the SDK does not need to call addMetadata()\n // for variant steps. See the companion executor change in inngest/inngest\n // for the server-side emission path.\n //\n // Also track whether any step tool is invoked to detect zero-step\n // variants.\n //\n // NOTE: experimentStepHashedId may be undefined on replay because it\n // is captured inside the selection step callback, which doesn't run\n // when memoized. We still set experimentContext (with an empty string\n // for the hashed ID fallback) so that variant sub-steps discovered on\n // replay still carry experiment fields in their opts and the executor\n // can attach metadata to their ClickHouse rows.\n const currentCtx = getAsyncCtxSync();\n const stepTracker = { found: false };\n let result: unknown;\n\n if (currentCtx?.execution && !isALSFallback()) {\n const als = await getAsyncLocalStorage();\n const nestedCtx: AsyncContext = {\n ...currentCtx,\n execution: {\n ...currentCtx.execution,\n experimentContext: {\n experimentStepID: experimentStepHashedId ?? \"\",\n experimentName: stepOpts.id,\n variant: selectedVariant,\n selectionStrategy: select.__experimentConfig.strategy,\n },\n experimentStepTracker: stepTracker,\n },\n };\n result = await als.run(nestedCtx, () => variantFn());\n } else {\n result = await variantFn();\n }\n\n // If the variant returned without invoking any step tools, it will\n // silently re-execute on every replay. Throw a non-retriable error\n // to prevent this.\n if (!stepTracker.found && !isALSFallback()) {\n throw new NonRetriableError(\n `group.experiment(\"${stepOpts.id}\"): variant \"${selectedVariant}\" ` +\n \"did not invoke any step tools. Wrap your variant logic in \" +\n \"step.run() to ensure it is memoized and not re-executed on replay.\",\n );\n }\n\n if (withVariant) {\n return { result, variant: selectedVariant };\n }\n\n return result;\n }) as GroupExperiment;\n\n return { parallel, experiment };\n};\n"],"mappings":"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"}
@@ -99,6 +99,8 @@ function prepareConnectionConfig(apps, inngest) {
99
99
  case require_consts.headerKeys.ContentLength.toString(): return asString.length.toString();
100
100
  case require_consts.headerKeys.InngestExpectedServerKind.toString(): return "connect";
101
101
  case require_consts.headerKeys.RequestVersion.toString(): return parsed.version.toString();
102
+ case require_consts.headerKeys.RequestId.toString(): return msg.requestId;
103
+ case require_consts.headerKeys.InngestJobId.toString(): return msg.jobId;
102
104
  case require_consts.headerKeys.Signature.toString(): return null;
103
105
  case require_consts.headerKeys.TraceParent.toString(): return userTraceCtx?.traceParent ?? null;
104
106
  case require_consts.headerKeys.TraceState.toString(): return userTraceCtx?.traceState ?? null;
@@ -1 +1 @@
1
- {"version":3,"file":"config.cjs","names":["result: Record<\n string,\n { client: Inngest.Like; functions: InngestFunction.Any[] }\n >","getEnvironmentName","hashSigningKey","capabilities: Capabilities","functionConfigs: Record<\n string,\n { client: Inngest.Like; functions: FunctionConfig[] }\n >","internalLoggerSymbol","connectionData: ConnectionEstablishData","requestHandlers: Record<string, RequestHandler>","inngestCommHandler: ConnectCommHandler","InngestCommHandler","DefaultMaxRuntime","parseFnData","parseTraceCtx","headerKeys","sdkResponseStatus: SDKResponseStatus","SDKResponseStatus","SDKResponse","version","PREFERRED_ASYNC_EXECUTION_VERSION","queryKeys"],"sources":["../../../src/components/connect/config.ts"],"sourcesContent":["/**\n * Connection configuration preparation.\n *\n * Encapsulates signing key hashing, function config building,\n * InngestCommHandler creation, and connection data assembly — everything\n * needed before handing off to a connection strategy.\n */\n\nimport { envKeys, headerKeys, queryKeys } from \"../../helpers/consts.ts\";\nimport { getEnvironmentName } from \"../../helpers/env.ts\";\nimport { parseFnData } from \"../../helpers/functions.ts\";\nimport { hashSigningKey } from \"../../helpers/strings.ts\";\nimport {\n type GatewayExecutorRequestData,\n SDKResponse,\n SDKResponseStatus,\n} from \"../../proto/src/components/connect/protobuf/connect.ts\";\nimport {\n type Capabilities,\n DefaultMaxRuntime,\n type FunctionConfig,\n} from \"../../types.ts\";\nimport { version } from \"../../version.ts\";\nimport { PREFERRED_ASYNC_EXECUTION_VERSION } from \"../execution/InngestExecution.ts\";\nimport { type Inngest, internalLoggerSymbol } from \"../Inngest.ts\";\nimport { InngestCommHandler } from \"../InngestCommHandler.ts\";\nimport type { InngestFunction } from \"../InngestFunction.ts\";\nimport type {\n ConnectionEstablishData,\n RequestHandler,\n} from \"./strategies/index.ts\";\nimport type { ConnectApp } from \"./types.ts\";\nimport { parseTraceCtx } from \"./util.ts\";\n\nconst InngestBranchEnvironmentSigningKeyPrefix = \"signkey-branch-\";\n\ntype ConnectCommHandler = InngestCommHandler<\n [GatewayExecutorRequestData],\n SDKResponse,\n // biome-ignore lint/suspicious/noExplicitAny: intentional\n any\n>;\n\nexport interface PreparedConnectionConfig {\n hashedSigningKey: string | undefined;\n hashedFallbackKey: string | undefined;\n envName: string | undefined;\n connectionData: ConnectionEstablishData;\n requestHandlers: Record<string, RequestHandler>;\n}\n\n/**\n * Collect per-app client + functions from ConnectApp definitions.\n */\nfunction collectFunctions(\n apps: ConnectApp[],\n): Record<string, { client: Inngest.Like; functions: InngestFunction.Any[] }> {\n const result: Record<\n string,\n { client: Inngest.Like; functions: InngestFunction.Any[] }\n > = {};\n\n for (const app of apps) {\n const client = app.client as Inngest.Any;\n if (result[client.id]) {\n throw new Error(`Duplicate app id: ${client.id}`);\n }\n result[client.id] = {\n client: app.client,\n functions: (app.functions as InngestFunction.Any[]) ?? client.funcs,\n };\n }\n\n return result;\n}\n\n/**\n * Prepare all connection configuration: signing keys, function configs,\n * connection data, and request handlers.\n */\nexport function prepareConnectionConfig(\n apps: ConnectApp[],\n inngest: Inngest.Any,\n): PreparedConnectionConfig {\n const envName = inngest.env ?? getEnvironmentName();\n\n const hashedSigningKey = inngest.signingKey\n ? hashSigningKey(inngest.signingKey)\n : undefined;\n\n if (\n inngest.signingKey &&\n inngest.signingKey.startsWith(InngestBranchEnvironmentSigningKeyPrefix) &&\n !envName\n ) {\n throw new Error(\n \"Environment is required when using branch environment signing keys\",\n );\n }\n\n const hashedFallbackKey = inngest.signingKeyFallback\n ? hashSigningKey(inngest.signingKeyFallback)\n : undefined;\n\n // Build capabilities\n const capabilities: Capabilities = {\n trust_probe: \"v1\",\n connect: \"v1\",\n };\n\n const functions = collectFunctions(apps);\n\n // Build function configs\n const functionConfigs: Record<\n string,\n { client: Inngest.Like; functions: FunctionConfig[] }\n > = {};\n for (const [appId, { client, functions: fns }] of Object.entries(functions)) {\n functionConfigs[appId] = {\n client: client,\n functions: fns.flatMap((f) =>\n f[\"getConfig\"]({\n baseUrl: new URL(\"wss://connect\"),\n appPrefix: (client as Inngest.Any).id,\n isConnect: true,\n }),\n ),\n };\n }\n\n inngest[internalLoggerSymbol].debug(\n {\n functionSlugs: Object.entries(functionConfigs).map(\n ([appId, { functions: fns }]) => {\n return JSON.stringify({\n appId,\n functions: fns.map((f) => ({\n id: f.id,\n stepUrls: Object.values(f.steps).map((s) => s.runtime[\"url\"]),\n })),\n });\n },\n ),\n },\n \"Prepared sync data\",\n );\n\n // Build connection establish data\n const connectionData: ConnectionEstablishData = {\n manualReadinessAck: true,\n marshaledCapabilities: JSON.stringify(capabilities),\n apps: Object.entries(functionConfigs).map(\n ([appId, { client, functions: fns }]) => ({\n appName: appId,\n appVersion: (client as Inngest.Any).appVersion,\n functions: new TextEncoder().encode(JSON.stringify(fns)),\n }),\n ),\n };\n\n // Build request handlers\n const requestHandlers: Record<string, RequestHandler> = {};\n for (const [appId, { client, functions: fns }] of Object.entries(functions)) {\n const inngestCommHandler: ConnectCommHandler = new InngestCommHandler({\n client: client,\n functions: fns,\n frameworkName: \"connect\",\n defaultMaxRuntime: DefaultMaxRuntime.connect,\n skipSignatureValidation: true,\n handler: (msg: GatewayExecutorRequestData) => {\n const asString = new TextDecoder().decode(msg.requestPayload);\n const parsed = parseFnData(\n JSON.parse(asString),\n undefined,\n inngest[internalLoggerSymbol],\n );\n\n const userTraceCtx = parseTraceCtx(msg.userTraceCtx);\n\n return {\n body() {\n return parsed;\n },\n method() {\n return \"POST\";\n },\n headers(key) {\n switch (key) {\n case headerKeys.ContentLength.toString():\n return asString.length.toString();\n case headerKeys.InngestExpectedServerKind.toString():\n return \"connect\";\n case headerKeys.RequestVersion.toString():\n return parsed.version.toString();\n case headerKeys.Signature.toString():\n return null;\n case headerKeys.TraceParent.toString():\n return userTraceCtx?.traceParent ?? null;\n case headerKeys.TraceState.toString():\n return userTraceCtx?.traceState ?? null;\n default:\n return null;\n }\n },\n transformResponse({ body, headers, status }) {\n let sdkResponseStatus: SDKResponseStatus = SDKResponseStatus.DONE;\n switch (status) {\n case 200:\n sdkResponseStatus = SDKResponseStatus.DONE;\n break;\n case 206:\n sdkResponseStatus = SDKResponseStatus.NOT_COMPLETED;\n break;\n case 500:\n sdkResponseStatus = SDKResponseStatus.ERROR;\n break;\n }\n\n return SDKResponse.create({\n requestId: msg.requestId,\n accountId: msg.accountId,\n envId: msg.envId,\n appId: msg.appId,\n status: sdkResponseStatus,\n body: new TextEncoder().encode(body),\n noRetry: headers[headerKeys.NoRetry] === \"true\",\n retryAfter: headers[headerKeys.RetryAfter],\n sdkVersion: `inngest-js:v${version}`,\n requestVersion: parseInt(\n headers[headerKeys.RequestVersion] ??\n PREFERRED_ASYNC_EXECUTION_VERSION.toString(),\n 10,\n ),\n systemTraceCtx: msg.systemTraceCtx,\n userTraceCtx: msg.userTraceCtx,\n runId: msg.runId,\n });\n },\n url() {\n const baseUrl = new URL(\"http://connect.inngest.com\");\n\n baseUrl.searchParams.set(queryKeys.FnId, msg.functionSlug);\n\n if (msg.stepId) {\n baseUrl.searchParams.set(queryKeys.StepId, msg.stepId);\n }\n\n return baseUrl;\n },\n };\n },\n });\n\n if (!inngestCommHandler.checkModeConfiguration()) {\n throw new Error(\"Signing key is required\");\n }\n\n const requestHandler = inngestCommHandler.createHandler();\n requestHandlers[appId] = requestHandler;\n }\n\n return {\n hashedSigningKey,\n hashedFallbackKey,\n envName,\n connectionData,\n requestHandlers,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"config.cjs","names":["result: Record<\n string,\n { client: Inngest.Like; functions: InngestFunction.Any[] }\n >","getEnvironmentName","hashSigningKey","capabilities: Capabilities","functionConfigs: Record<\n string,\n { client: Inngest.Like; functions: FunctionConfig[] }\n >","internalLoggerSymbol","connectionData: ConnectionEstablishData","requestHandlers: Record<string, RequestHandler>","inngestCommHandler: ConnectCommHandler","InngestCommHandler","DefaultMaxRuntime","parseFnData","parseTraceCtx","headerKeys","sdkResponseStatus: SDKResponseStatus","SDKResponseStatus","SDKResponse","version","PREFERRED_ASYNC_EXECUTION_VERSION","queryKeys"],"sources":["../../../src/components/connect/config.ts"],"sourcesContent":["/**\n * Connection configuration preparation.\n *\n * Encapsulates signing key hashing, function config building,\n * InngestCommHandler creation, and connection data assembly — everything\n * needed before handing off to a connection strategy.\n */\n\nimport { envKeys, headerKeys, queryKeys } from \"../../helpers/consts.ts\";\nimport { getEnvironmentName } from \"../../helpers/env.ts\";\nimport { parseFnData } from \"../../helpers/functions.ts\";\nimport { hashSigningKey } from \"../../helpers/strings.ts\";\nimport {\n type GatewayExecutorRequestData,\n SDKResponse,\n SDKResponseStatus,\n} from \"../../proto/src/components/connect/protobuf/connect.ts\";\nimport {\n type Capabilities,\n DefaultMaxRuntime,\n type FunctionConfig,\n} from \"../../types.ts\";\nimport { version } from \"../../version.ts\";\nimport { PREFERRED_ASYNC_EXECUTION_VERSION } from \"../execution/InngestExecution.ts\";\nimport { type Inngest, internalLoggerSymbol } from \"../Inngest.ts\";\nimport { InngestCommHandler } from \"../InngestCommHandler.ts\";\nimport type { InngestFunction } from \"../InngestFunction.ts\";\nimport type {\n ConnectionEstablishData,\n RequestHandler,\n} from \"./strategies/index.ts\";\nimport type { ConnectApp } from \"./types.ts\";\nimport { parseTraceCtx } from \"./util.ts\";\n\nconst InngestBranchEnvironmentSigningKeyPrefix = \"signkey-branch-\";\n\ntype ConnectCommHandler = InngestCommHandler<\n [GatewayExecutorRequestData],\n SDKResponse,\n // biome-ignore lint/suspicious/noExplicitAny: intentional\n any\n>;\n\nexport interface PreparedConnectionConfig {\n hashedSigningKey: string | undefined;\n hashedFallbackKey: string | undefined;\n envName: string | undefined;\n connectionData: ConnectionEstablishData;\n requestHandlers: Record<string, RequestHandler>;\n}\n\n/**\n * Collect per-app client + functions from ConnectApp definitions.\n */\nfunction collectFunctions(\n apps: ConnectApp[],\n): Record<string, { client: Inngest.Like; functions: InngestFunction.Any[] }> {\n const result: Record<\n string,\n { client: Inngest.Like; functions: InngestFunction.Any[] }\n > = {};\n\n for (const app of apps) {\n const client = app.client as Inngest.Any;\n if (result[client.id]) {\n throw new Error(`Duplicate app id: ${client.id}`);\n }\n result[client.id] = {\n client: app.client,\n functions: (app.functions as InngestFunction.Any[]) ?? client.funcs,\n };\n }\n\n return result;\n}\n\n/**\n * Prepare all connection configuration: signing keys, function configs,\n * connection data, and request handlers.\n */\nexport function prepareConnectionConfig(\n apps: ConnectApp[],\n inngest: Inngest.Any,\n): PreparedConnectionConfig {\n const envName = inngest.env ?? getEnvironmentName();\n\n const hashedSigningKey = inngest.signingKey\n ? hashSigningKey(inngest.signingKey)\n : undefined;\n\n if (\n inngest.signingKey &&\n inngest.signingKey.startsWith(InngestBranchEnvironmentSigningKeyPrefix) &&\n !envName\n ) {\n throw new Error(\n \"Environment is required when using branch environment signing keys\",\n );\n }\n\n const hashedFallbackKey = inngest.signingKeyFallback\n ? hashSigningKey(inngest.signingKeyFallback)\n : undefined;\n\n // Build capabilities\n const capabilities: Capabilities = {\n trust_probe: \"v1\",\n connect: \"v1\",\n };\n\n const functions = collectFunctions(apps);\n\n // Build function configs\n const functionConfigs: Record<\n string,\n { client: Inngest.Like; functions: FunctionConfig[] }\n > = {};\n for (const [appId, { client, functions: fns }] of Object.entries(functions)) {\n functionConfigs[appId] = {\n client: client,\n functions: fns.flatMap((f) =>\n f[\"getConfig\"]({\n baseUrl: new URL(\"wss://connect\"),\n appPrefix: (client as Inngest.Any).id,\n isConnect: true,\n }),\n ),\n };\n }\n\n inngest[internalLoggerSymbol].debug(\n {\n functionSlugs: Object.entries(functionConfigs).map(\n ([appId, { functions: fns }]) => {\n return JSON.stringify({\n appId,\n functions: fns.map((f) => ({\n id: f.id,\n stepUrls: Object.values(f.steps).map((s) => s.runtime[\"url\"]),\n })),\n });\n },\n ),\n },\n \"Prepared sync data\",\n );\n\n // Build connection establish data\n const connectionData: ConnectionEstablishData = {\n manualReadinessAck: true,\n marshaledCapabilities: JSON.stringify(capabilities),\n apps: Object.entries(functionConfigs).map(\n ([appId, { client, functions: fns }]) => ({\n appName: appId,\n appVersion: (client as Inngest.Any).appVersion,\n functions: new TextEncoder().encode(JSON.stringify(fns)),\n }),\n ),\n };\n\n // Build request handlers\n const requestHandlers: Record<string, RequestHandler> = {};\n for (const [appId, { client, functions: fns }] of Object.entries(functions)) {\n const inngestCommHandler: ConnectCommHandler = new InngestCommHandler({\n client: client,\n functions: fns,\n frameworkName: \"connect\",\n defaultMaxRuntime: DefaultMaxRuntime.connect,\n skipSignatureValidation: true,\n handler: (msg: GatewayExecutorRequestData) => {\n const asString = new TextDecoder().decode(msg.requestPayload);\n const parsed = parseFnData(\n JSON.parse(asString),\n undefined,\n inngest[internalLoggerSymbol],\n );\n\n const userTraceCtx = parseTraceCtx(msg.userTraceCtx);\n\n return {\n body() {\n return parsed;\n },\n method() {\n return \"POST\";\n },\n headers(key) {\n switch (key) {\n case headerKeys.ContentLength.toString():\n return asString.length.toString();\n case headerKeys.InngestExpectedServerKind.toString():\n return \"connect\";\n case headerKeys.RequestVersion.toString():\n return parsed.version.toString();\n case headerKeys.RequestId.toString():\n return msg.requestId;\n case headerKeys.InngestJobId.toString():\n return msg.jobId;\n case headerKeys.Signature.toString():\n return null;\n case headerKeys.TraceParent.toString():\n return userTraceCtx?.traceParent ?? null;\n case headerKeys.TraceState.toString():\n return userTraceCtx?.traceState ?? null;\n default:\n return null;\n }\n },\n transformResponse({ body, headers, status }) {\n let sdkResponseStatus: SDKResponseStatus = SDKResponseStatus.DONE;\n switch (status) {\n case 200:\n sdkResponseStatus = SDKResponseStatus.DONE;\n break;\n case 206:\n sdkResponseStatus = SDKResponseStatus.NOT_COMPLETED;\n break;\n case 500:\n sdkResponseStatus = SDKResponseStatus.ERROR;\n break;\n }\n\n return SDKResponse.create({\n requestId: msg.requestId,\n accountId: msg.accountId,\n envId: msg.envId,\n appId: msg.appId,\n status: sdkResponseStatus,\n body: new TextEncoder().encode(body),\n noRetry: headers[headerKeys.NoRetry] === \"true\",\n retryAfter: headers[headerKeys.RetryAfter],\n sdkVersion: `inngest-js:v${version}`,\n requestVersion: parseInt(\n headers[headerKeys.RequestVersion] ??\n PREFERRED_ASYNC_EXECUTION_VERSION.toString(),\n 10,\n ),\n systemTraceCtx: msg.systemTraceCtx,\n userTraceCtx: msg.userTraceCtx,\n runId: msg.runId,\n });\n },\n url() {\n const baseUrl = new URL(\"http://connect.inngest.com\");\n\n baseUrl.searchParams.set(queryKeys.FnId, msg.functionSlug);\n\n if (msg.stepId) {\n baseUrl.searchParams.set(queryKeys.StepId, msg.stepId);\n }\n\n return baseUrl;\n },\n };\n },\n });\n\n if (!inngestCommHandler.checkModeConfiguration()) {\n throw new Error(\"Signing key is required\");\n }\n\n const requestHandler = inngestCommHandler.createHandler();\n requestHandlers[appId] = requestHandler;\n }\n\n return {\n hashedSigningKey,\n hashedFallbackKey,\n envName,\n connectionData,\n requestHandlers,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAkCA,MAAM,2CAA2C;;;;AAoBjD,SAAS,iBACP,MAC4E;CAC5E,MAAMA,SAGF,EAAE;AAEN,MAAK,MAAM,OAAO,MAAM;EACtB,MAAM,SAAS,IAAI;AACnB,MAAI,OAAO,OAAO,IAChB,OAAM,IAAI,MAAM,qBAAqB,OAAO,KAAK;AAEnD,SAAO,OAAO,MAAM;GAClB,QAAQ,IAAI;GACZ,WAAY,IAAI,aAAuC,OAAO;GAC/D;;AAGH,QAAO;;;;;;AAOT,SAAgB,wBACd,MACA,SAC0B;CAC1B,MAAM,UAAU,QAAQ,OAAOC,gCAAoB;CAEnD,MAAM,mBAAmB,QAAQ,aAC7BC,+BAAe,QAAQ,WAAW,GAClC;AAEJ,KACE,QAAQ,cACR,QAAQ,WAAW,WAAW,yCAAyC,IACvE,CAAC,QAED,OAAM,IAAI,MACR,qEACD;CAGH,MAAM,oBAAoB,QAAQ,qBAC9BA,+BAAe,QAAQ,mBAAmB,GAC1C;CAGJ,MAAMC,eAA6B;EACjC,aAAa;EACb,SAAS;EACV;CAED,MAAM,YAAY,iBAAiB,KAAK;CAGxC,MAAMC,kBAGF,EAAE;AACN,MAAK,MAAM,CAAC,OAAO,EAAE,QAAQ,WAAW,UAAU,OAAO,QAAQ,UAAU,CACzE,iBAAgB,SAAS;EACf;EACR,WAAW,IAAI,SAAS,MACtB,EAAE,aAAa;GACb,SAAS,IAAI,IAAI,gBAAgB;GACjC,WAAY,OAAuB;GACnC,WAAW;GACZ,CAAC,CACH;EACF;AAGH,SAAQC,sCAAsB,MAC5B,EACE,eAAe,OAAO,QAAQ,gBAAgB,CAAC,KAC5C,CAAC,OAAO,EAAE,WAAW,WAAW;AAC/B,SAAO,KAAK,UAAU;GACpB;GACA,WAAW,IAAI,KAAK,OAAO;IACzB,IAAI,EAAE;IACN,UAAU,OAAO,OAAO,EAAE,MAAM,CAAC,KAAK,MAAM,EAAE,QAAQ,OAAO;IAC9D,EAAE;GACJ,CAAC;GAEL,EACF,EACD,qBACD;CAGD,MAAMC,iBAA0C;EAC9C,oBAAoB;EACpB,uBAAuB,KAAK,UAAU,aAAa;EACnD,MAAM,OAAO,QAAQ,gBAAgB,CAAC,KACnC,CAAC,OAAO,EAAE,QAAQ,WAAW,YAAY;GACxC,SAAS;GACT,YAAa,OAAuB;GACpC,WAAW,IAAI,aAAa,CAAC,OAAO,KAAK,UAAU,IAAI,CAAC;GACzD,EACF;EACF;CAGD,MAAMC,kBAAkD,EAAE;AAC1D,MAAK,MAAM,CAAC,OAAO,EAAE,QAAQ,WAAW,UAAU,OAAO,QAAQ,UAAU,EAAE;EAC3E,MAAMC,qBAAyC,IAAIC,8CAAmB;GAC5D;GACR,WAAW;GACX,eAAe;GACf,mBAAmBC,gCAAkB;GACrC,yBAAyB;GACzB,UAAU,QAAoC;IAC5C,MAAM,WAAW,IAAI,aAAa,CAAC,OAAO,IAAI,eAAe;IAC7D,MAAM,SAASC,8BACb,KAAK,MAAM,SAAS,EACpB,QACA,QAAQN,sCACT;IAED,MAAM,eAAeO,2BAAc,IAAI,aAAa;AAEpD,WAAO;KACL,OAAO;AACL,aAAO;;KAET,SAAS;AACP,aAAO;;KAET,QAAQ,KAAK;AACX,cAAQ,KAAR;OACE,KAAKC,0BAAW,cAAc,UAAU,CACtC,QAAO,SAAS,OAAO,UAAU;OACnC,KAAKA,0BAAW,0BAA0B,UAAU,CAClD,QAAO;OACT,KAAKA,0BAAW,eAAe,UAAU,CACvC,QAAO,OAAO,QAAQ,UAAU;OAClC,KAAKA,0BAAW,UAAU,UAAU,CAClC,QAAO,IAAI;OACb,KAAKA,0BAAW,aAAa,UAAU,CACrC,QAAO,IAAI;OACb,KAAKA,0BAAW,UAAU,UAAU,CAClC,QAAO;OACT,KAAKA,0BAAW,YAAY,UAAU,CACpC,QAAO,cAAc,eAAe;OACtC,KAAKA,0BAAW,WAAW,UAAU,CACnC,QAAO,cAAc,cAAc;OACrC,QACE,QAAO;;;KAGb,kBAAkB,EAAE,MAAM,SAAS,UAAU;MAC3C,IAAIC,oBAAuCC,kCAAkB;AAC7D,cAAQ,QAAR;OACE,KAAK;AACH,4BAAoBA,kCAAkB;AACtC;OACF,KAAK;AACH,4BAAoBA,kCAAkB;AACtC;OACF,KAAK;AACH,4BAAoBA,kCAAkB;AACtC;;AAGJ,aAAOC,4BAAY,OAAO;OACxB,WAAW,IAAI;OACf,WAAW,IAAI;OACf,OAAO,IAAI;OACX,OAAO,IAAI;OACX,QAAQ;OACR,MAAM,IAAI,aAAa,CAAC,OAAO,KAAK;OACpC,SAAS,QAAQH,0BAAW,aAAa;OACzC,YAAY,QAAQA,0BAAW;OAC/B,YAAY,eAAeI;OAC3B,gBAAgB,SACd,QAAQJ,0BAAW,mBACjBK,2DAAkC,UAAU,EAC9C,GACD;OACD,gBAAgB,IAAI;OACpB,cAAc,IAAI;OAClB,OAAO,IAAI;OACZ,CAAC;;KAEJ,MAAM;MACJ,MAAM,UAAU,IAAI,IAAI,6BAA6B;AAErD,cAAQ,aAAa,IAAIC,yBAAU,MAAM,IAAI,aAAa;AAE1D,UAAI,IAAI,OACN,SAAQ,aAAa,IAAIA,yBAAU,QAAQ,IAAI,OAAO;AAGxD,aAAO;;KAEV;;GAEJ,CAAC;AAEF,MAAI,CAAC,mBAAmB,wBAAwB,CAC9C,OAAM,IAAI,MAAM,0BAA0B;AAI5C,kBAAgB,SADO,mBAAmB,eAAe;;AAI3D,QAAO;EACL;EACA;EACA;EACA;EACA;EACD"}
@@ -99,6 +99,8 @@ function prepareConnectionConfig(apps, inngest) {
99
99
  case headerKeys.ContentLength.toString(): return asString.length.toString();
100
100
  case headerKeys.InngestExpectedServerKind.toString(): return "connect";
101
101
  case headerKeys.RequestVersion.toString(): return parsed.version.toString();
102
+ case headerKeys.RequestId.toString(): return msg.requestId;
103
+ case headerKeys.InngestJobId.toString(): return msg.jobId;
102
104
  case headerKeys.Signature.toString(): return null;
103
105
  case headerKeys.TraceParent.toString(): return userTraceCtx?.traceParent ?? null;
104
106
  case headerKeys.TraceState.toString(): return userTraceCtx?.traceState ?? null;
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","names":["result: Record<\n string,\n { client: Inngest.Like; functions: InngestFunction.Any[] }\n >","capabilities: Capabilities","functionConfigs: Record<\n string,\n { client: Inngest.Like; functions: FunctionConfig[] }\n >","connectionData: ConnectionEstablishData","requestHandlers: Record<string, RequestHandler>","inngestCommHandler: ConnectCommHandler","sdkResponseStatus: SDKResponseStatus"],"sources":["../../../src/components/connect/config.ts"],"sourcesContent":["/**\n * Connection configuration preparation.\n *\n * Encapsulates signing key hashing, function config building,\n * InngestCommHandler creation, and connection data assembly — everything\n * needed before handing off to a connection strategy.\n */\n\nimport { envKeys, headerKeys, queryKeys } from \"../../helpers/consts.ts\";\nimport { getEnvironmentName } from \"../../helpers/env.ts\";\nimport { parseFnData } from \"../../helpers/functions.ts\";\nimport { hashSigningKey } from \"../../helpers/strings.ts\";\nimport {\n type GatewayExecutorRequestData,\n SDKResponse,\n SDKResponseStatus,\n} from \"../../proto/src/components/connect/protobuf/connect.ts\";\nimport {\n type Capabilities,\n DefaultMaxRuntime,\n type FunctionConfig,\n} from \"../../types.ts\";\nimport { version } from \"../../version.ts\";\nimport { PREFERRED_ASYNC_EXECUTION_VERSION } from \"../execution/InngestExecution.ts\";\nimport { type Inngest, internalLoggerSymbol } from \"../Inngest.ts\";\nimport { InngestCommHandler } from \"../InngestCommHandler.ts\";\nimport type { InngestFunction } from \"../InngestFunction.ts\";\nimport type {\n ConnectionEstablishData,\n RequestHandler,\n} from \"./strategies/index.ts\";\nimport type { ConnectApp } from \"./types.ts\";\nimport { parseTraceCtx } from \"./util.ts\";\n\nconst InngestBranchEnvironmentSigningKeyPrefix = \"signkey-branch-\";\n\ntype ConnectCommHandler = InngestCommHandler<\n [GatewayExecutorRequestData],\n SDKResponse,\n // biome-ignore lint/suspicious/noExplicitAny: intentional\n any\n>;\n\nexport interface PreparedConnectionConfig {\n hashedSigningKey: string | undefined;\n hashedFallbackKey: string | undefined;\n envName: string | undefined;\n connectionData: ConnectionEstablishData;\n requestHandlers: Record<string, RequestHandler>;\n}\n\n/**\n * Collect per-app client + functions from ConnectApp definitions.\n */\nfunction collectFunctions(\n apps: ConnectApp[],\n): Record<string, { client: Inngest.Like; functions: InngestFunction.Any[] }> {\n const result: Record<\n string,\n { client: Inngest.Like; functions: InngestFunction.Any[] }\n > = {};\n\n for (const app of apps) {\n const client = app.client as Inngest.Any;\n if (result[client.id]) {\n throw new Error(`Duplicate app id: ${client.id}`);\n }\n result[client.id] = {\n client: app.client,\n functions: (app.functions as InngestFunction.Any[]) ?? client.funcs,\n };\n }\n\n return result;\n}\n\n/**\n * Prepare all connection configuration: signing keys, function configs,\n * connection data, and request handlers.\n */\nexport function prepareConnectionConfig(\n apps: ConnectApp[],\n inngest: Inngest.Any,\n): PreparedConnectionConfig {\n const envName = inngest.env ?? getEnvironmentName();\n\n const hashedSigningKey = inngest.signingKey\n ? hashSigningKey(inngest.signingKey)\n : undefined;\n\n if (\n inngest.signingKey &&\n inngest.signingKey.startsWith(InngestBranchEnvironmentSigningKeyPrefix) &&\n !envName\n ) {\n throw new Error(\n \"Environment is required when using branch environment signing keys\",\n );\n }\n\n const hashedFallbackKey = inngest.signingKeyFallback\n ? hashSigningKey(inngest.signingKeyFallback)\n : undefined;\n\n // Build capabilities\n const capabilities: Capabilities = {\n trust_probe: \"v1\",\n connect: \"v1\",\n };\n\n const functions = collectFunctions(apps);\n\n // Build function configs\n const functionConfigs: Record<\n string,\n { client: Inngest.Like; functions: FunctionConfig[] }\n > = {};\n for (const [appId, { client, functions: fns }] of Object.entries(functions)) {\n functionConfigs[appId] = {\n client: client,\n functions: fns.flatMap((f) =>\n f[\"getConfig\"]({\n baseUrl: new URL(\"wss://connect\"),\n appPrefix: (client as Inngest.Any).id,\n isConnect: true,\n }),\n ),\n };\n }\n\n inngest[internalLoggerSymbol].debug(\n {\n functionSlugs: Object.entries(functionConfigs).map(\n ([appId, { functions: fns }]) => {\n return JSON.stringify({\n appId,\n functions: fns.map((f) => ({\n id: f.id,\n stepUrls: Object.values(f.steps).map((s) => s.runtime[\"url\"]),\n })),\n });\n },\n ),\n },\n \"Prepared sync data\",\n );\n\n // Build connection establish data\n const connectionData: ConnectionEstablishData = {\n manualReadinessAck: true,\n marshaledCapabilities: JSON.stringify(capabilities),\n apps: Object.entries(functionConfigs).map(\n ([appId, { client, functions: fns }]) => ({\n appName: appId,\n appVersion: (client as Inngest.Any).appVersion,\n functions: new TextEncoder().encode(JSON.stringify(fns)),\n }),\n ),\n };\n\n // Build request handlers\n const requestHandlers: Record<string, RequestHandler> = {};\n for (const [appId, { client, functions: fns }] of Object.entries(functions)) {\n const inngestCommHandler: ConnectCommHandler = new InngestCommHandler({\n client: client,\n functions: fns,\n frameworkName: \"connect\",\n defaultMaxRuntime: DefaultMaxRuntime.connect,\n skipSignatureValidation: true,\n handler: (msg: GatewayExecutorRequestData) => {\n const asString = new TextDecoder().decode(msg.requestPayload);\n const parsed = parseFnData(\n JSON.parse(asString),\n undefined,\n inngest[internalLoggerSymbol],\n );\n\n const userTraceCtx = parseTraceCtx(msg.userTraceCtx);\n\n return {\n body() {\n return parsed;\n },\n method() {\n return \"POST\";\n },\n headers(key) {\n switch (key) {\n case headerKeys.ContentLength.toString():\n return asString.length.toString();\n case headerKeys.InngestExpectedServerKind.toString():\n return \"connect\";\n case headerKeys.RequestVersion.toString():\n return parsed.version.toString();\n case headerKeys.Signature.toString():\n return null;\n case headerKeys.TraceParent.toString():\n return userTraceCtx?.traceParent ?? null;\n case headerKeys.TraceState.toString():\n return userTraceCtx?.traceState ?? null;\n default:\n return null;\n }\n },\n transformResponse({ body, headers, status }) {\n let sdkResponseStatus: SDKResponseStatus = SDKResponseStatus.DONE;\n switch (status) {\n case 200:\n sdkResponseStatus = SDKResponseStatus.DONE;\n break;\n case 206:\n sdkResponseStatus = SDKResponseStatus.NOT_COMPLETED;\n break;\n case 500:\n sdkResponseStatus = SDKResponseStatus.ERROR;\n break;\n }\n\n return SDKResponse.create({\n requestId: msg.requestId,\n accountId: msg.accountId,\n envId: msg.envId,\n appId: msg.appId,\n status: sdkResponseStatus,\n body: new TextEncoder().encode(body),\n noRetry: headers[headerKeys.NoRetry] === \"true\",\n retryAfter: headers[headerKeys.RetryAfter],\n sdkVersion: `inngest-js:v${version}`,\n requestVersion: parseInt(\n headers[headerKeys.RequestVersion] ??\n PREFERRED_ASYNC_EXECUTION_VERSION.toString(),\n 10,\n ),\n systemTraceCtx: msg.systemTraceCtx,\n userTraceCtx: msg.userTraceCtx,\n runId: msg.runId,\n });\n },\n url() {\n const baseUrl = new URL(\"http://connect.inngest.com\");\n\n baseUrl.searchParams.set(queryKeys.FnId, msg.functionSlug);\n\n if (msg.stepId) {\n baseUrl.searchParams.set(queryKeys.StepId, msg.stepId);\n }\n\n return baseUrl;\n },\n };\n },\n });\n\n if (!inngestCommHandler.checkModeConfiguration()) {\n throw new Error(\"Signing key is required\");\n }\n\n const requestHandler = inngestCommHandler.createHandler();\n requestHandlers[appId] = requestHandler;\n }\n\n return {\n hashedSigningKey,\n hashedFallbackKey,\n envName,\n connectionData,\n requestHandlers,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"config.js","names":["result: Record<\n string,\n { client: Inngest.Like; functions: InngestFunction.Any[] }\n >","capabilities: Capabilities","functionConfigs: Record<\n string,\n { client: Inngest.Like; functions: FunctionConfig[] }\n >","connectionData: ConnectionEstablishData","requestHandlers: Record<string, RequestHandler>","inngestCommHandler: ConnectCommHandler","sdkResponseStatus: SDKResponseStatus"],"sources":["../../../src/components/connect/config.ts"],"sourcesContent":["/**\n * Connection configuration preparation.\n *\n * Encapsulates signing key hashing, function config building,\n * InngestCommHandler creation, and connection data assembly — everything\n * needed before handing off to a connection strategy.\n */\n\nimport { envKeys, headerKeys, queryKeys } from \"../../helpers/consts.ts\";\nimport { getEnvironmentName } from \"../../helpers/env.ts\";\nimport { parseFnData } from \"../../helpers/functions.ts\";\nimport { hashSigningKey } from \"../../helpers/strings.ts\";\nimport {\n type GatewayExecutorRequestData,\n SDKResponse,\n SDKResponseStatus,\n} from \"../../proto/src/components/connect/protobuf/connect.ts\";\nimport {\n type Capabilities,\n DefaultMaxRuntime,\n type FunctionConfig,\n} from \"../../types.ts\";\nimport { version } from \"../../version.ts\";\nimport { PREFERRED_ASYNC_EXECUTION_VERSION } from \"../execution/InngestExecution.ts\";\nimport { type Inngest, internalLoggerSymbol } from \"../Inngest.ts\";\nimport { InngestCommHandler } from \"../InngestCommHandler.ts\";\nimport type { InngestFunction } from \"../InngestFunction.ts\";\nimport type {\n ConnectionEstablishData,\n RequestHandler,\n} from \"./strategies/index.ts\";\nimport type { ConnectApp } from \"./types.ts\";\nimport { parseTraceCtx } from \"./util.ts\";\n\nconst InngestBranchEnvironmentSigningKeyPrefix = \"signkey-branch-\";\n\ntype ConnectCommHandler = InngestCommHandler<\n [GatewayExecutorRequestData],\n SDKResponse,\n // biome-ignore lint/suspicious/noExplicitAny: intentional\n any\n>;\n\nexport interface PreparedConnectionConfig {\n hashedSigningKey: string | undefined;\n hashedFallbackKey: string | undefined;\n envName: string | undefined;\n connectionData: ConnectionEstablishData;\n requestHandlers: Record<string, RequestHandler>;\n}\n\n/**\n * Collect per-app client + functions from ConnectApp definitions.\n */\nfunction collectFunctions(\n apps: ConnectApp[],\n): Record<string, { client: Inngest.Like; functions: InngestFunction.Any[] }> {\n const result: Record<\n string,\n { client: Inngest.Like; functions: InngestFunction.Any[] }\n > = {};\n\n for (const app of apps) {\n const client = app.client as Inngest.Any;\n if (result[client.id]) {\n throw new Error(`Duplicate app id: ${client.id}`);\n }\n result[client.id] = {\n client: app.client,\n functions: (app.functions as InngestFunction.Any[]) ?? client.funcs,\n };\n }\n\n return result;\n}\n\n/**\n * Prepare all connection configuration: signing keys, function configs,\n * connection data, and request handlers.\n */\nexport function prepareConnectionConfig(\n apps: ConnectApp[],\n inngest: Inngest.Any,\n): PreparedConnectionConfig {\n const envName = inngest.env ?? getEnvironmentName();\n\n const hashedSigningKey = inngest.signingKey\n ? hashSigningKey(inngest.signingKey)\n : undefined;\n\n if (\n inngest.signingKey &&\n inngest.signingKey.startsWith(InngestBranchEnvironmentSigningKeyPrefix) &&\n !envName\n ) {\n throw new Error(\n \"Environment is required when using branch environment signing keys\",\n );\n }\n\n const hashedFallbackKey = inngest.signingKeyFallback\n ? hashSigningKey(inngest.signingKeyFallback)\n : undefined;\n\n // Build capabilities\n const capabilities: Capabilities = {\n trust_probe: \"v1\",\n connect: \"v1\",\n };\n\n const functions = collectFunctions(apps);\n\n // Build function configs\n const functionConfigs: Record<\n string,\n { client: Inngest.Like; functions: FunctionConfig[] }\n > = {};\n for (const [appId, { client, functions: fns }] of Object.entries(functions)) {\n functionConfigs[appId] = {\n client: client,\n functions: fns.flatMap((f) =>\n f[\"getConfig\"]({\n baseUrl: new URL(\"wss://connect\"),\n appPrefix: (client as Inngest.Any).id,\n isConnect: true,\n }),\n ),\n };\n }\n\n inngest[internalLoggerSymbol].debug(\n {\n functionSlugs: Object.entries(functionConfigs).map(\n ([appId, { functions: fns }]) => {\n return JSON.stringify({\n appId,\n functions: fns.map((f) => ({\n id: f.id,\n stepUrls: Object.values(f.steps).map((s) => s.runtime[\"url\"]),\n })),\n });\n },\n ),\n },\n \"Prepared sync data\",\n );\n\n // Build connection establish data\n const connectionData: ConnectionEstablishData = {\n manualReadinessAck: true,\n marshaledCapabilities: JSON.stringify(capabilities),\n apps: Object.entries(functionConfigs).map(\n ([appId, { client, functions: fns }]) => ({\n appName: appId,\n appVersion: (client as Inngest.Any).appVersion,\n functions: new TextEncoder().encode(JSON.stringify(fns)),\n }),\n ),\n };\n\n // Build request handlers\n const requestHandlers: Record<string, RequestHandler> = {};\n for (const [appId, { client, functions: fns }] of Object.entries(functions)) {\n const inngestCommHandler: ConnectCommHandler = new InngestCommHandler({\n client: client,\n functions: fns,\n frameworkName: \"connect\",\n defaultMaxRuntime: DefaultMaxRuntime.connect,\n skipSignatureValidation: true,\n handler: (msg: GatewayExecutorRequestData) => {\n const asString = new TextDecoder().decode(msg.requestPayload);\n const parsed = parseFnData(\n JSON.parse(asString),\n undefined,\n inngest[internalLoggerSymbol],\n );\n\n const userTraceCtx = parseTraceCtx(msg.userTraceCtx);\n\n return {\n body() {\n return parsed;\n },\n method() {\n return \"POST\";\n },\n headers(key) {\n switch (key) {\n case headerKeys.ContentLength.toString():\n return asString.length.toString();\n case headerKeys.InngestExpectedServerKind.toString():\n return \"connect\";\n case headerKeys.RequestVersion.toString():\n return parsed.version.toString();\n case headerKeys.RequestId.toString():\n return msg.requestId;\n case headerKeys.InngestJobId.toString():\n return msg.jobId;\n case headerKeys.Signature.toString():\n return null;\n case headerKeys.TraceParent.toString():\n return userTraceCtx?.traceParent ?? null;\n case headerKeys.TraceState.toString():\n return userTraceCtx?.traceState ?? null;\n default:\n return null;\n }\n },\n transformResponse({ body, headers, status }) {\n let sdkResponseStatus: SDKResponseStatus = SDKResponseStatus.DONE;\n switch (status) {\n case 200:\n sdkResponseStatus = SDKResponseStatus.DONE;\n break;\n case 206:\n sdkResponseStatus = SDKResponseStatus.NOT_COMPLETED;\n break;\n case 500:\n sdkResponseStatus = SDKResponseStatus.ERROR;\n break;\n }\n\n return SDKResponse.create({\n requestId: msg.requestId,\n accountId: msg.accountId,\n envId: msg.envId,\n appId: msg.appId,\n status: sdkResponseStatus,\n body: new TextEncoder().encode(body),\n noRetry: headers[headerKeys.NoRetry] === \"true\",\n retryAfter: headers[headerKeys.RetryAfter],\n sdkVersion: `inngest-js:v${version}`,\n requestVersion: parseInt(\n headers[headerKeys.RequestVersion] ??\n PREFERRED_ASYNC_EXECUTION_VERSION.toString(),\n 10,\n ),\n systemTraceCtx: msg.systemTraceCtx,\n userTraceCtx: msg.userTraceCtx,\n runId: msg.runId,\n });\n },\n url() {\n const baseUrl = new URL(\"http://connect.inngest.com\");\n\n baseUrl.searchParams.set(queryKeys.FnId, msg.functionSlug);\n\n if (msg.stepId) {\n baseUrl.searchParams.set(queryKeys.StepId, msg.stepId);\n }\n\n return baseUrl;\n },\n };\n },\n });\n\n if (!inngestCommHandler.checkModeConfiguration()) {\n throw new Error(\"Signing key is required\");\n }\n\n const requestHandler = inngestCommHandler.createHandler();\n requestHandlers[appId] = requestHandler;\n }\n\n return {\n hashedSigningKey,\n hashedFallbackKey,\n envName,\n connectionData,\n requestHandlers,\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"InngestExecution.cjs","names":["ExecutionVersion","options: InngestExecutionOptions","debugPrefix"],"sources":["../../../src/components/execution/InngestExecution.ts"],"sourcesContent":["import Debug, { type Debugger } from \"debug\";\nimport { debugPrefix, ExecutionVersion } from \"../../helpers/consts.ts\";\nimport type { ServerTiming } from \"../../helpers/ServerTiming.ts\";\nimport type { MaybePromise, Simplify } from \"../../helpers/types.ts\";\nimport type {\n Context,\n IncomingOp,\n InternalCheckpointingOptions,\n OutgoingOp,\n StepMode,\n} from \"../../types.ts\";\nimport type { Inngest } from \"../Inngest.ts\";\nimport type { ActionResponse } from \"../InngestCommHandler.ts\";\nimport type { InngestFunction } from \"../InngestFunction.ts\";\nimport type {\n MetadataKind,\n MetadataOpcode,\n MetadataScope,\n} from \"../InngestMetadata.ts\";\nimport type { Middleware } from \"../middleware/middleware.ts\";\n\n// Re-export ExecutionVersion so it's correctly recognized as an enum and not\n// just a type. This can be lost when bundling if we don't re-export it here.\n// See `pnpm run test:dist`.\nexport { ExecutionVersion };\n\n/**\n * The possible results of an execution.\n */\nexport interface ExecutionResults {\n \"function-resolved\": { data: unknown };\n \"step-ran\": { step: OutgoingOp; retriable?: boolean | string };\n \"function-rejected\": { error: unknown; retriable: boolean | string };\n \"steps-found\": { steps: [OutgoingOp, ...OutgoingOp[]] };\n \"step-not-found\": {\n step: OutgoingOp;\n foundSteps: BasicFoundStep[];\n totalFoundSteps: number;\n };\n\n /**\n * Indicates that we need to relinquish control back to Inngest in order to\n * change step modes.\n */\n \"change-mode\": {\n to: StepMode;\n token: string;\n };\n}\n\nexport type ExecutionResult = {\n [K in keyof ExecutionResults]: Simplify<\n {\n type: K;\n ctx: Context.Any;\n ops: Record<string, MemoizedOp>;\n } & ExecutionResults[K]\n >;\n}[keyof ExecutionResults];\n\nexport interface BasicFoundStep {\n id: string;\n displayName?: string;\n}\n\nexport type ExecutionResultHandler<T = ActionResponse> = (\n result: ExecutionResult,\n) => MaybePromise<T>;\n\nexport type ExecutionResultHandlers<T = ActionResponse> = {\n [E in ExecutionResult as E[\"type\"]]: (result: E) => MaybePromise<T>;\n};\n\nexport interface MemoizedOp extends IncomingOp {\n /**\n * If the step has been hit during this run, these will be the arguments\n * passed to it.\n */\n rawArgs?: unknown[];\n fulfilled?: boolean;\n\n /**\n * The promise that has been returned to userland code.\n */\n promise?: Promise<unknown>;\n seen?: boolean;\n}\n\n/**\n * The preferred execution version that will be used by the SDK when handling\n * brand new runs where the Executor is allowing us to choose.\n *\n * Changing this should not ever be a breaking change, as this will only change\n * new runs, not existing ones.\n */\nexport const PREFERRED_ASYNC_EXECUTION_VERSION =\n ExecutionVersion.V2 satisfies ExecutionVersion;\n\n/**\n * Options for creating a new {@link InngestExecution} instance.\n */\nexport interface InngestExecutionOptions {\n client: Inngest.Any;\n fn: InngestFunction.Any;\n\n /**\n * The UUID that represents this function in Inngest.\n *\n * This is used to reference the function during async checkpointing, when we\n * know the function/run already exists and just wish to reference it\n * directly.\n */\n internalFnId?: string;\n reqArgs: unknown[];\n runId: string;\n data: Omit<Context.Any, \"step\" | \"group\" | \"publish\">;\n stepState: Record<string, MemoizedOp>;\n stepCompletionOrder: string[];\n stepMode: StepMode;\n checkpointingConfig?: InternalCheckpointingOptions;\n\n /**\n * If this execution is being run from a queue job, this will be an identifier\n * used to reference this execution in Inngest. SDKs are expected to parrot\n * this back in some responses to correctly attribute actions to this queue\n * item.\n */\n queueItemId?: string;\n\n /**\n * Headers to be sent with any request to Inngest during this execution.\n */\n headers: Record<string, string>;\n requestedRunStep?: string;\n timer?: ServerTiming;\n isFailureHandler?: boolean;\n disableImmediateExecution?: boolean;\n\n /**\n * Information about the incoming HTTP request that triggered this execution.\n * Used by middleware `wrapRequest` hooks.\n */\n requestInfo?: Middleware.Request;\n\n /**\n * Pre-created middleware instances to use for this execution. When provided,\n * the execution will use these instead of instantiating new ones from the\n * client. This ensures `wrapRequest` and other hooks share state on `this`.\n */\n middlewareInstances?: Middleware.BaseMiddleware[];\n\n /**\n * Whether the client accepts SSE (`Accept: text/event-stream`). When true,\n * the execution engine may deliver the result as an SSE stream even if\n * `stream.push()` was not called.\n */\n acceptsSse?: boolean;\n\n /**\n * Provide the ability to transform the context passed to the function before\n * the execution starts.\n */\n transformCtx?: (ctx: Readonly<Context.Any>) => Context.Any;\n\n /**\n * A hook that is called to create an {@link ActionResponse} from the returned\n * value of an execution.\n *\n * This is required for checkpointing executions.\n */\n createResponse?: (data: unknown) => MaybePromise<ActionResponse>;\n}\n\nexport type InngestExecutionFactory = (\n options: InngestExecutionOptions,\n) => IInngestExecution;\n\nexport class InngestExecution {\n protected devDebug: Debugger;\n\n constructor(protected options: InngestExecutionOptions) {\n this.devDebug = Debug(`${debugPrefix}:${this.options.runId}`);\n }\n}\n\nexport interface IInngestExecution {\n version: ExecutionVersion;\n start(): Promise<ExecutionResult>;\n\n addMetadata(\n stepId: string,\n kind: MetadataKind,\n scope: MetadataScope,\n op: MetadataOpcode,\n values: Record<string, unknown>,\n ): boolean;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AA+FA,MAAa,oCACXA,gCAAiB;AAiFnB,IAAa,mBAAb,MAA8B;CAC5B,AAAU;CAEV,YAAY,AAAUC,SAAkC;EAAlC;AACpB,OAAK,8BAAiB,GAAGC,2BAAY,GAAG,KAAK,QAAQ,QAAQ"}
1
+ {"version":3,"file":"InngestExecution.cjs","names":["ExecutionVersion","options: InngestExecutionOptions","debugPrefix"],"sources":["../../../src/components/execution/InngestExecution.ts"],"sourcesContent":["import Debug, { type Debugger } from \"debug\";\nimport { debugPrefix, ExecutionVersion } from \"../../helpers/consts.ts\";\nimport type { ServerTiming } from \"../../helpers/ServerTiming.ts\";\nimport type { MaybePromise, Simplify } from \"../../helpers/types.ts\";\nimport type {\n Context,\n IncomingOp,\n InternalCheckpointingOptions,\n OutgoingOp,\n StepMode,\n} from \"../../types.ts\";\nimport type { Inngest } from \"../Inngest.ts\";\nimport type { ActionResponse } from \"../InngestCommHandler.ts\";\nimport type { InngestFunction } from \"../InngestFunction.ts\";\nimport type {\n MetadataKind,\n MetadataOpcode,\n MetadataScope,\n} from \"../InngestMetadata.ts\";\nimport type { Middleware } from \"../middleware/middleware.ts\";\n\n// Re-export ExecutionVersion so it's correctly recognized as an enum and not\n// just a type. This can be lost when bundling if we don't re-export it here.\n// See `pnpm run test:dist`.\nexport { ExecutionVersion };\n\n/**\n * The possible results of an execution.\n */\nexport interface ExecutionResults {\n \"function-resolved\": { data: unknown };\n \"step-ran\": { step: OutgoingOp; retriable?: boolean | string };\n \"function-rejected\": { error: unknown; retriable: boolean | string };\n \"steps-found\": { steps: [OutgoingOp, ...OutgoingOp[]] };\n \"step-not-found\": {\n step: OutgoingOp;\n foundSteps: BasicFoundStep[];\n totalFoundSteps: number;\n };\n\n /**\n * Indicates that we need to relinquish control back to Inngest in order to\n * change step modes.\n */\n \"change-mode\": {\n to: StepMode;\n token: string;\n };\n}\n\nexport type ExecutionResult = {\n [K in keyof ExecutionResults]: Simplify<\n {\n type: K;\n ctx: Context.Any;\n ops: Record<string, MemoizedOp>;\n } & ExecutionResults[K]\n >;\n}[keyof ExecutionResults];\n\nexport interface BasicFoundStep {\n id: string;\n displayName?: string;\n}\n\nexport type ExecutionResultHandler<T = ActionResponse> = (\n result: ExecutionResult,\n) => MaybePromise<T>;\n\nexport type ExecutionResultHandlers<T = ActionResponse> = {\n [E in ExecutionResult as E[\"type\"]]: (result: E) => MaybePromise<T>;\n};\n\nexport interface MemoizedOp extends IncomingOp {\n /**\n * If the step has been hit during this run, these will be the arguments\n * passed to it.\n */\n rawArgs?: unknown[];\n fulfilled?: boolean;\n\n /**\n * The promise that has been returned to userland code.\n */\n promise?: Promise<unknown>;\n seen?: boolean;\n}\n\n/**\n * The preferred execution version that will be used by the SDK when handling\n * brand new runs where the Executor is allowing us to choose.\n *\n * Changing this should not ever be a breaking change, as this will only change\n * new runs, not existing ones.\n */\nexport const PREFERRED_ASYNC_EXECUTION_VERSION =\n ExecutionVersion.V2 satisfies ExecutionVersion;\n\n/**\n * Options for creating a new {@link InngestExecution} instance.\n */\nexport interface InngestExecutionOptions {\n client: Inngest.Any;\n fn: InngestFunction.Any;\n\n /**\n * The UUID that represents this function in Inngest.\n *\n * This is used to reference the function during async checkpointing, when we\n * know the function/run already exists and just wish to reference it\n * directly.\n */\n internalFnId?: string;\n reqArgs: unknown[];\n runId: string;\n data: Omit<Context.Any, \"step\" | \"group\" | \"publish\" | \"defer\">;\n stepState: Record<string, MemoizedOp>;\n\n /**\n * A map of hashed defer step IDs to their backend-side metadata\n * (e.g. `{ abortable: true }`). Defer ops are not steps in the\n * memoization sense — they don't produce results — but the backend\n * tracks which ones it has already received so the SDK can avoid\n * re-emitting them on replay.\n */\n priorDefers?: Record<string, unknown>;\n\n stepCompletionOrder: string[];\n stepMode: StepMode;\n checkpointingConfig?: InternalCheckpointingOptions;\n\n /**\n * If this execution is being run from a queue job, this will be an identifier\n * used to reference this execution in Inngest. SDKs are expected to parrot\n * this back in some responses to correctly attribute actions to this queue\n * item.\n */\n queueItemId?: string;\n\n /**\n * Headers to be sent with any request to Inngest during this execution.\n */\n headers: Record<string, string>;\n requestedRunStep?: string;\n timer?: ServerTiming;\n /**\n * Which handler variant is being executed. `\"failure\"` skips\n * trigger-schema validation and resolves `onFailure` instead of the\n * main handler. `\"defer\"` marks the fn as a standalone defer function\n * (created via `createDefer`); incoming event data is validated\n * against the defer function's schema.\n *\n * @default \"main\"\n */\n handlerKind?: \"main\" | \"failure\" | \"defer\";\n\n disableImmediateExecution?: boolean;\n\n /**\n * Information about the incoming HTTP request that triggered this execution.\n * Used by middleware `wrapRequest` hooks.\n */\n requestInfo?: Middleware.Request;\n\n /**\n * Pre-created middleware instances to use for this execution. When provided,\n * the execution will use these instead of instantiating new ones from the\n * client. This ensures `wrapRequest` and other hooks share state on `this`.\n */\n middlewareInstances?: Middleware.BaseMiddleware[];\n\n /**\n * Whether the client accepts SSE (`Accept: text/event-stream`). When true,\n * the execution engine may deliver the result as an SSE stream even if\n * `stream.push()` was not called.\n */\n acceptsSse?: boolean;\n\n /**\n * Provide the ability to transform the context passed to the function before\n * the execution starts.\n */\n transformCtx?: (ctx: Readonly<Context.Any>) => Context.Any;\n\n /**\n * A hook that is called to create an {@link ActionResponse} from the returned\n * value of an execution.\n *\n * This is required for checkpointing executions.\n */\n createResponse?: (data: unknown) => MaybePromise<ActionResponse>;\n}\n\nexport type InngestExecutionFactory = (\n options: InngestExecutionOptions,\n) => IInngestExecution;\n\nexport class InngestExecution {\n protected devDebug: Debugger;\n\n constructor(protected options: InngestExecutionOptions) {\n this.devDebug = Debug(`${debugPrefix}:${this.options.runId}`);\n }\n}\n\nexport interface IInngestExecution {\n version: ExecutionVersion;\n start(): Promise<ExecutionResult>;\n\n addMetadata(\n stepId: string,\n kind: MetadataKind,\n scope: MetadataScope,\n op: MetadataOpcode,\n values: Record<string, unknown>,\n ): boolean;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AA+FA,MAAa,oCACXA,gCAAiB;AAqGnB,IAAa,mBAAb,MAA8B;CAC5B,AAAU;CAEV,YAAY,AAAUC,SAAkC;EAAlC;AACpB,OAAK,8BAAiB,GAAGC,2BAAY,GAAG,KAAK,QAAQ,QAAQ"}
@@ -93,8 +93,16 @@ interface InngestExecutionOptions {
93
93
  internalFnId?: string;
94
94
  reqArgs: unknown[];
95
95
  runId: string;
96
- data: Omit<Context.Any, "step" | "group" | "publish">;
96
+ data: Omit<Context.Any, "step" | "group" | "publish" | "defer">;
97
97
  stepState: Record<string, MemoizedOp>;
98
+ /**
99
+ * A map of hashed defer step IDs to their backend-side metadata
100
+ * (e.g. `{ abortable: true }`). Defer ops are not steps in the
101
+ * memoization sense — they don't produce results — but the backend
102
+ * tracks which ones it has already received so the SDK can avoid
103
+ * re-emitting them on replay.
104
+ */
105
+ priorDefers?: Record<string, unknown>;
98
106
  stepCompletionOrder: string[];
99
107
  stepMode: StepMode;
100
108
  checkpointingConfig?: InternalCheckpointingOptions;
@@ -111,7 +119,16 @@ interface InngestExecutionOptions {
111
119
  headers: Record<string, string>;
112
120
  requestedRunStep?: string;
113
121
  timer?: ServerTiming;
114
- isFailureHandler?: boolean;
122
+ /**
123
+ * Which handler variant is being executed. `"failure"` skips
124
+ * trigger-schema validation and resolves `onFailure` instead of the
125
+ * main handler. `"defer"` marks the fn as a standalone defer function
126
+ * (created via `createDefer`); incoming event data is validated
127
+ * against the defer function's schema.
128
+ *
129
+ * @default "main"
130
+ */
131
+ handlerKind?: "main" | "failure" | "defer";
115
132
  disableImmediateExecution?: boolean;
116
133
  /**
117
134
  * Information about the incoming HTTP request that triggered this execution.
@@ -1 +1 @@
1
- {"version":3,"file":"InngestExecution.d.cts","names":[],"sources":["../../../src/components/execution/InngestExecution.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;UA6BiB,gBAAA;;;;;UAEK;;;;;;;;IAFL,KAAA,EAAA,CAIU,UAJM,EAAA,GAIS,UAJT,EAAA,CAAA;EAAA,CAAA;kBAEX,EAAA;IAEK,IAAA,EAEjB,UAFiB;IAAe,UAAA,EAG1B,cAH0B,EAAA;IAEhC,eAAA,EAAA,MAAA;;;;AAeV;;eACc,EAAA;IAEF,EAAA,EARJ,QAQI;IACD,KAAA,EAAQ,MAAA;;;AAEX,KANI,eAAA,GAMJ,QAAiB,MALX,gBAKW,GALQ,QAKR,CAAA;EALQ,IAAA,EAErB,CAFqB;EAOzB,GAAA,EAJG,OAAA,CAAQ,GAIX;EAAgB,GAAA,EAHb,MAGa,CAAA,MAAA,EAHE,UAGF,CAAA;AAEP,CAAA,GAJT,gBAIuB,CAJN,CAIM,CAAA,CAAA,EAK/B,CAAA,MAPQ,gBAOI,CAAA;AAAsB,UALjB,cAAA,CAKiB;MAAK,MAAA;aAC7B,CAAA,EAAA,MAAA;;AACL,KAFO,sBAEP,CAAA,IAFkC,cAElC,CAAA,GAAA,CAAA,MAAA,EADK,eACL,EAAA,GAAA,YAAA,CAAa,CAAb,CAAA;AAAY,KAEL,uBAFK,CAAA,IAEuB,cAFvB,CAAA,GAAA,QAGT,eADI,IACe,CADQ,CAAA,MAAA,CAAA,GAAA,CAAA,MAAA,EACa,CADb,EAAA,GACmB,YADnB,CACgC,CADhC,CAAA,EAAA;AAAK,UAIvB,UAAA,SAAmB,UAJI,CAAA;;;;;SACc,CAAA,EAAA,OAAA,EAAA;EAAY,SAAA,CAAA,EAAA,OAAA;EAGjD;;;SAAmB,CAAA,EAWxB,OAXwB,CAAA,OAAA,CAAA;EAAU,IAAA,CAAA,EAAA,OAAA;AAsB9C;AAMA;;;;;;;AAea,cArBA,iCAAA,GAqBA,gBAAA,CAAA,EAAA;;;;AAkBH,UAjCO,uBAAA,CAiCP;QAQM,EAxCN,OAAA,CAAQ,GAwCS;MAvCrB,eAAA,CAAgB,GA8Ca;;;;;;;AAwBnC;EAAmC,YAAA,CAAA,EAAA,MAAA;SACxB,EAAA,OAAA,EAAA;OACN,EAAA,MAAA;EAAiB,IAAA,EA5Dd,IA4Dc,CA5DT,OAAA,CAAQ,GA4DC,EAAA,MAAA,GAAA,OAAA,GAAA,SAAA,CAAA;EAET,SAAA,EA7DA,MA6DA,CAAA,MAAgB,EA7DD,UA6DC,CAAA;EAAA,mBAAA,EAAA,MAAA,EAAA;UAGI,EA9DrB,QA8DqB;qBAFX,CAAA,EA3DE,4BA2DF;;;AAOtB;;;;aAEW,CAAA,EAAA,MAAA;;;;SAOC,EA9DD,MA8DC,CAAA,MAAA,EAAA,MAAA,CAAA;EAAM,gBAAA,CAAA,EAAA,MAAA;UA5DR;;;;;;;gBAQM,UAAA,CAAW;;;;;;wBAOH,UAAA,CAAW;;;;;;;;;;;uBAaZ,SAAS,OAAA,CAAQ,SAAS,OAAA,CAAQ;;;;;;;sCAQnB,aAAa;;KAGvC,uBAAA,aACD,4BACN;cAEQ,gBAAA;qBAGoB;sBAFX;uBAEW;;UAKhB,iBAAA;WACN;WACA,QAAQ;oCAIT,qBACC,mBACH,wBACI"}
1
+ {"version":3,"file":"InngestExecution.d.cts","names":[],"sources":["../../../src/components/execution/InngestExecution.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;UA6BiB,gBAAA;;;;;UAEK;;;;;;;;IAFL,KAAA,EAAA,CAIU,UAJM,EAAA,GAIS,UAJT,EAAA,CAAA;EAAA,CAAA;kBAEX,EAAA;IAEK,IAAA,EAEjB,UAFiB;IAAe,UAAA,EAG1B,cAH0B,EAAA;IAEhC,eAAA,EAAA,MAAA;;;;AAeV;;eACc,EAAA;IAEF,EAAA,EARJ,QAQI;IACD,KAAA,EAAQ,MAAA;;;AAEX,KANI,eAAA,GAMJ,QAAiB,MALX,gBAKW,GALQ,QAKR,CAAA;EALQ,IAAA,EAErB,CAFqB;EAOzB,GAAA,EAJG,OAAA,CAAQ,GAIX;EAAgB,GAAA,EAHb,MAGa,CAAA,MAAA,EAHE,UAGF,CAAA;AAEP,CAAA,GAJT,gBAIuB,CAJN,CAIM,CAAA,CAAA,EAK/B,CAAA,MAPQ,gBAOI,CAAA;AAAsB,UALjB,cAAA,CAKiB;MAAK,MAAA;aAC7B,CAAA,EAAA,MAAA;;AACL,KAFO,sBAEP,CAAA,IAFkC,cAElC,CAAA,GAAA,CAAA,MAAA,EADK,eACL,EAAA,GAAA,YAAA,CAAa,CAAb,CAAA;AAAY,KAEL,uBAFK,CAAA,IAEuB,cAFvB,CAAA,GAAA,QAGT,eADI,IACe,CADQ,CAAA,MAAA,CAAA,GAAA,CAAA,MAAA,EACa,CADb,EAAA,GACmB,YADnB,CACgC,CADhC,CAAA,EAAA;AAAK,UAIvB,UAAA,SAAmB,UAJI,CAAA;;;;;SACc,CAAA,EAAA,OAAA,EAAA;EAAY,SAAA,CAAA,EAAA,OAAA;EAGjD;;;SAAmB,CAAA,EAWxB,OAXwB,CAAA,OAAA,CAAA;EAAU,IAAA,CAAA,EAAA,OAAA;AAsB9C;AAMA;;;;;;;AAea,cArBA,iCAAA,GAqBA,gBAAA,CAAA,EAAA;;;;AA0BF,UAzCM,uBAAA,CAyCN;QAED,EA1CA,OAAA,CAAQ,GA0CR;MAzCJ,eAAA,CAAgB,GA2DK;;;;;;;;EA+Bf,YAAA,CAAA,EAAA,MAAA;EAAuB,OAAA,EAAA,OAAA,EAAA;OACxB,EAAA,MAAA;MACN,EAhFG,IAgFH,CAhFQ,OAAA,CAAQ,GAgFhB,EAAA,MAAA,GAAA,OAAA,GAAA,SAAA,GAAA,OAAA,CAAA;EAAiB,SAAA,EA/ET,MA+ES,CAAA,MAAA,EA/EM,UA+EN,CAAA;EAET;;;;;;AAQb;EAAkC,WAAA,CAAA,EAhFlB,MAgFkB,CAAA,MAAA,EAAA,OAAA,CAAA;qBACvB,EAAA,MAAA,EAAA;UACQ,EA/EP,QA+EO;qBAAR,CAAA,EA9Ea,4BA8Eb;;;;;;;;;;;WAjEA;;UAED;;;;;;;;;;;;;;;;gBAkBM,UAAA,CAAW;;;;;;wBAOH,UAAA,CAAW;;;;;;;;;;;uBAaZ,SAAS,OAAA,CAAQ,SAAS,OAAA,CAAQ;;;;;;;sCAQnB,aAAa;;KAGvC,uBAAA,aACD,4BACN;cAEQ,gBAAA;qBAGoB;sBAFX;uBAEW;;UAKhB,iBAAA;WACN;WACA,QAAQ;oCAIT,qBACC,mBACH,wBACI"}
@@ -93,8 +93,16 @@ interface InngestExecutionOptions {
93
93
  internalFnId?: string;
94
94
  reqArgs: unknown[];
95
95
  runId: string;
96
- data: Omit<Context.Any, "step" | "group" | "publish">;
96
+ data: Omit<Context.Any, "step" | "group" | "publish" | "defer">;
97
97
  stepState: Record<string, MemoizedOp>;
98
+ /**
99
+ * A map of hashed defer step IDs to their backend-side metadata
100
+ * (e.g. `{ abortable: true }`). Defer ops are not steps in the
101
+ * memoization sense — they don't produce results — but the backend
102
+ * tracks which ones it has already received so the SDK can avoid
103
+ * re-emitting them on replay.
104
+ */
105
+ priorDefers?: Record<string, unknown>;
98
106
  stepCompletionOrder: string[];
99
107
  stepMode: StepMode;
100
108
  checkpointingConfig?: InternalCheckpointingOptions;
@@ -111,7 +119,16 @@ interface InngestExecutionOptions {
111
119
  headers: Record<string, string>;
112
120
  requestedRunStep?: string;
113
121
  timer?: ServerTiming;
114
- isFailureHandler?: boolean;
122
+ /**
123
+ * Which handler variant is being executed. `"failure"` skips
124
+ * trigger-schema validation and resolves `onFailure` instead of the
125
+ * main handler. `"defer"` marks the fn as a standalone defer function
126
+ * (created via `createDefer`); incoming event data is validated
127
+ * against the defer function's schema.
128
+ *
129
+ * @default "main"
130
+ */
131
+ handlerKind?: "main" | "failure" | "defer";
115
132
  disableImmediateExecution?: boolean;
116
133
  /**
117
134
  * Information about the incoming HTTP request that triggered this execution.
@@ -1 +1 @@
1
- {"version":3,"file":"InngestExecution.d.ts","names":[],"sources":["../../../src/components/execution/InngestExecution.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;UA6BiB,gBAAA;;;;;UAEK;;;;;;;;IAFL,KAAA,EAAA,CAIU,UAJM,EAAA,GAIS,UAJT,EAAA,CAAA;EAAA,CAAA;kBAEX,EAAA;IAEK,IAAA,EAEjB,UAFiB;IAAe,UAAA,EAG1B,cAH0B,EAAA;IAEhC,eAAA,EAAA,MAAA;;;;AAeV;;eACc,EAAA;IAEF,EAAA,EARJ,QAQI;IACD,KAAA,EAAQ,MAAA;;;AAEX,KANI,eAAA,GAMJ,QAAiB,MALX,gBAKW,GALQ,QAKR,CAAA;EALQ,IAAA,EAErB,CAFqB;EAOzB,GAAA,EAJG,OAAA,CAAQ,GAIX;EAAgB,GAAA,EAHb,MAGa,CAAA,MAAA,EAHE,UAGF,CAAA;AAEP,CAAA,GAJT,gBAIuB,CAJN,CAIM,CAAA,CAAA,EAK/B,CAAA,MAPQ,gBAOI,CAAA;AAAsB,UALjB,cAAA,CAKiB;MAAK,MAAA;aAC7B,CAAA,EAAA,MAAA;;AACL,KAFO,sBAEP,CAAA,IAFkC,cAElC,CAAA,GAAA,CAAA,MAAA,EADK,eACL,EAAA,GAAA,YAAA,CAAa,CAAb,CAAA;AAAY,KAEL,uBAFK,CAAA,IAEuB,cAFvB,CAAA,GAAA,QAGT,eADI,IACe,CADQ,CAAA,MAAA,CAAA,GAAA,CAAA,MAAA,EACa,CADb,EAAA,GACmB,YADnB,CACgC,CADhC,CAAA,EAAA;AAAK,UAIvB,UAAA,SAAmB,UAJI,CAAA;;;;;SACc,CAAA,EAAA,OAAA,EAAA;EAAY,SAAA,CAAA,EAAA,OAAA;EAGjD;;;SAAmB,CAAA,EAWxB,OAXwB,CAAA,OAAA,CAAA;EAAU,IAAA,CAAA,EAAA,OAAA;AAsB9C;AAMA;;;;;;;AAea,cArBA,iCAAA,GAqBA,gBAAA,CAAA,EAAA;;;;AAkBH,UAjCO,uBAAA,CAiCP;QAQM,EAxCN,OAAA,CAAQ,GAwCS;MAvCrB,eAAA,CAAgB,GA8Ca;;;;;;;AAwBnC;EAAmC,YAAA,CAAA,EAAA,MAAA;SACxB,EAAA,OAAA,EAAA;OACN,EAAA,MAAA;EAAiB,IAAA,EA5Dd,IA4Dc,CA5DT,OAAA,CAAQ,GA4DC,EAAA,MAAA,GAAA,OAAA,GAAA,SAAA,CAAA;EAET,SAAA,EA7DA,MA6DA,CAAA,MAAgB,EA7DD,UA6DC,CAAA;EAAA,mBAAA,EAAA,MAAA,EAAA;UAGI,EA9DrB,QA8DqB;qBAFX,CAAA,EA3DE,4BA2DF;;;AAOtB;;;;aAEW,CAAA,EAAA,MAAA;;;;SAOC,EA9DD,MA8DC,CAAA,MAAA,EAAA,MAAA,CAAA;EAAM,gBAAA,CAAA,EAAA,MAAA;UA5DR;;;;;;;gBAQM,UAAA,CAAW;;;;;;wBAOH,UAAA,CAAW;;;;;;;;;;;uBAaZ,SAAS,OAAA,CAAQ,SAAS,OAAA,CAAQ;;;;;;;sCAQnB,aAAa;;KAGvC,uBAAA,aACD,4BACN;cAEQ,gBAAA;qBAGoB;sBAFX;uBAEW;;UAKhB,iBAAA;WACN;WACA,QAAQ;oCAIT,qBACC,mBACH,wBACI"}
1
+ {"version":3,"file":"InngestExecution.d.ts","names":[],"sources":["../../../src/components/execution/InngestExecution.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;UA6BiB,gBAAA;;;;;UAEK;;;;;;;;IAFL,KAAA,EAAA,CAIU,UAJM,EAAA,GAIS,UAJT,EAAA,CAAA;EAAA,CAAA;kBAEX,EAAA;IAEK,IAAA,EAEjB,UAFiB;IAAe,UAAA,EAG1B,cAH0B,EAAA;IAEhC,eAAA,EAAA,MAAA;;;;AAeV;;eACc,EAAA;IAEF,EAAA,EARJ,QAQI;IACD,KAAA,EAAQ,MAAA;;;AAEX,KANI,eAAA,GAMJ,QAAiB,MALX,gBAKW,GALQ,QAKR,CAAA;EALQ,IAAA,EAErB,CAFqB;EAOzB,GAAA,EAJG,OAAA,CAAQ,GAIX;EAAgB,GAAA,EAHb,MAGa,CAAA,MAAA,EAHE,UAGF,CAAA;AAEP,CAAA,GAJT,gBAIuB,CAJN,CAIM,CAAA,CAAA,EAK/B,CAAA,MAPQ,gBAOI,CAAA;AAAsB,UALjB,cAAA,CAKiB;MAAK,MAAA;aAC7B,CAAA,EAAA,MAAA;;AACL,KAFO,sBAEP,CAAA,IAFkC,cAElC,CAAA,GAAA,CAAA,MAAA,EADK,eACL,EAAA,GAAA,YAAA,CAAa,CAAb,CAAA;AAAY,KAEL,uBAFK,CAAA,IAEuB,cAFvB,CAAA,GAAA,QAGT,eADI,IACe,CADQ,CAAA,MAAA,CAAA,GAAA,CAAA,MAAA,EACa,CADb,EAAA,GACmB,YADnB,CACgC,CADhC,CAAA,EAAA;AAAK,UAIvB,UAAA,SAAmB,UAJI,CAAA;;;;;SACc,CAAA,EAAA,OAAA,EAAA;EAAY,SAAA,CAAA,EAAA,OAAA;EAGjD;;;SAAmB,CAAA,EAWxB,OAXwB,CAAA,OAAA,CAAA;EAAU,IAAA,CAAA,EAAA,OAAA;AAsB9C;AAMA;;;;;;;AAea,cArBA,iCAAA,GAqBA,gBAAA,CAAA,EAAA;;;;AA0BF,UAzCM,uBAAA,CAyCN;QAED,EA1CA,OAAA,CAAQ,GA0CR;MAzCJ,eAAA,CAAgB,GA2DK;;;;;;;;EA+Bf,YAAA,CAAA,EAAA,MAAA;EAAuB,OAAA,EAAA,OAAA,EAAA;OACxB,EAAA,MAAA;MACN,EAhFG,IAgFH,CAhFQ,OAAA,CAAQ,GAgFhB,EAAA,MAAA,GAAA,OAAA,GAAA,SAAA,GAAA,OAAA,CAAA;EAAiB,SAAA,EA/ET,MA+ES,CAAA,MAAA,EA/EM,UA+EN,CAAA;EAET;;;;;;AAQb;EAAkC,WAAA,CAAA,EAhFlB,MAgFkB,CAAA,MAAA,EAAA,OAAA,CAAA;qBACvB,EAAA,MAAA,EAAA;UACQ,EA/EP,QA+EO;qBAAR,CAAA,EA9Ea,4BA8Eb;;;;;;;;;;;WAjEA;;UAED;;;;;;;;;;;;;;;;gBAkBM,UAAA,CAAW;;;;;;wBAOH,UAAA,CAAW;;;;;;;;;;;uBAaZ,SAAS,OAAA,CAAQ,SAAS,OAAA,CAAQ;;;;;;;sCAQnB,aAAa;;KAGvC,uBAAA,aACD,4BACN;cAEQ,gBAAA;qBAGoB;sBAFX;uBAEW;;UAKhB,iBAAA;WACN;WACA,QAAQ;oCAIT,qBACC,mBACH,wBACI"}
@@ -1 +1 @@
1
- {"version":3,"file":"InngestExecution.js","names":["options: InngestExecutionOptions"],"sources":["../../../src/components/execution/InngestExecution.ts"],"sourcesContent":["import Debug, { type Debugger } from \"debug\";\nimport { debugPrefix, ExecutionVersion } from \"../../helpers/consts.ts\";\nimport type { ServerTiming } from \"../../helpers/ServerTiming.ts\";\nimport type { MaybePromise, Simplify } from \"../../helpers/types.ts\";\nimport type {\n Context,\n IncomingOp,\n InternalCheckpointingOptions,\n OutgoingOp,\n StepMode,\n} from \"../../types.ts\";\nimport type { Inngest } from \"../Inngest.ts\";\nimport type { ActionResponse } from \"../InngestCommHandler.ts\";\nimport type { InngestFunction } from \"../InngestFunction.ts\";\nimport type {\n MetadataKind,\n MetadataOpcode,\n MetadataScope,\n} from \"../InngestMetadata.ts\";\nimport type { Middleware } from \"../middleware/middleware.ts\";\n\n// Re-export ExecutionVersion so it's correctly recognized as an enum and not\n// just a type. This can be lost when bundling if we don't re-export it here.\n// See `pnpm run test:dist`.\nexport { ExecutionVersion };\n\n/**\n * The possible results of an execution.\n */\nexport interface ExecutionResults {\n \"function-resolved\": { data: unknown };\n \"step-ran\": { step: OutgoingOp; retriable?: boolean | string };\n \"function-rejected\": { error: unknown; retriable: boolean | string };\n \"steps-found\": { steps: [OutgoingOp, ...OutgoingOp[]] };\n \"step-not-found\": {\n step: OutgoingOp;\n foundSteps: BasicFoundStep[];\n totalFoundSteps: number;\n };\n\n /**\n * Indicates that we need to relinquish control back to Inngest in order to\n * change step modes.\n */\n \"change-mode\": {\n to: StepMode;\n token: string;\n };\n}\n\nexport type ExecutionResult = {\n [K in keyof ExecutionResults]: Simplify<\n {\n type: K;\n ctx: Context.Any;\n ops: Record<string, MemoizedOp>;\n } & ExecutionResults[K]\n >;\n}[keyof ExecutionResults];\n\nexport interface BasicFoundStep {\n id: string;\n displayName?: string;\n}\n\nexport type ExecutionResultHandler<T = ActionResponse> = (\n result: ExecutionResult,\n) => MaybePromise<T>;\n\nexport type ExecutionResultHandlers<T = ActionResponse> = {\n [E in ExecutionResult as E[\"type\"]]: (result: E) => MaybePromise<T>;\n};\n\nexport interface MemoizedOp extends IncomingOp {\n /**\n * If the step has been hit during this run, these will be the arguments\n * passed to it.\n */\n rawArgs?: unknown[];\n fulfilled?: boolean;\n\n /**\n * The promise that has been returned to userland code.\n */\n promise?: Promise<unknown>;\n seen?: boolean;\n}\n\n/**\n * The preferred execution version that will be used by the SDK when handling\n * brand new runs where the Executor is allowing us to choose.\n *\n * Changing this should not ever be a breaking change, as this will only change\n * new runs, not existing ones.\n */\nexport const PREFERRED_ASYNC_EXECUTION_VERSION =\n ExecutionVersion.V2 satisfies ExecutionVersion;\n\n/**\n * Options for creating a new {@link InngestExecution} instance.\n */\nexport interface InngestExecutionOptions {\n client: Inngest.Any;\n fn: InngestFunction.Any;\n\n /**\n * The UUID that represents this function in Inngest.\n *\n * This is used to reference the function during async checkpointing, when we\n * know the function/run already exists and just wish to reference it\n * directly.\n */\n internalFnId?: string;\n reqArgs: unknown[];\n runId: string;\n data: Omit<Context.Any, \"step\" | \"group\" | \"publish\">;\n stepState: Record<string, MemoizedOp>;\n stepCompletionOrder: string[];\n stepMode: StepMode;\n checkpointingConfig?: InternalCheckpointingOptions;\n\n /**\n * If this execution is being run from a queue job, this will be an identifier\n * used to reference this execution in Inngest. SDKs are expected to parrot\n * this back in some responses to correctly attribute actions to this queue\n * item.\n */\n queueItemId?: string;\n\n /**\n * Headers to be sent with any request to Inngest during this execution.\n */\n headers: Record<string, string>;\n requestedRunStep?: string;\n timer?: ServerTiming;\n isFailureHandler?: boolean;\n disableImmediateExecution?: boolean;\n\n /**\n * Information about the incoming HTTP request that triggered this execution.\n * Used by middleware `wrapRequest` hooks.\n */\n requestInfo?: Middleware.Request;\n\n /**\n * Pre-created middleware instances to use for this execution. When provided,\n * the execution will use these instead of instantiating new ones from the\n * client. This ensures `wrapRequest` and other hooks share state on `this`.\n */\n middlewareInstances?: Middleware.BaseMiddleware[];\n\n /**\n * Whether the client accepts SSE (`Accept: text/event-stream`). When true,\n * the execution engine may deliver the result as an SSE stream even if\n * `stream.push()` was not called.\n */\n acceptsSse?: boolean;\n\n /**\n * Provide the ability to transform the context passed to the function before\n * the execution starts.\n */\n transformCtx?: (ctx: Readonly<Context.Any>) => Context.Any;\n\n /**\n * A hook that is called to create an {@link ActionResponse} from the returned\n * value of an execution.\n *\n * This is required for checkpointing executions.\n */\n createResponse?: (data: unknown) => MaybePromise<ActionResponse>;\n}\n\nexport type InngestExecutionFactory = (\n options: InngestExecutionOptions,\n) => IInngestExecution;\n\nexport class InngestExecution {\n protected devDebug: Debugger;\n\n constructor(protected options: InngestExecutionOptions) {\n this.devDebug = Debug(`${debugPrefix}:${this.options.runId}`);\n }\n}\n\nexport interface IInngestExecution {\n version: ExecutionVersion;\n start(): Promise<ExecutionResult>;\n\n addMetadata(\n stepId: string,\n kind: MetadataKind,\n scope: MetadataScope,\n op: MetadataOpcode,\n values: Record<string, unknown>,\n ): boolean;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA+FA,MAAa,oCACX,iBAAiB;AAiFnB,IAAa,mBAAb,MAA8B;CAC5B,AAAU;CAEV,YAAY,AAAUA,SAAkC;EAAlC;AACpB,OAAK,WAAW,MAAM,GAAG,YAAY,GAAG,KAAK,QAAQ,QAAQ"}
1
+ {"version":3,"file":"InngestExecution.js","names":["options: InngestExecutionOptions"],"sources":["../../../src/components/execution/InngestExecution.ts"],"sourcesContent":["import Debug, { type Debugger } from \"debug\";\nimport { debugPrefix, ExecutionVersion } from \"../../helpers/consts.ts\";\nimport type { ServerTiming } from \"../../helpers/ServerTiming.ts\";\nimport type { MaybePromise, Simplify } from \"../../helpers/types.ts\";\nimport type {\n Context,\n IncomingOp,\n InternalCheckpointingOptions,\n OutgoingOp,\n StepMode,\n} from \"../../types.ts\";\nimport type { Inngest } from \"../Inngest.ts\";\nimport type { ActionResponse } from \"../InngestCommHandler.ts\";\nimport type { InngestFunction } from \"../InngestFunction.ts\";\nimport type {\n MetadataKind,\n MetadataOpcode,\n MetadataScope,\n} from \"../InngestMetadata.ts\";\nimport type { Middleware } from \"../middleware/middleware.ts\";\n\n// Re-export ExecutionVersion so it's correctly recognized as an enum and not\n// just a type. This can be lost when bundling if we don't re-export it here.\n// See `pnpm run test:dist`.\nexport { ExecutionVersion };\n\n/**\n * The possible results of an execution.\n */\nexport interface ExecutionResults {\n \"function-resolved\": { data: unknown };\n \"step-ran\": { step: OutgoingOp; retriable?: boolean | string };\n \"function-rejected\": { error: unknown; retriable: boolean | string };\n \"steps-found\": { steps: [OutgoingOp, ...OutgoingOp[]] };\n \"step-not-found\": {\n step: OutgoingOp;\n foundSteps: BasicFoundStep[];\n totalFoundSteps: number;\n };\n\n /**\n * Indicates that we need to relinquish control back to Inngest in order to\n * change step modes.\n */\n \"change-mode\": {\n to: StepMode;\n token: string;\n };\n}\n\nexport type ExecutionResult = {\n [K in keyof ExecutionResults]: Simplify<\n {\n type: K;\n ctx: Context.Any;\n ops: Record<string, MemoizedOp>;\n } & ExecutionResults[K]\n >;\n}[keyof ExecutionResults];\n\nexport interface BasicFoundStep {\n id: string;\n displayName?: string;\n}\n\nexport type ExecutionResultHandler<T = ActionResponse> = (\n result: ExecutionResult,\n) => MaybePromise<T>;\n\nexport type ExecutionResultHandlers<T = ActionResponse> = {\n [E in ExecutionResult as E[\"type\"]]: (result: E) => MaybePromise<T>;\n};\n\nexport interface MemoizedOp extends IncomingOp {\n /**\n * If the step has been hit during this run, these will be the arguments\n * passed to it.\n */\n rawArgs?: unknown[];\n fulfilled?: boolean;\n\n /**\n * The promise that has been returned to userland code.\n */\n promise?: Promise<unknown>;\n seen?: boolean;\n}\n\n/**\n * The preferred execution version that will be used by the SDK when handling\n * brand new runs where the Executor is allowing us to choose.\n *\n * Changing this should not ever be a breaking change, as this will only change\n * new runs, not existing ones.\n */\nexport const PREFERRED_ASYNC_EXECUTION_VERSION =\n ExecutionVersion.V2 satisfies ExecutionVersion;\n\n/**\n * Options for creating a new {@link InngestExecution} instance.\n */\nexport interface InngestExecutionOptions {\n client: Inngest.Any;\n fn: InngestFunction.Any;\n\n /**\n * The UUID that represents this function in Inngest.\n *\n * This is used to reference the function during async checkpointing, when we\n * know the function/run already exists and just wish to reference it\n * directly.\n */\n internalFnId?: string;\n reqArgs: unknown[];\n runId: string;\n data: Omit<Context.Any, \"step\" | \"group\" | \"publish\" | \"defer\">;\n stepState: Record<string, MemoizedOp>;\n\n /**\n * A map of hashed defer step IDs to their backend-side metadata\n * (e.g. `{ abortable: true }`). Defer ops are not steps in the\n * memoization sense — they don't produce results — but the backend\n * tracks which ones it has already received so the SDK can avoid\n * re-emitting them on replay.\n */\n priorDefers?: Record<string, unknown>;\n\n stepCompletionOrder: string[];\n stepMode: StepMode;\n checkpointingConfig?: InternalCheckpointingOptions;\n\n /**\n * If this execution is being run from a queue job, this will be an identifier\n * used to reference this execution in Inngest. SDKs are expected to parrot\n * this back in some responses to correctly attribute actions to this queue\n * item.\n */\n queueItemId?: string;\n\n /**\n * Headers to be sent with any request to Inngest during this execution.\n */\n headers: Record<string, string>;\n requestedRunStep?: string;\n timer?: ServerTiming;\n /**\n * Which handler variant is being executed. `\"failure\"` skips\n * trigger-schema validation and resolves `onFailure` instead of the\n * main handler. `\"defer\"` marks the fn as a standalone defer function\n * (created via `createDefer`); incoming event data is validated\n * against the defer function's schema.\n *\n * @default \"main\"\n */\n handlerKind?: \"main\" | \"failure\" | \"defer\";\n\n disableImmediateExecution?: boolean;\n\n /**\n * Information about the incoming HTTP request that triggered this execution.\n * Used by middleware `wrapRequest` hooks.\n */\n requestInfo?: Middleware.Request;\n\n /**\n * Pre-created middleware instances to use for this execution. When provided,\n * the execution will use these instead of instantiating new ones from the\n * client. This ensures `wrapRequest` and other hooks share state on `this`.\n */\n middlewareInstances?: Middleware.BaseMiddleware[];\n\n /**\n * Whether the client accepts SSE (`Accept: text/event-stream`). When true,\n * the execution engine may deliver the result as an SSE stream even if\n * `stream.push()` was not called.\n */\n acceptsSse?: boolean;\n\n /**\n * Provide the ability to transform the context passed to the function before\n * the execution starts.\n */\n transformCtx?: (ctx: Readonly<Context.Any>) => Context.Any;\n\n /**\n * A hook that is called to create an {@link ActionResponse} from the returned\n * value of an execution.\n *\n * This is required for checkpointing executions.\n */\n createResponse?: (data: unknown) => MaybePromise<ActionResponse>;\n}\n\nexport type InngestExecutionFactory = (\n options: InngestExecutionOptions,\n) => IInngestExecution;\n\nexport class InngestExecution {\n protected devDebug: Debugger;\n\n constructor(protected options: InngestExecutionOptions) {\n this.devDebug = Debug(`${debugPrefix}:${this.options.runId}`);\n }\n}\n\nexport interface IInngestExecution {\n version: ExecutionVersion;\n start(): Promise<ExecutionResult>;\n\n addMetadata(\n stepId: string,\n kind: MetadataKind,\n scope: MetadataScope,\n op: MetadataOpcode,\n values: Record<string, unknown>,\n ): boolean;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA+FA,MAAa,oCACX,iBAAiB;AAqGnB,IAAa,mBAAb,MAA8B;CAC5B,AAAU;CAEV,YAAY,AAAUA,SAAkC;EAAlC;AACpB,OAAK,WAAW,MAAM,GAAG,YAAY,GAAG,KAAK,QAAQ,QAAQ"}