effect-inngest 0.1.3 → 0.3.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 (141) hide show
  1. package/README.md +89 -67
  2. package/dist/Client.d.ts +76 -28
  3. package/dist/Client.js +92 -30
  4. package/dist/Event.d.ts +43 -0
  5. package/dist/Event.js +46 -0
  6. package/dist/Events.d.ts +48 -76
  7. package/dist/Events.js +18 -23
  8. package/dist/Function.d.ts +46 -19
  9. package/dist/Function.js +32 -22
  10. package/dist/Group.d.ts +19 -8
  11. package/dist/Group.js +30 -72
  12. package/dist/HttpApi.d.ts +51 -56
  13. package/dist/HttpApi.js +38 -21
  14. package/dist/_virtual/_rolldown/runtime.js +13 -0
  15. package/dist/index.d.ts +2 -1
  16. package/dist/index.js +3 -3
  17. package/dist/internal/checkpoint/Config.d.ts +10 -0
  18. package/dist/internal/checkpoint/Config.js +29 -0
  19. package/dist/internal/checkpoint/Error.d.ts +11 -0
  20. package/dist/internal/checkpoint/Error.js +8 -0
  21. package/dist/internal/checkpoint/State.d.ts +1 -0
  22. package/dist/internal/checkpoint/State.js +54 -0
  23. package/dist/internal/checkpoint.d.ts +2 -0
  24. package/dist/internal/codec/EventPayload.d.ts +6 -0
  25. package/dist/internal/codec/EventPayload.js +60 -0
  26. package/dist/internal/codec/StepResult.js +55 -0
  27. package/dist/internal/domain/ExecutionInput.d.ts +40 -0
  28. package/dist/internal/domain/ExecutionInput.js +57 -0
  29. package/dist/internal/domain/ExecutionSuspension.d.ts +34 -0
  30. package/dist/internal/domain/ExecutionSuspension.js +64 -0
  31. package/dist/internal/domain/FunctionDefinition.js +13 -0
  32. package/dist/internal/domain/Memo.d.ts +22 -0
  33. package/dist/internal/domain/Memo.js +18 -0
  34. package/dist/internal/domain/StepCommand.d.ts +79 -0
  35. package/dist/internal/domain/StepCommand.js +124 -0
  36. package/dist/internal/domain/StepInfo.d.ts +12 -0
  37. package/dist/internal/domain/StepInfo.js +10 -0
  38. package/dist/internal/domain/StepInput.d.ts +10 -0
  39. package/dist/internal/driver.js +15 -114
  40. package/dist/internal/errors.d.ts +21 -48
  41. package/dist/internal/errors.js +9 -44
  42. package/dist/internal/execution/CheckpointRun.js +25 -0
  43. package/dist/internal/execution/ExecutionFailure.js +19 -0
  44. package/dist/internal/execution/ExecutionHeaders.js +58 -0
  45. package/dist/internal/execution/ExecutionResponse.js +68 -0
  46. package/dist/internal/execution/ExecutionResult.js +56 -0
  47. package/dist/internal/execution/ExecutionScope.js +30 -0
  48. package/dist/internal/execution/HandlerRun.js +16 -0
  49. package/dist/internal/handler.d.ts +5 -16
  50. package/dist/internal/handler.js +128 -96
  51. package/dist/internal/protocol.d.ts +143 -1
  52. package/dist/internal/protocol.js +333 -138
  53. package/dist/internal/runtime/CheckpointContext.js +5 -0
  54. package/dist/internal/runtime/HandlerContext.d.ts +13 -0
  55. package/dist/internal/runtime/HandlerContext.js +19 -0
  56. package/dist/internal/runtime/HandlerFiberScope.d.ts +10 -0
  57. package/dist/internal/runtime/HandlerFiberScope.js +5 -0
  58. package/dist/internal/runtime/StepCommandBus.d.ts +27 -0
  59. package/dist/internal/runtime/StepCommandBus.js +76 -0
  60. package/dist/internal/runtime/StepIdentity.d.ts +27 -0
  61. package/dist/internal/runtime/StepIdentity.js +46 -0
  62. package/dist/internal/runtime/StepTools.d.ts +83 -0
  63. package/dist/internal/runtime/StepTools.js +76 -0
  64. package/dist/internal/runtime/steps/InvokeStep.js +43 -0
  65. package/dist/internal/runtime/steps/SendEventStep.js +46 -0
  66. package/dist/internal/runtime/steps/SleepStep.js +22 -0
  67. package/dist/internal/runtime/steps/SleepUntilStep.js +22 -0
  68. package/dist/internal/runtime/steps/StepRun.js +48 -0
  69. package/dist/internal/runtime/steps/WaitForEventStep.js +27 -0
  70. package/dist/internal/serve/HttpApp.js +71 -0
  71. package/dist/internal/serve/Request.js +23 -0
  72. package/dist/internal/serve/Signature.d.ts +11 -0
  73. package/dist/internal/serve/Signature.js +123 -0
  74. package/dist/internal/wire/Duration.js +19 -0
  75. package/dist/internal/wire/Timestamp.js +14 -0
  76. package/package.json +34 -22
  77. package/src/Client.ts +269 -91
  78. package/src/Event.ts +107 -0
  79. package/src/Events.ts +50 -30
  80. package/src/Function.ts +102 -46
  81. package/src/Group.ts +56 -108
  82. package/src/HttpApi.ts +40 -30
  83. package/src/index.ts +21 -11
  84. package/src/internal/checkpoint/Config.ts +74 -0
  85. package/src/internal/checkpoint/Error.ts +6 -0
  86. package/src/internal/checkpoint/State.ts +107 -0
  87. package/src/internal/checkpoint.ts +3 -0
  88. package/src/internal/codec/EventPayload.ts +98 -0
  89. package/src/internal/codec/StepResult.ts +95 -0
  90. package/src/internal/domain/ExecutionInput.ts +66 -0
  91. package/src/internal/domain/ExecutionSuspension.ts +79 -0
  92. package/src/internal/domain/FunctionDefinition.ts +30 -0
  93. package/src/internal/domain/Memo.ts +28 -0
  94. package/src/internal/domain/StepCommand.ts +166 -0
  95. package/src/internal/domain/StepInfo.ts +8 -0
  96. package/src/internal/domain/StepInput.ts +10 -0
  97. package/src/internal/driver.ts +27 -185
  98. package/src/internal/errors.ts +14 -108
  99. package/src/internal/execution/CheckpointRun.ts +33 -0
  100. package/src/internal/execution/ExecutionFailure.ts +19 -0
  101. package/src/internal/execution/ExecutionHeaders.ts +86 -0
  102. package/src/internal/execution/ExecutionResponse.ts +79 -0
  103. package/src/internal/execution/ExecutionResult.ts +57 -0
  104. package/src/internal/execution/ExecutionScope.ts +41 -0
  105. package/src/internal/execution/HandlerRun.ts +38 -0
  106. package/src/internal/handler.ts +222 -172
  107. package/src/internal/protocol.ts +289 -78
  108. package/src/internal/runtime/CheckpointContext.ts +7 -0
  109. package/src/internal/runtime/HandlerContext.ts +21 -0
  110. package/src/internal/runtime/HandlerFiberScope.ts +9 -0
  111. package/src/internal/runtime/StepCommandBus.ts +129 -0
  112. package/src/internal/runtime/StepIdentity.ts +67 -0
  113. package/src/internal/runtime/StepTools.ts +161 -0
  114. package/src/internal/runtime/steps/InvokeStep.ts +71 -0
  115. package/src/internal/runtime/steps/SendEventStep.ts +67 -0
  116. package/src/internal/runtime/steps/SleepStep.ts +34 -0
  117. package/src/internal/runtime/steps/SleepUntilStep.ts +34 -0
  118. package/src/internal/runtime/steps/StepRun.ts +95 -0
  119. package/src/internal/runtime/steps/WaitForEventStep.ts +55 -0
  120. package/src/internal/serve/HttpApp.ts +123 -0
  121. package/src/internal/serve/Request.ts +27 -0
  122. package/src/internal/serve/Signature.ts +170 -0
  123. package/src/internal/wire/Duration.ts +31 -0
  124. package/src/internal/wire/Timestamp.ts +11 -0
  125. package/dist/_virtual/rolldown_runtime.js +0 -18
  126. package/dist/internal/constants.js +0 -15
  127. package/dist/internal/driver.d.ts +0 -5
  128. package/dist/internal/helpers.js +0 -44
  129. package/dist/internal/interrupts.d.ts +0 -2
  130. package/dist/internal/interrupts.js +0 -45
  131. package/dist/internal/memo.js +0 -56
  132. package/dist/internal/signature.d.ts +0 -18
  133. package/dist/internal/signature.js +0 -97
  134. package/dist/internal/step.d.ts +0 -59
  135. package/dist/internal/step.js +0 -192
  136. package/src/internal/constants.ts +0 -11
  137. package/src/internal/helpers.ts +0 -58
  138. package/src/internal/interrupts.ts +0 -62
  139. package/src/internal/memo.ts +0 -73
  140. package/src/internal/signature.ts +0 -158
  141. package/src/internal/step.ts +0 -394
@@ -0,0 +1,27 @@
1
+ import { StepInfo } from "../domain/StepInfo.js";
2
+ import { StepInput } from "../domain/StepInput.js";
3
+ import { Context, Effect, Layer, Schema } from "effect";
4
+
5
+ //#region src/internal/runtime/StepIdentity.d.ts
6
+ declare const StepReservation_base: Schema.Class<StepReservation, Schema.Struct<{
7
+ readonly id: Schema.String;
8
+ readonly name: Schema.String;
9
+ readonly effectiveId: Schema.String;
10
+ readonly sequence: Schema.Number;
11
+ readonly rawStepArg: Schema.Unknown;
12
+ }>, {}>;
13
+ declare class StepReservation extends StepReservation_base {}
14
+ declare const StepIdentity_base: Context.ServiceClass<StepIdentity, "effect-inngest/internal/runtime/StepIdentity", {
15
+ readonly reserve: (input: StepInput) => StepReservation;
16
+ readonly resolve: (reservation: StepReservation) => Effect.Effect<StepInfo>;
17
+ }> & {
18
+ readonly make: Effect.Effect<{
19
+ readonly reserve: (input: StepInput) => StepReservation;
20
+ readonly resolve: (reservation: StepReservation) => Effect.Effect<StepInfo>;
21
+ }, never, never>;
22
+ };
23
+ declare class StepIdentity extends StepIdentity_base {
24
+ static readonly layer: Layer.Layer<StepIdentity, never, never>;
25
+ }
26
+ //#endregion
27
+ export { StepIdentity };
@@ -0,0 +1,46 @@
1
+ import { StepInfo } from "../domain/StepInfo.js";
2
+ import { Context, Effect, Encoding, Layer, MutableHashMap, MutableRef, Number, Option, Predicate, Schema } from "effect";
3
+ //#region src/internal/runtime/StepIdentity.ts
4
+ var StepReservation = class extends Schema.Class("effect-inngest/internal/runtime/StepReservation")({
5
+ id: Schema.String,
6
+ name: Schema.String,
7
+ effectiveId: Schema.String,
8
+ sequence: Schema.Number,
9
+ rawStepArg: Schema.Unknown
10
+ }) {};
11
+ var StepIdentity = class extends Context.Service()("effect-inngest/internal/runtime/StepIdentity", { make: Effect.gen(function* () {
12
+ const counts = MutableHashMap.empty();
13
+ const sequence = MutableRef.make(0);
14
+ const textEncoder = new TextEncoder();
15
+ return {
16
+ reserve: (input) => {
17
+ const id = Predicate.isString(input) ? input : input.id;
18
+ const name = Predicate.isString(input) ? input : input.name ?? input.id;
19
+ const currentSequence = MutableRef.getAndUpdate(sequence, Number.increment);
20
+ const repeatIndex = Option.getOrElse(MutableHashMap.get(counts, id), () => 0);
21
+ MutableHashMap.set(counts, id, Number.increment(repeatIndex));
22
+ const effectiveId = repeatIndex > 0 ? `${id}:${repeatIndex}` : id;
23
+ return StepReservation.make({
24
+ id,
25
+ name,
26
+ effectiveId,
27
+ sequence: currentSequence,
28
+ rawStepArg: input
29
+ });
30
+ },
31
+ resolve: Effect.fnUntraced(function* (reservation) {
32
+ const buffer = yield* Effect.promise(() => globalThis.crypto.subtle.digest("SHA-1", textEncoder.encode(reservation.effectiveId)));
33
+ const hash = Encoding.encodeHex(new Uint8Array(buffer));
34
+ return StepInfo.make({
35
+ id: reservation.id,
36
+ name: reservation.name,
37
+ hash,
38
+ rawStepArg: reservation.rawStepArg
39
+ });
40
+ })
41
+ };
42
+ }) }) {
43
+ static layer = Layer.effect(this, this.make);
44
+ };
45
+ //#endregion
46
+ export { StepIdentity };
@@ -0,0 +1,83 @@
1
+ import { InngestClient, InngestConfig } from "../../Client.js";
2
+ import { EventType } from "../../Event.js";
3
+ import { InngestFunction } from "../../Function.js";
4
+ import { CurrentExecutionInput } from "../domain/ExecutionInput.js";
5
+ import { EventSchema } from "../codec/EventPayload.js";
6
+ import { SendEventError, StepError } from "../errors.js";
7
+ import { StepInput } from "../domain/StepInput.js";
8
+ import { HandlerFiberScope } from "./HandlerFiberScope.js";
9
+ import { StepCommandBus } from "./StepCommandBus.js";
10
+ import { StepIdentity } from "./StepIdentity.js";
11
+ import { Context, Duration, Effect, Layer, Option, Schema } from "effect";
12
+
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
+ interface WaitForEventOptions {
19
+ readonly timeout: Duration.Input;
20
+ readonly if?: string;
21
+ }
22
+ interface InvokeOptionsBase<F extends InngestFunction.Any> {
23
+ readonly function: F;
24
+ readonly user?: Record<string, unknown>;
25
+ readonly v?: string;
26
+ readonly timeout?: Duration.Input;
27
+ }
28
+ type InvokeOptions<F extends InngestFunction.Any> = [InngestFunction.EventPayload<F>] extends [never] ? InvokeOptionsBase<F> : InvokeOptionsBase<F> & {
29
+ readonly data: InngestFunction.EventPayload<F>;
30
+ };
31
+ 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>;
34
+ }
35
+ interface Sleep {
36
+ (id: StepInput, duration: Duration.Input): Effect.Effect<void>;
37
+ }
38
+ interface SleepUntil {
39
+ (id: StepInput, timestamp: Date | number | string): Effect.Effect<void>;
40
+ }
41
+ interface WaitForEvent {
42
+ <E extends EventSchema>(id: StepInput, event: E, options: WaitForEventOptions): Effect.Effect<Option.Option<EventType<E>>, StepError>;
43
+ }
44
+ interface Invoke {
45
+ <F extends InngestFunction.Any>(id: StepInput, options: InvokeOptions<F>): Effect.Effect<InngestFunction.Success<F>, StepError>;
46
+ }
47
+ interface OutgoingEvent {
48
+ readonly name: string;
49
+ readonly data: unknown;
50
+ }
51
+ interface SendEvent {
52
+ (id: StepInput, payload: OutgoingEvent | ReadonlyArray<OutgoingEvent>): Effect.Effect<{
53
+ readonly ids: ReadonlyArray<string>;
54
+ }, SendEventError, InngestClient>;
55
+ }
56
+ declare namespace StepTools {
57
+ interface Service {
58
+ readonly run: Run;
59
+ readonly sleep: Sleep;
60
+ readonly sleepUntil: SleepUntil;
61
+ readonly waitForEvent: WaitForEvent;
62
+ readonly invoke: Invoke;
63
+ readonly sendEvent: SendEvent;
64
+ }
65
+ }
66
+ declare const StepTools_base: Context.ServiceClass<StepTools, "effect-inngest/internal/runtime/StepTools", StepTools.Service>;
67
+ declare class StepTools extends StepTools_base {
68
+ 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
+ };
73
+ sleep: Sleep;
74
+ sleepUntil: SleepUntil;
75
+ waitForEvent: WaitForEvent;
76
+ invoke: Invoke;
77
+ 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>;
81
+ }
82
+ //#endregion
83
+ export { StepTools };
@@ -0,0 +1,76 @@
1
+ import { InngestConfig } from "../../Client.js";
2
+ import { CurrentExecutionInput } from "../domain/ExecutionInput.js";
3
+ import { CurrentCheckpoint } from "./CheckpointContext.js";
4
+ import { HandlerFiberScope } from "./HandlerFiberScope.js";
5
+ import { StepCommandBus } from "./StepCommandBus.js";
6
+ import { StepIdentity } from "./StepIdentity.js";
7
+ import { invoke } from "./steps/InvokeStep.js";
8
+ import { sendEvent } from "./steps/SendEventStep.js";
9
+ import { sleep } from "./steps/SleepStep.js";
10
+ import { sleepUntil } from "./steps/SleepUntilStep.js";
11
+ import { run } from "./steps/StepRun.js";
12
+ import { waitForEvent } from "./steps/WaitForEventStep.js";
13
+ import { Context, Effect, Layer, Predicate, pipe } from "effect";
14
+ //#region src/internal/runtime/StepTools.ts
15
+ var StepTools = class extends Context.Service()("effect-inngest/internal/runtime/StepTools") {
16
+ static make = Effect.gen(function* () {
17
+ const input = yield* CurrentExecutionInput;
18
+ const checkpoint = yield* CurrentCheckpoint;
19
+ const config = yield* InngestConfig;
20
+ const identity = yield* StepIdentity;
21
+ const bus = yield* StepCommandBus;
22
+ const handlerFiberScope = yield* HandlerFiberScope;
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));
31
+ return run({
32
+ input,
33
+ id: identity.reserve(id),
34
+ effect
35
+ }).pipe(Effect.provide(runtime));
36
+ }
37
+ const sleep$1 = (id, duration) => sleep({
38
+ input,
39
+ id: identity.reserve(id),
40
+ duration
41
+ }).pipe(Effect.provide(runtime));
42
+ const sleepUntil$1 = (id, timestamp) => sleepUntil({
43
+ input,
44
+ id: identity.reserve(id),
45
+ timestamp
46
+ }).pipe(Effect.provide(runtime));
47
+ const waitForEvent$1 = (id, event, options) => waitForEvent({
48
+ input,
49
+ id: identity.reserve(id),
50
+ event,
51
+ options
52
+ }).pipe(Effect.provide(runtime));
53
+ const invoke$1 = (id, options) => invoke({
54
+ input,
55
+ id: identity.reserve(id),
56
+ options
57
+ }).pipe(Effect.provide(runtime));
58
+ const sendEvent$1 = (id, payload) => sendEvent({
59
+ input,
60
+ id: identity.reserve(id),
61
+ payload
62
+ }).pipe(Effect.provide(runtime));
63
+ return {
64
+ run: run$1,
65
+ sleep: sleep$1,
66
+ sleepUntil: sleepUntil$1,
67
+ waitForEvent: waitForEvent$1,
68
+ invoke: invoke$1,
69
+ sendEvent: sendEvent$1
70
+ };
71
+ });
72
+ static layer = Layer.effect(this, this.make);
73
+ static live = this.layer.pipe(Layer.provide(StepCommandBus.layer));
74
+ };
75
+ //#endregion
76
+ export { StepTools };
@@ -0,0 +1,43 @@
1
+ import { InngestDuration } from "../../wire/Duration.js";
2
+ import { InngestConfig } from "../../../Client.js";
3
+ import { StepError } from "../../errors.js";
4
+ import { InvokeFunction } from "../../domain/StepCommand.js";
5
+ import { StepCommandBus } from "../StepCommandBus.js";
6
+ import { StepIdentity } from "../StepIdentity.js";
7
+ import { decodeMemo } from "../../codec/StepResult.js";
8
+ import { Duration, Effect, Match, Predicate, Schema } from "effect";
9
+ //#region src/internal/runtime/steps/InvokeStep.ts
10
+ const invoke = (args) => Effect.gen(function* () {
11
+ const config = yield* InngestConfig;
12
+ const identity = yield* StepIdentity;
13
+ const bus = yield* StepCommandBus;
14
+ const info = yield* identity.resolve(args.id);
15
+ 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({
17
+ stepId: info.id,
18
+ message: Predicate.hasProperty(error, "message") ? String(error.message) : "Invoke failed",
19
+ cause: error
20
+ }))), Match.tag("MemoTimeout", () => Effect.fail(StepError.make({
21
+ stepId: info.id,
22
+ message: "Invoke timed out",
23
+ noRetry: true
24
+ }))), Match.tag("MemoInput", () => Effect.succeed(void 0)), Match.tag("MemoNone", () => Effect.gen(function* () {
25
+ if (!args.input.shouldExecuteStep(info)) return yield* Effect.void;
26
+ const event = Predicate.hasProperty(args.options, "data") ? args.options.data : void 0;
27
+ const data = Predicate.isObject(event) && Predicate.hasProperty(event, "data") ? event.data : event;
28
+ yield* bus.suspend(InvokeFunction.make({
29
+ info,
30
+ sequence: args.id.sequence,
31
+ functionId: `${config.id}-${args.options.function._tag}`,
32
+ payload: {
33
+ data,
34
+ ...Predicate.isNotUndefined(args.options.user) ? { user: args.options.user } : {},
35
+ ...Predicate.isNotUndefined(args.options.v) ? { v: args.options.v } : {}
36
+ },
37
+ timeout: args.options.timeout ? Schema.encodeSync(InngestDuration)(Duration.fromInputUnsafe(args.options.timeout)) : void 0
38
+ }));
39
+ return yield* Effect.void;
40
+ })), Match.exhaustive);
41
+ });
42
+ //#endregion
43
+ export { invoke };
@@ -0,0 +1,46 @@
1
+ import { InngestClient } from "../../../Client.js";
2
+ import { SendEventError } from "../../errors.js";
3
+ import { SendEventPlanned, SendEventResult } from "../../domain/StepCommand.js";
4
+ import { StepCommandBus } from "../StepCommandBus.js";
5
+ import { StepIdentity } from "../StepIdentity.js";
6
+ import { Array, Effect, Match, Predicate, Schema } from "effect";
7
+ //#region src/internal/runtime/steps/SendEventStep.ts
8
+ const SendEventMemoData = Schema.Struct({ ids: Schema.Array(Schema.String) });
9
+ const sendEventDecodeError = (error) => SendEventError.make({
10
+ message: `Invalid sendEvent memo data: ${Predicate.hasProperty(error, "message") ? String(error.message) : String(error)}`,
11
+ events: []
12
+ });
13
+ const sendEvent = (args) => Effect.gen(function* () {
14
+ const identity = yield* StepIdentity;
15
+ const bus = yield* StepCommandBus;
16
+ const info = yield* identity.resolve(args.id);
17
+ const memo = args.input.memoForStep(info);
18
+ return yield* Match.value(memo).pipe(Match.tag("MemoData", ({ data }) => Schema.decodeUnknownEffect(SendEventMemoData)(data).pipe(Effect.mapError(sendEventDecodeError))), Match.tag("MemoError", () => Effect.fail(SendEventError.make({
19
+ message: "SendEvent failed",
20
+ events: []
21
+ }))), Match.tag("MemoTimeout", () => Effect.fail(SendEventError.make({
22
+ message: "SendEvent timed out",
23
+ events: []
24
+ }))), Match.tag("MemoInput", () => Effect.succeed({ ids: [] })), Match.tag("MemoNone", () => Effect.gen(function* () {
25
+ if (!args.input.shouldExecuteStep(info)) return { ids: [] };
26
+ const planned = SendEventPlanned.make({
27
+ info,
28
+ sequence: args.id.sequence
29
+ });
30
+ if (args.input.shouldPlanStep(info)) {
31
+ yield* bus.plan(planned);
32
+ return { ids: [] };
33
+ }
34
+ if (yield* bus.planCheckpointedFork(planned)) return { ids: [] };
35
+ const events = Array.ensure(args.payload);
36
+ const result = yield* InngestClient.use((client) => client.sendEvent(events));
37
+ yield* bus.complete(SendEventResult.make({
38
+ info,
39
+ data: { ids: [...result.ids] },
40
+ rawPayload: Array.isArray(args.payload) ? events : events[0]
41
+ }));
42
+ return result;
43
+ })), Match.exhaustive);
44
+ });
45
+ //#endregion
46
+ export { sendEvent };
@@ -0,0 +1,22 @@
1
+ import { InngestDuration } from "../../wire/Duration.js";
2
+ import { Sleep } from "../../domain/StepCommand.js";
3
+ import { StepCommandBus } from "../StepCommandBus.js";
4
+ import { StepIdentity } from "../StepIdentity.js";
5
+ import { Duration, Effect, Predicate, Schema } from "effect";
6
+ //#region src/internal/runtime/steps/SleepStep.ts
7
+ const sleep = (args) => Effect.gen(function* () {
8
+ const identity = yield* StepIdentity;
9
+ const bus = yield* StepCommandBus;
10
+ const info = yield* identity.resolve(args.id);
11
+ const memo = args.input.memoForStep(info);
12
+ if (!Predicate.isTagged(memo, "MemoNone") || !args.input.shouldExecuteStep(info)) return;
13
+ const command = Sleep.make({
14
+ info,
15
+ sequence: args.id.sequence,
16
+ duration: Schema.encodeSync(InngestDuration)(Duration.fromInputUnsafe(args.duration))
17
+ });
18
+ if (yield* bus.planCheckpointedFork(command)) return;
19
+ return yield* bus.suspend(command);
20
+ });
21
+ //#endregion
22
+ export { sleep };
@@ -0,0 +1,22 @@
1
+ import { Sleep } from "../../domain/StepCommand.js";
2
+ import { StepCommandBus } from "../StepCommandBus.js";
3
+ import { StepIdentity } from "../StepIdentity.js";
4
+ import { InngestTimestamp } from "../../wire/Timestamp.js";
5
+ import { Effect, Predicate, Schema } from "effect";
6
+ //#region src/internal/runtime/steps/SleepUntilStep.ts
7
+ const sleepUntil = (args) => Effect.gen(function* () {
8
+ const identity = yield* StepIdentity;
9
+ const bus = yield* StepCommandBus;
10
+ const info = yield* identity.resolve(args.id);
11
+ const memo = args.input.memoForStep(info);
12
+ if (!Predicate.isTagged(memo, "MemoNone") || !args.input.shouldExecuteStep(info)) return;
13
+ const command = Sleep.make({
14
+ info,
15
+ sequence: args.id.sequence,
16
+ duration: Schema.decodeUnknownSync(InngestTimestamp)(args.timestamp)
17
+ });
18
+ if (yield* bus.planCheckpointedFork(command)) return;
19
+ return yield* bus.suspend(command);
20
+ });
21
+ //#endregion
22
+ export { sleepUntil };
@@ -0,0 +1,48 @@
1
+ import { StepRunError, StepRunPlanned, StepRunResult, stepRunFailureForAttempt } from "../../domain/StepCommand.js";
2
+ import { StepCommandBus } from "../StepCommandBus.js";
3
+ import { StepIdentity } from "../StepIdentity.js";
4
+ import { decodeStepRunMemo, encodeStepRunMemo, failStepRunMemoError, failStepRunMemoTimeout, failUnexpectedStepRunMemoInput } from "../../codec/StepResult.js";
5
+ import { Effect, Match, Option, Schema } from "effect";
6
+ //#region src/internal/runtime/steps/StepRun.ts
7
+ function run(args) {
8
+ const memoCodec = args.options ? Option.some(Schema.toCodecJson(args.options.schema)) : Option.none();
9
+ return Effect.gen(function* () {
10
+ const identity = yield* StepIdentity;
11
+ const bus = yield* StepCommandBus;
12
+ const info = yield* identity.resolve(args.id);
13
+ const memo = args.input.memoForStep(info);
14
+ return yield* Match.value(memo).pipe(Match.tag("MemoData", ({ data }) => decodeStepRunMemo(memoCodec, info.id)(data)), Match.tag("MemoError", ({ error }) => failStepRunMemoError(info.id, error)), Match.tag("MemoTimeout", () => failStepRunMemoTimeout(info.id)), Match.tag("MemoInput", ({ input }) => failUnexpectedStepRunMemoInput(info.id, input)), Match.tag("MemoNone", () => Effect.gen(function* () {
15
+ if (!args.input.shouldExecuteStep(info)) return yield* Effect.void;
16
+ const planned = StepRunPlanned.make({
17
+ info,
18
+ sequence: args.id.sequence
19
+ });
20
+ if (args.input.shouldPlanStep(info)) {
21
+ yield* bus.plan(planned);
22
+ return yield* Effect.void;
23
+ }
24
+ if (yield* bus.planCheckpointedRunBoundary(planned)) return yield* Effect.void;
25
+ return yield* args.effect.pipe(Effect.matchEffect({
26
+ onFailure: (error) => bus.fail(stepRunFailureForAttempt({
27
+ info,
28
+ error,
29
+ attempt: args.input.run.attempt,
30
+ maxAttempts: args.input.run.maxAttempts
31
+ })),
32
+ onSuccess: (value) => Effect.gen(function* () {
33
+ const data = yield* encodeStepRunMemo(memoCodec, info.id)(value);
34
+ yield* bus.complete(StepRunResult.make({
35
+ info,
36
+ data
37
+ }));
38
+ return yield* decodeStepRunMemo(memoCodec, info.id)(data);
39
+ })
40
+ }), Effect.catchDefect((defect) => bus.fail(StepRunError.make({
41
+ info,
42
+ error: defect
43
+ }))));
44
+ })), Match.exhaustive);
45
+ });
46
+ }
47
+ //#endregion
48
+ export { run };
@@ -0,0 +1,27 @@
1
+ import { InngestDuration } from "../../wire/Duration.js";
2
+ import { WaitForEvent } from "../../domain/StepCommand.js";
3
+ import { StepCommandBus } from "../StepCommandBus.js";
4
+ import { StepIdentity } from "../StepIdentity.js";
5
+ import { failMemoDecode, mapMemoDecodeError } from "../../codec/StepResult.js";
6
+ import { decodeMemoData } from "../../codec/EventPayload.js";
7
+ import { Duration, Effect, Match, Option, Schema } from "effect";
8
+ //#region src/internal/runtime/steps/WaitForEventStep.ts
9
+ const waitForEvent = (args) => Effect.gen(function* () {
10
+ const identity = yield* StepIdentity;
11
+ const bus = yield* StepCommandBus;
12
+ const info = yield* identity.resolve(args.id);
13
+ const memo = args.input.memoForStep(info);
14
+ return yield* Match.value(memo).pipe(Match.tag("MemoData", ({ data }) => decodeMemoData(args.event)(data).pipe(mapMemoDecodeError(info.id), Effect.map(Option.some))), Match.tag("MemoTimeout", () => Effect.succeed(Option.none())), Match.tag("MemoError", ({ error }) => failMemoDecode(info.id, error)), Match.tag("MemoInput", ({ input }) => failMemoDecode(info.id, input)), Match.tag("MemoNone", () => Effect.gen(function* () {
15
+ if (!args.input.shouldExecuteStep(info)) return Option.none();
16
+ yield* bus.suspend(WaitForEvent.make({
17
+ info,
18
+ sequence: args.id.sequence,
19
+ event: args.event.identifier,
20
+ timeout: Schema.encodeSync(InngestDuration)(Duration.fromInputUnsafe(args.options.timeout)),
21
+ if: args.options.if
22
+ }));
23
+ return Option.none();
24
+ })), Match.exhaustive);
25
+ });
26
+ //#endregion
27
+ export { waitForEvent };
@@ -0,0 +1,71 @@
1
+ import { Headers } from "../protocol.js";
2
+ import { SignatureLive } from "./Signature.js";
3
+ import { handleExecution, handleIntrospection, handleRegistration, verifyAndParseRequestBody } from "../handler.js";
4
+ import { Effect, Option, Predicate, Schema } from "effect";
5
+ import "effect/unstable/http/HttpClient";
6
+ import * as HttpEffect from "effect/unstable/http/HttpEffect";
7
+ import * as HttpServerRequest from "effect/unstable/http/HttpServerRequest";
8
+ import * as HttpServerResponse from "effect/unstable/http/HttpServerResponse";
9
+ import * as UrlParams from "effect/unstable/http/UrlParams";
10
+ Schema.TaggedErrorClass()("MethodNotAllowed", { method: Schema.String });
11
+ Schema.TaggedErrorClass()("InvalidQueryParams", { message: Schema.String });
12
+ const toHttpApp = (group) => Effect.gen(function* () {
13
+ const request = yield* HttpServerRequest.HttpServerRequest;
14
+ const method = request.method;
15
+ const requestUrl = Option.match(HttpServerRequest.toURL(request), {
16
+ onNone: () => request.url,
17
+ onSome: (url) => url.toString()
18
+ });
19
+ if (method === "GET") {
20
+ const result = yield* handleIntrospection(group, requestUrl);
21
+ return yield* HttpServerResponse.json(result.body, {
22
+ status: result.status,
23
+ headers: result.headers
24
+ });
25
+ }
26
+ if (method === "PUT") {
27
+ const result = yield* handleRegistration(group, requestUrl);
28
+ return yield* HttpServerResponse.json(result.body, {
29
+ status: result.status,
30
+ headers: result.headers
31
+ });
32
+ }
33
+ if (method === "POST") {
34
+ const url = yield* Option.match(HttpServerRequest.toURL(request), {
35
+ onNone: () => Effect.fail(HttpServerResponse.jsonUnsafe({ error: "Unable to parse request URL" }, {
36
+ status: 400,
37
+ headers: { [Headers.NoRetry]: "true" }
38
+ })),
39
+ onSome: (u) => Effect.succeed(u)
40
+ });
41
+ const ExecuteParamsSchema = UrlParams.schemaRecord.pipe(Schema.decodeTo(Schema.Struct({
42
+ fnId: Schema.String,
43
+ stepId: Schema.optional(Schema.String)
44
+ })));
45
+ const params = yield* Schema.decodeUnknownEffect(ExecuteParamsSchema)(UrlParams.fromInput(url.searchParams)).pipe(Effect.catch((error) => Effect.fail(HttpServerResponse.jsonUnsafe({ error: `Missing or invalid fnId query parameter: ${String(error)}` }, {
46
+ status: 400,
47
+ headers: { [Headers.NoRetry]: "true" }
48
+ }))));
49
+ const body = yield* verifyAndParseRequestBody(request).pipe(Effect.provide(SignatureLive), Effect.catch((error) => Effect.fail(HttpServerResponse.jsonUnsafe({ error: error.message }, {
50
+ status: Predicate.isTagged(error, "SignatureError") ? 401 : 400,
51
+ headers: { [Headers.NoRetry]: "true" }
52
+ }))));
53
+ const result = yield* handleExecution({
54
+ group,
55
+ fnId: params.fnId,
56
+ urlStepId: params.stepId,
57
+ body
58
+ });
59
+ return yield* HttpServerResponse.json(result.body, {
60
+ status: result.status,
61
+ headers: result.headers
62
+ });
63
+ }
64
+ return yield* HttpServerResponse.json({ error: `Method ${method} not allowed` }, { status: 405 });
65
+ }).pipe(Effect.catchCause((cause) => HttpServerResponse.json({
66
+ error: "Internal server error",
67
+ cause: String(cause)
68
+ }, { status: 500 }).pipe(Effect.orDie)));
69
+ const toWebHandler = (args) => HttpEffect.toWebHandlerLayer(toHttpApp(args.group), args.options.layer);
70
+ //#endregion
71
+ export { toHttpApp, toWebHandler };
@@ -0,0 +1,23 @@
1
+ import { Headers as Headers$1 } from "../protocol.js";
2
+ import { Signature, SignatureHeader, SignedPayload } from "./Signature.js";
3
+ import { Effect, Function, Option, Schema } from "effect";
4
+ import "effect/unstable/http/HttpServerRequest";
5
+ import * as Headers from "effect/unstable/http/Headers";
6
+ //#region src/internal/serve/Request.ts
7
+ const verifySignature = Function.dual(2, (body, request) => Effect.gen(function* () {
8
+ const sig = yield* Signature;
9
+ const signature = yield* Option.match(Headers.get(request.headers, Headers$1.Signature), {
10
+ onNone: () => Effect.succeed(Option.none()),
11
+ onSome: (header) => SignatureHeader.decode(header).pipe(Effect.map(Option.some))
12
+ });
13
+ yield* sig.verify(SignedPayload.make({
14
+ body,
15
+ signature
16
+ }));
17
+ }));
18
+ const schemaBodyJson = (schema) => (body) => {
19
+ const bodyText = new TextDecoder().decode(body);
20
+ return Schema.decodeUnknownEffect(Schema.fromJsonString(schema))(bodyText);
21
+ };
22
+ //#endregion
23
+ export { schemaBodyJson, verifySignature };
@@ -0,0 +1,11 @@
1
+ import { Context, Effect, Layer, Option, Schema } from "effect";
2
+ import * as _$effect_Cause0 from "effect/Cause";
3
+
4
+ //#region src/internal/serve/Signature.d.ts
5
+ declare const SignatureError_base: Schema.Class<SignatureError, Schema.TaggedStruct<"SignatureError", {
6
+ readonly reason: Schema.Literals<readonly ["missing_header", "invalid_format", "expired", "invalid_signature", "missing_signing_key"]>;
7
+ readonly message: Schema.String;
8
+ }>, _$effect_Cause0.YieldableError>;
9
+ declare class SignatureError extends SignatureError_base {}
10
+ //#endregion
11
+ export { SignatureError };