inngest
Version:
Official SDK for Inngest.com. Inngest is the reliability layer for modern applications. Inngest combines durable execution, events, and queues into a zero-infra platform with built-in observability.
472 lines (470 loc) • 15.8 kB
text/typescript
import { MaybePromise } from "../../helpers/types.cjs";
import { Jsonify } from "../../helpers/jsonify.cjs";
import { OpenStringUnion } from "./types.cjs";
import { createStepTools } from "../InngestStepTools.cjs";
import { InngestFunction } from "../InngestFunction.cjs";
import { Context, EventPayload, JsonError, SendEventBaseOutput, StepOptions } from "../../types.cjs";
import { Inngest } from "../Inngest.cjs";
//#region src/components/middleware/middleware.d.ts
/**
* Namespace containing middleware-related types and base class.
*/
declare namespace Middleware {
/**
* Base interface for output transformers. Extend this and override `Out` to
* create custom transformers. This is necessary because TypeScript doesn't
* support higher-kinded types.
*
* @example
* ```ts
* interface BooleanToStringTransform extends Middleware.StaticTransform {
* Out: this["In"] extends boolean ? string : this["In"];
* }
* ```
*/
export type StaticTransform = {
In: unknown;
Out: unknown;
};
/**
* Default transform. Applies the same transform as `JSON.stringify`.
*/
export interface DefaultStaticTransform extends StaticTransform {
Out: Jsonify<this["In"]>;
}
/**
* The step tools available to middleware for extending step functionality.
* This is the same type as `step` in the function handler context.
*/
export type StepTools = ReturnType<typeof createStepTools<Inngest.Any>>;
/**
* The argument passed to `transformSendEvent`.
*/
export type TransformSendEventArgs = {
events: EventPayload<Record<string, unknown>>[];
readonly fn: DeepReadonly<InngestFunction.Any> | null;
};
/**
* The argument passed to `transformStepInput`.
*/
export type TransformStepInputArgs = {
readonly fn: DeepReadonly<InngestFunction.Any>;
readonly stepInfo: Readonly<Pick<StepInfo, "hashedId" | "memoized" | "stepType">>;
stepOptions: StepOptions;
input: unknown[];
};
/** The argument passed to `wrapStepHandler`. */
export type WrapStepHandlerArgs = DeepReadonly<{
ctx: Context.Any;
fn: InngestFunction.Any;
next: () => Promise<unknown>;
stepInfo: StepInfo;
}>;
/**
* A single memoized step entry received in `transformFunctionInput`.
*/
type MemoizedStep = {
type: "data";
data: unknown;
} | {
type: "error";
error: JsonError;
} | {
type: "input";
input: unknown;
};
/**
* Memoized step state keyed by hashed step ID.
*/
type MemoizedSteps = Record<string, MemoizedStep>;
/**
* The argument passed to `transformFunctionInput`.
*/
export type TransformFunctionInputArgs = {
ctx: Context.Any;
readonly fn: DeepReadonly<InngestFunction.Any>;
steps: MemoizedSteps;
};
/**
* The argument passed to the static `onRegister` hook.
*/
export type OnRegisterArgs = Readonly<{
client: Inngest.Any;
fn: InngestFunction.Any | null;
}>;
/**
* Information about the incoming HTTP request that triggered this execution.
*/
export type Request = {
body: () => Promise<unknown>;
headers: Readonly<Record<string, string>>;
method: string;
url: URL;
};
/** The argument passed to `wrapFunctionHandler`. */
export type WrapFunctionHandlerArgs = DeepReadonly<{
ctx: Context.Any;
fn: InngestFunction.Any;
next: () => Promise<unknown>;
}>;
/** The argument passed to `wrapRequest`. */
export type WrapRequestArgs = DeepReadonly<{
fn: InngestFunction.Any | null;
next: () => Promise<Response>;
requestArgs: readonly unknown[];
requestInfo: Request;
runId: string;
}>;
/** The argument passed to `wrapSendEvent`. */
export type WrapSendEventArgs = DeepReadonly<{
events: EventPayload<Record<string, unknown>>[];
fn: InngestFunction.Any | null;
next: () => Promise<SendEventBaseOutput>;
}>;
/** The argument passed to `wrapStep`. */
export type WrapStepArgs = DeepReadonly<{
ctx: Context.Any;
fn: InngestFunction.Any;
next: () => Promise<unknown>;
stepInfo: StepInfo;
}>;
/**
* The shape of the HTTP response returned by the middleware chain.
* This is what `next()` resolves with inside `wrapRequest`.
*/
export type Response = {
body: string;
headers: Record<string, string>;
status: number;
};
/**
* The argument passed to `onMemoizationEnd`.
*/
export type OnMemoizationEndArgs = DeepReadonly<{
ctx: Context.Any;
fn: InngestFunction.Any;
}>;
/**
* The argument passed to `onStepStart`.
*/
export type OnStepStartArgs = DeepReadonly<{
ctx: Context.Any;
fn: InngestFunction.Any;
stepInfo: StepInfo;
}>;
/**
* The argument passed to `onStepError`.
*/
export type OnStepErrorArgs = DeepReadonly<{
ctx: Context.Any;
error: Error;
fn: InngestFunction.Any;
/**
* Whether this is the final attempt for the step, meaning retries are
* exhausted or the error is non-retriable. When `false`, the step will be
* retried.
*/
isFinalAttempt: boolean;
stepInfo: StepInfo;
}>;
/**
* The argument passed to `onStepComplete`.
*/
export type OnStepCompleteArgs = DeepReadonly<{
ctx: Context.Any;
fn: InngestFunction.Any;
output: unknown;
stepInfo: StepInfo;
}>;
/**
* The argument passed to `onRunStart`.
*/
export type OnRunStartArgs = DeepReadonly<{
ctx: Context.Any;
fn: InngestFunction.Any;
}>;
/**
* The argument passed to `onRunComplete`.
*/
export type OnRunCompleteArgs = DeepReadonly<{
ctx: Context.Any;
fn: InngestFunction.Any;
output: unknown;
}>;
/**
* The argument passed to `onRunError`.
*/
export type OnRunErrorArgs = DeepReadonly<{
ctx: Context.Any;
error: Error;
fn: InngestFunction.Any;
/**
* Whether this is the final attempt for the function, meaning retries are
* exhausted or the error is non-retriable. When `false`, the function will
* be retried.
*/
isFinalAttempt: boolean;
}>;
/**
* The type of step. This union may be extended in the future, and will not be
* considered a breaking change.
*/
export type StepType = OpenStringUnion<"ai.infer" | "ai.wrap" | "fetch" | "group.experiment" | "invoke" | "realtime.publish" | "run" | "sendEvent" | "sleep" | "waitForEvent">;
export type StepInfo = {
/**
* Unique ID for the step. This is a hash of the user-defined step ID,
* including the implicit index if the user-defined ID is not unique.
*/
hashedId: string;
/**
* The arguments passed to the step function, if any. For `step.run()`,
* these are the arguments after the id and handler function.
*/
input?: unknown[];
/**
* Whether the step result is being retrieved from memoized state (true)
* or being executed fresh (false).
*/
memoized: boolean;
/**
* Based on the first argument passed to the `step` method.
*/
options: StepOptions;
stepType: StepType;
};
/**
* Base class for creating middleware. Extend this class to create custom
* middleware with hooks for step execution.
*/
export abstract class BaseMiddleware {
readonly client: Inngest.Any;
/**
* Used to identify the middleware instance in logs. Uniqueness is not
* required, though using multiple middleware with the same ID in the same
* app may cause confusion when debugging.
*/
abstract readonly id: string;
/**
* Declare this to statically specify how function return types are
* transformed. By default, the function return type is Jsonified.
*
* Must match the same structure as `StaticTransform` to imitate
* higher-kinded types.
*
* @example
* ```ts
* interface PreserveDate extends Middleware.StaticTransform {
* Out: this["In"] extends Date ? Date : Jsonify<this["In"]>;
* }
*
* class MyMiddleware extends Middleware.BaseMiddleware {
* declare functionOutputTransform: PreserveDate;
* }
* ```
*
* @default Middleware.DefaultStaticTransform (e.g. Date -> string)
*/
functionOutputTransform: DefaultStaticTransform;
/**
* Declare this to statically specify how step output types are transformed.
* By default, the step output type is Jsonified.
*
* Must match the same structure as `StaticTransform` to imitate
* higher-kinded types.
*
* @example
* ```ts
* interface PreserveDate extends Middleware.StaticTransform {
* Out: this["In"] extends Date ? Date : Jsonify<this["In"]>;
* }
*
* class MyMiddleware extends Middleware.BaseMiddleware {
* declare stepOutputTransform: PreserveDate;
* }
* ```
*
* @default Middleware.DefaultStaticTransform (e.g. Date -> string)
*/
stepOutputTransform: DefaultStaticTransform;
constructor({
client
}: {
client: Inngest.Any;
});
/**
* Called when the middleware class is added to an Inngest client or Inngest
* function. Use this for one-time setup that needs a reference to the
* client instance (e.g. registering processors, setting feature flags).
*
* Do not mutate arguments.
*/
static onRegister?(args: Middleware.OnRegisterArgs): void;
/**
* Called 1 time per request, after memoization completes.
*
* If all memoized steps have been resolved/rejected, then this hook calls.
* This is at the top of the function handler when there are 0 memoized
* steps.
*
* If a new step is found before resolving/rejecting all memoized steps,
* then this calls.
*
* Do not mutate arguments.
*/
onMemoizationEnd?(arg: Middleware.OnMemoizationEndArgs): MaybePromise<void>;
/**
* Called when the run completes successfully. Does NOT call when the run
* errors: `onRunError` calls instead.
*
* Do not mutate arguments.
*/
onRunComplete?(arg: Middleware.OnRunCompleteArgs): MaybePromise<void>;
/**
* Called when the function throws an error.
*
* Do not mutate arguments.
*/
onRunError?(arg: Middleware.OnRunErrorArgs): MaybePromise<void>;
/**
* Called 1 time per run on the very first request (0 memoized steps,
* attempt 0). Does NOT call on subsequent requests where steps are being
* replayed.
*
* Do not mutate arguments.
*/
onRunStart?(arg: Middleware.OnRunStartArgs): MaybePromise<void>;
/**
* Called when a step successfully completes. Only called for `step.run`
* and `step.sendEvent`. Never called for memoized step outputs. Does NOT
* call when the step errors: `onStepError` calls instead.
*
* Do not mutate arguments.
*/
onStepComplete?(arg: Middleware.OnStepCompleteArgs): MaybePromise<void>;
/**
* Called each time a step errors. Only called for `step.run` and
* `step.sendEvent`. Never called for memoized errors.
*
* Do not mutate arguments.
*/
onStepError?(arg: Middleware.OnStepErrorArgs): MaybePromise<void>;
/**
* Called 1 time per step before running its handler. Only called for
* `step.run` and `step.sendEvent`.
*
* Do not mutate arguments.
*/
onStepStart?(arg: Middleware.OnStepStartArgs): MaybePromise<void>;
/**
* Called 1 time per request (likely multiple times per run). Return the
* (potentially modified) arg object.
*
* Use cases:
* - Dependency injection.
* - Deserialize events before passing it to the function handler.
*
* Do not mutate arguments.
*/
transformFunctionInput?(arg: Middleware.TransformFunctionInputArgs): MaybePromise<Middleware.TransformFunctionInputArgs>;
/**
* Called when sending events. This is either `step.sendEvent` or
* `client.send`. Return the (potentially modified) arg object.
*
* Use cases:
* - Serialize event data before sending it to the Inngest Server.
*
* Do not mutate arguments.
*/
transformSendEvent?(arg: Middleware.TransformSendEventArgs): MaybePromise<Middleware.TransformSendEventArgs>;
/**
* Called 1 time per step per request (likely multiple times per step).
* Return the (potentially modified) arg object.
*
* Use cases:
* - Modify step options (e.g. the step ID).
* - Modify step input args.
*
* Do not mutate arguments.
*/
transformStepInput?(arg: TransformStepInputArgs): MaybePromise<TransformStepInputArgs>;
/**
* Called 1 time per request.
*
* Use cases:
* - AsyncLocalStorage context.
* - Function-level output/error transformation.
* - Prepend/append steps around the function handler.
*
* Must call `next()` to continue processing. Do not mutate arguments.
*
* **Important:** `next()` only resolves when the function completes. On
* requests where a fresh step is discovered, control flow is interrupted
* and `next()` never resolves.
*/
wrapFunctionHandler?(args: WrapFunctionHandlerArgs): Promise<unknown>;
/**
* Called 1 time per request.
*
* Use cases:
* - Custom auth.
* - Expose request data to the Inngest function handler.
* - Metrics.
*
* Must call `next()` to continue processing. Do not mutate arguments.
*/
wrapRequest?(args: WrapRequestArgs): Promise<Response>;
/**
* Called each time events are sent (either `client.send` or
* `step.sendEvent`).
*
* Use cases:
* - Backup events (e.g. blob store) when they fail to send.
* - Metrics.
*
* Must call `next()` to continue processing. Do not mutate arguments.
*/
wrapSendEvent?(args: WrapSendEventArgs): Promise<SendEventBaseOutput>;
/**
* Called 1 time per step per request. Called for all step kinds. Depending
* on your use case, you may want `wrapStepHandler` instead.
*
* Use cases:
* - Deserialize step output before returning it to the function handler.
* - Handle step failure errors (after exhausting retries).
* - Prepend/append steps around a step.
*
* Must call `next()` to continue processing. Do not mutate arguments.
*
* NOTE: `next()` only resolves when the step completes/fails. On requests
* where a fresh step is discovered, control flow is interrupted and
* `next()` never resolves.
*/
wrapStep?(args: WrapStepArgs): Promise<unknown>;
/**
* Called 1 time per step attempt. Wraps the step's handler. Only called for
* `step.run` and `step.sendEvent`. Use this to modify the handler's
* returned output or thrown error before it's sent to the Inngest Server.
*
* Use cases:
* - Serialize step output before sending it to the Inngest Server.
* - Handle step attempt errors (before exhausting retries).
*
* Must call `next()` to continue processing. Do not mutate arguments.
*/
wrapStepHandler?(args: WrapStepHandlerArgs): Promise<unknown>;
}
/**
* A no-arg constructor for a BaseMiddleware subclass. Used in client and
* function options so that fresh instances are created per-request.
*/
export type Class = (new (args: {
client: Inngest.Any;
}) => BaseMiddleware) & {
onRegister?(arg: OnRegisterArgs): void;
};
export {};
}
type DeepReadonly<T> = T extends (infer U)[] ? readonly DeepReadonly<U>[] : T extends Function ? T : T extends Date | RegExp | Error | Map<unknown, unknown> | Set<unknown> ? Readonly<T> : T extends object ? { readonly [K in keyof T]: DeepReadonly<T[K]> } : T;
//#endregion
export { Middleware };
//# sourceMappingURL=middleware.d.cts.map