UNPKG

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.

1 lines 7.5 kB
{"version":3,"file":"DeferredFunction.cjs","names":["InngestFunction","markerKey","internalEvents"],"sources":["../../src/components/DeferredFunction.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport { internalEvents } from \"../helpers/consts.ts\";\nimport { type Marker, markerKey } from \"../helpers/marker.ts\";\nimport type {\n ApplyAllMiddlewareCtxExtensions,\n ApplyAllMiddlewareStepExtensions,\n BaseContext,\n FunctionConfig,\n Handler,\n} from \"../types.ts\";\nimport type {\n builtInMiddleware,\n ClientOptionsFromInngest,\n Inngest,\n} from \"./Inngest.ts\";\nimport { InngestFunction } from \"./InngestFunction.ts\";\nimport type { createStepTools } from \"./InngestStepTools.ts\";\nimport type { Middleware } from \"./middleware/index.ts\";\n\nconst idDenyRegex = /['\\\\\\n\\r]/;\n\n/**\n * EXPERIMENTAL: This API is not yet stable and may change in the future without\n * a major version bump.\n *\n * A defer (companion) function created via `createDefer(...)`. Real\n * `InngestFunction` at runtime, but with the trigger pinned to\n * `inngest/deferred.schedule` (see `getConfigTriggers`), `triggers` and\n * `onFailure` disallowed, and the schema carried as a typed instance\n * property so callers of `defer(id, { function, data })` can extract it.\n *\n * Identify a defer function at runtime via `isDeferredFunction(value)` from\n * `helpers/marker.ts`. Prefer that over `instanceof`, which fails across\n * duplicate SDK copies in the same process.\n *\n * @public\n */\nexport class DeferredFunction<\n TSchema extends\n | StandardSchemaV1<Record<string, unknown>>\n | undefined = undefined,\n> extends InngestFunction<\n InngestFunction.Options<[], never>,\n Handler.Any,\n never,\n Inngest.Any,\n []\n> {\n readonly schema: TSchema;\n readonly [markerKey]: Marker = { kind: \"deferredFunction\" };\n\n constructor(\n client: Inngest.Any,\n opts: DeferredFunction.Options,\n handler: Handler.Any,\n schema: TSchema,\n ) {\n // The id is interpolated into a CEL trigger expression\n // (`event.data._inngest.fn_slug == '${fnId}'`). Reject characters that\n // would break the single-quoted string literal.\n if (idDenyRegex.test(opts.id)) {\n throw new Error(\n `invalid id \"${opts.id}\"; must match ${idDenyRegex.source}`,\n );\n }\n super(\n client,\n { ...opts, triggers: [] } as InngestFunction.Options<[], never>,\n handler,\n );\n this.schema = schema;\n }\n\n protected override getConfigTriggers(\n fnId: string,\n ): FunctionConfig[\"triggers\"] {\n return [\n {\n event: internalEvents.DeferredSchedule,\n expression: `event.data._inngest.fn_slug == '${fnId}'`,\n },\n ];\n }\n}\n\n/**\n * @public\n */\nexport namespace DeferredFunction {\n /**\n * Matches any `DeferredFunction` regardless of its schema. Use as the\n * constraint for the `function` argument of `defer()`.\n */\n // biome-ignore lint/suspicious/noExplicitAny: widest schema constraint for inference\n export type Any = DeferredFunction<StandardSchemaV1<any> | undefined>;\n\n /**\n * The user-facing options accepted by `createDefer(client, opts, handler)`.\n * Mirrors `InngestFunction.Options` minus `triggers` (implicit), `onFailure`\n * (not yet supported), and `batchEvents` (each `defer(...)` is its own run).\n */\n export type Options = Omit<\n InngestFunction.Options<[], never>,\n \"triggers\" | \"onFailure\" | \"batchEvents\"\n >;\n}\n\n/**\n * The `event` shape a defer handler receives. With a schema, `data`\n * narrows to its inferred type; without one, it falls back to\n * `Record<string, any>`.\n */\ntype DeferEvent<TSchema> = {\n name: internalEvents.DeferredSchedule;\n data: TSchema extends StandardSchemaV1<\n infer D extends Record<string, unknown>\n >\n ? D\n : // biome-ignore lint/suspicious/noExplicitAny: no schema = any\n Record<string, any>;\n};\n\n/**\n * Base ctx shape for a defer handler: the standard function context\n * (`runId`, `attempt`, `group`, `step` with middleware step extensions)\n * with `event`/`events` pinned to `inngest/deferred.schedule` and the\n * schema-typed payload.\n */\ntype BaseDeferCtx<\n TClient extends Inngest.Any,\n TFnMiddleware extends Middleware.Class[] | undefined,\n TSchema extends StandardSchemaV1<Record<string, unknown>> | undefined,\n> = Omit<BaseContext<TClient>, \"event\" | \"events\" | \"step\"> & {\n event: DeferEvent<TSchema>;\n events: [DeferEvent<TSchema>];\n step: ReturnType<typeof createStepTools<TClient, TFnMiddleware>> &\n ApplyAllMiddlewareStepExtensions<\n ClientOptionsFromInngest<TClient>[\"middleware\"]\n > &\n ApplyAllMiddlewareStepExtensions<TFnMiddleware>;\n};\n\n/**\n * Input type for `createDefer`. Same shape as `DeferredFunction.Options`\n * plus `schema` (the StandardSchema describing `event.data` that flows\n * to caller `defer(id, { function, data })` call sites) and `middleware`.\n */\nexport type CreateDeferInput<\n TFnMiddleware extends Middleware.Class[] | undefined,\n TSchema extends StandardSchemaV1<Record<string, unknown>> | undefined,\n> = DeferredFunction.Options & {\n schema?: TSchema;\n middleware?: TFnMiddleware;\n};\n\n/**\n * EXPERIMENTAL: This API is not yet stable and may change in the future without\n * a major version bump.\n *\n * Create a typed defer function. One `createDefer` call = one Inngest\n * function. Returns a `DeferredFunction<TSchema>` so callers of `defer(id,\n * { function, data })` get the data type inferred from the schema.\n *\n * Mirrors `inngest.createFunction(opts, handler)`, with three differences:\n * the client is the first positional arg, `triggers` is not accepted (the\n * SDK emits an implicit `inngest/deferred.schedule` trigger), and `schema`\n * describes the payload that callers will send via `defer(id, { function,\n * data })`.\n *\n * Pass the result to `serve()` alongside regular functions so the SDK\n * registers it.\n */\nexport function createDefer<\n TClient extends Inngest.Any,\n TSchema extends\n | StandardSchemaV1<Record<string, unknown>>\n | undefined = undefined,\n const TFnMiddleware extends Middleware.Class[] | undefined = undefined,\n THandler extends Handler.Any = (\n ctx: BaseDeferCtx<TClient, TFnMiddleware, TSchema> &\n ApplyAllMiddlewareCtxExtensions<\n [...ReturnType<typeof builtInMiddleware>]\n > &\n ApplyAllMiddlewareCtxExtensions<\n ClientOptionsFromInngest<TClient>[\"middleware\"]\n > &\n ApplyAllMiddlewareCtxExtensions<TFnMiddleware>,\n ) => unknown,\n>(\n client: TClient,\n options: CreateDeferInput<TFnMiddleware, TSchema>,\n handler: THandler,\n): DeferredFunction<TSchema> {\n const { schema, ...rest } = options;\n return new DeferredFunction<TSchema>(\n client,\n rest,\n handler as Handler.Any,\n schema as TSchema,\n );\n}\n"],"mappings":";;;;;AAmBA,MAAM,cAAc;;;;;;;;;;;;;;;;;AAkBpB,IAAa,mBAAb,cAIUA,wCAMR;CACA,AAAS;CACT,CAAUC,4BAAqB,EAAE,MAAM,oBAAoB;CAE3D,YACE,QACA,MACA,SACA,QACA;AAIA,MAAI,YAAY,KAAK,KAAK,GAAG,CAC3B,OAAM,IAAI,MACR,eAAe,KAAK,GAAG,gBAAgB,YAAY,SACpD;AAEH,QACE,QACA;GAAE,GAAG;GAAM,UAAU,EAAE;GAAE,EACzB,QACD;AACD,OAAK,SAAS;;CAGhB,AAAmB,kBACjB,MAC4B;AAC5B,SAAO,CACL;GACE,OAAOC,8BAAe;GACtB,YAAY,mCAAmC,KAAK;GACrD,CACF;;;;;;;;;;;;;;;;;;;;AA2FL,SAAgB,YAiBd,QACA,SACA,SAC2B;CAC3B,MAAM,EAAE,QAAQ,GAAG,SAAS;AAC5B,QAAO,IAAI,iBACT,QACA,MACA,SACA,OACD"}