effect-inngest 0.1.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 (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +457 -0
  3. package/dist/Client.d.ts +167 -0
  4. package/dist/Client.js +144 -0
  5. package/dist/Events.d.ts +110 -0
  6. package/dist/Events.js +93 -0
  7. package/dist/Function.d.ts +384 -0
  8. package/dist/Function.js +104 -0
  9. package/dist/Group.d.ts +152 -0
  10. package/dist/Group.js +164 -0
  11. package/dist/HttpApi.d.ts +75 -0
  12. package/dist/HttpApi.js +47 -0
  13. package/dist/_virtual/rolldown_runtime.js +18 -0
  14. package/dist/index.d.ts +7 -0
  15. package/dist/index.js +8 -0
  16. package/dist/internal/constants.js +15 -0
  17. package/dist/internal/driver.d.ts +5 -0
  18. package/dist/internal/driver.js +117 -0
  19. package/dist/internal/errors.d.ts +56 -0
  20. package/dist/internal/errors.js +61 -0
  21. package/dist/internal/handler.d.ts +20 -0
  22. package/dist/internal/handler.js +145 -0
  23. package/dist/internal/helpers.js +44 -0
  24. package/dist/internal/interrupts.d.ts +2 -0
  25. package/dist/internal/interrupts.js +45 -0
  26. package/dist/internal/memo.js +56 -0
  27. package/dist/internal/protocol.d.ts +1 -0
  28. package/dist/internal/protocol.js +191 -0
  29. package/dist/internal/signature.d.ts +18 -0
  30. package/dist/internal/signature.js +97 -0
  31. package/dist/internal/step.d.ts +59 -0
  32. package/dist/internal/step.js +183 -0
  33. package/package.json +121 -0
  34. package/src/Client.ts +279 -0
  35. package/src/Events.ts +87 -0
  36. package/src/Function.ts +493 -0
  37. package/src/Group.ts +314 -0
  38. package/src/HttpApi.ts +82 -0
  39. package/src/index.ts +171 -0
  40. package/src/internal/constants.ts +11 -0
  41. package/src/internal/driver.ts +194 -0
  42. package/src/internal/errors.ts +130 -0
  43. package/src/internal/handler.ts +222 -0
  44. package/src/internal/helpers.ts +58 -0
  45. package/src/internal/interrupts.ts +62 -0
  46. package/src/internal/memo.ts +73 -0
  47. package/src/internal/protocol.ts +218 -0
  48. package/src/internal/signature.ts +158 -0
  49. package/src/internal/step.ts +377 -0
package/src/Group.ts ADDED
@@ -0,0 +1,314 @@
1
+ /**
2
+ * @since 0.1.0
3
+ */
4
+ import * as HttpApp from "@effect/platform/HttpApp";
5
+ import * as HttpClient from "@effect/platform/HttpClient";
6
+ import * as HttpServerRequest from "@effect/platform/HttpServerRequest";
7
+ import * as HttpServerResponse from "@effect/platform/HttpServerResponse";
8
+ import * as UrlParams from "@effect/platform/UrlParams";
9
+ import * as Context from "effect/Context";
10
+ import * as Effect from "effect/Effect";
11
+ import * as Layer from "effect/Layer";
12
+ import * as Option from "effect/Option";
13
+ import * as Schema from "effect/Schema";
14
+ import type { InngestFunction } from "./Function.js";
15
+ import { InngestClient } from "./Client.js";
16
+ import * as InternalHandler from "./internal/handler.js";
17
+ import * as Protocol from "./internal/protocol.js";
18
+ import { SignatureLive } from "./internal/signature.js";
19
+
20
+ import { type HandlerContext } from "./internal/step.js";
21
+
22
+ /**
23
+ * Re-export HandlerContext from internal step module.
24
+ * @since 0.1.0
25
+ * @category models
26
+ */
27
+ export { type HandlerContext };
28
+
29
+ /**
30
+ * @since 0.1.0
31
+ * @category type ids
32
+ */
33
+ export const TypeId: unique symbol = Symbol.for("effect-inngest/Group");
34
+
35
+ /**
36
+ * @since 0.1.0
37
+ * @category type ids
38
+ */
39
+ export type TypeId = typeof TypeId;
40
+
41
+ /**
42
+ * @since 0.1.0
43
+ * @category models
44
+ */
45
+ export type HandlerFn<F extends InngestFunction.Any> = (
46
+ context: HandlerContext<F>,
47
+ ) => Effect.Effect<InngestFunction.Success<F>, unknown, unknown>;
48
+
49
+ /**
50
+ * @since 0.1.0
51
+ * @category models
52
+ */
53
+ export type HandlersFrom<Fns extends InngestFunction.Any> = {
54
+ readonly [F in Fns as InngestFunction.Tag<F>]: HandlerFn<F>;
55
+ };
56
+
57
+ /**
58
+ * @since 0.1.0
59
+ * @category models
60
+ */
61
+ export type HandlerFrom<Fns extends InngestFunction.Any, Tag extends InngestFunction.Tag<Fns>> =
62
+ Extract<Fns, { readonly _tag: Tag }> extends infer Current
63
+ ? Current extends InngestFunction.Any
64
+ ? HandlerFn<Current>
65
+ : never
66
+ : never;
67
+
68
+ /**
69
+ * @since 0.1.0
70
+ * @category models
71
+ */
72
+ export type HandlersRequirements<H> =
73
+ H extends Record<string, (...args: ReadonlyArray<unknown>) => Effect.Effect<unknown, unknown, infer R>> ? R : never;
74
+
75
+ /**
76
+ * @since 0.1.0
77
+ * @category models
78
+ */
79
+ export type HandlerRequirements<Handler> = Handler extends (
80
+ ...args: ReadonlyArray<unknown>
81
+ ) => Effect.Effect<unknown, unknown, infer R>
82
+ ? R
83
+ : never;
84
+
85
+ /**
86
+ * A nominal type representing a registered handler for a specific function tag.
87
+ * @since 0.1.0
88
+ * @category models
89
+ */
90
+ export interface Handler<Tag extends string> {
91
+ readonly _: unique symbol;
92
+ readonly tag: Tag;
93
+ readonly handler: (context: unknown) => Effect.Effect<unknown, unknown, unknown>;
94
+ readonly context: Context.Context<never>;
95
+ }
96
+
97
+ /**
98
+ * Maps a function to its Handler type.
99
+ * @since 0.1.0
100
+ * @category models
101
+ */
102
+ export type ToHandler<F extends InngestFunction.Any> =
103
+ F extends InngestFunction<infer _Tag, infer _Triggers, infer _Success> ? Handler<_Tag> : never;
104
+
105
+ /**
106
+ * @since 0.1.0
107
+ * @category models
108
+ */
109
+ export interface InngestGroup<Fns extends InngestFunction.Any> {
110
+ readonly [TypeId]: TypeId;
111
+ readonly functions: ReadonlyMap<string, Fns>;
112
+
113
+ /**
114
+ * Implement all handlers for the functions in this group.
115
+ */
116
+ readonly toLayer: <H extends HandlersFrom<Fns>>(
117
+ handlers: H,
118
+ ) => Layer.Layer<ToHandler<Fns>, never, HandlersRequirements<H>>;
119
+
120
+ /**
121
+ * Implement a single handler from the group.
122
+ */
123
+ readonly toLayerHandler: <Tag extends InngestFunction.Tag<Fns>, H extends HandlerFrom<Fns, Tag>>(
124
+ tag: Tag,
125
+ handler: H,
126
+ ) => Layer.Layer<Handler<Tag>, never, HandlerRequirements<H>>;
127
+ }
128
+
129
+ /**
130
+ * @since 0.1.0
131
+ * @category models
132
+ */
133
+ export declare namespace InngestGroup {
134
+ export type Any = InngestGroup<InngestFunction.Any>;
135
+ export type Functions<G> = G extends InngestGroup<infer Fns> ? Fns : never;
136
+ export type FunctionTags<G> = G extends InngestGroup<infer Fns> ? InngestFunction.Tag<Fns> : never;
137
+ export type Handlers<G> = G extends InngestGroup<infer Fns> ? HandlersFrom<Fns> : never;
138
+ }
139
+
140
+ const Proto = {
141
+ [TypeId]: TypeId,
142
+
143
+ toLayer(this: InngestGroup<InngestFunction.Any>, handlers: Record<string, unknown>) {
144
+ const functions = this.functions;
145
+ return Layer.effectContext(
146
+ Effect.gen(function* () {
147
+ const context = yield* Effect.context<never>();
148
+ const contextMap = new Map<string, unknown>();
149
+ for (const [tag, handler] of Object.entries(handlers)) {
150
+ const fn = functions.get(tag)!;
151
+ contextMap.set(fn.key, { handler, context });
152
+ }
153
+ return Context.unsafeMake(contextMap);
154
+ }),
155
+ );
156
+ },
157
+
158
+ toLayerHandler(this: InngestGroup<InngestFunction.Any>, tag: string, handler: unknown) {
159
+ const fn = this.functions.get(tag)!;
160
+ return Layer.effectContext(
161
+ Effect.gen(function* () {
162
+ const context = yield* Effect.context<never>();
163
+ const contextMap = new Map<string, unknown>();
164
+ contextMap.set(fn.key, { handler, context });
165
+ return Context.unsafeMake(contextMap);
166
+ }),
167
+ );
168
+ },
169
+ };
170
+
171
+ /**
172
+ * @since 0.1.0
173
+ * @category constructors
174
+ */
175
+ export const make = <Fns extends ReadonlyArray<InngestFunction.Any>>(...fns: Fns): InngestGroup<Fns[number]> => {
176
+ const functions = new Map(fns.map((fn) => [fn._tag, fn]));
177
+ const group = Object.create(Proto);
178
+ group.functions = functions;
179
+ return group;
180
+ };
181
+
182
+ /**
183
+ * Build an HttpApp from an InngestGroup.
184
+ *
185
+ * @since 0.1.0
186
+ * @category http
187
+ * @example
188
+ * ```ts
189
+ * import { Effect, Layer } from "effect"
190
+ * import { HttpServer } from "@effect/platform"
191
+ * import { NodeHttpServer, NodeRuntime } from "@effect/platform-node"
192
+ * import { InngestGroup, InngestClient } from "effect-inngest"
193
+ *
194
+ * InngestGroup.toHttpApp(MyGroup).pipe(
195
+ * Effect.flatMap((app) => HttpServer.serve(app)),
196
+ * Effect.provide(InngestClient.layer({ id: "my-app" })),
197
+ * Effect.provide(NodeHttpServer.layer({ port: 3000 })),
198
+ * NodeRuntime.runMain,
199
+ * )
200
+ * ```
201
+ */
202
+ export const toHttpApp = (group: InngestGroup.Any): HttpApp.Default<never, InngestClient | HttpClient.HttpClient> =>
203
+ Effect.gen(function* () {
204
+ const request = yield* HttpServerRequest.HttpServerRequest;
205
+ const method = request.method;
206
+ const requestUrl = Option.match(HttpServerRequest.toURL(request), {
207
+ onNone: () => request.url,
208
+ onSome: (url) => url.toString(),
209
+ });
210
+
211
+ if (method === "GET") {
212
+ const result = yield* InternalHandler.handleIntrospection(group, requestUrl);
213
+ return yield* HttpServerResponse.json(result.body, {
214
+ status: result.status,
215
+ headers: result.headers,
216
+ });
217
+ }
218
+
219
+ if (method === "PUT") {
220
+ const result = yield* InternalHandler.handleRegistration(group, requestUrl);
221
+ return yield* HttpServerResponse.json(result.body, {
222
+ status: result.status,
223
+ headers: result.headers,
224
+ });
225
+ }
226
+
227
+ if (method === "POST") {
228
+ const url = Option.getOrThrow(HttpServerRequest.toURL(request));
229
+
230
+ const ExecuteParams = Schema.Struct({
231
+ fnId: Schema.String,
232
+ stepId: Schema.optional(Schema.String),
233
+ });
234
+
235
+ const params = yield* UrlParams.schemaStruct(ExecuteParams)(UrlParams.fromInput(url.searchParams)).pipe(
236
+ Effect.catchAll(() =>
237
+ Effect.fail(
238
+ HttpServerResponse.unsafeJson(
239
+ { error: "Missing or invalid fnId query parameter" },
240
+ { status: 400, headers: { [Protocol.Headers.NoRetry]: "true" } },
241
+ ),
242
+ ),
243
+ ),
244
+ );
245
+
246
+ const body = yield* InternalHandler.verifyAndParseRequestBody(request).pipe(
247
+ Effect.provide(SignatureLive),
248
+ Effect.catchAll((error) =>
249
+ Effect.fail(
250
+ HttpServerResponse.unsafeJson(
251
+ { error: error.message },
252
+ {
253
+ status: error._tag === "SignatureError" ? 401 : 400,
254
+ headers: { [Protocol.Headers.NoRetry]: "true" },
255
+ },
256
+ ),
257
+ ),
258
+ ),
259
+ );
260
+
261
+ const result = yield* InternalHandler.handleExecution(group, params.fnId, params.stepId, body);
262
+
263
+ return yield* HttpServerResponse.json(result.body, {
264
+ status: result.status,
265
+ headers: result.headers,
266
+ });
267
+ }
268
+
269
+ return yield* HttpServerResponse.json({ error: `Method ${method} not allowed` }, { status: 405 });
270
+ }).pipe(
271
+ Effect.catchAllCause((cause) =>
272
+ HttpServerResponse.json({ error: "Internal server error", cause: String(cause) }, { status: 500 }).pipe(
273
+ Effect.orDie,
274
+ ),
275
+ ),
276
+ );
277
+
278
+ /**
279
+ * Create a standalone web handler from an InngestGroup.
280
+ *
281
+ * @since 0.1.0
282
+ * @category http
283
+ * @example
284
+ * ```ts
285
+ * import { InngestGroup, InngestClient } from "effect-inngest"
286
+ * import { HttpClient } from "@effect/platform"
287
+ * import { FetchHttpClient } from "@effect/platform"
288
+ *
289
+ * const { handler, dispose } = InngestGroup.toWebHandler(MyGroup, {
290
+ * layer: InngestClient.layer({ id: "my-app" }).pipe(
291
+ * Layer.provide(FetchHttpClient.layer),
292
+ * ),
293
+ * })
294
+ *
295
+ * // Use with any web framework
296
+ * Bun.serve({ fetch: handler, port: 3000 })
297
+ *
298
+ * // Call dispose() on shutdown
299
+ * process.on("SIGTERM", dispose)
300
+ * ```
301
+ */
302
+ export const toWebHandler = <R, E>(
303
+ group: InngestGroup.Any,
304
+ options: {
305
+ readonly layer: Layer.Layer<InngestClient | HttpClient.HttpClient | R, E, never>;
306
+ readonly memoMap?: Layer.MemoMap;
307
+ },
308
+ ): {
309
+ readonly handler: (request: Request) => Promise<Response>;
310
+ readonly dispose: () => Promise<void>;
311
+ } =>
312
+ HttpApp.toWebHandlerLayer(toHttpApp(group), Layer.mergeAll(options.layer, Layer.scope), {
313
+ memoMap: options.memoMap,
314
+ });
package/src/HttpApi.ts ADDED
@@ -0,0 +1,82 @@
1
+ /**
2
+ * @since 0.1.0
3
+ */
4
+ import * as HttpApi from "@effect/platform/HttpApi";
5
+ import * as HttpApiBuilder from "@effect/platform/HttpApiBuilder";
6
+ import * as HttpApiEndpoint from "@effect/platform/HttpApiEndpoint";
7
+ import * as HttpApiGroup from "@effect/platform/HttpApiGroup";
8
+ import * as HttpClient from "@effect/platform/HttpClient";
9
+ import * as HttpServerRequest from "@effect/platform/HttpServerRequest";
10
+ import * as Effect from "effect/Effect";
11
+ import * as Layer from "effect/Layer";
12
+ import * as Option from "effect/Option";
13
+ import * as Schema from "effect/Schema";
14
+ import { InngestClient } from "./Client.js";
15
+ import type { InngestGroup } from "./Group.js";
16
+ import * as InternalHandler from "./internal/handler.js";
17
+ import * as Protocol from "./internal/protocol.js";
18
+ import { SignatureLive } from "./internal/signature.js";
19
+
20
+ const ExecuteParams = Schema.Struct({
21
+ fnId: Schema.String,
22
+ stepId: Schema.optional(Schema.String),
23
+ });
24
+
25
+ class FunctionNotFoundError extends Schema.TaggedError<FunctionNotFoundError>()("FunctionNotFoundError", {
26
+ message: Schema.String,
27
+ }) {}
28
+
29
+ const IntrospectEndpoint = HttpApiEndpoint.get("introspect", "/").addSuccess(Protocol.IntrospectionResponse);
30
+ const RegisterEndpoint = HttpApiEndpoint.put("register", "/").addSuccess(Protocol.RegisterResponse);
31
+ const ExecuteEndpoint = HttpApiEndpoint.post("execute", "/").setUrlParams(ExecuteParams).addSuccess(Schema.Unknown);
32
+
33
+ /**
34
+ * @since 0.1.0
35
+ * @category api
36
+ */
37
+ export const InngestApiGroup = HttpApiGroup.make("inngest")
38
+ .add(IntrospectEndpoint)
39
+ .add(RegisterEndpoint)
40
+ .add(ExecuteEndpoint)
41
+ .addError(FunctionNotFoundError, { status: 404 })
42
+ .addError(InternalHandler.InvalidRequestError, { status: 400 })
43
+ .addError(InternalHandler.SignatureError, { status: 401 });
44
+
45
+ type InngestApiGroupType = typeof InngestApiGroup;
46
+
47
+ /**
48
+ * @since 0.1.0
49
+ * @category layers
50
+ */
51
+ export const layerGroup = <ApiId extends string, Groups extends HttpApiGroup.HttpApiGroup.Any, ApiError, ApiR>(
52
+ api: HttpApi.HttpApi<ApiId, Groups, ApiError, ApiR>,
53
+ group: InngestGroup.Any,
54
+ ): Layer.Layer<HttpApiGroup.ApiGroup<ApiId, "inngest">, never, InngestClient | HttpClient.HttpClient> => {
55
+ const toUrl = (req: HttpServerRequest.HttpServerRequest) =>
56
+ Option.match(HttpServerRequest.toURL(req), {
57
+ onNone: () => req.url,
58
+ onSome: (url) => url.toString(),
59
+ });
60
+
61
+ return HttpApiBuilder.group(
62
+ api as unknown as HttpApi.HttpApi<ApiId, InngestApiGroupType, ApiError, ApiR>,
63
+ "inngest",
64
+ (handlers) =>
65
+ handlers
66
+ .handle("introspect", ({ request }) =>
67
+ InternalHandler.handleIntrospection(group, toUrl(request)).pipe(Effect.map((r) => r.body)),
68
+ )
69
+ .handle("register", ({ request }) =>
70
+ InternalHandler.handleRegistration(group, toUrl(request)).pipe(Effect.map((r) => r.body)),
71
+ )
72
+ .handleRaw("execute", ({ urlParams, request }) =>
73
+ InternalHandler.verifyAndParseRequestBody(request).pipe(
74
+ Effect.provide(SignatureLive),
75
+ Effect.flatMap((payload) =>
76
+ InternalHandler.handleExecution(group, urlParams.fnId, urlParams.stepId, payload),
77
+ ),
78
+ Effect.map((r) => r.body),
79
+ ),
80
+ ),
81
+ ) as Layer.Layer<HttpApiGroup.ApiGroup<ApiId, "inngest">, never, InngestClient | HttpClient.HttpClient>;
82
+ };
package/src/index.ts ADDED
@@ -0,0 +1,171 @@
1
+ /**
2
+ * This module provides types and functions for defining Inngest functions.
3
+ *
4
+ * Functions are the core building blocks of Inngest applications. Each function
5
+ * defines what events trigger it, what it returns on success, and optional
6
+ * configuration like retries, concurrency limits, rate limiting, and more.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { Effect, Schema } from "effect"
11
+ * import { InngestFunction, InngestGroup } from "effect-inngest"
12
+ *
13
+ * // Define events as TaggedClass
14
+ * class UserCreated extends Schema.TaggedClass<UserCreated>()("user/created", {
15
+ * userId: Schema.String,
16
+ * email: Schema.String,
17
+ * }) {}
18
+ *
19
+ * // Define functions
20
+ * const SendWelcomeEmail = InngestFunction.make("send-welcome-email", {
21
+ * event: UserCreated,
22
+ * success: Schema.Void,
23
+ * retries: 3,
24
+ * })
25
+ *
26
+ * // Create a group
27
+ * const MyGroup = InngestGroup.make(SendWelcomeEmail)
28
+ *
29
+ * // Implement handlers
30
+ * const HandlersLive = MyGroup.toLayer({
31
+ * "send-welcome-email": (event) =>
32
+ * Effect.gen(function* () {
33
+ * yield* sendEmail(event.email)
34
+ * }),
35
+ * })
36
+ * ```
37
+ *
38
+ * @module InngestFunction
39
+ * @since 0.1.0
40
+ */
41
+ export * as InngestFunction from "./Function.js";
42
+
43
+ /**
44
+ * This module provides types and functions for grouping Inngest functions
45
+ * and creating handler layers.
46
+ *
47
+ * Groups aggregate functions and provide a way to define handlers as a single
48
+ * layer that can be composed with the rest of your Effect application.
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * import { Effect } from "effect"
53
+ * import { InngestGroup } from "effect-inngest"
54
+ *
55
+ * const MyGroup = InngestGroup.make(ProcessOrder, SendNotification)
56
+ *
57
+ * const HandlersLive = MyGroup.toLayer({
58
+ * "process-order": (event) => Effect.succeed({ processed: true }),
59
+ * "send-notification": (event) => Effect.void,
60
+ * })
61
+ * ```
62
+ *
63
+ * @module InngestGroup
64
+ * @since 0.1.0
65
+ */
66
+ export * as InngestGroup from "./Group.js";
67
+
68
+ /**
69
+ * This module provides the InngestClient service for communicating with Inngest.
70
+ *
71
+ * The client handles event sending, function registration, and API communication.
72
+ * It supports both development (local dev server) and cloud modes, with automatic
73
+ * mode detection from environment variables.
74
+ *
75
+ * @example
76
+ * ```ts
77
+ * import { Effect } from "effect"
78
+ * import { HttpClient } from "@effect/platform"
79
+ * import { InngestClient } from "effect-inngest"
80
+ *
81
+ * // Create a layer with explicit config
82
+ * const ClientLive = InngestClient.layer({
83
+ * id: "my-app",
84
+ * eventKey: "my-event-key",
85
+ * })
86
+ *
87
+ * // Or use environment variables
88
+ * const ClientFromEnv = InngestClient.layerFromEnv
89
+ *
90
+ * // Use in your program
91
+ * const program = Effect.gen(function* () {
92
+ * const client = yield* InngestClient.InngestClientTag
93
+ * yield* client.sendEvent([{ name: "user/created", data: { userId: "123" } }])
94
+ * })
95
+ * ```
96
+ *
97
+ * @module InngestClient
98
+ * @since 0.1.0
99
+ */
100
+ export * as InngestClient from "./Client.js";
101
+
102
+ /**
103
+ * This module provides integration with `@effect/platform` HttpApi.
104
+ *
105
+ * Use `InngestHttpApi.InngestApiGroup` to add Inngest endpoints to your HttpApi,
106
+ * then use `InngestHttpApi.layerGroup` to implement the handlers.
107
+ *
108
+ * @example
109
+ * ```ts
110
+ * import { HttpApi, HttpApiBuilder } from "@effect/platform"
111
+ * import { InngestHttpApi, InngestGroup, InngestClient } from "effect-inngest"
112
+ * import { Layer } from "effect"
113
+ *
114
+ * // Add InngestApiGroup to your HttpApi
115
+ * class MyApi extends HttpApi.make("my-api")
116
+ * .add(InngestHttpApi.InngestApiGroup.prefix("/api/inngest")) {}
117
+ *
118
+ * // Create the implementation layer
119
+ * const InngestLayer = InngestHttpApi.layerGroup(MyApi, MyFunctions)
120
+ *
121
+ * // Wire it up with HttpApiBuilder
122
+ * const ApiLive = HttpApiBuilder.api(MyApi).pipe(
123
+ * Layer.provide(InngestLayer),
124
+ * Layer.provide(FunctionsLayer),
125
+ * Layer.provide(InngestClient.layer({ id: "my-app" })),
126
+ * )
127
+ * ```
128
+ *
129
+ * @module InngestHttpApi
130
+ * @since 0.1.0
131
+ */
132
+ export * as InngestHttpApi from "./HttpApi.js";
133
+
134
+ /**
135
+ * Internal Inngest events that the platform sends automatically.
136
+ * Use these as triggers to react to function lifecycle events.
137
+ *
138
+ * @example
139
+ * ```ts
140
+ * import { Effect } from "effect"
141
+ * import { InngestFunction, InngestEvents } from "effect-inngest"
142
+ *
143
+ * // React to function failures
144
+ * const HandleFailure = InngestFunction.make("handle-failure", {
145
+ * trigger: { event: InngestEvents.FunctionFailed },
146
+ * success: Schema.Void,
147
+ * })
148
+ * ```
149
+ *
150
+ * @module InngestEvents
151
+ * @since 0.1.0
152
+ */
153
+ export * as InngestEvents from "./Events.js";
154
+
155
+ /**
156
+ * Error thrown to indicate that an operation should not be retried.
157
+ * Use this when you know retrying won't help (e.g., validation errors, auth failures).
158
+ *
159
+ * @since 0.1.0
160
+ * @category errors
161
+ */
162
+ export { NonRetriableError } from "./internal/errors.js";
163
+
164
+ /**
165
+ * Error thrown to indicate that an operation should be retried after a specific delay.
166
+ * Use this for rate limiting or when you know when a resource will become available.
167
+ *
168
+ * @since 0.1.0
169
+ * @category errors
170
+ */
171
+ export { RetryAfterError } from "./internal/errors.js";
@@ -0,0 +1,11 @@
1
+ export const OtelAttributes = {
2
+ RunId: "inngest.run_id",
3
+ FunctionId: "inngest.function_id",
4
+ AppId: "inngest.app_id",
5
+ Attempt: "inngest.attempt",
6
+ StepId: "inngest.step.id",
7
+ StepType: "inngest.step.type",
8
+ ExceptionType: "exception.type",
9
+ ExceptionMessage: "exception.message",
10
+ ExceptionStacktrace: "exception.stacktrace",
11
+ } as const;