effect-inngest 0.3.0-beta.4 → 0.4.0-beta2
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 +69 -75
- package/dist/Client.js +1 -1
- package/dist/Cron.d.ts +17 -0
- package/dist/Cron.js +24 -0
- package/dist/Events.d.ts +1 -1
- package/dist/Events.js +1 -1
- package/dist/Function.d.ts +28 -26
- package/dist/Function.js +19 -11
- package/dist/Group.d.ts +8 -8
- package/dist/Group.js +1 -0
- package/dist/HttpApi.d.ts +3 -3
- package/dist/Inngest.d.ts +60 -0
- package/dist/Inngest.js +61 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +4 -2
- package/dist/internal/codec/StepResult.js +2 -12
- package/dist/internal/driver.js +1 -0
- package/dist/internal/execution/HandlerRun.js +2 -1
- package/dist/internal/runtime/HandlerContext.d.ts +0 -2
- package/dist/internal/runtime/HandlerContext.js +0 -3
- package/dist/internal/runtime/StepTools.d.ts +8 -16
- package/dist/internal/runtime/StepTools.js +2 -8
- package/dist/internal/runtime/steps/InvokeStep.js +1 -2
- package/dist/internal/runtime/steps/StepRun.js +25 -19
- package/dist/internal/utils/safe-stringify.js +50 -0
- package/package.json +17 -1
- package/src/Client.ts +1 -1
- package/src/Cron.ts +33 -0
- package/src/Events.ts +1 -1
- package/src/Function.ts +62 -34
- package/src/Group.ts +10 -7
- package/src/Inngest.ts +85 -0
- package/src/index.ts +21 -7
- package/src/internal/codec/StepResult.ts +1 -43
- package/src/internal/driver.ts +13 -2
- package/src/internal/execution/HandlerRun.ts +3 -2
- package/src/internal/runtime/HandlerContext.ts +2 -5
- package/src/internal/runtime/StepTools.ts +4 -31
- package/src/internal/runtime/steps/InvokeStep.ts +1 -4
- package/src/internal/runtime/steps/StepRun.ts +28 -44
- package/src/internal/utils/safe-stringify.ts +84 -0
|
@@ -1,43 +1,19 @@
|
|
|
1
|
-
import { Effect, Match
|
|
1
|
+
import { Effect, Match } from "effect";
|
|
2
2
|
import type { StepError } from "../../errors.js";
|
|
3
3
|
import * as StepResult from "../../codec/StepResult.js";
|
|
4
4
|
import type { ExecutionInput } from "../../domain/ExecutionInput.js";
|
|
5
5
|
import { CurrentExecutionInput } from "../../domain/ExecutionInput.js";
|
|
6
6
|
import * as StepCommand from "../../domain/StepCommand.js";
|
|
7
|
+
import * as SafeStringify from "../../utils/safe-stringify.js";
|
|
7
8
|
import { HandlerFiberScope } from "../HandlerFiberScope.js";
|
|
8
|
-
import type { JsonSchema, RunOptions } from "../StepTools.js";
|
|
9
9
|
import { StepIdentity, type StepReservation } from "../StepIdentity.js";
|
|
10
10
|
import { StepCommandBus } from "../StepCommandBus.js";
|
|
11
11
|
|
|
12
|
-
export function run<Err, R>(args: {
|
|
12
|
+
export function run<A, Err, R>(args: {
|
|
13
13
|
readonly input: ExecutionInput;
|
|
14
14
|
readonly id: StepReservation;
|
|
15
|
-
readonly effect: Effect.Effect<
|
|
16
|
-
}): Effect.Effect<
|
|
17
|
-
export function run<S extends JsonSchema, Err, R>(args: {
|
|
18
|
-
readonly input: ExecutionInput;
|
|
19
|
-
readonly id: StepReservation;
|
|
20
|
-
readonly effect: Effect.Effect<S["Type"], Err, R>;
|
|
21
|
-
readonly options: RunOptions<S>;
|
|
22
|
-
}): Effect.Effect<
|
|
23
|
-
S["Type"],
|
|
24
|
-
StepError | Err,
|
|
25
|
-
R | StepIdentity | StepCommandBus | CurrentExecutionInput | HandlerFiberScope
|
|
26
|
-
>;
|
|
27
|
-
export function run<S extends JsonSchema, Err, R>(args: {
|
|
28
|
-
readonly input: ExecutionInput;
|
|
29
|
-
readonly id: StepReservation;
|
|
30
|
-
readonly effect: Effect.Effect<S["Type"] | void, Err, R>;
|
|
31
|
-
readonly options?: RunOptions<S>;
|
|
32
|
-
}): Effect.Effect<
|
|
33
|
-
void | S["Type"],
|
|
34
|
-
StepError | Err,
|
|
35
|
-
R | StepIdentity | StepCommandBus | CurrentExecutionInput | HandlerFiberScope
|
|
36
|
-
> {
|
|
37
|
-
const memoCodec: StepResult.OptionalMemoCodec<S["Type"]> = args.options
|
|
38
|
-
? Option.some(Schema.toCodecJson(args.options.schema))
|
|
39
|
-
: Option.none();
|
|
40
|
-
|
|
15
|
+
readonly effect: Effect.Effect<A, Err, R>;
|
|
16
|
+
}): Effect.Effect<A, StepError | Err, R | StepIdentity | StepCommandBus | CurrentExecutionInput | HandlerFiberScope> {
|
|
41
17
|
return Effect.gen(function* () {
|
|
42
18
|
const identity = yield* StepIdentity;
|
|
43
19
|
const bus = yield* StepCommandBus;
|
|
@@ -45,47 +21,55 @@ export function run<S extends JsonSchema, Err, R>(args: {
|
|
|
45
21
|
const memo = args.input.memoForStep(info);
|
|
46
22
|
|
|
47
23
|
return yield* Match.value(memo).pipe(
|
|
48
|
-
Match.tag("MemoData", ({ data }) =>
|
|
24
|
+
Match.tag("MemoData", ({ data }) => Effect.succeed(data as A)),
|
|
49
25
|
Match.tag("MemoError", ({ error }) => StepResult.failStepRunMemoError(info.id, error)),
|
|
50
26
|
Match.tag("MemoTimeout", () => StepResult.failStepRunMemoTimeout(info.id)),
|
|
51
27
|
Match.tag("MemoInput", ({ input }) => StepResult.failUnexpectedStepRunMemoInput(info.id, input)),
|
|
52
28
|
Match.tag("MemoNone", () =>
|
|
53
29
|
Effect.gen(function* () {
|
|
54
30
|
if (!args.input.shouldExecuteStep(info)) {
|
|
55
|
-
return yield* Effect.
|
|
31
|
+
return yield* Effect.interrupt;
|
|
56
32
|
}
|
|
57
33
|
|
|
58
34
|
const planned = StepCommand.StepRunPlanned.make({ info, sequence: args.id.sequence });
|
|
59
35
|
|
|
60
36
|
if (args.input.shouldPlanStep(info)) {
|
|
61
37
|
yield* bus.plan(planned);
|
|
62
|
-
return yield* Effect.
|
|
38
|
+
return yield* Effect.interrupt;
|
|
63
39
|
}
|
|
64
40
|
|
|
65
41
|
if (yield* bus.planCheckpointedRunBoundary(planned)) {
|
|
66
|
-
return yield* Effect.
|
|
42
|
+
return yield* Effect.interrupt;
|
|
67
43
|
}
|
|
68
44
|
|
|
69
45
|
return yield* args.effect.pipe(
|
|
70
46
|
Effect.matchEffect({
|
|
71
47
|
onFailure: (error) =>
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
48
|
+
Effect.gen(function* () {
|
|
49
|
+
yield* bus.fail(
|
|
50
|
+
StepCommand.stepRunFailureForAttempt({
|
|
51
|
+
info,
|
|
52
|
+
error,
|
|
53
|
+
attempt: args.input.run.attempt,
|
|
54
|
+
maxAttempts: args.input.run.maxAttempts,
|
|
55
|
+
}),
|
|
56
|
+
);
|
|
57
|
+
return yield* Effect.interrupt;
|
|
58
|
+
}),
|
|
80
59
|
onSuccess: (value) =>
|
|
81
60
|
Effect.gen(function* () {
|
|
82
|
-
const data =
|
|
61
|
+
const data = SafeStringify.normalize(value);
|
|
83
62
|
|
|
84
63
|
yield* bus.complete(StepCommand.StepRunResult.make({ info, data }));
|
|
85
|
-
return
|
|
64
|
+
return data as A;
|
|
86
65
|
}),
|
|
87
66
|
}),
|
|
88
|
-
Effect.catchDefect((defect) =>
|
|
67
|
+
Effect.catchDefect((defect) =>
|
|
68
|
+
Effect.gen(function* () {
|
|
69
|
+
yield* bus.fail(StepCommand.StepRunError.make({ info, error: defect }));
|
|
70
|
+
return yield* Effect.interrupt;
|
|
71
|
+
}),
|
|
72
|
+
),
|
|
89
73
|
);
|
|
90
74
|
}),
|
|
91
75
|
),
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Array as Arr, Option, Predicate } from "effect";
|
|
2
|
+
|
|
3
|
+
export type Replacer = (this: unknown, key: string, value: unknown) => unknown;
|
|
4
|
+
export type CycleReplacer = (this: unknown, key: string, value: unknown) => unknown;
|
|
5
|
+
|
|
6
|
+
interface State {
|
|
7
|
+
readonly stack: Array<unknown>;
|
|
8
|
+
readonly keys: Array<string>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const findReference = (state: State, value: unknown): Option.Option<number> =>
|
|
12
|
+
Arr.findFirstIndex(state.stack, (candidate) => Object.is(candidate, value));
|
|
13
|
+
|
|
14
|
+
const isTracked = (state: State, value: unknown): boolean => Option.isSome(findReference(state, value));
|
|
15
|
+
|
|
16
|
+
const pushReference = (state: State, key: string, value: unknown): void => {
|
|
17
|
+
state.stack.push(value);
|
|
18
|
+
state.keys.push(key);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const trimToParent = (state: State, key: string, parentIndex: number): void => {
|
|
22
|
+
state.stack.splice(parentIndex + 1);
|
|
23
|
+
state.keys.splice(parentIndex, Infinity, key);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const refreshParent = (state: State, key: string, parent: unknown): void => {
|
|
27
|
+
Option.match(findReference(state, parent), {
|
|
28
|
+
onNone: () => {
|
|
29
|
+
if (Predicate.isObjectOrArray(parent)) {
|
|
30
|
+
pushReference(state, key, parent);
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
onSome: (parentIndex) => trimToParent(state, key, parentIndex),
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const defaultCycleReplacer = (state: State): CycleReplacer =>
|
|
38
|
+
function (_key, value) {
|
|
39
|
+
const valueIndex = Option.getOrElse(findReference(state, value), () => -1);
|
|
40
|
+
if (Object.is(state.stack[0], value)) {
|
|
41
|
+
return "[Circular ~]";
|
|
42
|
+
}
|
|
43
|
+
return `[Circular ~.${state.keys.slice(0, valueIndex).join(".")}]`;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export function stringify(
|
|
47
|
+
obj: unknown,
|
|
48
|
+
replacer?: Replacer,
|
|
49
|
+
spaces?: string | number,
|
|
50
|
+
cycleReplacer?: CycleReplacer,
|
|
51
|
+
): string | undefined {
|
|
52
|
+
return JSON.stringify(obj, getSerialize(replacer, cycleReplacer), spaces);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export const normalize = (value: unknown): unknown => {
|
|
56
|
+
const json = stringify(value, (_key, child) => {
|
|
57
|
+
if (!Predicate.isBigInt(child)) {
|
|
58
|
+
return child;
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
return Predicate.isUndefined(json) ? null : JSON.parse(json);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export function getSerialize(replacer?: Replacer, cycleReplacer?: CycleReplacer): Replacer {
|
|
66
|
+
const state: State = { stack: [], keys: [] };
|
|
67
|
+
const replaceCycle = cycleReplacer ?? defaultCycleReplacer(state);
|
|
68
|
+
|
|
69
|
+
return function (key, value) {
|
|
70
|
+
if (Arr.isArrayNonEmpty(state.stack)) {
|
|
71
|
+
refreshParent(state, key, this);
|
|
72
|
+
|
|
73
|
+
if (Predicate.isObjectKeyword(value) && isTracked(state, value)) {
|
|
74
|
+
value = replaceCycle.call(this, key, value);
|
|
75
|
+
}
|
|
76
|
+
} else {
|
|
77
|
+
state.stack.push(value);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return replacer ? replacer.call(this, key, value) : value;
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export default stringify;
|