effect-inngest 0.1.1 → 0.1.2
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/HttpApi.d.ts +3 -3
- package/dist/internal/protocol.js +3 -7
- package/dist/internal/step.js +25 -16
- package/package.json +1 -1
- package/src/internal/protocol.ts +3 -7
- package/src/internal/step.ts +41 -22
package/dist/HttpApi.d.ts
CHANGED
|
@@ -24,20 +24,20 @@ declare class FunctionNotFoundError extends FunctionNotFoundError_base {}
|
|
|
24
24
|
* @category api
|
|
25
25
|
*/
|
|
26
26
|
declare const InngestApiGroup: HttpApiGroup.HttpApiGroup<"inngest", HttpApiEndpoint.HttpApiEndpoint<"introspect", "GET", never, never, never, never, ({
|
|
27
|
-
readonly mode: "cloud" | "dev";
|
|
28
27
|
readonly function_count: number;
|
|
29
28
|
readonly has_event_key: boolean;
|
|
30
29
|
readonly has_signing_key: boolean;
|
|
31
30
|
readonly has_signing_key_fallback: boolean;
|
|
31
|
+
readonly mode: "cloud" | "dev";
|
|
32
32
|
readonly schema_version: "2024-05-24";
|
|
33
33
|
readonly extra?: {
|
|
34
34
|
readonly [x: string]: unknown;
|
|
35
35
|
} | undefined;
|
|
36
36
|
} & {
|
|
37
|
-
readonly env: string | null;
|
|
38
37
|
readonly authentication_succeeded: true;
|
|
39
38
|
readonly api_origin: string;
|
|
40
39
|
readonly app_id: string;
|
|
40
|
+
readonly env: string | null;
|
|
41
41
|
readonly event_api_origin: string;
|
|
42
42
|
readonly event_key_hash: string | null;
|
|
43
43
|
readonly framework: string;
|
|
@@ -48,11 +48,11 @@ declare const InngestApiGroup: HttpApiGroup.HttpApiGroup<"inngest", HttpApiEndpo
|
|
|
48
48
|
readonly signing_key_fallback_hash: string | null;
|
|
49
49
|
readonly signing_key_hash: string | null;
|
|
50
50
|
}) | ({
|
|
51
|
-
readonly mode: "cloud" | "dev";
|
|
52
51
|
readonly function_count: number;
|
|
53
52
|
readonly has_event_key: boolean;
|
|
54
53
|
readonly has_signing_key: boolean;
|
|
55
54
|
readonly has_signing_key_fallback: boolean;
|
|
55
|
+
readonly mode: "cloud" | "dev";
|
|
56
56
|
readonly schema_version: "2024-05-24";
|
|
57
57
|
readonly extra?: {
|
|
58
58
|
readonly [x: string]: unknown;
|
|
@@ -6,18 +6,14 @@ import * as Schema$1 from "effect/Schema";
|
|
|
6
6
|
* Wire protocol schemas and opcode factories for Inngest communication.
|
|
7
7
|
* @internal
|
|
8
8
|
*/
|
|
9
|
-
const
|
|
10
|
-
if (Predicate.isRecord(value))
|
|
11
|
-
const stripped = Struct.omit(value, "_tag");
|
|
12
|
-
return Object.fromEntries(Object.entries(stripped).map(([k, v]) => [k, stripTags(v)]));
|
|
13
|
-
}
|
|
14
|
-
if (Array.isArray(value)) return value.map(stripTags);
|
|
9
|
+
const stripTopLevelTag = (value) => {
|
|
10
|
+
if (Predicate.isRecord(value)) return Struct.omit(value, "_tag");
|
|
15
11
|
return value;
|
|
16
12
|
};
|
|
17
13
|
const WireUnknown = Schema$1.transform(Schema$1.Unknown, Schema$1.Unknown, {
|
|
18
14
|
strict: true,
|
|
19
15
|
decode: (value) => value,
|
|
20
|
-
encode: (value) =>
|
|
16
|
+
encode: (value) => stripTopLevelTag(value)
|
|
21
17
|
});
|
|
22
18
|
const Opcode = {
|
|
23
19
|
None: "None",
|
package/dist/internal/step.js
CHANGED
|
@@ -8,7 +8,7 @@ import * as Duration from "effect/Duration";
|
|
|
8
8
|
import * as Context from "effect/Context";
|
|
9
9
|
import * as Effect from "effect/Effect";
|
|
10
10
|
import * as Option from "effect/Option";
|
|
11
|
-
import "effect/Schema";
|
|
11
|
+
import * as Schema from "effect/Schema";
|
|
12
12
|
import * as Predicate from "effect/Predicate";
|
|
13
13
|
import * as Arr from "effect/Array";
|
|
14
14
|
import * as HashMap from "effect/HashMap";
|
|
@@ -38,6 +38,11 @@ const errorOtelAttributes = (err) => {
|
|
|
38
38
|
} else attrs[OtelAttributes.ExceptionMessage] = String(err);
|
|
39
39
|
return attrs;
|
|
40
40
|
};
|
|
41
|
+
const encodeTaggedEvent = (event) => {
|
|
42
|
+
const ctor = event.constructor;
|
|
43
|
+
if (Schema.isSchema(ctor)) return Schema.encode(ctor)(event).pipe(Effect.orElseSucceed(() => event));
|
|
44
|
+
return Effect.succeed(event);
|
|
45
|
+
};
|
|
41
46
|
var Step = class extends Context.Tag("effect-inngest/Step")() {};
|
|
42
47
|
const normalizeOpts = (opts) => typeof opts === "string" ? {
|
|
43
48
|
id: opts,
|
|
@@ -89,16 +94,20 @@ const createStepTools = (request, appName, stepIdCounts) => {
|
|
|
89
94
|
timeout: timeStr(options.timeout),
|
|
90
95
|
if: options.if
|
|
91
96
|
}))), Match.exhaustive));
|
|
92
|
-
const invoke = (opts, options) => Effect.flatMap(getInfo(opts), (info) => pipe(getMemo(info.hash), Match.value, Match.tag("MemoData", ({ data }) => Effect.succeed(data)), Match.tag("MemoError", ({ error }) => stepError(info.id, Predicate.hasProperty(error, "message") ? String(error.message) : "Invoke failed", { cause: error })), Match.tag("MemoTimeout", () => stepError(info.id, "Invoke timed out", { noRetry: true })), Match.tag("MemoInput", () => Effect.succeed(void 0)), Match.tag("MemoNone", () =>
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
97
|
+
const invoke = (opts, options) => Effect.flatMap(getInfo(opts), (info) => pipe(getMemo(info.hash), Match.value, Match.tag("MemoData", ({ data }) => Effect.succeed(data)), Match.tag("MemoError", ({ error }) => stepError(info.id, Predicate.hasProperty(error, "message") ? String(error.message) : "Invoke failed", { cause: error })), Match.tag("MemoTimeout", () => stepError(info.id, "Invoke timed out", { noRetry: true })), Match.tag("MemoInput", () => Effect.succeed(void 0)), Match.tag("MemoNone", () => {
|
|
98
|
+
const rawData = Predicate.hasProperty(options, "data") ? options.data : void 0;
|
|
99
|
+
const encodeData = rawData ? encodeTaggedEvent(rawData) : Effect.succeed(void 0);
|
|
100
|
+
return Effect.flatMap(encodeData, (encodedData) => Effect.fail(invokeInterrupt({
|
|
101
|
+
info,
|
|
102
|
+
functionId: `${appName}-${options.function._tag}`,
|
|
103
|
+
payload: {
|
|
104
|
+
data: encodedData,
|
|
105
|
+
user: options.user ?? {},
|
|
106
|
+
v: options.v ?? "1"
|
|
107
|
+
},
|
|
108
|
+
timeout: options.timeout ? timeStr(options.timeout) : "365d"
|
|
109
|
+
})));
|
|
110
|
+
}), Match.exhaustive));
|
|
102
111
|
const run = (opts, effect) => Effect.flatMap(getInfo(opts), (info) => pipe(getMemo(info.hash), Match.value, Match.tag("MemoData", ({ data }) => Effect.succeed(data)), Match.tag("MemoError", ({ error }) => stepError(info.id, Predicate.hasProperty(error, "message") ? String(error.message) : "Step failed", { noRetry: true })), Match.tag("MemoTimeout", () => stepError(info.id, "Step timed out", { noRetry: true })), Match.tag("MemoInput", () => stepError(info.id, "Unexpected step result type: input")), Match.tag("MemoNone", () => {
|
|
103
112
|
if (isBlocked(info.hash) || !canExecute(info.hash)) return Effect.fail(plannedInterrupt({ info }));
|
|
104
113
|
return effect.pipe(Effect.withSpan(`inngest.step/run/${info.id}`, { attributes: {
|
|
@@ -132,17 +141,17 @@ const createStepTools = (request, appName, stepIdCounts) => {
|
|
|
132
141
|
events: []
|
|
133
142
|
}))), Match.tag("MemoInput", () => Effect.succeed({ ids: [] })), Match.tag("MemoNone", () => {
|
|
134
143
|
if (isBlocked(info.hash) || !canExecute(info.hash)) return Effect.fail(plannedInterrupt({ info }));
|
|
135
|
-
const
|
|
144
|
+
const events = Arr.ensure(payload);
|
|
145
|
+
return Effect.flatMap(Effect.forEach(events, (e) => Effect.map(encodeTaggedEvent(e), (encoded) => ({
|
|
136
146
|
name: e._tag,
|
|
137
|
-
data:
|
|
138
|
-
}))
|
|
139
|
-
return Effect.flatMap(InngestClient, (client) => client.sendEvent(eventPayloads).pipe(Effect.withSpan(`inngest.step/sendEvent/${info.id}`, { attributes: {
|
|
147
|
+
data: encoded
|
|
148
|
+
}))), (eventPayloads) => Effect.flatMap(InngestClient, (client) => client.sendEvent(eventPayloads).pipe(Effect.withSpan(`inngest.step/sendEvent/${info.id}`, { attributes: {
|
|
140
149
|
[OtelAttributes.StepId]: info.id,
|
|
141
150
|
[OtelAttributes.StepType]: "sendEvent"
|
|
142
151
|
} }), Effect.flatMap((result) => Effect.fail(runInterrupt({
|
|
143
152
|
info,
|
|
144
153
|
data: result
|
|
145
|
-
})))));
|
|
154
|
+
}))))));
|
|
146
155
|
}), Match.exhaustive));
|
|
147
156
|
return {
|
|
148
157
|
run,
|
package/package.json
CHANGED
package/src/internal/protocol.ts
CHANGED
|
@@ -5,13 +5,9 @@
|
|
|
5
5
|
import { Predicate, Struct } from "effect";
|
|
6
6
|
import * as Schema from "effect/Schema";
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
const stripTopLevelTag = (value: unknown): unknown => {
|
|
9
9
|
if (Predicate.isRecord(value)) {
|
|
10
|
-
|
|
11
|
-
return Object.fromEntries(Object.entries(stripped).map(([k, v]) => [k, stripTags(v)]));
|
|
12
|
-
}
|
|
13
|
-
if (Array.isArray(value)) {
|
|
14
|
-
return value.map(stripTags);
|
|
10
|
+
return Struct.omit(value as Record<string, unknown>, "_tag");
|
|
15
11
|
}
|
|
16
12
|
return value;
|
|
17
13
|
};
|
|
@@ -19,7 +15,7 @@ const stripTags = (value: unknown): unknown => {
|
|
|
19
15
|
const WireUnknown = Schema.transform(Schema.Unknown, Schema.Unknown, {
|
|
20
16
|
strict: true,
|
|
21
17
|
decode: (value) => value,
|
|
22
|
-
encode: (value) =>
|
|
18
|
+
encode: (value) => stripTopLevelTag(value),
|
|
23
19
|
});
|
|
24
20
|
|
|
25
21
|
export const Opcode = {
|
package/src/internal/step.ts
CHANGED
|
@@ -86,6 +86,16 @@ type InvokeOptions<F extends InngestFunction.Any> = [InngestFunction.EventType<F
|
|
|
86
86
|
type EventSchema = Schema.Schema.Any & { readonly _tag: string };
|
|
87
87
|
type TaggedEvent = { readonly _tag: string };
|
|
88
88
|
|
|
89
|
+
const encodeTaggedEvent = (event: TaggedEvent): Effect.Effect<unknown, never> => {
|
|
90
|
+
const ctor = event.constructor;
|
|
91
|
+
if (Schema.isSchema(ctor)) {
|
|
92
|
+
return Schema.encode(ctor as unknown as Schema.Schema.AnyNoContext)(event).pipe(
|
|
93
|
+
Effect.orElseSucceed(() => event),
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
return Effect.succeed(event);
|
|
97
|
+
};
|
|
98
|
+
|
|
89
99
|
interface StepTools {
|
|
90
100
|
readonly run: <A, Err, R>(
|
|
91
101
|
id: StepOptionsOrId,
|
|
@@ -226,20 +236,24 @@ export const createStepTools = (
|
|
|
226
236
|
),
|
|
227
237
|
Match.tag("MemoTimeout", () => stepError(info.id, "Invoke timed out", { noRetry: true })),
|
|
228
238
|
Match.tag("MemoInput", () => Effect.succeed(undefined as InngestFunction.Success<F>)),
|
|
229
|
-
Match.tag("MemoNone", () =>
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
239
|
+
Match.tag("MemoNone", () => {
|
|
240
|
+
const rawData = Predicate.hasProperty(options, "data") ? (options.data as TaggedEvent) : undefined;
|
|
241
|
+
const encodeData = rawData ? encodeTaggedEvent(rawData) : Effect.succeed(undefined);
|
|
242
|
+
return Effect.flatMap(encodeData, (encodedData) =>
|
|
243
|
+
Effect.fail(
|
|
244
|
+
invokeInterrupt({
|
|
245
|
+
info,
|
|
246
|
+
functionId: `${appName}-${options.function._tag}`,
|
|
247
|
+
payload: {
|
|
248
|
+
data: encodedData,
|
|
249
|
+
user: options.user ?? {},
|
|
250
|
+
v: options.v ?? "1",
|
|
251
|
+
},
|
|
252
|
+
timeout: options.timeout ? timeStr(options.timeout) : "365d",
|
|
253
|
+
}),
|
|
254
|
+
),
|
|
255
|
+
);
|
|
256
|
+
}),
|
|
243
257
|
Match.exhaustive,
|
|
244
258
|
),
|
|
245
259
|
);
|
|
@@ -311,15 +325,20 @@ export const createStepTools = (
|
|
|
311
325
|
return Effect.fail(plannedInterrupt({ info }));
|
|
312
326
|
}
|
|
313
327
|
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
Effect.withSpan(`inngest.step/sendEvent/${info.id}`, {
|
|
319
|
-
attributes: { [OtelAttributes.StepId]: info.id, [OtelAttributes.StepType]: "sendEvent" },
|
|
320
|
-
}),
|
|
321
|
-
Effect.flatMap((result) => Effect.fail(runInterrupt({ info, data: result }))),
|
|
328
|
+
const events = Arr.ensure(payload);
|
|
329
|
+
return Effect.flatMap(
|
|
330
|
+
Effect.forEach(events, (e) =>
|
|
331
|
+
Effect.map(encodeTaggedEvent(e), (encoded) => ({ name: e._tag, data: encoded })),
|
|
322
332
|
),
|
|
333
|
+
(eventPayloads) =>
|
|
334
|
+
Effect.flatMap(InngestClient, (client) =>
|
|
335
|
+
client.sendEvent(eventPayloads).pipe(
|
|
336
|
+
Effect.withSpan(`inngest.step/sendEvent/${info.id}`, {
|
|
337
|
+
attributes: { [OtelAttributes.StepId]: info.id, [OtelAttributes.StepType]: "sendEvent" },
|
|
338
|
+
}),
|
|
339
|
+
Effect.flatMap((result) => Effect.fail(runInterrupt({ info, data: result }))),
|
|
340
|
+
),
|
|
341
|
+
),
|
|
323
342
|
);
|
|
324
343
|
}),
|
|
325
344
|
Match.exhaustive,
|