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.
- package/README.md +89 -67
- package/dist/Client.d.ts +76 -28
- package/dist/Client.js +92 -30
- package/dist/Event.d.ts +43 -0
- package/dist/Event.js +46 -0
- package/dist/Events.d.ts +48 -76
- package/dist/Events.js +18 -23
- package/dist/Function.d.ts +46 -19
- package/dist/Function.js +32 -22
- package/dist/Group.d.ts +19 -8
- package/dist/Group.js +30 -72
- package/dist/HttpApi.d.ts +51 -56
- package/dist/HttpApi.js +38 -21
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -3
- package/dist/internal/checkpoint/Config.d.ts +10 -0
- package/dist/internal/checkpoint/Config.js +29 -0
- package/dist/internal/checkpoint/Error.d.ts +11 -0
- package/dist/internal/checkpoint/Error.js +8 -0
- package/dist/internal/checkpoint/State.d.ts +1 -0
- package/dist/internal/checkpoint/State.js +54 -0
- package/dist/internal/checkpoint.d.ts +2 -0
- package/dist/internal/codec/EventPayload.d.ts +6 -0
- package/dist/internal/codec/EventPayload.js +60 -0
- package/dist/internal/codec/StepResult.js +55 -0
- package/dist/internal/domain/ExecutionInput.d.ts +40 -0
- package/dist/internal/domain/ExecutionInput.js +57 -0
- package/dist/internal/domain/ExecutionSuspension.d.ts +34 -0
- package/dist/internal/domain/ExecutionSuspension.js +64 -0
- package/dist/internal/domain/FunctionDefinition.js +13 -0
- package/dist/internal/domain/Memo.d.ts +22 -0
- package/dist/internal/domain/Memo.js +18 -0
- package/dist/internal/domain/StepCommand.d.ts +79 -0
- package/dist/internal/domain/StepCommand.js +124 -0
- package/dist/internal/domain/StepInfo.d.ts +12 -0
- package/dist/internal/domain/StepInfo.js +10 -0
- package/dist/internal/domain/StepInput.d.ts +10 -0
- package/dist/internal/driver.js +15 -114
- package/dist/internal/errors.d.ts +21 -48
- package/dist/internal/errors.js +9 -44
- package/dist/internal/execution/CheckpointRun.js +25 -0
- package/dist/internal/execution/ExecutionFailure.js +19 -0
- package/dist/internal/execution/ExecutionHeaders.js +58 -0
- package/dist/internal/execution/ExecutionResponse.js +68 -0
- package/dist/internal/execution/ExecutionResult.js +56 -0
- package/dist/internal/execution/ExecutionScope.js +30 -0
- package/dist/internal/execution/HandlerRun.js +16 -0
- package/dist/internal/handler.d.ts +5 -16
- package/dist/internal/handler.js +128 -96
- package/dist/internal/protocol.d.ts +143 -1
- package/dist/internal/protocol.js +333 -138
- package/dist/internal/runtime/CheckpointContext.js +5 -0
- package/dist/internal/runtime/HandlerContext.d.ts +13 -0
- package/dist/internal/runtime/HandlerContext.js +19 -0
- package/dist/internal/runtime/HandlerFiberScope.d.ts +10 -0
- package/dist/internal/runtime/HandlerFiberScope.js +5 -0
- package/dist/internal/runtime/StepCommandBus.d.ts +27 -0
- package/dist/internal/runtime/StepCommandBus.js +76 -0
- package/dist/internal/runtime/StepIdentity.d.ts +27 -0
- package/dist/internal/runtime/StepIdentity.js +46 -0
- package/dist/internal/runtime/StepTools.d.ts +83 -0
- package/dist/internal/runtime/StepTools.js +76 -0
- package/dist/internal/runtime/steps/InvokeStep.js +43 -0
- package/dist/internal/runtime/steps/SendEventStep.js +46 -0
- package/dist/internal/runtime/steps/SleepStep.js +22 -0
- package/dist/internal/runtime/steps/SleepUntilStep.js +22 -0
- package/dist/internal/runtime/steps/StepRun.js +48 -0
- package/dist/internal/runtime/steps/WaitForEventStep.js +27 -0
- package/dist/internal/serve/HttpApp.js +71 -0
- package/dist/internal/serve/Request.js +23 -0
- package/dist/internal/serve/Signature.d.ts +11 -0
- package/dist/internal/serve/Signature.js +123 -0
- package/dist/internal/wire/Duration.js +19 -0
- package/dist/internal/wire/Timestamp.js +14 -0
- package/package.json +34 -22
- package/src/Client.ts +269 -91
- package/src/Event.ts +107 -0
- package/src/Events.ts +50 -30
- package/src/Function.ts +102 -46
- package/src/Group.ts +56 -108
- package/src/HttpApi.ts +40 -30
- package/src/index.ts +21 -11
- package/src/internal/checkpoint/Config.ts +74 -0
- package/src/internal/checkpoint/Error.ts +6 -0
- package/src/internal/checkpoint/State.ts +107 -0
- package/src/internal/checkpoint.ts +3 -0
- package/src/internal/codec/EventPayload.ts +98 -0
- package/src/internal/codec/StepResult.ts +95 -0
- package/src/internal/domain/ExecutionInput.ts +66 -0
- package/src/internal/domain/ExecutionSuspension.ts +79 -0
- package/src/internal/domain/FunctionDefinition.ts +30 -0
- package/src/internal/domain/Memo.ts +28 -0
- package/src/internal/domain/StepCommand.ts +166 -0
- package/src/internal/domain/StepInfo.ts +8 -0
- package/src/internal/domain/StepInput.ts +10 -0
- package/src/internal/driver.ts +27 -185
- package/src/internal/errors.ts +14 -108
- package/src/internal/execution/CheckpointRun.ts +33 -0
- package/src/internal/execution/ExecutionFailure.ts +19 -0
- package/src/internal/execution/ExecutionHeaders.ts +86 -0
- package/src/internal/execution/ExecutionResponse.ts +79 -0
- package/src/internal/execution/ExecutionResult.ts +57 -0
- package/src/internal/execution/ExecutionScope.ts +41 -0
- package/src/internal/execution/HandlerRun.ts +38 -0
- package/src/internal/handler.ts +222 -172
- package/src/internal/protocol.ts +289 -78
- package/src/internal/runtime/CheckpointContext.ts +7 -0
- package/src/internal/runtime/HandlerContext.ts +21 -0
- package/src/internal/runtime/HandlerFiberScope.ts +9 -0
- package/src/internal/runtime/StepCommandBus.ts +129 -0
- package/src/internal/runtime/StepIdentity.ts +67 -0
- package/src/internal/runtime/StepTools.ts +161 -0
- package/src/internal/runtime/steps/InvokeStep.ts +71 -0
- package/src/internal/runtime/steps/SendEventStep.ts +67 -0
- package/src/internal/runtime/steps/SleepStep.ts +34 -0
- package/src/internal/runtime/steps/SleepUntilStep.ts +34 -0
- package/src/internal/runtime/steps/StepRun.ts +95 -0
- package/src/internal/runtime/steps/WaitForEventStep.ts +55 -0
- package/src/internal/serve/HttpApp.ts +123 -0
- package/src/internal/serve/Request.ts +27 -0
- package/src/internal/serve/Signature.ts +170 -0
- package/src/internal/wire/Duration.ts +31 -0
- package/src/internal/wire/Timestamp.ts +11 -0
- package/dist/_virtual/rolldown_runtime.js +0 -18
- package/dist/internal/constants.js +0 -15
- package/dist/internal/driver.d.ts +0 -5
- package/dist/internal/helpers.js +0 -44
- package/dist/internal/interrupts.d.ts +0 -2
- package/dist/internal/interrupts.js +0 -45
- package/dist/internal/memo.js +0 -56
- package/dist/internal/signature.d.ts +0 -18
- package/dist/internal/signature.js +0 -97
- package/dist/internal/step.d.ts +0 -59
- package/dist/internal/step.js +0 -192
- package/src/internal/constants.ts +0 -11
- package/src/internal/helpers.ts +0 -58
- package/src/internal/interrupts.ts +0 -62
- package/src/internal/memo.ts +0 -73
- package/src/internal/signature.ts +0 -158
- package/src/internal/step.ts +0 -394
package/dist/internal/driver.js
CHANGED
|
@@ -1,117 +1,18 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import * as Headers from "@effect/platform/Headers";
|
|
8
|
-
import * as HttpTraceContext from "@effect/platform/HttpTraceContext";
|
|
9
|
-
|
|
1
|
+
import "./protocol.js";
|
|
2
|
+
import { provide } from "./execution/ExecutionScope.js";
|
|
3
|
+
import { run, withCheckpointDeadline } from "./execution/HandlerRun.js";
|
|
4
|
+
import "./execution/ExecutionResult.js";
|
|
5
|
+
import { fromExit } from "./execution/ExecutionResponse.js";
|
|
6
|
+
import { Context, Effect, Layer, Option } from "effect";
|
|
10
7
|
//#region src/internal/driver.ts
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
status: Schema.Literal(200, 206, 500),
|
|
18
|
-
body: Schema.Unknown,
|
|
19
|
-
headers: Schema.Record({
|
|
20
|
-
key: Schema.String,
|
|
21
|
-
value: Schema.String
|
|
22
|
-
})
|
|
23
|
-
}) {};
|
|
24
|
-
const isStepInterrupt = Schema.is(StepInterrupt);
|
|
25
|
-
const isSomeWithValue = (v) => Predicate.isRecord(v) && Predicate.hasProperty(v, "_tag") && v._tag === "Some" && Predicate.hasProperty(v, "value");
|
|
26
|
-
const extractStepInterrupt = (value) => pipe(Option.liftPredicate(isStepInterrupt)(value), Option.orElse(() => pipe(Option.liftPredicate(isSomeWithValue)(value), Option.flatMap((v) => Option.liftPredicate(isStepInterrupt)(v.value)))));
|
|
27
|
-
const collectStepInterruptsFromError = (error) => pipe(extractStepInterrupt(error), Option.match({
|
|
28
|
-
onSome: Chunk.of,
|
|
29
|
-
onNone: () => Array.isArray(error) ? Chunk.fromIterable(Array$1.filterMap(error, extractStepInterrupt)) : Chunk.empty()
|
|
8
|
+
const execute = (args) => run({
|
|
9
|
+
fn: args.fn,
|
|
10
|
+
handler: args.handler
|
|
11
|
+
}).pipe(withCheckpointDeadline, Effect.scoped, Effect.exit, Effect.flatMap(fromExit), provide({
|
|
12
|
+
request: args.request,
|
|
13
|
+
checkpointConfig: args.checkpointConfig ?? Option.none()
|
|
30
14
|
}));
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
message: Predicate.hasProperty(error, "message") ? String(error.message) : String(error),
|
|
34
|
-
stack: Predicate.hasProperty(error, "stack") ? String(error.stack) : void 0
|
|
35
|
-
});
|
|
36
|
-
const baseHeaders = () => ({
|
|
37
|
-
"Content-Type": "application/json",
|
|
38
|
-
[Headers$1.SDK]: `effect-inngest:v${SDK_VERSION}`,
|
|
39
|
-
[Headers$1.RequestVersion]: "1"
|
|
40
|
-
});
|
|
41
|
-
const execute = (fn, handler, request, appName, traceHeaders = {}) => Effect.gen(function* () {
|
|
42
|
-
const step = createStepTools(request, appName, yield* Ref.make(HashMap.empty()));
|
|
43
|
-
const context = buildHandlerContext(fn, step, request);
|
|
44
|
-
const headers = baseHeaders();
|
|
45
|
-
return yield* handler(context).pipe(Effect.provideService(Step, step), Effect.map((value) => ExecutionResult.make({
|
|
46
|
-
status: 200,
|
|
47
|
-
body: value,
|
|
48
|
-
headers
|
|
49
|
-
})), Effect.catchAll((error) => {
|
|
50
|
-
const interrupts = collectStepInterruptsFromError(error);
|
|
51
|
-
if (!Chunk.isEmpty(interrupts)) {
|
|
52
|
-
const interruptArray = Chunk.toReadonlyArray(interrupts);
|
|
53
|
-
const opcodes = interruptArray.map((interrupt) => interrupt.opcode);
|
|
54
|
-
const hasNonRetriableError = opcodes.some((op) => op.op === Opcode.StepError && Predicate.isRecord(op.error) && Predicate.hasProperty(op.error, "noRetry") && op.error.noRetry === true);
|
|
55
|
-
const retryAfterMs = interruptArray.find((i) => i.retryAfterMs !== void 0)?.retryAfterMs;
|
|
56
|
-
const responseHeaders = hasNonRetriableError ? {
|
|
57
|
-
...headers,
|
|
58
|
-
[Headers$1.NoRetry]: "true"
|
|
59
|
-
} : headers;
|
|
60
|
-
if (retryAfterMs !== void 0) responseHeaders[Headers$1.RetryAfter] = String(Math.ceil(retryAfterMs / 1e3));
|
|
61
|
-
const encodedOpcodes = Schema.encodeSync(Schema.Array(GeneratorOpcode))(opcodes);
|
|
62
|
-
return Effect.succeed(ExecutionResult.make({
|
|
63
|
-
status: 206,
|
|
64
|
-
body: encodedOpcodes,
|
|
65
|
-
headers: responseHeaders
|
|
66
|
-
}));
|
|
67
|
-
}
|
|
68
|
-
if (isRetryAfterError(error)) {
|
|
69
|
-
const retryAfterMs = Duration.toMillis(error.retryAfter);
|
|
70
|
-
const retryAfterSeconds = Math.ceil(retryAfterMs / 1e3);
|
|
71
|
-
return Effect.succeed(ExecutionResult.make({
|
|
72
|
-
status: 500,
|
|
73
|
-
body: { error: toUserError(error) },
|
|
74
|
-
headers: {
|
|
75
|
-
...headers,
|
|
76
|
-
[Headers$1.NoRetry]: "false",
|
|
77
|
-
[Headers$1.RetryAfter]: String(retryAfterSeconds)
|
|
78
|
-
}
|
|
79
|
-
}));
|
|
80
|
-
}
|
|
81
|
-
const noRetry = isNonRetriableError(error) || isStepError(error) && error.noRetry === true ? "true" : "false";
|
|
82
|
-
return Effect.succeed(ExecutionResult.make({
|
|
83
|
-
status: 500,
|
|
84
|
-
body: { error: toUserError(error) },
|
|
85
|
-
headers: {
|
|
86
|
-
...headers,
|
|
87
|
-
[Headers$1.NoRetry]: noRetry
|
|
88
|
-
}
|
|
89
|
-
}));
|
|
90
|
-
}), Effect.catchAllDefect((defect) => Effect.succeed(ExecutionResult.make({
|
|
91
|
-
status: 500,
|
|
92
|
-
body: { error: toUserError(defect) },
|
|
93
|
-
headers: {
|
|
94
|
-
...headers,
|
|
95
|
-
[Headers$1.NoRetry]: "false"
|
|
96
|
-
}
|
|
97
|
-
}))));
|
|
98
|
-
}).pipe((base) => {
|
|
99
|
-
const headers = {};
|
|
100
|
-
if (traceHeaders.traceparent) headers["traceparent"] = traceHeaders.traceparent;
|
|
101
|
-
if (traceHeaders.tracestate) headers["tracestate"] = traceHeaders.tracestate;
|
|
102
|
-
return pipe(HttpTraceContext.fromHeaders(Headers.fromInput(headers)), Option.match({
|
|
103
|
-
onNone: () => base,
|
|
104
|
-
onSome: (externalSpan) => Effect.withParentSpan(base, externalSpan)
|
|
105
|
-
}));
|
|
106
|
-
}, Effect.withSpan(`inngest.function/${fn._tag}`, {
|
|
107
|
-
kind: "server",
|
|
108
|
-
attributes: {
|
|
109
|
-
[OtelAttributes.RunId]: request.ctx.run_id,
|
|
110
|
-
[OtelAttributes.FunctionId]: fn._tag,
|
|
111
|
-
[OtelAttributes.AppId]: appName,
|
|
112
|
-
[OtelAttributes.Attempt]: request.ctx.attempt
|
|
113
|
-
}
|
|
114
|
-
}));
|
|
115
|
-
|
|
15
|
+
var Driver = class extends Context.Service()("effect-inngest/Driver") {};
|
|
16
|
+
Layer.succeed(Driver, { execute });
|
|
116
17
|
//#endregion
|
|
117
|
-
export { execute };
|
|
18
|
+
export { execute };
|
|
@@ -1,56 +1,29 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
import * as _$effect_Cause0 from "effect/Cause";
|
|
2
3
|
|
|
3
4
|
//#region src/internal/errors.d.ts
|
|
4
|
-
declare const SendEventError_base: Schema.
|
|
5
|
-
readonly
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
events: Schema.Array$<typeof Schema.String>;
|
|
9
|
-
}>;
|
|
10
|
-
/**
|
|
11
|
-
* @internal
|
|
12
|
-
*/
|
|
5
|
+
declare const SendEventError_base: Schema.Class<SendEventError, Schema.TaggedStruct<"SendEventError", {
|
|
6
|
+
readonly message: Schema.String;
|
|
7
|
+
readonly events: Schema.$Array<Schema.String>;
|
|
8
|
+
}>, _$effect_Cause0.YieldableError>;
|
|
13
9
|
declare class SendEventError extends SendEventError_base {}
|
|
14
|
-
declare const StepError_base: Schema.
|
|
15
|
-
readonly
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
noRetry: Schema.optional<typeof Schema.Boolean>;
|
|
21
|
-
}>;
|
|
22
|
-
/**
|
|
23
|
-
* @internal
|
|
24
|
-
*/
|
|
10
|
+
declare const StepError_base: Schema.Class<StepError, Schema.TaggedStruct<"StepError", {
|
|
11
|
+
readonly message: Schema.String;
|
|
12
|
+
readonly stepId: Schema.String;
|
|
13
|
+
readonly cause: Schema.optional<Schema.Unknown>;
|
|
14
|
+
readonly noRetry: Schema.optional<Schema.Boolean>;
|
|
15
|
+
}>, _$effect_Cause0.YieldableError>;
|
|
25
16
|
declare class StepError extends StepError_base {}
|
|
26
|
-
declare const NonRetriableError_base: Schema.
|
|
27
|
-
readonly
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
cause: Schema.optional<typeof Schema.Unknown>;
|
|
31
|
-
}>;
|
|
32
|
-
/**
|
|
33
|
-
* Thrown to indicate that the error should not be retried.
|
|
34
|
-
* Use this when you know retrying won't help (e.g., validation errors, auth failures).
|
|
35
|
-
*
|
|
36
|
-
* @since 0.1.0
|
|
37
|
-
* @category errors
|
|
38
|
-
*/
|
|
17
|
+
declare const NonRetriableError_base: Schema.Class<NonRetriableError, Schema.TaggedStruct<"NonRetriableError", {
|
|
18
|
+
readonly message: Schema.String;
|
|
19
|
+
readonly cause: Schema.optional<Schema.Unknown>;
|
|
20
|
+
}>, _$effect_Cause0.YieldableError>;
|
|
39
21
|
declare class NonRetriableError extends NonRetriableError_base {}
|
|
40
|
-
declare const RetryAfterError_base: Schema.
|
|
41
|
-
readonly
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
cause: Schema.optional<typeof Schema.Unknown>;
|
|
46
|
-
}>;
|
|
47
|
-
/**
|
|
48
|
-
* Thrown to indicate that the operation should be retried after a specific delay.
|
|
49
|
-
* Use this for rate limiting or when you know when a resource will become available.
|
|
50
|
-
*
|
|
51
|
-
* @since 0.1.0
|
|
52
|
-
* @category errors
|
|
53
|
-
*/
|
|
22
|
+
declare const RetryAfterError_base: Schema.Class<RetryAfterError, Schema.TaggedStruct<"RetryAfterError", {
|
|
23
|
+
readonly message: Schema.String;
|
|
24
|
+
readonly retryAfter: Schema.DurationFromMillis;
|
|
25
|
+
readonly cause: Schema.optional<Schema.Unknown>;
|
|
26
|
+
}>, _$effect_Cause0.YieldableError>;
|
|
54
27
|
declare class RetryAfterError extends RetryAfterError_base {}
|
|
55
28
|
//#endregion
|
|
56
29
|
export { NonRetriableError, RetryAfterError, SendEventError, StepError };
|
package/dist/internal/errors.js
CHANGED
|
@@ -1,61 +1,26 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import { Predicate, Schema } from "effect";
|
|
3
2
|
//#region src/internal/errors.ts
|
|
4
|
-
|
|
5
|
-
* Internal error types for the Effect Inngest SDK.
|
|
6
|
-
* @internal
|
|
7
|
-
*/
|
|
8
|
-
/**
|
|
9
|
-
* @internal
|
|
10
|
-
*/
|
|
11
|
-
var SendEventError = class extends Schema.TaggedError()("SendEventError", {
|
|
3
|
+
var SendEventError = class extends Schema.TaggedErrorClass()("SendEventError", {
|
|
12
4
|
message: Schema.String,
|
|
13
5
|
events: Schema.Array(Schema.String)
|
|
14
6
|
}) {};
|
|
15
|
-
|
|
16
|
-
* @internal
|
|
17
|
-
*/
|
|
18
|
-
var StepError = class extends Schema.TaggedError()("StepError", {
|
|
7
|
+
var StepError = class extends Schema.TaggedErrorClass()("StepError", {
|
|
19
8
|
message: Schema.String,
|
|
20
9
|
stepId: Schema.String,
|
|
21
10
|
cause: Schema.optional(Schema.Unknown),
|
|
22
11
|
noRetry: Schema.optional(Schema.Boolean)
|
|
23
12
|
}) {};
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
*/
|
|
27
|
-
const isStepError = Schema.is(StepError);
|
|
28
|
-
/**
|
|
29
|
-
* Thrown to indicate that the error should not be retried.
|
|
30
|
-
* Use this when you know retrying won't help (e.g., validation errors, auth failures).
|
|
31
|
-
*
|
|
32
|
-
* @since 0.1.0
|
|
33
|
-
* @category errors
|
|
34
|
-
*/
|
|
35
|
-
var NonRetriableError = class extends Schema.TaggedError()("NonRetriableError", {
|
|
13
|
+
const isStepError = Predicate.isTagged("StepError");
|
|
14
|
+
var NonRetriableError = class extends Schema.TaggedErrorClass()("NonRetriableError", {
|
|
36
15
|
message: Schema.String,
|
|
37
16
|
cause: Schema.optional(Schema.Unknown)
|
|
38
17
|
}) {};
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
*/
|
|
42
|
-
const isNonRetriableError = Schema.is(NonRetriableError);
|
|
43
|
-
/**
|
|
44
|
-
* Thrown to indicate that the operation should be retried after a specific delay.
|
|
45
|
-
* Use this for rate limiting or when you know when a resource will become available.
|
|
46
|
-
*
|
|
47
|
-
* @since 0.1.0
|
|
48
|
-
* @category errors
|
|
49
|
-
*/
|
|
50
|
-
var RetryAfterError = class extends Schema.TaggedError()("RetryAfterError", {
|
|
18
|
+
const isNonRetriableError = Predicate.isTagged("NonRetriableError");
|
|
19
|
+
var RetryAfterError = class extends Schema.TaggedErrorClass()("RetryAfterError", {
|
|
51
20
|
message: Schema.String,
|
|
52
21
|
retryAfter: Schema.DurationFromMillis,
|
|
53
22
|
cause: Schema.optional(Schema.Unknown)
|
|
54
23
|
}) {};
|
|
55
|
-
|
|
56
|
-
* @internal
|
|
57
|
-
*/
|
|
58
|
-
const isRetryAfterError = Schema.is(RetryAfterError);
|
|
59
|
-
|
|
24
|
+
const isRetryAfterError = Predicate.isTagged("RetryAfterError");
|
|
60
25
|
//#endregion
|
|
61
|
-
export { NonRetriableError, RetryAfterError, SendEventError, StepError, isNonRetriableError, isRetryAfterError, isStepError };
|
|
26
|
+
export { NonRetriableError, RetryAfterError, SendEventError, StepError, isNonRetriableError, isRetryAfterError, isStepError };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { make as make$1 } from "../checkpoint/State.js";
|
|
2
|
+
import "../protocol.js";
|
|
3
|
+
import { InngestClient } from "../../Client.js";
|
|
4
|
+
import { Effect, Option } from "effect";
|
|
5
|
+
//#region src/internal/execution/CheckpointRun.ts
|
|
6
|
+
const make = (args) => Option.match(args.config, {
|
|
7
|
+
onNone: () => Effect.succeed(Option.none()),
|
|
8
|
+
onSome: (config) => InngestClient.use((client) => make$1({
|
|
9
|
+
config,
|
|
10
|
+
runId: args.request.ctx.run_id,
|
|
11
|
+
fnId: args.request.ctx.fn_id,
|
|
12
|
+
qiId: args.request.ctx.qi_id,
|
|
13
|
+
checkpointAsync: (steps) => client.checkpointAsync({
|
|
14
|
+
runId: args.request.ctx.run_id,
|
|
15
|
+
fnId: args.request.ctx.fn_id,
|
|
16
|
+
qiId: args.request.ctx.qi_id,
|
|
17
|
+
requestId: args.request.ctx.request_id,
|
|
18
|
+
generationId: args.request.ctx.generation_id,
|
|
19
|
+
requestStartedAt: args.requestStartedAt,
|
|
20
|
+
steps
|
|
21
|
+
})
|
|
22
|
+
}).pipe(Effect.map(Option.some)))
|
|
23
|
+
});
|
|
24
|
+
//#endregion
|
|
25
|
+
export { make };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { UserError } from "../protocol.js";
|
|
2
|
+
import { Cause, Option, Schema } from "effect";
|
|
3
|
+
//#region src/internal/execution/ExecutionFailure.ts
|
|
4
|
+
var ExecutionFailure = class ExecutionFailure extends Schema.Class("effect-inngest/internal/execution/ExecutionFailure")({ error: Schema.Unknown }) {
|
|
5
|
+
static fromCause(cause) {
|
|
6
|
+
return ExecutionFailure.make({ error: ExecutionFailure.errorFromCause(cause) });
|
|
7
|
+
}
|
|
8
|
+
static errorFromCause(cause) {
|
|
9
|
+
return Option.orElse(Cause.findErrorOption(cause), () => {
|
|
10
|
+
const dieReason = cause.reasons.find(Cause.isDieReason);
|
|
11
|
+
return dieReason ? Option.some(dieReason.defect) : Option.none();
|
|
12
|
+
}).pipe(Option.getOrElse(() => UserError.make({
|
|
13
|
+
name: "Error",
|
|
14
|
+
message: "Unknown error"
|
|
15
|
+
})));
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
//#endregion
|
|
19
|
+
export { ExecutionFailure };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Headers as Headers$1 } from "../protocol.js";
|
|
2
|
+
import { isNonRetriableError, isRetryAfterError, isStepError } from "../errors.js";
|
|
3
|
+
import { Duration, Option, Schema } from "effect";
|
|
4
|
+
import * as Headers from "effect/unstable/http/Headers";
|
|
5
|
+
//#region src/internal/execution/ExecutionHeaders.ts
|
|
6
|
+
const SDK_VERSION = "2.0.0";
|
|
7
|
+
var RetryDisposition = class RetryDisposition extends Schema.Class("effect-inngest/internal/execution/RetryDisposition")({
|
|
8
|
+
noRetry: Schema.Boolean,
|
|
9
|
+
isFailure: Schema.Boolean,
|
|
10
|
+
retryAfterMs: Schema.Option(Schema.Number)
|
|
11
|
+
}) {
|
|
12
|
+
static none = RetryDisposition.make({
|
|
13
|
+
noRetry: false,
|
|
14
|
+
isFailure: false,
|
|
15
|
+
retryAfterMs: Option.none()
|
|
16
|
+
});
|
|
17
|
+
static failure(args) {
|
|
18
|
+
return RetryDisposition.make({
|
|
19
|
+
noRetry: args.noRetry,
|
|
20
|
+
isFailure: true,
|
|
21
|
+
retryAfterMs: args.retryAfterMs ?? Option.none()
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
static fromSuspension(commands) {
|
|
25
|
+
if (!commands.hasFailure && Option.isNone(commands.retryAfterMs)) return RetryDisposition.none;
|
|
26
|
+
return RetryDisposition.failure({
|
|
27
|
+
noRetry: commands.noRetry,
|
|
28
|
+
retryAfterMs: commands.retryAfterMs
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
static fromError(error) {
|
|
32
|
+
if (isRetryAfterError(error)) return RetryDisposition.failure({
|
|
33
|
+
noRetry: false,
|
|
34
|
+
retryAfterMs: Option.some(Duration.toMillis(error.retryAfter))
|
|
35
|
+
});
|
|
36
|
+
return RetryDisposition.failure({ noRetry: isNonRetriableError(error) || isStepError(error) && error.noRetry === true });
|
|
37
|
+
}
|
|
38
|
+
toHeaders() {
|
|
39
|
+
if (Option.isSome(this.retryAfterMs)) return Headers.fromInput({
|
|
40
|
+
[Headers$1.NoRetry]: "false",
|
|
41
|
+
[Headers$1.RetryAfter]: String(Math.ceil(this.retryAfterMs.value / 1e3))
|
|
42
|
+
});
|
|
43
|
+
if (this.noRetry) return Headers.fromInput({ [Headers$1.NoRetry]: "true" });
|
|
44
|
+
if (this.isFailure) return Headers.fromInput({ [Headers$1.NoRetry]: "false" });
|
|
45
|
+
return Headers.empty;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const base = (config) => Headers.fromInput({
|
|
49
|
+
"Content-Type": "application/json",
|
|
50
|
+
"User-Agent": `effect-inngest:v${SDK_VERSION}`,
|
|
51
|
+
[Headers$1.SDK]: `effect-inngest:v${SDK_VERSION}`,
|
|
52
|
+
[Headers$1.SDKHandled]: "true",
|
|
53
|
+
[Headers$1.RequestVersion]: "2",
|
|
54
|
+
...config.framework ? { [Headers$1.Framework]: config.framework } : {}
|
|
55
|
+
});
|
|
56
|
+
const merge = (headers, retry) => Headers.merge(headers, retry.toHeaders());
|
|
57
|
+
//#endregion
|
|
58
|
+
export { RetryDisposition, base, merge };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { GeneratorOpcode } from "../protocol.js";
|
|
2
|
+
import { InngestConfig } from "../../Client.js";
|
|
3
|
+
import { CurrentCheckpoint } from "../runtime/CheckpointContext.js";
|
|
4
|
+
import { StepCommandBus } from "../runtime/StepCommandBus.js";
|
|
5
|
+
import { ExecutionFailure } from "./ExecutionFailure.js";
|
|
6
|
+
import { RetryDisposition, base } from "./ExecutionHeaders.js";
|
|
7
|
+
import { ExecutionResult } from "./ExecutionResult.js";
|
|
8
|
+
import { Cause, Effect, Exit, Match, Option } from "effect";
|
|
9
|
+
//#region src/internal/execution/ExecutionResponse.ts
|
|
10
|
+
const fromSuccess = (args) => Effect.gen(function* () {
|
|
11
|
+
const bus = yield* StepCommandBus;
|
|
12
|
+
const checkpoint = yield* CurrentCheckpoint;
|
|
13
|
+
const completed = yield* bus.takeCompleted();
|
|
14
|
+
if (Option.isSome(checkpoint)) {
|
|
15
|
+
const terminal = Match.value(args.completion).pipe(Match.tag("CheckpointDeadlineElapsed", () => GeneratorOpcode.discoveryRequest()), Match.tag("HandlerSucceeded", (completion) => GeneratorOpcode.runComplete(completion.value)), Match.exhaustive);
|
|
16
|
+
return ExecutionResult.opcodes({
|
|
17
|
+
opcodes: [...completed, terminal],
|
|
18
|
+
headers: args.headers
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return Match.value(args.completion).pipe(Match.tag("HandlerSucceeded", (completion) => ExecutionResult.success({
|
|
22
|
+
body: completion.value,
|
|
23
|
+
headers: args.headers
|
|
24
|
+
})), Match.tag("CheckpointDeadlineElapsed", () => ExecutionResult.checkpointDeadlineOutsideCheckpoint(args)), Match.exhaustive);
|
|
25
|
+
});
|
|
26
|
+
const fromFailure = (args) => Effect.gen(function* () {
|
|
27
|
+
const commands = yield* (yield* StepCommandBus).takeSuspension();
|
|
28
|
+
if (commands.suspendedCount > 0 && Cause.hasInterruptsOnly(args.cause)) return ExecutionResult.opcodesWithRetry({
|
|
29
|
+
opcodes: commands.opcodes,
|
|
30
|
+
headers: args.headers,
|
|
31
|
+
disposition: RetryDisposition.fromSuspension(commands)
|
|
32
|
+
});
|
|
33
|
+
if (Cause.hasInterruptsOnly(args.cause)) return yield* Effect.interrupt;
|
|
34
|
+
const failure = ExecutionFailure.fromCause(args.cause);
|
|
35
|
+
const disposition = RetryDisposition.fromError(failure.error);
|
|
36
|
+
if (commands.completed.length > 0) return ExecutionResult.opcodesWithRetry({
|
|
37
|
+
opcodes: commands.completed,
|
|
38
|
+
headers: args.headers,
|
|
39
|
+
disposition
|
|
40
|
+
});
|
|
41
|
+
return ExecutionResult.userError({
|
|
42
|
+
error: failure.error,
|
|
43
|
+
headers: args.headers,
|
|
44
|
+
disposition
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
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();
|
|
52
|
+
if (planned.length > 0) return ExecutionResult.opcodes({
|
|
53
|
+
opcodes: planned,
|
|
54
|
+
headers
|
|
55
|
+
});
|
|
56
|
+
return yield* Exit.match(exit, {
|
|
57
|
+
onSuccess: (completion) => fromSuccess({
|
|
58
|
+
completion,
|
|
59
|
+
headers
|
|
60
|
+
}),
|
|
61
|
+
onFailure: (cause) => fromFailure({
|
|
62
|
+
cause,
|
|
63
|
+
headers
|
|
64
|
+
})
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
//#endregion
|
|
68
|
+
export { fromExit };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { GeneratorOpcode, UserError } from "../protocol.js";
|
|
2
|
+
import { RetryDisposition, merge } from "./ExecutionHeaders.js";
|
|
3
|
+
import { Schema } from "effect";
|
|
4
|
+
import * as Headers from "effect/unstable/http/Headers";
|
|
5
|
+
//#region src/internal/execution/ExecutionResult.ts
|
|
6
|
+
var ExecutionResult = class ExecutionResult extends Schema.Class("ExecutionResult")({
|
|
7
|
+
status: Schema.Literals([
|
|
8
|
+
200,
|
|
9
|
+
206,
|
|
10
|
+
400,
|
|
11
|
+
500
|
|
12
|
+
]),
|
|
13
|
+
body: Schema.Unknown,
|
|
14
|
+
headers: Headers.HeadersSchema
|
|
15
|
+
}) {
|
|
16
|
+
static success(args) {
|
|
17
|
+
return ExecutionResult.make({
|
|
18
|
+
status: 200,
|
|
19
|
+
body: args.body,
|
|
20
|
+
headers: args.headers
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
static opcodes(args) {
|
|
24
|
+
return ExecutionResult.make({
|
|
25
|
+
status: 206,
|
|
26
|
+
body: encodeOpcodes(args.opcodes),
|
|
27
|
+
headers: args.headers
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
static opcodesWithRetry(args) {
|
|
31
|
+
return ExecutionResult.opcodes({
|
|
32
|
+
opcodes: args.opcodes,
|
|
33
|
+
headers: merge(args.headers, args.disposition)
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
static userError(args) {
|
|
37
|
+
return ExecutionResult.make({
|
|
38
|
+
status: args.disposition.noRetry ? 400 : 500,
|
|
39
|
+
body: UserError.fromUnknown(args.error),
|
|
40
|
+
headers: merge(args.headers, args.disposition)
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
static checkpointDeadlineOutsideCheckpoint(args) {
|
|
44
|
+
return ExecutionResult.make({
|
|
45
|
+
status: 500,
|
|
46
|
+
body: UserError.make({
|
|
47
|
+
name: "Error",
|
|
48
|
+
message: "Checkpoint deadline elapsed outside checkpoint mode"
|
|
49
|
+
}),
|
|
50
|
+
headers: merge(args.headers, RetryDisposition.failure({ noRetry: false }))
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
const encodeOpcodes = (opcodes) => Schema.encodeSync(Schema.Array(GeneratorOpcode))(opcodes);
|
|
55
|
+
//#endregion
|
|
56
|
+
export { ExecutionResult };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import "../protocol.js";
|
|
2
|
+
import { InngestClient, InngestConfig } from "../../Client.js";
|
|
3
|
+
import { make } from "./CheckpointRun.js";
|
|
4
|
+
import { CurrentExecutionInput, ExecutionInput } from "../domain/ExecutionInput.js";
|
|
5
|
+
import { CurrentCheckpoint } from "../runtime/CheckpointContext.js";
|
|
6
|
+
import { HandlerFiberScope } from "../runtime/HandlerFiberScope.js";
|
|
7
|
+
import { StepCommandBus } from "../runtime/StepCommandBus.js";
|
|
8
|
+
import { StepIdentity } from "../runtime/StepIdentity.js";
|
|
9
|
+
import { StepTools } from "../runtime/StepTools.js";
|
|
10
|
+
import { Clock, Context, Effect } from "effect";
|
|
11
|
+
//#region src/internal/execution/ExecutionScope.ts
|
|
12
|
+
const provide = (args) => (effect) => Effect.gen(function* () {
|
|
13
|
+
const client = yield* InngestClient;
|
|
14
|
+
const rootFiberId = yield* Effect.fiberId;
|
|
15
|
+
const requestStartedAt = yield* Clock.currentTimeMillis;
|
|
16
|
+
const input = ExecutionInput.fromSdkRequestBody(args.request);
|
|
17
|
+
const checkpoint = yield* make({
|
|
18
|
+
request: args.request,
|
|
19
|
+
config: args.checkpointConfig,
|
|
20
|
+
requestStartedAt
|
|
21
|
+
});
|
|
22
|
+
const bus = yield* StepCommandBus.make;
|
|
23
|
+
const identity = yield* StepIdentity.make;
|
|
24
|
+
const baseContext = Context.make(CurrentExecutionInput, input).pipe(Context.add(CurrentCheckpoint, checkpoint), Context.add(InngestConfig, client.config), Context.add(StepCommandBus, bus), Context.add(StepIdentity, identity), Context.add(HandlerFiberScope, { isForkedFromHandlerRoot: Effect.map(Effect.fiberId, (fiberId) => fiberId !== rootFiberId) }));
|
|
25
|
+
const stepTools = yield* StepTools.make.pipe(Effect.provide(baseContext));
|
|
26
|
+
const context = Context.add(baseContext, StepTools, stepTools);
|
|
27
|
+
return yield* effect.pipe(Effect.provide(context));
|
|
28
|
+
});
|
|
29
|
+
//#endregion
|
|
30
|
+
export { provide };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CurrentCheckpoint } from "../runtime/CheckpointContext.js";
|
|
2
|
+
import { make } from "../runtime/HandlerContext.js";
|
|
3
|
+
import { Effect, Option, Schema } from "effect";
|
|
4
|
+
//#region src/internal/execution/HandlerRun.ts
|
|
5
|
+
var HandlerSucceeded = class extends Schema.TaggedClass()("HandlerSucceeded", { value: Schema.Unknown }) {};
|
|
6
|
+
Schema.TaggedClass()("CheckpointDeadlineElapsed", {});
|
|
7
|
+
const run = (args) => make({ fn: args.fn }).pipe(Effect.flatMap(args.handler), Effect.map((value) => HandlerSucceeded.make({ value })));
|
|
8
|
+
const withCheckpointDeadline = (effect) => Effect.gen(function* () {
|
|
9
|
+
const checkpoint = yield* CurrentCheckpoint;
|
|
10
|
+
return yield* Option.match(checkpoint, {
|
|
11
|
+
onNone: () => effect,
|
|
12
|
+
onSome: (state) => Effect.sleep(state.config.maxRuntime).pipe(Effect.andThen(state.markRuntimeExceeded), Effect.forkScoped, Effect.andThen(effect))
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
//#endregion
|
|
16
|
+
export { run, withCheckpointDeadline };
|
|
@@ -1,20 +1,9 @@
|
|
|
1
|
-
import "
|
|
2
|
-
import "
|
|
3
|
-
import "../Group.js";
|
|
4
|
-
import { SignatureError } from "./signature.js";
|
|
5
|
-
import "./driver.js";
|
|
6
|
-
import "@effect/platform/HttpClient";
|
|
7
|
-
import "@effect/platform/HttpServerRequest";
|
|
8
|
-
import "effect/Context";
|
|
9
|
-
import "effect/Effect";
|
|
10
|
-
import * as Schema from "effect/Schema";
|
|
11
|
-
|
|
1
|
+
import { SignatureError } from "./serve/Signature.js";
|
|
2
|
+
import { Cause, Context, Effect, Schema } from "effect";
|
|
12
3
|
//#region src/internal/handler.d.ts
|
|
13
|
-
declare const InvalidRequestError_base: Schema.
|
|
14
|
-
readonly
|
|
15
|
-
}
|
|
16
|
-
message: typeof Schema.String;
|
|
17
|
-
}>;
|
|
4
|
+
declare const InvalidRequestError_base: Schema.Class<InvalidRequestError, Schema.TaggedStruct<"InvalidRequestError", {
|
|
5
|
+
readonly message: Schema.String;
|
|
6
|
+
}>, Cause.YieldableError>;
|
|
18
7
|
declare class InvalidRequestError extends InvalidRequestError_base {}
|
|
19
8
|
//#endregion
|
|
20
9
|
export { InvalidRequestError };
|