effect-inngest 0.3.0-beta.3 → 0.4.0-beta1

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 (58) hide show
  1. package/README.md +69 -75
  2. package/dist/Client.js +1 -1
  3. package/dist/Cron.d.ts +17 -0
  4. package/dist/Cron.js +24 -0
  5. package/dist/Events.d.ts +1 -1
  6. package/dist/Events.js +1 -1
  7. package/dist/Function.d.ts +28 -26
  8. package/dist/Function.js +19 -11
  9. package/dist/Group.d.ts +7 -7
  10. package/dist/Group.js +1 -0
  11. package/dist/HttpApi.js +2 -1
  12. package/dist/Inngest.d.ts +60 -0
  13. package/dist/Inngest.js +61 -0
  14. package/dist/index.d.ts +3 -1
  15. package/dist/index.js +4 -2
  16. package/dist/internal/checkpoint/Abort.d.ts +1 -0
  17. package/dist/internal/checkpoint/Abort.js +5 -0
  18. package/dist/internal/checkpoint/State.d.ts +1 -1
  19. package/dist/internal/checkpoint/State.js +8 -1
  20. package/dist/internal/codec/StepResult.js +2 -12
  21. package/dist/internal/driver.js +1 -0
  22. package/dist/internal/errors.js +1 -1
  23. package/dist/internal/execution/ExecutionResponse.js +33 -4
  24. package/dist/internal/execution/HandlerRun.js +2 -1
  25. package/dist/internal/handler.js +37 -24
  26. package/dist/internal/protocol.js +3 -0
  27. package/dist/internal/runtime/HandlerContext.d.ts +0 -2
  28. package/dist/internal/runtime/HandlerContext.js +0 -3
  29. package/dist/internal/runtime/StepTools.d.ts +8 -16
  30. package/dist/internal/runtime/StepTools.js +2 -8
  31. package/dist/internal/runtime/steps/InvokeStep.js +1 -2
  32. package/dist/internal/runtime/steps/StepRun.js +25 -19
  33. package/dist/internal/serve/HttpApp.js +2 -1
  34. package/dist/internal/utils/safe-stringify.js +50 -0
  35. package/package.json +17 -1
  36. package/src/Client.ts +1 -1
  37. package/src/Cron.ts +33 -0
  38. package/src/Events.ts +1 -1
  39. package/src/Function.ts +58 -34
  40. package/src/Group.ts +10 -7
  41. package/src/HttpApi.ts +7 -1
  42. package/src/Inngest.ts +85 -0
  43. package/src/index.ts +21 -7
  44. package/src/internal/checkpoint/Abort.ts +5 -0
  45. package/src/internal/checkpoint/State.ts +8 -0
  46. package/src/internal/codec/StepResult.ts +1 -43
  47. package/src/internal/driver.ts +13 -2
  48. package/src/internal/errors.ts +1 -3
  49. package/src/internal/execution/ExecutionResponse.ts +44 -1
  50. package/src/internal/execution/HandlerRun.ts +3 -2
  51. package/src/internal/handler.ts +39 -34
  52. package/src/internal/protocol.ts +3 -0
  53. package/src/internal/runtime/HandlerContext.ts +2 -5
  54. package/src/internal/runtime/StepTools.ts +4 -31
  55. package/src/internal/runtime/steps/InvokeStep.ts +1 -4
  56. package/src/internal/runtime/steps/StepRun.ts +28 -44
  57. package/src/internal/serve/HttpApp.ts +1 -0
  58. package/src/internal/utils/safe-stringify.ts +84 -0
package/dist/Group.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { InngestClient } from "./Client.js";
2
2
  import { InngestFunction } from "./Function.js";
3
3
  import { HandlerContext } from "./internal/runtime/HandlerContext.js";
4
+ import { StepTools } from "./internal/runtime/StepTools.js";
4
5
  import { Context, Effect, Layer } from "effect";
5
6
  import * as HttpClient from "effect/unstable/http/HttpClient";
6
7
  import * as _$effect_unstable_http_HttpServerRequest0 from "effect/unstable/http/HttpServerRequest";
@@ -24,7 +25,7 @@ type TypeId = typeof TypeId;
24
25
  * @since 0.1.0
25
26
  * @category models
26
27
  */
27
- type HandlerFn<F extends InngestFunction.Any> = (context: HandlerContext<F>) => Effect.Effect<InngestFunction.Success<F>, unknown, unknown>;
28
+ type HandlerFn<F extends InngestFunction.Any> = (context: HandlerContext<F>) => Effect.Effect<unknown, unknown, unknown>;
28
29
  /**
29
30
  * @since 0.1.0
30
31
  * @category models
@@ -41,12 +42,13 @@ type HandlerFrom<Fns extends InngestFunction.Any, Tag extends InngestFunction.Ta
41
42
  * @since 0.1.0
42
43
  * @category models
43
44
  */
44
- type HandlersRequirements<H> = H extends Record<string, (...args: ReadonlyArray<unknown>) => Effect.Effect<unknown, unknown, infer R>> ? R : never;
45
+ type RuntimeRequirements = InngestClient | StepTools;
46
+ type HandlersRequirements<H> = H extends Record<string, (...args: ReadonlyArray<unknown>) => Effect.Effect<unknown, unknown, infer R>> ? Exclude<R, RuntimeRequirements> : never;
45
47
  /**
46
48
  * @since 0.1.0
47
49
  * @category models
48
50
  */
49
- type HandlerRequirements<Handler> = Handler extends ((...args: ReadonlyArray<unknown>) => Effect.Effect<unknown, unknown, infer R>) ? R : never;
51
+ type HandlerRequirements<Handler> = Handler extends ((...args: ReadonlyArray<unknown>) => Effect.Effect<unknown, unknown, infer R>) ? Exclude<R, RuntimeRequirements> : never;
50
52
  /**
51
53
  * A nominal type representing a registered handler for a specific function tag.
52
54
  * @since 0.1.0
@@ -63,7 +65,7 @@ interface Handler<Tag extends string> {
63
65
  * @since 0.1.0
64
66
  * @category models
65
67
  */
66
- type ToHandler<F extends InngestFunction.Any> = F extends InngestFunction<infer Tag, infer _Triggers, infer _Success> ? Handler<Tag> : never;
68
+ type ToHandler<F extends InngestFunction.Any> = F extends InngestFunction<infer Tag, infer _Triggers> ? Handler<Tag> : never;
67
69
  /**
68
70
  * @since 0.1.0
69
71
  * @category models
@@ -88,9 +90,7 @@ interface InngestGroup<Fns extends InngestFunction.Any> {
88
90
  */
89
91
  readonly accessHandler: <Tag extends InngestFunction.Tag<Fns>>(tag: Tag) => Effect.Effect<(context: HandlerContext<Extract<Fns, {
90
92
  readonly _tag: Tag;
91
- }>>) => Effect.Effect<InngestFunction.Success<Extract<Fns, {
92
- readonly _tag: Tag;
93
- }>>, unknown>, never, Handler<Tag>>;
93
+ }>>) => Effect.Effect<unknown, unknown>, never, Handler<Tag>>;
94
94
  }
95
95
  /**
96
96
  * @since 0.1.0
package/dist/Group.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { __exportAll } from "./_virtual/_rolldown/runtime.js";
2
+ import "./internal/runtime/StepTools.js";
2
3
  import "./internal/runtime/HandlerContext.js";
3
4
  import { toHttpApp as toHttpApp$1, toWebHandler as toWebHandler$1 } from "./internal/serve/HttpApp.js";
4
5
  import { Context, Effect, Layer } from "effect";
package/dist/HttpApi.js CHANGED
@@ -56,7 +56,8 @@ const layerGroup = (api, group) => {
56
56
  group,
57
57
  fnId: query.fnId,
58
58
  urlStepId: query.stepId,
59
- body: payload
59
+ body: payload,
60
+ headers: request.headers
60
61
  })), Effect.map((r) => r.body)));
61
62
  })).pipe(Layer.provide(SignatureLive));
62
63
  };
@@ -0,0 +1,60 @@
1
+ import { InngestClient } from "./Client.js";
2
+ import { EventType as EventType$1 } from "./Event.js";
3
+ import { InngestFunction } from "./Function.js";
4
+ import { EventSchema } from "./internal/codec/EventPayload.js";
5
+ import { SendEventError, StepError } from "./internal/errors.js";
6
+ import { StepInput } from "./internal/domain/StepInput.js";
7
+ import { InvokeOptions, OutgoingEvent, StepTools, WaitForEventOptions } from "./internal/runtime/StepTools.js";
8
+ import { Duration, Effect, Option } from "effect";
9
+
10
+ //#region src/Inngest.d.ts
11
+ declare namespace Inngest_d_exports {
12
+ export { EventType, invoke, run, sendEvent, sleep, sleepUntil, waitForEvent };
13
+ }
14
+ /**
15
+ * Execute an Effect as a durable, memoized step.
16
+ *
17
+ * @since 0.1.0
18
+ * @category steps
19
+ */
20
+ declare const run: <A, Err, R>(id: StepInput, effect: Effect.Effect<A, Err, R>) => Effect.Effect<A, StepError | Err, R | StepTools>;
21
+ /**
22
+ * Sleep durably for a duration.
23
+ *
24
+ * @since 0.1.0
25
+ * @category steps
26
+ */
27
+ declare const sleep: (id: StepInput, duration: Duration.Input) => Effect.Effect<void, never, StepTools>;
28
+ /**
29
+ * Sleep durably until a timestamp.
30
+ *
31
+ * @since 0.1.0
32
+ * @category steps
33
+ */
34
+ declare const sleepUntil: (id: StepInput, timestamp: Date | number | string) => Effect.Effect<void, never, StepTools>;
35
+ /**
36
+ * Wait for a matching event.
37
+ *
38
+ * @since 0.1.0
39
+ * @category steps
40
+ */
41
+ declare const waitForEvent: <E extends EventSchema>(id: StepInput, event: E, options: WaitForEventOptions) => Effect.Effect<Option.Option<EventType$1<E>>, StepError, StepTools>;
42
+ /**
43
+ * Invoke another Inngest function.
44
+ *
45
+ * @since 0.1.0
46
+ * @category steps
47
+ */
48
+ declare const invoke: <F extends InngestFunction.Any>(id: StepInput, options: InvokeOptions<F>) => Effect.Effect<unknown, StepError, StepTools>;
49
+ /**
50
+ * Send one or more Inngest events.
51
+ *
52
+ * @since 0.1.0
53
+ * @category steps
54
+ */
55
+ declare const sendEvent: (id: StepInput, payload: OutgoingEvent | ReadonlyArray<OutgoingEvent>) => Effect.Effect<{
56
+ readonly ids: ReadonlyArray<string>;
57
+ }, SendEventError, StepTools | InngestClient>;
58
+ type EventType<E extends EventSchema> = EventType$1<E>;
59
+ //#endregion
60
+ export { Inngest_d_exports };
@@ -0,0 +1,61 @@
1
+ import { __exportAll } from "./_virtual/_rolldown/runtime.js";
2
+ import { StepTools } from "./internal/runtime/StepTools.js";
3
+ import { Effect } from "effect";
4
+ //#region src/Inngest.ts
5
+ /**
6
+ * Durable workflow operations for Inngest handlers.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ var Inngest_exports = /* @__PURE__ */ __exportAll({
11
+ invoke: () => invoke,
12
+ run: () => run,
13
+ sendEvent: () => sendEvent,
14
+ sleep: () => sleep,
15
+ sleepUntil: () => sleepUntil,
16
+ waitForEvent: () => waitForEvent
17
+ });
18
+ /**
19
+ * Execute an Effect as a durable, memoized step.
20
+ *
21
+ * @since 0.1.0
22
+ * @category steps
23
+ */
24
+ const run = (id, effect) => Effect.flatMap(StepTools, (step) => step.run(id, effect));
25
+ /**
26
+ * Sleep durably for a duration.
27
+ *
28
+ * @since 0.1.0
29
+ * @category steps
30
+ */
31
+ const sleep = (id, duration) => Effect.flatMap(StepTools, (step) => step.sleep(id, duration));
32
+ /**
33
+ * Sleep durably until a timestamp.
34
+ *
35
+ * @since 0.1.0
36
+ * @category steps
37
+ */
38
+ const sleepUntil = (id, timestamp) => Effect.flatMap(StepTools, (step) => step.sleepUntil(id, timestamp));
39
+ /**
40
+ * Wait for a matching event.
41
+ *
42
+ * @since 0.1.0
43
+ * @category steps
44
+ */
45
+ const waitForEvent = (id, event, options) => Effect.flatMap(StepTools, (step) => step.waitForEvent(id, event, options));
46
+ /**
47
+ * Invoke another Inngest function.
48
+ *
49
+ * @since 0.1.0
50
+ * @category steps
51
+ */
52
+ const invoke = (id, options) => Effect.flatMap(StepTools, (step) => step.invoke(id, options));
53
+ /**
54
+ * Send one or more Inngest events.
55
+ *
56
+ * @since 0.1.0
57
+ * @category steps
58
+ */
59
+ const sendEvent = (id, payload) => Effect.flatMap(StepTools, (step) => step.sendEvent(id, payload));
60
+ //#endregion
61
+ export { Inngest_exports };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  import { Client_d_exports } from "./Client.js";
2
2
  import { Event_d_exports } from "./Event.js";
3
3
  import { Events_d_exports } from "./Events.js";
4
+ import { Cron_d_exports } from "./Cron.js";
4
5
  import { Function_d_exports } from "./Function.js";
5
6
  import { NonRetriableError, RetryAfterError } from "./internal/errors.js";
6
7
  import { Group_d_exports } from "./Group.js";
7
8
  import { HttpApi_d_exports } from "./HttpApi.js";
8
- export { Client_d_exports as InngestClient, Event_d_exports as InngestEvent, Events_d_exports as InngestEvents, Function_d_exports as InngestFunction, Group_d_exports as InngestGroup, HttpApi_d_exports as InngestHttpApi, NonRetriableError, RetryAfterError };
9
+ import { Inngest_d_exports } from "./Inngest.js";
10
+ export { Inngest_d_exports as Inngest, Client_d_exports as InngestClient, Cron_d_exports as InngestCron, Event_d_exports as InngestEvent, Events_d_exports as InngestEvents, Function_d_exports as InngestFunction, Group_d_exports as InngestGroup, HttpApi_d_exports as InngestHttpApi, NonRetriableError, RetryAfterError };
package/dist/index.js CHANGED
@@ -1,8 +1,10 @@
1
- import { Function_exports } from "./Function.js";
2
1
  import { Event_exports } from "./Event.js";
2
+ import { Cron_exports } from "./Cron.js";
3
+ import { Function_exports } from "./Function.js";
3
4
  import { Client_exports } from "./Client.js";
4
5
  import { NonRetriableError, RetryAfterError } from "./internal/errors.js";
5
6
  import { Events_exports } from "./Events.js";
6
7
  import { Group_exports } from "./Group.js";
8
+ import { Inngest_exports } from "./Inngest.js";
7
9
  import { HttpApi_exports } from "./HttpApi.js";
8
- export { Client_exports as InngestClient, Event_exports as InngestEvent, Events_exports as InngestEvents, Function_exports as InngestFunction, Group_exports as InngestGroup, HttpApi_exports as InngestHttpApi, NonRetriableError, RetryAfterError };
10
+ export { Inngest_exports as Inngest, Client_exports as InngestClient, Cron_exports as InngestCron, Event_exports as InngestEvent, Events_exports as InngestEvents, Function_exports as InngestFunction, Group_exports as InngestGroup, HttpApi_exports as InngestHttpApi, NonRetriableError, RetryAfterError };
@@ -0,0 +1 @@
1
+ import { Schema } from "effect";
@@ -0,0 +1,5 @@
1
+ import { Schema } from "effect";
2
+ //#region src/internal/checkpoint/Abort.ts
3
+ var StaleDispatch = class extends Schema.TaggedClass()("StaleDispatch", {}) {};
4
+ //#endregion
5
+ export { StaleDispatch };
@@ -1 +1 @@
1
- import { Effect } from "effect";
1
+ import { Effect, Option } from "effect";
@@ -1,3 +1,4 @@
1
+ import { StaleDispatch } from "./Abort.js";
1
2
  import { Array, Clock, Duration, Effect, Option, Ref, Result } from "effect";
2
3
  //#region src/internal/checkpoint/State.ts
3
4
  const make = (args) => Effect.sync(() => {
@@ -5,12 +6,17 @@ const make = (args) => Effect.sync(() => {
5
6
  const plannedBuffer = Ref.makeUnsafe(Array.empty());
6
7
  const intervalStartedAt = Ref.makeUnsafe(Option.none());
7
8
  const runtimeExceeded = Ref.makeUnsafe(false);
9
+ const abort = Ref.makeUnsafe(Option.none());
8
10
  const maxIntervalMs = Duration.toMillis(args.config.maxInterval);
9
11
  const flushInner = Effect.gen(function* () {
10
12
  const steps = yield* Ref.modify(buffer, (current) => [current, Array.empty()]);
11
13
  if (steps.length === 0) return;
12
14
  const result = yield* Effect.result(args.checkpointAsync(steps));
13
15
  if (Result.isFailure(result)) {
16
+ if (result.failure.status === 409) {
17
+ yield* Ref.set(abort, Option.some(StaleDispatch.make({})));
18
+ return yield* Effect.interrupt;
19
+ }
14
20
  yield* Ref.update(buffer, (current) => [...steps, ...current]);
15
21
  return;
16
22
  }
@@ -47,7 +53,8 @@ const make = (args) => Effect.sync(() => {
47
53
  flush: flushInner,
48
54
  takeCompleted,
49
55
  markRuntimeExceeded: Ref.set(runtimeExceeded, true),
50
- isRuntimeExceeded: Ref.get(runtimeExceeded)
56
+ isRuntimeExceeded: Ref.get(runtimeExceeded),
57
+ abort: Ref.get(abort)
51
58
  };
52
59
  });
53
60
  //#endregion
@@ -1,5 +1,5 @@
1
1
  import { StepError } from "../errors.js";
2
- import { Effect, Function, Option, Predicate, Schema } from "effect";
2
+ import { Effect, Function, Predicate } from "effect";
3
3
  //#region src/internal/codec/StepResult.ts
4
4
  const messageFromCause = (cause) => {
5
5
  if (Predicate.hasProperty(cause, "cause")) {
@@ -25,16 +25,6 @@ const mapMemoDecodeError = Function.dual(2, (effect, stepId) => effect.pipe(Effe
25
25
  stepId,
26
26
  cause
27
27
  }))));
28
- const decodeMemo = Function.dual(3, (value, schema, stepId) => Schema.decodeUnknownEffect(schema)(value).pipe(mapMemoDecodeError(stepId)));
29
- const encodeMemo = Function.dual(3, (value, schema, stepId) => Schema.encodeUnknownEffect(Schema.toCodecJson(schema))(value).pipe(mapMemoDecodeError(stepId)));
30
- const decodeStepRunMemo = (schema, stepId) => (value) => Option.match(schema, {
31
- onNone: () => Effect.void,
32
- onSome: (codec) => decodeMemo(codec, stepId)(value)
33
- });
34
- const encodeStepRunMemo = (schema, stepId) => (value) => Option.match(schema, {
35
- onNone: () => Predicate.isUndefined(value) ? Effect.succeed(void 0) : decodeMemo(Schema.Json, stepId)(value),
36
- onSome: (codec) => encodeMemo(codec, stepId)(value)
37
- });
38
28
  const failStepRunMemoError = (stepId, error) => Effect.fail(StepError.make({
39
29
  stepId,
40
30
  message: Predicate.hasProperty(error, "message") ? String(error.message) : "Step failed",
@@ -52,4 +42,4 @@ const failUnexpectedStepRunMemoInput = (stepId, input) => Effect.fail(StepError.
52
42
  cause: input
53
43
  }));
54
44
  //#endregion
55
- export { decodeMemo, decodeStepRunMemo, encodeStepRunMemo, failMemoDecode, failStepRunMemoError, failStepRunMemoTimeout, failUnexpectedStepRunMemoInput, mapMemoDecodeError };
45
+ export { failMemoDecode, failStepRunMemoError, failStepRunMemoTimeout, failUnexpectedStepRunMemoInput, mapMemoDecodeError };
@@ -1,4 +1,5 @@
1
1
  import "./protocol.js";
2
+ import "./runtime/StepTools.js";
2
3
  import { provide } from "./execution/ExecutionScope.js";
3
4
  import { run, withCheckpointDeadline } from "./execution/HandlerRun.js";
4
5
  import "./execution/ExecutionResult.js";
@@ -21,6 +21,6 @@ var RetryAfterError = class extends Schema.TaggedErrorClass()("RetryAfterError",
21
21
  retryAfter: Schema.DurationFromMillis,
22
22
  cause: Schema.optional(Schema.Unknown)
23
23
  }) {};
24
- const isRetryAfterError = Predicate.isTagged("RetryAfterError");
24
+ const isRetryAfterError = Schema.is(RetryAfterError);
25
25
  //#endregion
26
26
  export { NonRetriableError, RetryAfterError, SendEventError, StepError, isNonRetriableError, isRetryAfterError, isStepError };
@@ -1,6 +1,7 @@
1
1
  import { GeneratorOpcode } from "../protocol.js";
2
2
  import { InngestConfig } from "../../Client.js";
3
3
  import { CurrentCheckpoint } from "../runtime/CheckpointContext.js";
4
+ import { StepError } from "../errors.js";
4
5
  import { StepCommandBus } from "../runtime/StepCommandBus.js";
5
6
  import { ExecutionFailure } from "./ExecutionFailure.js";
6
7
  import { RetryDisposition, base } from "./ExecutionHeaders.js";
@@ -23,7 +24,27 @@ const fromSuccess = (args) => Effect.gen(function* () {
23
24
  headers: args.headers
24
25
  })), Match.tag("CheckpointDeadlineElapsed", () => ExecutionResult.checkpointDeadlineOutsideCheckpoint(args)), Match.exhaustive);
25
26
  });
27
+ const fromCheckpointAbort = (args) => Match.value(args.abort).pipe(Match.tag("StaleDispatch", () => {
28
+ const error = new StepError({
29
+ stepId: "checkpoint",
30
+ message: "Stale dispatch: checkpoint returned 409",
31
+ noRetry: true
32
+ });
33
+ return ExecutionResult.userError({
34
+ error,
35
+ headers: args.headers,
36
+ disposition: RetryDisposition.fromError(error)
37
+ });
38
+ }), Match.exhaustive);
26
39
  const fromFailure = (args) => Effect.gen(function* () {
40
+ const checkpoint = yield* CurrentCheckpoint;
41
+ if (Cause.hasInterruptsOnly(args.cause) && Option.isSome(checkpoint)) {
42
+ const abort = yield* checkpoint.value.abort;
43
+ if (Option.isSome(abort)) return fromCheckpointAbort({
44
+ abort: abort.value,
45
+ headers: args.headers
46
+ });
47
+ }
27
48
  const commands = yield* (yield* StepCommandBus).takeSuspension();
28
49
  if (commands.suspendedCount > 0 && Cause.hasInterruptsOnly(args.cause)) return ExecutionResult.opcodesWithRetry({
29
50
  opcodes: commands.opcodes,
@@ -45,10 +66,18 @@ const fromFailure = (args) => Effect.gen(function* () {
45
66
  });
46
67
  });
47
68
  const fromExit = (exit) => Effect.gen(function* () {
48
- const config = yield* InngestConfig;
49
- const bus = yield* StepCommandBus;
50
- const headers = base(config);
51
- const planned = yield* bus.takePlanned();
69
+ const headers = base(yield* InngestConfig);
70
+ if (Exit.isFailure(exit) && Cause.hasInterruptsOnly(exit.cause)) {
71
+ const checkpoint = yield* CurrentCheckpoint;
72
+ if (Option.isSome(checkpoint)) {
73
+ const abort = yield* checkpoint.value.abort;
74
+ if (Option.isSome(abort)) return fromCheckpointAbort({
75
+ abort: abort.value,
76
+ headers
77
+ });
78
+ }
79
+ }
80
+ const planned = yield* (yield* StepCommandBus).takePlanned();
52
81
  if (planned.length > 0) return ExecutionResult.opcodes({
53
82
  opcodes: planned,
54
83
  headers
@@ -1,10 +1,11 @@
1
1
  import { CurrentCheckpoint } from "../runtime/CheckpointContext.js";
2
+ import { normalize } from "../utils/safe-stringify.js";
2
3
  import { make } from "../runtime/HandlerContext.js";
3
4
  import { Effect, Option, Schema } from "effect";
4
5
  //#region src/internal/execution/HandlerRun.ts
5
6
  var HandlerSucceeded = class extends Schema.TaggedClass()("HandlerSucceeded", { value: Schema.Unknown }) {};
6
7
  Schema.TaggedClass()("CheckpointDeadlineElapsed", {});
7
- const run = (args) => make({ fn: args.fn }).pipe(Effect.flatMap(args.handler), Effect.map((value) => HandlerSucceeded.make({ value })));
8
+ const run = (args) => make({ fn: args.fn }).pipe(Effect.flatMap(args.handler), Effect.map((value) => HandlerSucceeded.make({ value: normalize(value) })));
8
9
  const withCheckpointDeadline = (effect) => Effect.gen(function* () {
9
10
  const checkpoint = yield* CurrentCheckpoint;
10
11
  return yield* Option.match(checkpoint, {
@@ -1,5 +1,5 @@
1
1
  import { resolveConfig } from "./checkpoint/Config.js";
2
- import { Headers, RegisterServerResponse, SDKRequestBody, SDKRequestContext, UserError } from "./protocol.js";
2
+ import { Headers as Headers$1, RegisterServerResponse, SDKRequestBody, SDKRequestContext, UserError } from "./protocol.js";
3
3
  import "./serve/Signature.js";
4
4
  import { InngestClient } from "../Client.js";
5
5
  import { schemaBodyJson, verifySignature } from "./serve/Request.js";
@@ -9,16 +9,17 @@ import * as HttpClient from "effect/unstable/http/HttpClient";
9
9
  import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest";
10
10
  import * as HttpClientResponse from "effect/unstable/http/HttpClientResponse";
11
11
  import "effect/unstable/http/HttpServerRequest";
12
+ import * as Headers from "effect/unstable/http/Headers";
12
13
  //#region src/internal/handler.ts
13
14
  var InvalidRequestError = class extends Schema.TaggedErrorClass()("InvalidRequestError", { message: Schema.String }) {};
14
15
  const SDK_VERSION = "2.0.0";
15
16
  const baseHeaders = (framework) => ({
16
17
  "Content-Type": "application/json",
17
18
  "User-Agent": `effect-inngest:v${SDK_VERSION}`,
18
- [Headers.SDK]: `effect-inngest:v${SDK_VERSION}`,
19
- [Headers.SDKHandled]: "true",
20
- [Headers.RequestVersion]: "2",
21
- ...framework ? { [Headers.Framework]: framework } : {}
19
+ [Headers$1.SDK]: `effect-inngest:v${SDK_VERSION}`,
20
+ [Headers$1.SDKHandled]: "true",
21
+ [Headers$1.RequestVersion]: "2",
22
+ ...framework ? { [Headers$1.Framework]: framework } : {}
22
23
  });
23
24
  const buildServeUrl = (args) => {
24
25
  const url = new URL(args.requestUrl);
@@ -66,11 +67,11 @@ const handleRegistration = Effect.fn("effect-inngest/handler/handleRegistration"
66
67
  const framework = config.framework;
67
68
  const registerUrl = new URL("fn/register", client.apiBaseUrl).toString();
68
69
  const registerHeaders = baseHeaders(framework);
69
- delete registerHeaders[Headers.RequestVersion];
70
+ delete registerHeaders[Headers$1.RequestVersion];
70
71
  const request = HttpClientRequest.post(registerUrl).pipe(HttpClientRequest.setHeaders({
71
72
  ...registerHeaders,
72
73
  Authorization: `Bearer ${config.signingKey ?? ""}`,
73
- [Headers.SyncKind]: "out_of_band"
74
+ [Headers$1.SyncKind]: "out_of_band"
74
75
  }), HttpClientRequest.bodyJsonUnsafe({
75
76
  url: url.href,
76
77
  deployType: "ping",
@@ -99,7 +100,7 @@ const handleRegistration = Effect.fn("effect-inngest/handler/handleRegistration"
99
100
  status: 200,
100
101
  headers: {
101
102
  ...baseHeaders(config.framework),
102
- [Headers.SyncKind]: "out_of_band"
103
+ [Headers$1.SyncKind]: "out_of_band"
103
104
  },
104
105
  body: {
105
106
  message: "Successfully registered",
@@ -131,7 +132,7 @@ const handleExecution = Effect.fn("effect-inngest/handler/handleExecution")(func
131
132
  status: 500,
132
133
  headers: {
133
134
  ...baseHeaders(client.config.framework),
134
- [Headers.NoRetry]: "false"
135
+ [Headers$1.NoRetry]: "false"
135
136
  },
136
137
  body: UserError.make({
137
138
  name: "FunctionNotFoundError",
@@ -139,27 +140,39 @@ const handleExecution = Effect.fn("effect-inngest/handler/handleExecution")(func
139
140
  })
140
141
  };
141
142
  const requestedStepId = args.urlStepId === "step" ? void 0 : args.urlStepId;
143
+ const requestId = (args.headers ? Option.getOrUndefined(Headers.get(args.headers, Headers$1.RequestId)) : void 0) ?? args.body.ctx.request_id;
144
+ const rawGenerationId = args.headers ? Option.getOrUndefined(Headers.get(args.headers, Headers$1.GenerationId)) : void 0;
145
+ const parsedGenerationId = rawGenerationId ? Number(rawGenerationId) : void 0;
146
+ const generationId = Predicate.isNumber(parsedGenerationId) && Number.isInteger(parsedGenerationId) ? parsedGenerationId : args.body.ctx.generation_id;
147
+ const withExecutionHeaders = (ctx) => SDKRequestContext.make({
148
+ fn_id: ctx.fn_id,
149
+ run_id: ctx.run_id,
150
+ env: ctx.env,
151
+ step_id: requestedStepId ?? ctx.step_id,
152
+ attempt: ctx.attempt,
153
+ max_attempts: ctx.max_attempts,
154
+ qi_id: ctx.qi_id,
155
+ ...Predicate.isNotUndefined(requestId) ? { request_id: requestId } : {},
156
+ ...Predicate.isNotUndefined(generationId) ? { generation_id: generationId } : {},
157
+ disable_immediate_execution: ctx.disable_immediate_execution,
158
+ use_api: ctx.use_api,
159
+ stack: ctx.stack
160
+ });
142
161
  const effectiveBody = requestedStepId && requestedStepId !== args.body.ctx.step_id ? SDKRequestBody.make({
143
162
  event: args.body.event,
144
163
  events: args.body.events,
145
164
  steps: args.body.steps,
146
- ctx: SDKRequestContext.make({
147
- fn_id: args.body.ctx.fn_id,
148
- run_id: args.body.ctx.run_id,
149
- env: args.body.ctx.env,
150
- step_id: requestedStepId,
151
- attempt: args.body.ctx.attempt,
152
- max_attempts: args.body.ctx.max_attempts,
153
- qi_id: args.body.ctx.qi_id,
154
- ...Predicate.isNotUndefined(args.body.ctx.request_id) ? { request_id: args.body.ctx.request_id } : {},
155
- ...Predicate.isNotUndefined(args.body.ctx.generation_id) ? { generation_id: args.body.ctx.generation_id } : {},
156
- disable_immediate_execution: args.body.ctx.disable_immediate_execution,
157
- use_api: args.body.ctx.use_api,
158
- stack: args.body.ctx.stack
159
- }),
165
+ ctx: withExecutionHeaders(args.body.ctx),
160
166
  version: args.body.version,
161
167
  use_api: args.body.use_api
162
- }) : args.body;
168
+ }) : SDKRequestBody.make({
169
+ event: args.body.event,
170
+ events: args.body.events,
171
+ steps: args.body.steps,
172
+ ctx: withExecutionHeaders(args.body.ctx),
173
+ version: args.body.version,
174
+ use_api: args.body.use_api
175
+ });
163
176
  const checkpointConfig = !requestedStepId && effectiveBody.ctx.fn_id !== "" && !effectiveBody.ctx.disable_immediate_execution && effectiveBody.ctx.attempt === 0 ? Option.fromNullishOr(resolveConfig(fn.options.checkpointing, client.config.checkpointing)) : Option.none();
164
177
  const result = yield* Effect.provide(execute({
165
178
  fn,
@@ -90,6 +90,9 @@ const Headers = {
90
90
  SyncKind: "x-inngest-sync-kind",
91
91
  ServerKind: "X-Inngest-Server-Kind",
92
92
  ExpectedServerKind: "X-Inngest-Expected-Server-Kind",
93
+ RequestId: "x-request-id",
94
+ GenerationId: "x-inngest-generation-id",
95
+ JobId: "x-inngest-job-id",
93
96
  RunID: "X-Run-ID",
94
97
  Framework: "X-Inngest-Framework",
95
98
  Platform: "X-Inngest-Platform",
@@ -1,12 +1,10 @@
1
1
  import { InngestFunction } from "../../Function.js";
2
2
  import { ExecutionInput } from "../domain/ExecutionInput.js";
3
- import { StepTools } from "./StepTools.js";
4
3
  import { Effect } from "effect";
5
4
 
6
5
  //#region src/internal/runtime/HandlerContext.d.ts
7
6
  interface HandlerContext<F extends InngestFunction.Any = InngestFunction.Any> {
8
7
  readonly event: InngestFunction.EventType<F>;
9
- readonly step: StepTools.Service;
10
8
  readonly run: ExecutionInput["run"];
11
9
  }
12
10
  //#endregion
@@ -1,17 +1,14 @@
1
1
  import { CurrentExecutionInput } from "../domain/ExecutionInput.js";
2
2
  import { decodeInvocation } from "../codec/EventPayload.js";
3
- import { StepTools } from "./StepTools.js";
4
3
  import { Effect } from "effect";
5
4
  //#region src/internal/runtime/HandlerContext.ts
6
5
  const make = (args) => Effect.gen(function* () {
7
6
  const input = yield* CurrentExecutionInput;
8
- const step = yield* StepTools;
9
7
  return {
10
8
  event: yield* decodeInvocation({
11
9
  fn: args.fn,
12
10
  input
13
11
  }),
14
- step,
15
12
  run: input.run
16
13
  };
17
14
  });
@@ -8,13 +8,9 @@ import { StepInput } from "../domain/StepInput.js";
8
8
  import { HandlerFiberScope } from "./HandlerFiberScope.js";
9
9
  import { StepCommandBus } from "./StepCommandBus.js";
10
10
  import { StepIdentity } from "./StepIdentity.js";
11
- import { Context, Duration, Effect, Layer, Option, Schema } from "effect";
11
+ import { Context, Duration, Effect, Layer, Option } from "effect";
12
12
 
13
13
  //#region src/internal/runtime/StepTools.d.ts
14
- type JsonSchema<A = unknown> = Schema.Codec<A, unknown, never, never>;
15
- interface RunOptions<S extends JsonSchema> {
16
- readonly schema: S;
17
- }
18
14
  interface WaitForEventOptions {
19
15
  readonly timeout: Duration.Input;
20
16
  readonly if?: string;
@@ -29,8 +25,7 @@ type InvokeOptions<F extends InngestFunction.Any> = [InngestFunction.EventPayloa
29
25
  readonly data: InngestFunction.EventPayload<F>;
30
26
  };
31
27
  interface Run {
32
- <Err, R>(id: StepInput, effect: Effect.Effect<void, Err, R>): Effect.Effect<void, StepError | Err, R>;
33
- <S extends JsonSchema, Err, R>(id: StepInput, effect: Effect.Effect<Schema.Schema.Type<S>, Err, R>, options: RunOptions<S>): Effect.Effect<Schema.Schema.Type<S>, StepError | Err, R>;
28
+ <A, Err, R>(id: StepInput, effect: Effect.Effect<A, Err, R>): Effect.Effect<A, StepError | Err, R>;
34
29
  }
35
30
  interface Sleep {
36
31
  (id: StepInput, duration: Duration.Input): Effect.Effect<void>;
@@ -42,7 +37,7 @@ interface WaitForEvent {
42
37
  <E extends EventSchema>(id: StepInput, event: E, options: WaitForEventOptions): Effect.Effect<Option.Option<EventType<E>>, StepError>;
43
38
  }
44
39
  interface Invoke {
45
- <F extends InngestFunction.Any>(id: StepInput, options: InvokeOptions<F>): Effect.Effect<InngestFunction.Success<F>, StepError>;
40
+ <F extends InngestFunction.Any>(id: StepInput, options: InvokeOptions<F>): Effect.Effect<unknown, StepError>;
46
41
  }
47
42
  interface OutgoingEvent {
48
43
  readonly name: string;
@@ -66,18 +61,15 @@ declare namespace StepTools {
66
61
  declare const StepTools_base: Context.ServiceClass<StepTools, "effect-inngest/internal/runtime/StepTools", StepTools.Service>;
67
62
  declare class StepTools extends StepTools_base {
68
63
  static readonly make: Effect.Effect<{
69
- run: {
70
- <Err, R>(id: StepInput, effect: Effect.Effect<void, Err, R>): Effect.Effect<void, StepError | Err, R>;
71
- <S extends JsonSchema, Err, R>(id: StepInput, effect: Effect.Effect<Schema.Schema.Type<S>, Err, R>, options: RunOptions<S>): Effect.Effect<Schema.Schema.Type<S>, StepError | Err, R>;
72
- };
64
+ run: <A, Err, R>(id: StepInput, effect: Effect.Effect<A, Err, R>) => Effect.Effect<A, StepError | Err, Exclude<R, CurrentExecutionInput | HandlerFiberScope | InngestConfig | StepCommandBus | StepIdentity>>;
73
65
  sleep: Sleep;
74
66
  sleepUntil: SleepUntil;
75
67
  waitForEvent: WaitForEvent;
76
68
  invoke: Invoke;
77
69
  sendEvent: SendEvent;
78
- }, never, InngestConfig | CurrentExecutionInput | StepIdentity | StepCommandBus | HandlerFiberScope>;
79
- static readonly layer: Layer.Layer<StepTools, never, InngestConfig | CurrentExecutionInput | StepIdentity | StepCommandBus | HandlerFiberScope>;
80
- static readonly live: Layer.Layer<StepTools, never, InngestConfig | CurrentExecutionInput | StepIdentity | HandlerFiberScope>;
70
+ }, never, CurrentExecutionInput | HandlerFiberScope | InngestConfig | StepCommandBus | StepIdentity>;
71
+ static readonly layer: Layer.Layer<StepTools, never, CurrentExecutionInput | HandlerFiberScope | InngestConfig | StepCommandBus | StepIdentity>;
72
+ static readonly live: Layer.Layer<StepTools, never, CurrentExecutionInput | HandlerFiberScope | InngestConfig | StepIdentity>;
81
73
  }
82
74
  //#endregion
83
- export { StepTools };
75
+ export { InvokeOptions, OutgoingEvent, StepTools, WaitForEventOptions };
@@ -10,7 +10,7 @@ import { sleep } from "./steps/SleepStep.js";
10
10
  import { sleepUntil } from "./steps/SleepUntilStep.js";
11
11
  import { run } from "./steps/StepRun.js";
12
12
  import { waitForEvent } from "./steps/WaitForEventStep.js";
13
- import { Context, Effect, Layer, Predicate, pipe } from "effect";
13
+ import { Context, Effect, Layer, pipe } from "effect";
14
14
  //#region src/internal/runtime/StepTools.ts
15
15
  var StepTools = class extends Context.Service()("effect-inngest/internal/runtime/StepTools") {
16
16
  static make = Effect.gen(function* () {
@@ -21,13 +21,7 @@ var StepTools = class extends Context.Service()("effect-inngest/internal/runtime
21
21
  const bus = yield* StepCommandBus;
22
22
  const handlerFiberScope = yield* HandlerFiberScope;
23
23
  const runtime = pipe(Context.make(StepIdentity, identity), Context.add(StepCommandBus, bus), Context.add(CurrentExecutionInput, input), Context.add(CurrentCheckpoint, checkpoint), Context.add(InngestConfig, config), Context.add(HandlerFiberScope, handlerFiberScope));
24
- function run$1(id, effect, options) {
25
- if (Predicate.isNotUndefined(options)) return run({
26
- input,
27
- id: identity.reserve(id),
28
- effect,
29
- options
30
- }).pipe(Effect.provide(runtime));
24
+ function run$1(id, effect) {
31
25
  return run({
32
26
  input,
33
27
  id: identity.reserve(id),
@@ -4,7 +4,6 @@ import { StepError } from "../../errors.js";
4
4
  import { InvokeFunction } from "../../domain/StepCommand.js";
5
5
  import { StepCommandBus } from "../StepCommandBus.js";
6
6
  import { StepIdentity } from "../StepIdentity.js";
7
- import { decodeMemo } from "../../codec/StepResult.js";
8
7
  import { Duration, Effect, Match, Predicate, Schema } from "effect";
9
8
  //#region src/internal/runtime/steps/InvokeStep.ts
10
9
  const invoke = (args) => Effect.gen(function* () {
@@ -13,7 +12,7 @@ const invoke = (args) => Effect.gen(function* () {
13
12
  const bus = yield* StepCommandBus;
14
13
  const info = yield* identity.resolve(args.id);
15
14
  const memo = args.input.memoForStep(info);
16
- return yield* Match.value(memo).pipe(Match.tag("MemoData", ({ data }) => decodeMemo(Schema.toCodecJson(args.options.function.success), info.id)(data)), Match.tag("MemoError", ({ error }) => Effect.fail(StepError.make({
15
+ return yield* Match.value(memo).pipe(Match.tag("MemoData", ({ data }) => Effect.succeed(data)), Match.tag("MemoError", ({ error }) => Effect.fail(StepError.make({
17
16
  stepId: info.id,
18
17
  message: Predicate.hasProperty(error, "message") ? String(error.message) : "Invoke failed",
19
18
  cause: error