effect-inngest 0.1.3 → 0.2.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Client.d.ts +55 -24
- package/dist/Client.js +84 -25
- package/dist/Events.d.ts +36 -61
- package/dist/Events.js +5 -13
- package/dist/Function.d.ts +35 -15
- package/dist/Function.js +14 -8
- package/dist/Group.d.ts +5 -4
- package/dist/Group.js +26 -24
- package/dist/HttpApi.d.ts +49 -54
- package/dist/HttpApi.js +32 -17
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/index.js +1 -2
- package/dist/internal/checkpoint.d.ts +32 -0
- package/dist/internal/checkpoint.js +112 -0
- package/dist/internal/constants.js +1 -2
- package/dist/internal/driver.d.ts +1 -5
- package/dist/internal/driver.js +164 -52
- package/dist/internal/errors.d.ts +20 -27
- package/dist/internal/errors.js +29 -15
- package/dist/internal/handler.d.ts +4 -13
- package/dist/internal/handler.js +70 -43
- package/dist/internal/helpers.js +12 -9
- package/dist/internal/interrupts.d.ts +1 -2
- package/dist/internal/interrupts.js +1 -3
- package/dist/internal/memo.js +22 -20
- package/dist/internal/protocol.d.ts +28 -1
- package/dist/internal/protocol.js +84 -52
- package/dist/internal/signature.d.ts +5 -9
- package/dist/internal/signature.js +34 -18
- package/dist/internal/step.d.ts +5 -11
- package/dist/internal/step.js +48 -32
- package/package.json +26 -21
- package/src/Client.ts +244 -68
- package/src/Events.ts +3 -3
- package/src/Function.ts +52 -15
- package/src/Group.ts +39 -26
- package/src/HttpApi.ts +38 -27
- package/src/internal/checkpoint.ts +218 -0
- package/src/internal/driver.ts +241 -93
- package/src/internal/errors.ts +21 -14
- package/src/internal/handler.ts +185 -142
- package/src/internal/helpers.ts +9 -9
- package/src/internal/memo.ts +48 -33
- package/src/internal/protocol.ts +89 -45
- package/src/internal/signature.ts +76 -58
- package/src/internal/step.ts +84 -31
- package/dist/_virtual/rolldown_runtime.js +0 -18
package/src/internal/driver.ts
CHANGED
|
@@ -2,15 +2,28 @@
|
|
|
2
2
|
* Driver execution logic.
|
|
3
3
|
* @internal
|
|
4
4
|
*/
|
|
5
|
-
import * as Headers from "
|
|
6
|
-
import * as HttpTraceContext from "
|
|
7
|
-
import
|
|
5
|
+
import * as Headers from "effect/unstable/http/Headers";
|
|
6
|
+
import * as HttpTraceContext from "effect/unstable/http/HttpTraceContext";
|
|
7
|
+
import * as Cause from "effect/Cause";
|
|
8
|
+
import * as Chunk from "effect/Chunk";
|
|
9
|
+
import * as Context from "effect/Context";
|
|
10
|
+
import * as Duration from "effect/Duration";
|
|
11
|
+
import * as Effect from "effect/Effect";
|
|
12
|
+
import * as HashMap from "effect/HashMap";
|
|
13
|
+
import * as Layer from "effect/Layer";
|
|
14
|
+
import * as Option from "effect/Option";
|
|
15
|
+
import { pipe } from "effect/Function";
|
|
16
|
+
import * as Predicate from "effect/Predicate";
|
|
17
|
+
import * as Ref from "effect/Ref";
|
|
18
|
+
import * as Schema from "effect/Schema";
|
|
8
19
|
import type { InngestFunction } from "../Function.js";
|
|
9
20
|
import { InngestClient } from "../Client.js";
|
|
21
|
+
import * as Checkpoint from "./checkpoint.js";
|
|
22
|
+
import type { CheckpointConfig, CheckpointState } from "./checkpoint.js";
|
|
10
23
|
import { isRetryAfterError, isNonRetriableError, isStepError, type RetryAfterError, type StepError } from "./errors.js";
|
|
11
24
|
import * as Protocol from "./protocol.js";
|
|
12
25
|
import { StepInterrupt } from "./interrupts.js";
|
|
13
|
-
import { createStepTools, buildHandlerContext,
|
|
26
|
+
import { createStepTools, buildHandlerContext, type HandlerContext } from "./step.js";
|
|
14
27
|
import { OtelAttributes } from "./constants.js";
|
|
15
28
|
|
|
16
29
|
/** Trace context headers extracted from incoming request */
|
|
@@ -22,36 +35,22 @@ export interface TraceHeaders {
|
|
|
22
35
|
const SDK_VERSION = "2.0.0";
|
|
23
36
|
|
|
24
37
|
export class ExecutionResult extends Schema.Class<ExecutionResult>("ExecutionResult")({
|
|
25
|
-
status: Schema.
|
|
38
|
+
status: Schema.Literals([200, 206, 400, 500]),
|
|
26
39
|
body: Schema.Unknown,
|
|
27
|
-
headers: Schema.Record(
|
|
40
|
+
headers: Schema.Record(Schema.String, Schema.String),
|
|
28
41
|
}) {}
|
|
29
42
|
|
|
30
43
|
const isStepInterrupt = Schema.is(StepInterrupt);
|
|
31
44
|
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
Option.flatMap((v) => Option.liftPredicate(isStepInterrupt)(v.value)),
|
|
42
|
-
),
|
|
43
|
-
),
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
const collectStepInterruptsFromError = (error: unknown): Chunk.Chunk<StepInterrupt> =>
|
|
47
|
-
pipe(
|
|
48
|
-
extractStepInterrupt(error),
|
|
49
|
-
Option.match({
|
|
50
|
-
onSome: Chunk.of,
|
|
51
|
-
onNone: () =>
|
|
52
|
-
Array.isArray(error) ? Chunk.fromIterable(Arr.filterMap(error, extractStepInterrupt)) : Chunk.empty(),
|
|
53
|
-
}),
|
|
54
|
-
);
|
|
45
|
+
const collectStepInterruptsFromCause = <E>(cause: Cause.Cause<E>): Chunk.Chunk<StepInterrupt> => {
|
|
46
|
+
const interrupts: Array<StepInterrupt> = [];
|
|
47
|
+
for (const reason of cause.reasons) {
|
|
48
|
+
if (Cause.isFailReason(reason) && isStepInterrupt(reason.error)) {
|
|
49
|
+
interrupts.push(reason.error);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return Chunk.fromIterable(interrupts);
|
|
53
|
+
};
|
|
55
54
|
|
|
56
55
|
const toUserError = (error: unknown): typeof Protocol.UserError.Type =>
|
|
57
56
|
Protocol.UserError.make({
|
|
@@ -63,89 +62,236 @@ const toUserError = (error: unknown): typeof Protocol.UserError.Type =>
|
|
|
63
62
|
const baseHeaders = (): Record<string, string> => ({
|
|
64
63
|
"Content-Type": "application/json",
|
|
65
64
|
[Protocol.Headers.SDK]: `effect-inngest:v${SDK_VERSION}`,
|
|
66
|
-
[Protocol.Headers.RequestVersion]: "
|
|
65
|
+
[Protocol.Headers.RequestVersion]: "2",
|
|
67
66
|
});
|
|
68
67
|
|
|
68
|
+
const encodeOpcodes = (opcodes: ReadonlyArray<typeof Protocol.GeneratorOpcode.Type>): unknown =>
|
|
69
|
+
Schema.encodeSync(Schema.Array(Protocol.GeneratorOpcode))(opcodes);
|
|
70
|
+
|
|
69
71
|
export const execute = <F extends InngestFunction.Any, R>(
|
|
70
72
|
fn: F,
|
|
71
73
|
handler: (ctx: HandlerContext<F>) => Effect.Effect<InngestFunction.Success<F>, unknown, R>,
|
|
72
74
|
request: Protocol.SDKRequestBody,
|
|
73
75
|
appName: string,
|
|
74
76
|
traceHeaders: TraceHeaders = {},
|
|
77
|
+
checkpointConfig: Option.Option<CheckpointConfig> = Option.none(),
|
|
75
78
|
): Effect.Effect<ExecutionResult, never, R | InngestClient> =>
|
|
76
79
|
Effect.gen(function* () {
|
|
77
80
|
const stepIdCounts = yield* Ref.make(HashMap.empty<string, number>());
|
|
78
|
-
const step = createStepTools(request, appName, stepIdCounts);
|
|
79
|
-
const context = buildHandlerContext<F>(fn, step, request);
|
|
80
81
|
const headers = baseHeaders();
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
83
|
+
// Build the optional CheckpointState. In checkpoint mode the step tools
|
|
84
|
+
// buffer StepRun results into this state and yield (drain + DiscoveryRequest /
|
|
85
|
+
// RunComplete / interrupt) once the handler resolves.
|
|
86
|
+
const checkpointState: Option.Option<CheckpointState> = yield* Option.match(checkpointConfig, {
|
|
87
|
+
onNone: () => Effect.succeed(Option.none<CheckpointState>()),
|
|
88
|
+
onSome: (config) =>
|
|
89
|
+
Effect.gen(function* () {
|
|
90
|
+
const client = yield* InngestClient;
|
|
91
|
+
const state = yield* Checkpoint.make({
|
|
92
|
+
config,
|
|
93
|
+
runId: request.ctx.run_id,
|
|
94
|
+
fnId: request.ctx.fn_id,
|
|
95
|
+
qiId: request.ctx.qi_id,
|
|
96
|
+
checkpointAsync: (steps) =>
|
|
97
|
+
client.checkpointAsync({
|
|
98
|
+
runId: request.ctx.run_id,
|
|
99
|
+
fnId: request.ctx.fn_id,
|
|
100
|
+
qiId: request.ctx.qi_id,
|
|
101
|
+
steps,
|
|
102
|
+
}),
|
|
103
|
+
});
|
|
104
|
+
return Option.some(state);
|
|
105
|
+
}),
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const step = createStepTools(request, appName, stepIdCounts, checkpointState);
|
|
109
|
+
const context = buildHandlerContext<F>(fn, step, request);
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Drain any unflushed buffered opcodes (no-op outside checkpoint mode).
|
|
113
|
+
* Used at every terminal branch so step results are never lost.
|
|
114
|
+
*/
|
|
115
|
+
const drainBuffer: Effect.Effect<ReadonlyArray<typeof Protocol.GeneratorOpcode.Type>> = Option.match(
|
|
116
|
+
checkpointState,
|
|
117
|
+
{
|
|
118
|
+
onNone: () => Effect.succeed([] as ReadonlyArray<typeof Protocol.GeneratorOpcode.Type>),
|
|
119
|
+
onSome: (state) => state.drain,
|
|
120
|
+
},
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* In checkpoint mode wrap the handler in `Effect.raceFirst` against a
|
|
125
|
+
* `maxRuntime` deadline. Branches produce disjoint `Option` variants —
|
|
126
|
+
* `Some(value)` for a successful handler result, `None` for the deadline
|
|
127
|
+
* winning — so no type cast is required. Spec §10.4.1 #7.
|
|
128
|
+
*/
|
|
129
|
+
type RaceResult = Option.Option<InngestFunction.Success<F>>;
|
|
130
|
+
const handlerWithRace: Effect.Effect<RaceResult, unknown, R> = Option.match(checkpointState, {
|
|
131
|
+
onNone: () => Effect.map(handler(context), Option.some<InngestFunction.Success<F>>),
|
|
132
|
+
onSome: (state) =>
|
|
133
|
+
// raceFirst (not race) so a handler failure (e.g. sleepInterrupt) is
|
|
134
|
+
// surfaced immediately instead of waiting for the deadline. Race
|
|
135
|
+
// would block until a side succeeds — handler interrupts would hang.
|
|
136
|
+
Effect.raceFirst(
|
|
137
|
+
Effect.map(handler(context), Option.some<InngestFunction.Success<F>>),
|
|
138
|
+
Effect.sleep(state.config.maxRuntime).pipe(
|
|
139
|
+
Effect.tap(() => state.markRuntimeExceeded),
|
|
140
|
+
Effect.as(Option.none<InngestFunction.Success<F>>()),
|
|
141
|
+
),
|
|
142
|
+
),
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
const result = yield* Effect.scoped(handlerWithRace).pipe(
|
|
146
|
+
Effect.flatMap((raced) =>
|
|
147
|
+
Effect.gen(function* () {
|
|
148
|
+
const drained = yield* drainBuffer;
|
|
149
|
+
// Checkpoint mode: assemble [drained..., RunComplete | DiscoveryRequest]
|
|
150
|
+
// even when buffer is empty — TS reference always emits RunComplete on
|
|
151
|
+
// completion so the executor can correlate (spec §10.4.1 #8).
|
|
152
|
+
if (Option.isSome(checkpointState)) {
|
|
153
|
+
const state = checkpointState.value;
|
|
154
|
+
const exceeded = (yield* state.isRuntimeExceeded) || Option.isNone(raced);
|
|
155
|
+
const terminal = exceeded ? Protocol.discoveryRequest() : Protocol.runComplete(raced.value);
|
|
156
|
+
const opcodes = [...drained, terminal];
|
|
157
|
+
return ExecutionResult.make({ status: 206, body: encodeOpcodes(opcodes), headers });
|
|
158
|
+
}
|
|
159
|
+
// Async mode: classic 200 with the bare return value.
|
|
160
|
+
// `raced` is always Some in async mode (no deadline branch).
|
|
161
|
+
return ExecutionResult.make({
|
|
162
|
+
status: 200,
|
|
163
|
+
body: Option.getOrThrow(raced),
|
|
164
|
+
headers,
|
|
165
|
+
});
|
|
166
|
+
}),
|
|
167
|
+
),
|
|
168
|
+
Effect.catchCause((cause) =>
|
|
169
|
+
Effect.gen(function* () {
|
|
170
|
+
// Drain buffer for inclusion in 206 / error response so step results
|
|
171
|
+
// are never lost (spec §10.4.3 graceful fallback).
|
|
172
|
+
const drained = yield* drainBuffer;
|
|
173
|
+
|
|
174
|
+
// Collect all step interrupts from the cause (handles parallel failures)
|
|
175
|
+
const interrupts = collectStepInterruptsFromCause(cause);
|
|
176
|
+
|
|
177
|
+
if (!Chunk.isEmpty(interrupts)) {
|
|
178
|
+
const interruptArray = Chunk.toReadonlyArray(interrupts);
|
|
179
|
+
const opcodes = [...drained, ...interruptArray.map((interrupt) => interrupt.opcode)];
|
|
180
|
+
|
|
181
|
+
const hasNonRetriableError = opcodes.some(
|
|
182
|
+
(op) =>
|
|
183
|
+
op.op === Protocol.Opcode.StepError &&
|
|
184
|
+
Predicate.isObject(op.error) &&
|
|
185
|
+
Predicate.hasProperty(op.error, "noRetry") &&
|
|
186
|
+
op.error.noRetry === true,
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
const retryAfterMs = interruptArray.find((i) => i.retryAfterMs !== undefined)?.retryAfterMs;
|
|
190
|
+
const responseHeaders: Record<string, string> = hasNonRetriableError
|
|
191
|
+
? { ...headers, [Protocol.Headers.NoRetry]: "true" }
|
|
192
|
+
: headers;
|
|
193
|
+
if (retryAfterMs !== undefined) {
|
|
194
|
+
responseHeaders[Protocol.Headers.RetryAfter] = String(Math.ceil(retryAfterMs / 1000));
|
|
195
|
+
// Spec §4.4.3: "If `Retry-After` is set, an SDK MUST also set
|
|
196
|
+
// `X-Inngest-No-Retry: false`." Overrides any prior value from
|
|
197
|
+
// the non-retriable branch above — the presence of RetryAfter
|
|
198
|
+
// implies the caller wants a retry at the specified delay.
|
|
199
|
+
responseHeaders[Protocol.Headers.NoRetry] = "false";
|
|
200
|
+
}
|
|
201
|
+
return ExecutionResult.make({ status: 206, body: encodeOpcodes(opcodes), headers: responseHeaders });
|
|
106
202
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
203
|
+
|
|
204
|
+
// Extract the first error from cause for non-interrupt error handling.
|
|
205
|
+
// `findErrorOption` only matches typed failures; fall back to the first
|
|
206
|
+
// defect (Effect.die, unchecked throws) so we surface the original error.
|
|
207
|
+
const errorOpt = Option.orElse(Cause.findErrorOption(cause), () => {
|
|
208
|
+
const dieReason = cause.reasons.find(Cause.isDieReason);
|
|
209
|
+
return dieReason ? Option.some(dieReason.defect) : Option.none();
|
|
210
|
+
});
|
|
211
|
+
if (Option.isNone(errorOpt)) {
|
|
212
|
+
// No error in cause - shouldn't happen, but handle gracefully.
|
|
213
|
+
// Buffered steps still surface in a 206 wrapping if any exist.
|
|
214
|
+
if (drained.length > 0) {
|
|
215
|
+
return ExecutionResult.make({
|
|
216
|
+
status: 206,
|
|
217
|
+
body: encodeOpcodes(drained),
|
|
218
|
+
headers,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
return ExecutionResult.make({
|
|
117
222
|
status: 500,
|
|
118
|
-
body: {
|
|
223
|
+
body: { name: "Error", message: "Unknown error" },
|
|
224
|
+
headers: { ...headers, [Protocol.Headers.NoRetry]: "false" },
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
const error = errorOpt.value;
|
|
228
|
+
|
|
229
|
+
// Check for RetryAfterError - use type guard and direct access
|
|
230
|
+
if (isRetryAfterError(error)) {
|
|
231
|
+
const retryAfterMs = Duration.toMillis((error as RetryAfterError).retryAfter);
|
|
232
|
+
const retryAfterSeconds = Math.ceil(retryAfterMs / 1000);
|
|
233
|
+
// Spec §10.4.3: include drained buffered steps in response when
|
|
234
|
+
// present; otherwise existing 500 behavior.
|
|
235
|
+
if (drained.length > 0) {
|
|
236
|
+
return ExecutionResult.make({
|
|
237
|
+
status: 206,
|
|
238
|
+
body: encodeOpcodes(drained),
|
|
239
|
+
headers: {
|
|
240
|
+
...headers,
|
|
241
|
+
[Protocol.Headers.NoRetry]: "false",
|
|
242
|
+
[Protocol.Headers.RetryAfter]: String(retryAfterSeconds),
|
|
243
|
+
},
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
return ExecutionResult.make({
|
|
247
|
+
status: 500,
|
|
248
|
+
body: toUserError(error),
|
|
119
249
|
headers: {
|
|
120
250
|
...headers,
|
|
121
251
|
[Protocol.Headers.NoRetry]: "false",
|
|
122
252
|
[Protocol.Headers.RetryAfter]: String(retryAfterSeconds),
|
|
123
253
|
},
|
|
124
|
-
})
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Check for NonRetriableError or StepError with noRetry
|
|
258
|
+
const noRetryValue =
|
|
259
|
+
isNonRetriableError(error) || (isStepError(error) && (error as StepError).noRetry === true);
|
|
260
|
+
const noRetry = noRetryValue ? "true" : "false";
|
|
261
|
+
if (drained.length > 0) {
|
|
262
|
+
return ExecutionResult.make({
|
|
263
|
+
status: 206,
|
|
264
|
+
body: encodeOpcodes(drained),
|
|
265
|
+
headers: { ...headers, [Protocol.Headers.NoRetry]: noRetry },
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
// Spec §4.4.3: non-retriable function errors MUST return 400 with
|
|
269
|
+
// the error payload at the response root; retriable errors return
|
|
270
|
+
// 500 with the same root shape.
|
|
271
|
+
return ExecutionResult.make({
|
|
272
|
+
status: noRetryValue ? 400 : 500,
|
|
273
|
+
body: toUserError(error),
|
|
136
274
|
headers: { ...headers, [Protocol.Headers.NoRetry]: noRetry },
|
|
137
|
-
})
|
|
138
|
-
)
|
|
139
|
-
|
|
275
|
+
});
|
|
276
|
+
}),
|
|
277
|
+
),
|
|
140
278
|
|
|
141
|
-
Effect.
|
|
142
|
-
Effect.
|
|
143
|
-
|
|
279
|
+
Effect.catchDefect((defect) =>
|
|
280
|
+
Effect.gen(function* () {
|
|
281
|
+
const drained = yield* drainBuffer;
|
|
282
|
+
if (drained.length > 0) {
|
|
283
|
+
return ExecutionResult.make({
|
|
284
|
+
status: 206,
|
|
285
|
+
body: encodeOpcodes(drained),
|
|
286
|
+
headers: { ...headers, [Protocol.Headers.NoRetry]: "false" },
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
return ExecutionResult.make({
|
|
144
290
|
status: 500,
|
|
145
|
-
body:
|
|
291
|
+
body: toUserError(defect),
|
|
146
292
|
headers: { ...headers, [Protocol.Headers.NoRetry]: "false" },
|
|
147
|
-
})
|
|
148
|
-
),
|
|
293
|
+
});
|
|
294
|
+
}),
|
|
149
295
|
),
|
|
150
296
|
);
|
|
151
297
|
|
|
@@ -179,16 +325,18 @@ export interface DriverService {
|
|
|
179
325
|
fn: F,
|
|
180
326
|
handler: (ctx: HandlerContext<F>) => Effect.Effect<InngestFunction.Success<F>, unknown, R>,
|
|
181
327
|
request: Protocol.SDKRequestBody,
|
|
328
|
+
checkpointConfig?: Option.Option<CheckpointConfig>,
|
|
182
329
|
) => Effect.Effect<ExecutionResult, never, R | InngestClient>;
|
|
183
330
|
}
|
|
184
331
|
|
|
185
|
-
export class Driver extends Context.
|
|
332
|
+
export class Driver extends Context.Service<Driver, DriverService>()("effect-inngest/Driver") {}
|
|
186
333
|
|
|
187
|
-
export const layer = (options: { readonly appName: string }) =>
|
|
188
|
-
|
|
334
|
+
export const layer = (options: { readonly appName: string }): Layer.Layer<Driver> =>
|
|
335
|
+
Layer.succeed(Driver, {
|
|
189
336
|
execute: <F extends InngestFunction.Any, R>(
|
|
190
337
|
fn: F,
|
|
191
338
|
handler: (ctx: HandlerContext<F>) => Effect.Effect<InngestFunction.Success<F>, unknown, R>,
|
|
192
339
|
request: Protocol.SDKRequestBody,
|
|
193
|
-
|
|
194
|
-
|
|
340
|
+
checkpointConfig: Option.Option<CheckpointConfig> = Option.none(),
|
|
341
|
+
) => execute(fn, handler, request, options.appName, {}, checkpointConfig),
|
|
342
|
+
});
|
package/src/internal/errors.ts
CHANGED
|
@@ -2,19 +2,20 @@
|
|
|
2
2
|
* Internal error types for the Effect Inngest SDK.
|
|
3
3
|
* @internal
|
|
4
4
|
*/
|
|
5
|
+
import * as Predicate from "effect/Predicate";
|
|
5
6
|
import * as Schema from "effect/Schema";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* @internal
|
|
9
10
|
*/
|
|
10
|
-
export class SignatureError extends Schema.
|
|
11
|
+
export class SignatureError extends Schema.TaggedErrorClass<SignatureError>()("SignatureError", {
|
|
11
12
|
message: Schema.String,
|
|
12
13
|
}) {}
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* @internal
|
|
16
17
|
*/
|
|
17
|
-
export class RegistrationError extends Schema.
|
|
18
|
+
export class RegistrationError extends Schema.TaggedErrorClass<RegistrationError>()("RegistrationError", {
|
|
18
19
|
message: Schema.String,
|
|
19
20
|
functions: Schema.Array(Schema.String),
|
|
20
21
|
}) {}
|
|
@@ -22,7 +23,7 @@ export class RegistrationError extends Schema.TaggedError<RegistrationError>()("
|
|
|
22
23
|
/**
|
|
23
24
|
* @internal
|
|
24
25
|
*/
|
|
25
|
-
export class FunctionNotFoundError extends Schema.
|
|
26
|
+
export class FunctionNotFoundError extends Schema.TaggedErrorClass<FunctionNotFoundError>()("FunctionNotFoundError", {
|
|
26
27
|
message: Schema.String,
|
|
27
28
|
functionId: Schema.String,
|
|
28
29
|
}) {}
|
|
@@ -30,7 +31,7 @@ export class FunctionNotFoundError extends Schema.TaggedError<FunctionNotFoundEr
|
|
|
30
31
|
/**
|
|
31
32
|
* @internal
|
|
32
33
|
*/
|
|
33
|
-
export class SendEventError extends Schema.
|
|
34
|
+
export class SendEventError extends Schema.TaggedErrorClass<SendEventError>()("SendEventError", {
|
|
34
35
|
message: Schema.String,
|
|
35
36
|
events: Schema.Array(Schema.String),
|
|
36
37
|
}) {}
|
|
@@ -38,17 +39,17 @@ export class SendEventError extends Schema.TaggedError<SendEventError>()("SendEv
|
|
|
38
39
|
/**
|
|
39
40
|
* @internal
|
|
40
41
|
*/
|
|
41
|
-
export class UseApiFetchError extends Schema.
|
|
42
|
+
export class UseApiFetchError extends Schema.TaggedErrorClass<UseApiFetchError>()("UseApiFetchError", {
|
|
42
43
|
message: Schema.String,
|
|
43
|
-
endpoint: Schema.
|
|
44
|
+
endpoint: Schema.Literals(["batch", "actions"]),
|
|
44
45
|
runId: Schema.String,
|
|
45
|
-
statusCode: Schema.
|
|
46
|
+
statusCode: Schema.optional(Schema.Number),
|
|
46
47
|
}) {}
|
|
47
48
|
|
|
48
49
|
/**
|
|
49
50
|
* @internal
|
|
50
51
|
*/
|
|
51
|
-
export class StepError extends Schema.
|
|
52
|
+
export class StepError extends Schema.TaggedErrorClass<StepError>()("StepError", {
|
|
52
53
|
message: Schema.String,
|
|
53
54
|
stepId: Schema.String,
|
|
54
55
|
cause: Schema.optional(Schema.Unknown),
|
|
@@ -58,12 +59,14 @@ export class StepError extends Schema.TaggedError<StepError>()("StepError", {
|
|
|
58
59
|
/**
|
|
59
60
|
* @internal
|
|
60
61
|
*/
|
|
61
|
-
export const isStepError =
|
|
62
|
+
export const isStepError: (u: unknown) => u is StepError = Predicate.isTagged("StepError") as (
|
|
63
|
+
u: unknown,
|
|
64
|
+
) => u is StepError;
|
|
62
65
|
|
|
63
66
|
/**
|
|
64
67
|
* @internal
|
|
65
68
|
*/
|
|
66
|
-
export class TimeoutError extends Schema.
|
|
69
|
+
export class TimeoutError extends Schema.TaggedErrorClass<TimeoutError>()("TimeoutError", {
|
|
67
70
|
message: Schema.String,
|
|
68
71
|
stepId: Schema.optional(Schema.String),
|
|
69
72
|
timeout: Schema.DurationFromMillis,
|
|
@@ -76,7 +79,7 @@ export class TimeoutError extends Schema.TaggedError<TimeoutError>()("TimeoutErr
|
|
|
76
79
|
* @since 0.1.0
|
|
77
80
|
* @category errors
|
|
78
81
|
*/
|
|
79
|
-
export class NonRetriableError extends Schema.
|
|
82
|
+
export class NonRetriableError extends Schema.TaggedErrorClass<NonRetriableError>()("NonRetriableError", {
|
|
80
83
|
message: Schema.String,
|
|
81
84
|
cause: Schema.optional(Schema.Unknown),
|
|
82
85
|
}) {}
|
|
@@ -84,7 +87,9 @@ export class NonRetriableError extends Schema.TaggedError<NonRetriableError>()("
|
|
|
84
87
|
/**
|
|
85
88
|
* @internal
|
|
86
89
|
*/
|
|
87
|
-
export const isNonRetriableError =
|
|
90
|
+
export const isNonRetriableError: (u: unknown) => u is NonRetriableError = Predicate.isTagged("NonRetriableError") as (
|
|
91
|
+
u: unknown,
|
|
92
|
+
) => u is NonRetriableError;
|
|
88
93
|
|
|
89
94
|
/**
|
|
90
95
|
* Thrown to indicate that the operation should be retried after a specific delay.
|
|
@@ -93,7 +98,7 @@ export const isNonRetriableError = Schema.is(NonRetriableError);
|
|
|
93
98
|
* @since 0.1.0
|
|
94
99
|
* @category errors
|
|
95
100
|
*/
|
|
96
|
-
export class RetryAfterError extends Schema.
|
|
101
|
+
export class RetryAfterError extends Schema.TaggedErrorClass<RetryAfterError>()("RetryAfterError", {
|
|
97
102
|
message: Schema.String,
|
|
98
103
|
retryAfter: Schema.DurationFromMillis,
|
|
99
104
|
cause: Schema.optional(Schema.Unknown),
|
|
@@ -102,7 +107,9 @@ export class RetryAfterError extends Schema.TaggedError<RetryAfterError>()("Retr
|
|
|
102
107
|
/**
|
|
103
108
|
* @internal
|
|
104
109
|
*/
|
|
105
|
-
export const isRetryAfterError =
|
|
110
|
+
export const isRetryAfterError: (u: unknown) => u is RetryAfterError = Predicate.isTagged("RetryAfterError") as (
|
|
111
|
+
u: unknown,
|
|
112
|
+
) => u is RetryAfterError;
|
|
106
113
|
|
|
107
114
|
/**
|
|
108
115
|
* @internal
|