effect-inngest 0.1.3 → 0.2.0-beta.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 (47) hide show
  1. package/dist/Client.d.ts +55 -24
  2. package/dist/Client.js +84 -25
  3. package/dist/Events.d.ts +36 -61
  4. package/dist/Events.js +5 -13
  5. package/dist/Function.d.ts +35 -15
  6. package/dist/Function.js +14 -8
  7. package/dist/Group.d.ts +5 -4
  8. package/dist/Group.js +26 -24
  9. package/dist/HttpApi.d.ts +49 -54
  10. package/dist/HttpApi.js +32 -17
  11. package/dist/_virtual/_rolldown/runtime.js +13 -0
  12. package/dist/index.js +1 -2
  13. package/dist/internal/checkpoint.d.ts +32 -0
  14. package/dist/internal/checkpoint.js +112 -0
  15. package/dist/internal/constants.js +1 -2
  16. package/dist/internal/driver.d.ts +1 -5
  17. package/dist/internal/driver.js +164 -52
  18. package/dist/internal/errors.d.ts +20 -27
  19. package/dist/internal/errors.js +29 -15
  20. package/dist/internal/handler.d.ts +4 -13
  21. package/dist/internal/handler.js +70 -43
  22. package/dist/internal/helpers.js +12 -9
  23. package/dist/internal/interrupts.d.ts +1 -2
  24. package/dist/internal/interrupts.js +1 -3
  25. package/dist/internal/memo.js +22 -20
  26. package/dist/internal/protocol.d.ts +28 -1
  27. package/dist/internal/protocol.js +84 -52
  28. package/dist/internal/signature.d.ts +5 -9
  29. package/dist/internal/signature.js +34 -18
  30. package/dist/internal/step.d.ts +5 -11
  31. package/dist/internal/step.js +48 -32
  32. package/package.json +26 -21
  33. package/src/Client.ts +244 -68
  34. package/src/Events.ts +3 -3
  35. package/src/Function.ts +52 -15
  36. package/src/Group.ts +39 -26
  37. package/src/HttpApi.ts +38 -27
  38. package/src/internal/checkpoint.ts +218 -0
  39. package/src/internal/driver.ts +241 -93
  40. package/src/internal/errors.ts +21 -14
  41. package/src/internal/handler.ts +185 -142
  42. package/src/internal/helpers.ts +9 -9
  43. package/src/internal/memo.ts +48 -33
  44. package/src/internal/protocol.ts +89 -45
  45. package/src/internal/signature.ts +76 -58
  46. package/src/internal/step.ts +84 -31
  47. package/dist/_virtual/rolldown_runtime.js +0 -18
package/dist/Function.js CHANGED
@@ -1,7 +1,8 @@
1
- import { __exportAll } from "./_virtual/rolldown_runtime.js";
1
+ import { __exportAll } from "./_virtual/_rolldown/runtime.js";
2
2
  import { timeStr } from "./internal/helpers.js";
3
- import { Array, Duration, Predicate, Schema } from "effect";
4
-
3
+ import { resolveConfig, toRegistration } from "./internal/checkpoint.js";
4
+ import { Array, Predicate } from "effect";
5
+ import { pipeArguments } from "effect/Pipeable";
5
6
  //#region src/Function.ts
6
7
  /**
7
8
  * @since 0.1.0
@@ -18,10 +19,13 @@ const TypeId = Symbol.for("effect-inngest/Function");
18
19
  const isEventTrigger = (t) => Predicate.hasProperty(t, "event");
19
20
  const Proto = {
20
21
  [TypeId]: TypeId,
22
+ pipe() {
23
+ return pipeArguments(this, arguments);
24
+ },
21
25
  toRegistration(config) {
22
26
  const triggers = [];
23
27
  for (const t of this.triggers) if (isEventTrigger(t)) triggers.push({
24
- event: t.event._tag,
28
+ event: t.event.identifier,
25
29
  expression: t.if
26
30
  });
27
31
  else triggers.push({ cron: t.cron });
@@ -51,7 +55,7 @@ const Proto = {
51
55
  period: timeStr(opts.debounce.period),
52
56
  timeout: opts.debounce.timeout ? timeStr(opts.debounce.timeout) : void 0
53
57
  } : void 0;
54
- const concurrency = opts.concurrency != null ? typeof opts.concurrency === "number" ? [{ limit: opts.concurrency }] : Array.ensure(opts.concurrency).map((c) => ({
58
+ const concurrency = opts.concurrency != null ? Predicate.isNumber(opts.concurrency) ? [{ limit: opts.concurrency }] : Array.ensure(opts.concurrency).map((c) => ({
55
59
  key: c.key,
56
60
  limit: c.limit,
57
61
  scope: c.scope
@@ -67,6 +71,8 @@ const Proto = {
67
71
  key: opts.batchEvents.key
68
72
  } : void 0;
69
73
  const idempotency = opts.idempotency;
74
+ const resolvedCheckpoint = opts.checkpointing !== void 0 ? resolveConfig(opts.checkpointing, void 0) : void 0;
75
+ const checkpoint = resolvedCheckpoint ? toRegistration(resolvedCheckpoint) : void 0;
70
76
  const fnId = `${config.appId}-${this._tag}`;
71
77
  const stepUrl = new URL(config.url);
72
78
  stepUrl.searchParams.set("fnId", fnId);
@@ -93,7 +99,8 @@ const Proto = {
93
99
  priority,
94
100
  singleton,
95
101
  batchEvents,
96
- idempotency
102
+ idempotency,
103
+ checkpoint
97
104
  };
98
105
  }
99
106
  };
@@ -139,6 +146,5 @@ function make(tag, options) {
139
146
  fn.options = options;
140
147
  return fn;
141
148
  }
142
-
143
149
  //#endregion
144
- export { Function_exports, TypeId, make };
150
+ export { Function_exports, TypeId, make };
package/dist/Group.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import { InngestClient } from "./Client.js";
2
2
  import { InngestFunction } from "./Function.js";
3
3
  import { HandlerContext } from "./internal/step.js";
4
- import * as HttpApp from "@effect/platform/HttpApp";
5
- import * as HttpClient from "@effect/platform/HttpClient";
6
- import * as Context from "effect/Context";
7
4
  import * as Effect from "effect/Effect";
5
+ import * as HttpClient from "effect/unstable/http/HttpClient";
6
+ import * as HttpServerRequest from "effect/unstable/http/HttpServerRequest";
7
+ import * as HttpServerResponse from "effect/unstable/http/HttpServerResponse";
8
+ import * as Context from "effect/Context";
8
9
  import * as Layer from "effect/Layer";
9
10
 
10
11
  //#region src/Group.d.ts
@@ -116,7 +117,7 @@ declare const make: <Fns extends ReadonlyArray<InngestFunction.Any>>(...fns: Fns
116
117
  * )
117
118
  * ```
118
119
  */
119
- declare const toHttpApp: (group: InngestGroup.Any) => HttpApp.Default<never, InngestClient | HttpClient.HttpClient>;
120
+ declare const toHttpApp: (group: InngestGroup.Any) => Effect.Effect<HttpServerResponse.HttpServerResponse, never, InngestClient | HttpClient.HttpClient | HttpServerRequest.HttpServerRequest>;
120
121
  /**
121
122
  * Create a standalone web handler from an InngestGroup.
122
123
  *
package/dist/Group.js CHANGED
@@ -1,22 +1,19 @@
1
- import { __exportAll } from "./_virtual/rolldown_runtime.js";
1
+ import { __exportAll } from "./_virtual/_rolldown/runtime.js";
2
2
  import { Headers } from "./internal/protocol.js";
3
3
  import { SignatureLive } from "./internal/signature.js";
4
+ import "./internal/step.js";
4
5
  import { handleExecution, handleIntrospection, handleRegistration, verifyAndParseRequestBody } from "./internal/handler.js";
5
- import * as HttpApp from "@effect/platform/HttpApp";
6
- import "@effect/platform/HttpClient";
7
- import * as HttpServerRequest from "@effect/platform/HttpServerRequest";
8
- import * as HttpServerResponse from "@effect/platform/HttpServerResponse";
9
- import * as UrlParams from "@effect/platform/UrlParams";
10
- import * as Context from "effect/Context";
11
6
  import * as Effect from "effect/Effect";
12
- import * as Layer from "effect/Layer";
13
7
  import * as Option from "effect/Option";
14
8
  import * as Schema from "effect/Schema";
15
-
9
+ import "effect/unstable/http/HttpClient";
10
+ import * as HttpEffect from "effect/unstable/http/HttpEffect";
11
+ import * as HttpServerRequest from "effect/unstable/http/HttpServerRequest";
12
+ import * as HttpServerResponse from "effect/unstable/http/HttpServerResponse";
13
+ import * as UrlParams from "effect/unstable/http/UrlParams";
14
+ import * as Context from "effect/Context";
15
+ import * as Layer from "effect/Layer";
16
16
  //#region src/Group.ts
17
- /**
18
- * @since 0.1.0
19
- */
20
17
  var Group_exports = /* @__PURE__ */ __exportAll({
21
18
  TypeId: () => TypeId,
22
19
  make: () => make,
@@ -42,7 +39,7 @@ const Proto = {
42
39
  context
43
40
  });
44
41
  }
45
- return Context.unsafeMake(contextMap);
42
+ return Context.makeUnsafe(contextMap);
46
43
  }));
47
44
  },
48
45
  toLayerHandler(tag, handler) {
@@ -54,7 +51,7 @@ const Proto = {
54
51
  handler,
55
52
  context
56
53
  });
57
- return Context.unsafeMake(contextMap);
54
+ return Context.makeUnsafe(contextMap);
58
55
  }));
59
56
  }
60
57
  };
@@ -88,7 +85,7 @@ const make = (...fns) => {
88
85
  * )
89
86
  * ```
90
87
  */
91
- const toHttpApp = (group) => Effect.gen(function* () {
88
+ const toHttpApp = Effect.fn("InngestGroup.toHttpApp")(function* (group) {
92
89
  const request = yield* HttpServerRequest.HttpServerRequest;
93
90
  const method = request.method;
94
91
  const requestUrl = Option.match(HttpServerRequest.toURL(request), {
@@ -110,16 +107,22 @@ const toHttpApp = (group) => Effect.gen(function* () {
110
107
  });
111
108
  }
112
109
  if (method === "POST") {
113
- const url = Option.getOrThrow(HttpServerRequest.toURL(request));
114
- const ExecuteParams = Schema.Struct({
110
+ const url = yield* Option.match(HttpServerRequest.toURL(request), {
111
+ onNone: () => Effect.fail(HttpServerResponse.jsonUnsafe({ error: "Unable to parse request URL" }, {
112
+ status: 400,
113
+ headers: { [Headers.NoRetry]: "true" }
114
+ })),
115
+ onSome: (u) => Effect.succeed(u)
116
+ });
117
+ const ExecuteParamsSchema = UrlParams.schemaRecord.pipe(Schema.decodeTo(Schema.Struct({
115
118
  fnId: Schema.String,
116
119
  stepId: Schema.optional(Schema.String)
117
- });
118
- const params = yield* UrlParams.schemaStruct(ExecuteParams)(UrlParams.fromInput(url.searchParams)).pipe(Effect.catchAll(() => Effect.fail(HttpServerResponse.unsafeJson({ error: "Missing or invalid fnId query parameter" }, {
120
+ })));
121
+ const params = yield* Schema.decodeUnknownEffect(ExecuteParamsSchema)(UrlParams.fromInput(url.searchParams)).pipe(Effect.catch(() => Effect.fail(HttpServerResponse.jsonUnsafe({ error: "Missing or invalid fnId query parameter" }, {
119
122
  status: 400,
120
123
  headers: { [Headers.NoRetry]: "true" }
121
124
  }))));
122
- const body = yield* verifyAndParseRequestBody(request).pipe(Effect.provide(SignatureLive), Effect.catchAll((error) => Effect.fail(HttpServerResponse.unsafeJson({ error: error.message }, {
125
+ const body = yield* verifyAndParseRequestBody(request).pipe(Effect.provide(SignatureLive), Effect.catch((error) => Effect.fail(HttpServerResponse.jsonUnsafe({ error: error.message }, {
123
126
  status: error._tag === "SignatureError" ? 401 : 400,
124
127
  headers: { [Headers.NoRetry]: "true" }
125
128
  }))));
@@ -130,7 +133,7 @@ const toHttpApp = (group) => Effect.gen(function* () {
130
133
  });
131
134
  }
132
135
  return yield* HttpServerResponse.json({ error: `Method ${method} not allowed` }, { status: 405 });
133
- }).pipe(Effect.catchAllCause((cause) => HttpServerResponse.json({
136
+ }, Effect.catchCause((cause) => HttpServerResponse.json({
134
137
  error: "Internal server error",
135
138
  cause: String(cause)
136
139
  }, { status: 500 }).pipe(Effect.orDie)));
@@ -158,7 +161,6 @@ const toHttpApp = (group) => Effect.gen(function* () {
158
161
  * process.on("SIGTERM", dispose)
159
162
  * ```
160
163
  */
161
- const toWebHandler = (group, options) => HttpApp.toWebHandlerLayer(toHttpApp(group), Layer.mergeAll(options.layer, Layer.scope));
162
-
164
+ const toWebHandler = (group, options) => HttpEffect.toWebHandlerLayer(toHttpApp(group), options.layer);
163
165
  //#endregion
164
- export { Group_exports, TypeId, make, toHttpApp, toWebHandler };
166
+ export { Group_exports, TypeId, make, toHttpApp, toWebHandler };
package/dist/HttpApi.d.ts CHANGED
@@ -2,74 +2,69 @@ import { InngestClient } from "./Client.js";
2
2
  import { InngestGroup } from "./Group.js";
3
3
  import { SignatureError } from "./internal/signature.js";
4
4
  import { InvalidRequestError } from "./internal/handler.js";
5
- import * as HttpClient from "@effect/platform/HttpClient";
6
- import * as Layer from "effect/Layer";
7
5
  import * as Schema from "effect/Schema";
8
- import * as HttpApi from "@effect/platform/HttpApi";
9
- import * as HttpApiEndpoint from "@effect/platform/HttpApiEndpoint";
10
- import * as HttpApiGroup from "@effect/platform/HttpApiGroup";
6
+ import * as HttpClient from "effect/unstable/http/HttpClient";
7
+ import * as Layer from "effect/Layer";
8
+ import * as _$effect_Cause0 from "effect/Cause";
9
+ import * as HttpApi from "effect/unstable/httpapi/HttpApi";
10
+ import * as HttpApiEndpoint from "effect/unstable/httpapi/HttpApiEndpoint";
11
+ import * as HttpApiGroup from "effect/unstable/httpapi/HttpApiGroup";
11
12
 
12
13
  //#region src/HttpApi.d.ts
13
14
  declare namespace HttpApi_d_exports {
14
15
  export { InngestApiGroup, layerGroup };
15
16
  }
16
- declare const FunctionNotFoundError_base: Schema.TaggedErrorClass<FunctionNotFoundError, "FunctionNotFoundError", {
17
- readonly _tag: Schema.tag<"FunctionNotFoundError">;
18
- } & {
19
- message: typeof Schema.String;
20
- }>;
17
+ declare const FunctionNotFoundError_base: Schema.Class<FunctionNotFoundError, Schema.TaggedStruct<"FunctionNotFoundError", {
18
+ readonly message: Schema.String;
19
+ }>, _$effect_Cause0.YieldableError>;
21
20
  declare class FunctionNotFoundError extends FunctionNotFoundError_base {}
21
+ declare const InngestApiGroup_base: HttpApiGroup.HttpApiGroup<"inngest", HttpApiEndpoint.HttpApiEndpoint<"introspect", "GET", "/", HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<Schema.Union<readonly [Schema.Struct<{
22
+ readonly function_count: Schema.Number;
23
+ readonly has_event_key: Schema.Boolean;
24
+ readonly has_signing_key: Schema.Boolean;
25
+ readonly has_signing_key_fallback: Schema.Boolean;
26
+ readonly mode: Schema.Literals<readonly ["cloud", "dev"]>;
27
+ readonly schema_version: Schema.Literal<"2024-05-24">;
28
+ readonly extra: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
29
+ readonly authentication_succeeded: Schema.Literal<true>;
30
+ readonly api_origin: Schema.String;
31
+ readonly app_id: Schema.String;
32
+ readonly env: Schema.NullOr<Schema.String>;
33
+ readonly event_api_origin: Schema.String;
34
+ readonly event_key_hash: Schema.NullOr<Schema.String>;
35
+ readonly framework: Schema.String;
36
+ readonly sdk_language: Schema.String;
37
+ readonly sdk_version: Schema.String;
38
+ readonly serve_origin: Schema.NullOr<Schema.String>;
39
+ readonly serve_path: Schema.NullOr<Schema.String>;
40
+ readonly signing_key_fallback_hash: Schema.NullOr<Schema.String>;
41
+ readonly signing_key_hash: Schema.NullOr<Schema.String>;
42
+ }>, Schema.Struct<{
43
+ readonly function_count: Schema.Number;
44
+ readonly has_event_key: Schema.Boolean;
45
+ readonly has_signing_key: Schema.Boolean;
46
+ readonly has_signing_key_fallback: Schema.Boolean;
47
+ readonly mode: Schema.Literals<readonly ["cloud", "dev"]>;
48
+ readonly schema_version: Schema.Literal<"2024-05-24">;
49
+ readonly extra: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
50
+ readonly authentication_succeeded: Schema.Union<readonly [Schema.Literal<false>, Schema.Null]>;
51
+ readonly functions: Schema.optionalKey<Schema.$Array<Schema.Unknown>>;
52
+ }>]>>, HttpApiEndpoint.Json<typeof FunctionNotFoundError | typeof InvalidRequestError | typeof SignatureError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"register", "PUT", "/", HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<Schema.Struct<{
53
+ readonly message: Schema.String;
54
+ readonly modified: Schema.Boolean;
55
+ }>>, HttpApiEndpoint.Json<typeof FunctionNotFoundError | typeof InvalidRequestError | typeof SignatureError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"execute", "POST", "/", HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<Schema.Struct<{
56
+ readonly fnId: Schema.String;
57
+ readonly stepId: Schema.optional<Schema.String>;
58
+ }>>, HttpApiEndpoint.Json<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<Schema.Unknown>, HttpApiEndpoint.Json<typeof FunctionNotFoundError | typeof InvalidRequestError | typeof SignatureError>, never, never>, false>;
22
59
  /**
23
60
  * @since 0.1.0
24
61
  * @category api
25
62
  */
26
- declare const InngestApiGroup: HttpApiGroup.HttpApiGroup<"inngest", HttpApiEndpoint.HttpApiEndpoint<"introspect", "GET", never, never, never, never, ({
27
- readonly function_count: number;
28
- readonly has_event_key: boolean;
29
- readonly has_signing_key: boolean;
30
- readonly has_signing_key_fallback: boolean;
31
- readonly mode: "cloud" | "dev";
32
- readonly schema_version: "2024-05-24";
33
- readonly extra?: {
34
- readonly [x: string]: unknown;
35
- } | undefined;
36
- } & {
37
- readonly authentication_succeeded: true;
38
- readonly api_origin: string;
39
- readonly app_id: string;
40
- readonly env: string | null;
41
- readonly event_api_origin: string;
42
- readonly event_key_hash: string | null;
43
- readonly framework: string;
44
- readonly sdk_language: string;
45
- readonly sdk_version: string;
46
- readonly serve_origin: string | null;
47
- readonly serve_path: string | null;
48
- readonly signing_key_fallback_hash: string | null;
49
- readonly signing_key_hash: string | null;
50
- }) | ({
51
- readonly function_count: number;
52
- readonly has_event_key: boolean;
53
- readonly has_signing_key: boolean;
54
- readonly has_signing_key_fallback: boolean;
55
- readonly mode: "cloud" | "dev";
56
- readonly schema_version: "2024-05-24";
57
- readonly extra?: {
58
- readonly [x: string]: unknown;
59
- } | undefined;
60
- } & {
61
- readonly authentication_succeeded: false | null;
62
- readonly functions?: readonly unknown[] | undefined;
63
- }), never, never, never> | HttpApiEndpoint.HttpApiEndpoint<"register", "PUT", never, never, never, never, {
64
- readonly message?: string | undefined;
65
- }, never, never, never> | HttpApiEndpoint.HttpApiEndpoint<"execute", "POST", never, {
66
- readonly fnId: string;
67
- readonly stepId?: string | undefined;
68
- }, never, never, unknown, never, never, never>, FunctionNotFoundError | InvalidRequestError | SignatureError, never, false>;
63
+ declare class InngestApiGroup extends InngestApiGroup_base {}
69
64
  /**
70
65
  * @since 0.1.0
71
66
  * @category layers
72
67
  */
73
- declare const layerGroup: <ApiId extends string, Groups extends HttpApiGroup.HttpApiGroup.Any, ApiError, ApiR>(api: HttpApi.HttpApi<ApiId, Groups, ApiError, ApiR>, group: InngestGroup.Any) => Layer.Layer<HttpApiGroup.ApiGroup<ApiId, "inngest">, never, InngestClient | HttpClient.HttpClient>;
68
+ declare const layerGroup: <ApiId extends string, Groups extends HttpApiGroup.Any>(api: HttpApi.HttpApi<ApiId, Groups>, group: InngestGroup.Any) => Layer.Layer<HttpApiGroup.ApiGroup<ApiId, "inngest">, never, InngestClient | HttpClient.HttpClient>;
74
69
  //#endregion
75
70
  export { HttpApi_d_exports, InngestApiGroup, layerGroup };
package/dist/HttpApi.js CHANGED
@@ -1,18 +1,17 @@
1
- import { __exportAll } from "./_virtual/rolldown_runtime.js";
1
+ import { __exportAll } from "./_virtual/_rolldown/runtime.js";
2
2
  import { IntrospectionResponse, RegisterResponse } from "./internal/protocol.js";
3
3
  import { SignatureError, SignatureLive } from "./internal/signature.js";
4
4
  import { InvalidRequestError, handleExecution, handleIntrospection, handleRegistration, verifyAndParseRequestBody } from "./internal/handler.js";
5
- import "@effect/platform/HttpClient";
6
- import * as HttpServerRequest from "@effect/platform/HttpServerRequest";
7
5
  import * as Effect from "effect/Effect";
8
- import "effect/Layer";
9
6
  import * as Option from "effect/Option";
10
7
  import * as Schema from "effect/Schema";
11
- import "@effect/platform/HttpApi";
12
- import * as HttpApiBuilder from "@effect/platform/HttpApiBuilder";
13
- import * as HttpApiEndpoint from "@effect/platform/HttpApiEndpoint";
14
- import * as HttpApiGroup from "@effect/platform/HttpApiGroup";
15
-
8
+ import "effect/unstable/http/HttpClient";
9
+ import * as HttpServerRequest from "effect/unstable/http/HttpServerRequest";
10
+ import * as Layer from "effect/Layer";
11
+ import "effect/unstable/httpapi/HttpApi";
12
+ import * as HttpApiBuilder from "effect/unstable/httpapi/HttpApiBuilder";
13
+ import * as HttpApiEndpoint from "effect/unstable/httpapi/HttpApiEndpoint";
14
+ import * as HttpApiGroup from "effect/unstable/httpapi/HttpApiGroup";
16
15
  //#region src/HttpApi.ts
17
16
  var HttpApi_exports = /* @__PURE__ */ __exportAll({
18
17
  InngestApiGroup: () => InngestApiGroup,
@@ -22,15 +21,30 @@ const ExecuteParams = Schema.Struct({
22
21
  fnId: Schema.String,
23
22
  stepId: Schema.optional(Schema.String)
24
23
  });
25
- var FunctionNotFoundError = class extends Schema.TaggedError()("FunctionNotFoundError", { message: Schema.String }) {};
26
- const IntrospectEndpoint = HttpApiEndpoint.get("introspect", "/").addSuccess(IntrospectionResponse);
27
- const RegisterEndpoint = HttpApiEndpoint.put("register", "/").addSuccess(RegisterResponse);
28
- const ExecuteEndpoint = HttpApiEndpoint.post("execute", "/").setUrlParams(ExecuteParams).addSuccess(Schema.Unknown);
24
+ var FunctionNotFoundError = class extends Schema.TaggedErrorClass()("FunctionNotFoundError", { message: Schema.String }) {};
25
+ const CommonErrors = [
26
+ FunctionNotFoundError,
27
+ InvalidRequestError,
28
+ SignatureError
29
+ ];
30
+ const IntrospectEndpoint = HttpApiEndpoint.get("introspect", "/", {
31
+ success: IntrospectionResponse,
32
+ error: CommonErrors
33
+ });
34
+ const RegisterEndpoint = HttpApiEndpoint.put("register", "/", {
35
+ success: RegisterResponse,
36
+ error: CommonErrors
37
+ });
38
+ const ExecuteEndpoint = HttpApiEndpoint.post("execute", "/", {
39
+ query: ExecuteParams,
40
+ success: Schema.Unknown,
41
+ error: CommonErrors
42
+ });
29
43
  /**
30
44
  * @since 0.1.0
31
45
  * @category api
32
46
  */
33
- const InngestApiGroup = HttpApiGroup.make("inngest").add(IntrospectEndpoint).add(RegisterEndpoint).add(ExecuteEndpoint).addError(FunctionNotFoundError, { status: 404 }).addError(InvalidRequestError, { status: 400 }).addError(SignatureError, { status: 401 });
47
+ var InngestApiGroup = class extends HttpApiGroup.make("inngest").add(IntrospectEndpoint).add(RegisterEndpoint).add(ExecuteEndpoint) {};
34
48
  /**
35
49
  * @since 0.1.0
36
50
  * @category layers
@@ -40,8 +54,9 @@ const layerGroup = (api, group) => {
40
54
  onNone: () => req.url,
41
55
  onSome: (url) => url.toString()
42
56
  });
43
- return HttpApiBuilder.group(api, "inngest", (handlers) => handlers.handle("introspect", ({ request }) => handleIntrospection(group, toUrl(request)).pipe(Effect.map((r) => r.body))).handle("register", ({ request }) => handleRegistration(group, toUrl(request)).pipe(Effect.map((r) => r.body))).handleRaw("execute", ({ urlParams, request }) => verifyAndParseRequestBody(request).pipe(Effect.provide(SignatureLive), Effect.flatMap((payload) => handleExecution(group, urlParams.fnId, urlParams.stepId, payload)), Effect.map((r) => r.body))));
57
+ return HttpApiBuilder.group(api, "inngest", Effect.fn(function* (handlers) {
58
+ return handlers.handle("introspect", ({ request }) => handleIntrospection(group, toUrl(request)).pipe(Effect.map((r) => r.body))).handle("register", ({ request }) => handleRegistration(group, toUrl(request)).pipe(Effect.map((r) => r.body))).handleRaw("execute", ({ query, request }) => verifyAndParseRequestBody(request).pipe(Effect.flatMap((payload) => handleExecution(group, query.fnId, query.stepId, payload)), Effect.map((r) => r.body)));
59
+ })).pipe(Layer.provide(SignatureLive));
44
60
  };
45
-
46
61
  //#endregion
47
- export { HttpApi_exports, InngestApiGroup, layerGroup };
62
+ export { HttpApi_exports, InngestApiGroup, layerGroup };
@@ -0,0 +1,13 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __defProp = Object.defineProperty;
3
+ var __exportAll = (all, no_symbols) => {
4
+ let target = {};
5
+ for (var name in all) __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true
8
+ });
9
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
10
+ return target;
11
+ };
12
+ //#endregion
13
+ export { __exportAll };
package/dist/index.js CHANGED
@@ -4,5 +4,4 @@ import { NonRetriableError, RetryAfterError } from "./internal/errors.js";
4
4
  import { Group_exports } from "./Group.js";
5
5
  import { HttpApi_exports } from "./HttpApi.js";
6
6
  import { Events_exports } from "./Events.js";
7
-
8
- export { Client_exports as InngestClient, Events_exports as InngestEvents, Function_exports as InngestFunction, Group_exports as InngestGroup, HttpApi_exports as InngestHttpApi, NonRetriableError, RetryAfterError };
7
+ export { Client_exports as InngestClient, Events_exports as InngestEvents, Function_exports as InngestFunction, Group_exports as InngestGroup, HttpApi_exports as InngestHttpApi, NonRetriableError, RetryAfterError };
@@ -0,0 +1,32 @@
1
+ import * as Duration from "effect/Duration";
2
+ import * as Schema from "effect/Schema";
3
+ import * as _$effect_Cause0 from "effect/Cause";
4
+
5
+ //#region src/internal/checkpoint.d.ts
6
+ declare const CheckpointApiError_base: Schema.Class<CheckpointApiError, Schema.TaggedStruct<"CheckpointApiError", {
7
+ readonly message: Schema.String;
8
+ readonly status: Schema.optionalKey<Schema.Number>;
9
+ }>, _$effect_Cause0.YieldableError>;
10
+ /**
11
+ * Tagged error returned by `InngestClient.checkpointAsync` when the API call
12
+ * fails (network error or non-2xx after retries). The driver and step tools
13
+ * treat this as a graceful-fallback signal — buffered steps are restored to
14
+ * the buffer so they get included in the final 206 response.
15
+ */
16
+ declare class CheckpointApiError extends CheckpointApiError_base {}
17
+ /**
18
+ * User-facing checkpointing option, accepted on `ClientConfig.checkpointing`
19
+ * and `FunctionOptions.checkpointing`.
20
+ *
21
+ * - `false` disables checkpointing entirely (no API calls; classic 206-per-step).
22
+ * - `true` enables checkpointing with the safe defaults
23
+ * (`bufferedSteps: 1`, `maxInterval: 0`, `maxRuntime: 10 seconds`).
24
+ * - An object lets you tune `bufferedSteps`, `maxInterval`, `maxRuntime`.
25
+ */
26
+ type CheckpointingOption = boolean | {
27
+ readonly bufferedSteps?: number;
28
+ readonly maxInterval?: Duration.Input;
29
+ readonly maxRuntime?: Duration.Input;
30
+ };
31
+ //#endregion
32
+ export { CheckpointApiError, CheckpointingOption };
@@ -0,0 +1,112 @@
1
+ import { timeStr } from "./helpers.js";
2
+ import * as Clock from "effect/Clock";
3
+ import * as Duration from "effect/Duration";
4
+ import * as Effect from "effect/Effect";
5
+ import * as Option from "effect/Option";
6
+ import * as Ref from "effect/Ref";
7
+ import * as Result from "effect/Result";
8
+ import * as Schema from "effect/Schema";
9
+ //#region src/internal/checkpoint.ts
10
+ /**
11
+ * Checkpoint configuration + per-execution state for spec §10 async
12
+ * checkpointing.
13
+ *
14
+ * Sync checkpointing (§10.3.2 / §10.4.2) is intentionally out of scope —
15
+ * it requires a durable endpoint primitive the SDK does not yet expose.
16
+ *
17
+ * @internal
18
+ */
19
+ /**
20
+ * Tagged error returned by `InngestClient.checkpointAsync` when the API call
21
+ * fails (network error or non-2xx after retries). The driver and step tools
22
+ * treat this as a graceful-fallback signal — buffered steps are restored to
23
+ * the buffer so they get included in the final 206 response.
24
+ */
25
+ var CheckpointApiError = class extends Schema.TaggedErrorClass()("CheckpointApiError", {
26
+ message: Schema.String,
27
+ status: Schema.optionalKey(Schema.Number)
28
+ }) {};
29
+ const DEFAULTS = {
30
+ bufferedSteps: 1,
31
+ maxInterval: Duration.millis(0),
32
+ maxRuntime: Duration.seconds(10)
33
+ };
34
+ const normalize = (option) => ({
35
+ bufferedSteps: option.bufferedSteps ?? DEFAULTS.bufferedSteps,
36
+ maxInterval: option.maxInterval !== void 0 ? Duration.fromInputUnsafe(option.maxInterval) : DEFAULTS.maxInterval,
37
+ maxRuntime: option.maxRuntime !== void 0 ? Duration.fromInputUnsafe(option.maxRuntime) : DEFAULTS.maxRuntime
38
+ });
39
+ /**
40
+ * Resolve final config from function-level + client-level settings.
41
+ *
42
+ * Precedence: function-level explicit > client-level explicit > built-in
43
+ * defaults (default-ON, matching the TS reference SDK).
44
+ *
45
+ * Returns `undefined` if either level explicitly disables checkpointing.
46
+ */
47
+ const resolveConfig = (fnLevel, clientLevel) => {
48
+ if (fnLevel === false) return void 0;
49
+ if (fnLevel === true) return DEFAULTS;
50
+ if (fnLevel !== void 0) return normalize(fnLevel);
51
+ if (clientLevel === false) return void 0;
52
+ if (clientLevel === true) return DEFAULTS;
53
+ if (clientLevel !== void 0) return normalize(clientLevel);
54
+ return DEFAULTS;
55
+ };
56
+ const toRegistration = (cfg) => ({
57
+ batch_steps: cfg.bufferedSteps,
58
+ batch_interval: timeStr(cfg.maxInterval),
59
+ max_runtime: timeStr(cfg.maxRuntime)
60
+ });
61
+ /**
62
+ * Construct a `CheckpointState`. Caller supplies a pre-bound `checkpointAsync`
63
+ * callback (typically `(steps) => client.checkpointAsync({runId, fnId, qiId, steps})`),
64
+ * so this module has no dependency on `InngestClient`.
65
+ */
66
+ const make = (args) => Effect.sync(() => {
67
+ const buffer = Ref.makeUnsafe([]);
68
+ const intervalStartedAt = Ref.makeUnsafe(Option.none());
69
+ const runtimeExceeded = Ref.makeUnsafe(false);
70
+ const maxIntervalMs = Duration.toMillis(args.config.maxInterval);
71
+ const flushInner = Effect.gen(function* () {
72
+ const steps = yield* Ref.modify(buffer, (current) => [current, []]);
73
+ if (steps.length === 0) return;
74
+ const result = yield* Effect.result(args.checkpointAsync(steps));
75
+ if (Result.isFailure(result)) {
76
+ yield* Ref.update(buffer, (current) => [...steps, ...current]);
77
+ return;
78
+ }
79
+ yield* Ref.set(intervalStartedAt, Option.none());
80
+ });
81
+ const bufferStep = (op) => Effect.gen(function* () {
82
+ const len = yield* Ref.modify(buffer, (current) => {
83
+ const next = [...current, op];
84
+ return [next.length, next];
85
+ });
86
+ const now = yield* Clock.currentTimeMillis;
87
+ const start = yield* Ref.get(intervalStartedAt);
88
+ if (len >= args.config.bufferedSteps) {
89
+ yield* flushInner;
90
+ return;
91
+ }
92
+ if (Option.isSome(start) && maxIntervalMs > 0 && now - start.value >= maxIntervalMs) {
93
+ yield* flushInner;
94
+ return;
95
+ }
96
+ if (Option.isNone(start) && maxIntervalMs > 0) yield* Ref.set(intervalStartedAt, Option.some(now));
97
+ });
98
+ const drain = Ref.modify(buffer, (current) => [current, []]);
99
+ return {
100
+ config: args.config,
101
+ runId: args.runId,
102
+ fnId: args.fnId,
103
+ qiId: args.qiId,
104
+ bufferStep,
105
+ flush: flushInner,
106
+ drain,
107
+ markRuntimeExceeded: Ref.set(runtimeExceeded, true),
108
+ isRuntimeExceeded: Ref.get(runtimeExceeded)
109
+ };
110
+ });
111
+ //#endregion
112
+ export { CheckpointApiError, make, resolveConfig, toRegistration };
@@ -10,6 +10,5 @@ const OtelAttributes = {
10
10
  ExceptionMessage: "exception.message",
11
11
  ExceptionStacktrace: "exception.stacktrace"
12
12
  };
13
-
14
13
  //#endregion
15
- export { OtelAttributes };
14
+ export { OtelAttributes };
@@ -1,5 +1 @@
1
- import "../Client.js";
2
- import "../Function.js";
3
- import "./protocol.js";
4
- import "./step.js";
5
- import { Effect, Schema } from "effect";
1
+ export { };