effect-cf 0.45.0 → 0.46.1
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/CHANGELOG.md +12 -0
- package/dist/AiGateway.d.mts +7 -8
- package/dist/AnalyticsEngine.d.mts +5 -6
- package/dist/Artifacts.d.mts +24 -25
- package/dist/Cache.d.mts +11 -12
- package/dist/DurableObject.d.mts +2 -1
- package/dist/DurableObject.mjs +2 -2
- package/dist/Email.d.mts +7 -8
- package/dist/Images.d.mts +53 -54
- package/dist/Kv.d.mts +0 -1
- package/dist/QueueBinding.d.mts +11 -12
- package/dist/R2.d.mts +14 -15
- package/dist/Vectorize.d.mts +17 -18
- package/dist/WebTransport.d.mts +0 -1
- package/dist/WebTransport.mjs +31 -0
- package/dist/Worker.d.mts +2 -1
- package/dist/Worker.mjs +2 -2
- package/dist/WorkersAi.d.mts +0 -1
- package/dist/Workflow.d.mts +8 -3
- package/dist/Workflow.mjs +8 -2
- package/dist/WorkflowBinding.d.mts +14 -15
- package/dist/internal/Runtime.d.mts +20 -0
- package/dist/internal/Runtime.mjs +15 -3
- package/package.json +1 -1
- package/src/AiGateway.ts +2 -3
- package/src/AnalyticsEngine.ts +2 -6
- package/src/Artifacts.ts +8 -16
- package/src/Cache.ts +7 -13
- package/src/DurableObject.ts +3 -2
- package/src/Email.ts +5 -11
- package/src/Images.ts +31 -60
- package/src/Kv.ts +2 -6
- package/src/QueueBinding.ts +8 -17
- package/src/R2.ts +29 -49
- package/src/Vectorize.ts +11 -29
- package/src/WebTransport.ts +2 -4
- package/src/Worker.ts +3 -2
- package/src/WorkersAi.ts +2 -17
- package/src/Workflow.ts +26 -2
- package/src/WorkflowBinding.ts +14 -26
- package/src/internal/Runtime.ts +54 -3
package/src/WorkersAi.ts
CHANGED
|
@@ -5,18 +5,6 @@ import * as Option from "effect/Option";
|
|
|
5
5
|
import * as Predicate from "effect/Predicate";
|
|
6
6
|
import * as S from "effect/Schema";
|
|
7
7
|
import type { Layer } from "effect";
|
|
8
|
-
import type {
|
|
9
|
-
Ai as CloudflareAi,
|
|
10
|
-
AiAsyncBatchResponse,
|
|
11
|
-
AiGateway as CloudflareAiGateway,
|
|
12
|
-
AiModelListType,
|
|
13
|
-
AiModels,
|
|
14
|
-
AiModelsSearchObject,
|
|
15
|
-
AiModelsSearchParams,
|
|
16
|
-
AiOptions,
|
|
17
|
-
AiTextEmbeddingsInput,
|
|
18
|
-
Ai_Cf_Qwen_Qwen3_Embedding_0_6B_Input,
|
|
19
|
-
} from "@cloudflare/workers-types";
|
|
20
8
|
|
|
21
9
|
import * as Binding from "./Binding";
|
|
22
10
|
import type { WorkerEnvironment } from "./Environment";
|
|
@@ -40,8 +28,7 @@ export interface WorkersAiDefinition {
|
|
|
40
28
|
readonly binding: string;
|
|
41
29
|
}
|
|
42
30
|
|
|
43
|
-
export type WorkersAiBinding<ModelList extends AiModelListType = AiModels> =
|
|
44
|
-
CloudflareAi<ModelList>;
|
|
31
|
+
export type WorkersAiBinding<ModelList extends AiModelListType = AiModels> = Ai<ModelList>;
|
|
45
32
|
export type WorkersAiOptions = AiOptions;
|
|
46
33
|
export type WorkersAiModelsSearchParams = AiModelsSearchParams;
|
|
47
34
|
export type WorkersAiModelsSearchObject = AiModelsSearchObject;
|
|
@@ -113,9 +100,7 @@ export interface WorkersAiClient<ModelList extends AiModelListType = AiModels> {
|
|
|
113
100
|
readonly models: (
|
|
114
101
|
params?: WorkersAiModelsSearchParams,
|
|
115
102
|
) => Effect.Effect<ReadonlyArray<WorkersAiModelsSearchObject>, WorkersAiOperationError>;
|
|
116
|
-
readonly gateway: (
|
|
117
|
-
gatewayId: string,
|
|
118
|
-
) => Effect.Effect<CloudflareAiGateway, WorkersAiOperationError>;
|
|
103
|
+
readonly gateway: (gatewayId: string) => Effect.Effect<AiGateway, WorkersAiOperationError>;
|
|
119
104
|
readonly rawUnsafe: Effect.Effect<WorkersAiBinding<ModelList>>;
|
|
120
105
|
readonly definition: WorkersAiDefinition;
|
|
121
106
|
}
|
package/src/Workflow.ts
CHANGED
|
@@ -218,6 +218,11 @@ const fromWorkflowStep = (step: CloudflareWorkflowStep): WorkflowStepService =>
|
|
|
218
218
|
|
|
219
219
|
type RuntimeContext<ROut> = ExecutionContext | WorkerContext | WorkerEnvironment | ROut;
|
|
220
220
|
|
|
221
|
+
/** Override to instrument the whole workflow run, then call super[RunSymbol]. */
|
|
222
|
+
export const RunSymbol = Symbol.for("effect-cf/Workflow/run");
|
|
223
|
+
|
|
224
|
+
export interface RunOptions extends Runtime.RunOptions {}
|
|
225
|
+
|
|
221
226
|
export type WorkflowRunContext<ROut> =
|
|
222
227
|
| RuntimeContext<ROut>
|
|
223
228
|
| WorkflowEvent
|
|
@@ -232,10 +237,14 @@ export interface WorkflowOptions<ROut, Payload = unknown, Result = unknown> {
|
|
|
232
237
|
readonly run: WorkflowHandler<ROut, Payload, Result>;
|
|
233
238
|
}
|
|
234
239
|
|
|
235
|
-
export type WorkflowClass<Payload, Result,
|
|
240
|
+
export type WorkflowClass<Payload, Result, ROut> = new (
|
|
236
241
|
ctx: globalThis.ExecutionContext,
|
|
237
242
|
env: WorkerEnv,
|
|
238
243
|
) => CloudflareWorkflowEntrypoint<WorkerEnv, Payload> & {
|
|
244
|
+
[RunSymbol]<A, E>(
|
|
245
|
+
effect: Effect.Effect<A, E, RuntimeContext<ROut> | Scope.Scope>,
|
|
246
|
+
options?: RunOptions,
|
|
247
|
+
): Promise<A>;
|
|
239
248
|
run(
|
|
240
249
|
event: Readonly<CloudflareWorkflowEvent<Payload>>,
|
|
241
250
|
step: CloudflareWorkflowStep,
|
|
@@ -275,7 +284,22 @@ export const make = <ROut, LayerError, Payload = unknown, Result = unknown>(
|
|
|
275
284
|
Layer.succeed(WorkflowStep, fromWorkflowStep(step)),
|
|
276
285
|
);
|
|
277
286
|
|
|
278
|
-
return
|
|
287
|
+
return this[RunSymbol](
|
|
288
|
+
options.run(event.payload).pipe(Effect.provide(workflowServices, { local: true })),
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
[RunSymbol]<A, E>(
|
|
293
|
+
effect: Effect.Effect<A, E, RuntimeContext<ROut> | Scope.Scope>,
|
|
294
|
+
runOptions: RunOptions = {},
|
|
295
|
+
): Promise<A> {
|
|
296
|
+
return Runtime.runEventPromise(
|
|
297
|
+
this.runtime,
|
|
298
|
+
effect,
|
|
299
|
+
undefined,
|
|
300
|
+
undefined,
|
|
301
|
+
runOptions.onFailure,
|
|
302
|
+
);
|
|
279
303
|
}
|
|
280
304
|
}
|
|
281
305
|
|
package/src/WorkflowBinding.ts
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
InstanceStatus as CloudflareInstanceStatus,
|
|
3
|
-
Workflow as CloudflareWorkflow,
|
|
4
|
-
WorkflowInstance as CloudflareWorkflowInstance,
|
|
5
|
-
WorkflowInstanceCreateOptions as CloudflareWorkflowInstanceCreateOptions,
|
|
6
|
-
WorkflowInstanceLocationHint as CloudflareWorkflowInstanceLocationHint,
|
|
7
|
-
WorkflowInstanceRestartOptions as CloudflareWorkflowInstanceRestartOptions,
|
|
8
|
-
WorkflowInstanceTerminateOptions as CloudflareWorkflowInstanceTerminateOptions,
|
|
9
|
-
} from "@cloudflare/workers-types";
|
|
10
1
|
import * as Data from "effect/Data";
|
|
11
2
|
import * as Effect from "effect/Effect";
|
|
12
3
|
import * as Option from "effect/Option";
|
|
@@ -21,7 +12,7 @@ import * as ErrorMessage from "./internal/ErrorMessage";
|
|
|
21
12
|
const expectedWorkflow = "Workflow binding with create(), createBatch(), and get()";
|
|
22
13
|
|
|
23
14
|
export type WorkflowInstanceCreateOptions<Payload> = Omit<
|
|
24
|
-
|
|
15
|
+
globalThis.WorkflowInstanceCreateOptions<Payload>,
|
|
25
16
|
"params"
|
|
26
17
|
>;
|
|
27
18
|
|
|
@@ -29,11 +20,11 @@ export type WorkflowInstanceCreateBatchOptions<Payload, EncodedPayload = unknown
|
|
|
29
20
|
{ readonly payload: Payload } & WorkflowInstanceCreateOptions<EncodedPayload>
|
|
30
21
|
>;
|
|
31
22
|
|
|
32
|
-
export type
|
|
33
|
-
export type
|
|
34
|
-
export type
|
|
23
|
+
export type WorkflowInstanceLocationHint = globalThis.WorkflowInstanceLocationHint;
|
|
24
|
+
export type WorkflowInstanceRestartOptions = globalThis.WorkflowInstanceRestartOptions;
|
|
25
|
+
export type WorkflowInstanceTerminateOptions = globalThis.WorkflowInstanceTerminateOptions;
|
|
35
26
|
|
|
36
|
-
export type WorkflowInstanceStatusName =
|
|
27
|
+
export type WorkflowInstanceStatusName = InstanceStatus["status"];
|
|
37
28
|
|
|
38
29
|
export interface WorkflowInstanceStatus<Result> {
|
|
39
30
|
readonly status: WorkflowInstanceStatusName;
|
|
@@ -45,7 +36,7 @@ export interface WorkflowInstanceStatus<Result> {
|
|
|
45
36
|
}
|
|
46
37
|
|
|
47
38
|
export interface WorkflowInstance<Result> {
|
|
48
|
-
readonly raw:
|
|
39
|
+
readonly raw: globalThis.WorkflowInstance;
|
|
49
40
|
readonly id: string;
|
|
50
41
|
readonly pause: Effect.Effect<void, WorkflowOperationError>;
|
|
51
42
|
readonly resume: Effect.Effect<void, WorkflowOperationError>;
|
|
@@ -97,7 +88,7 @@ export interface WorkflowBindingClient<
|
|
|
97
88
|
readonly get: (
|
|
98
89
|
instanceId: string,
|
|
99
90
|
) => Effect.Effect<WorkflowInstance<S.Schema.Type<Result>>, WorkflowOperationError>;
|
|
100
|
-
readonly rawUnsafe: Effect.Effect<
|
|
91
|
+
readonly rawUnsafe: Effect.Effect<Workflow<S.Codec.Encoded<Payload>>>;
|
|
101
92
|
}
|
|
102
93
|
|
|
103
94
|
export class WorkflowOperationError extends Data.TaggedError("WorkflowOperationError")<{
|
|
@@ -136,7 +127,7 @@ const tryWorkflowPromise = <A>(
|
|
|
136
127
|
type WorkflowBindingValue = S.Schema.Type<typeof S.Unknown>;
|
|
137
128
|
|
|
138
129
|
const WorkflowBindingSchema = S.declare(
|
|
139
|
-
(value: WorkflowBindingValue): value is
|
|
130
|
+
(value: WorkflowBindingValue): value is Workflow<WorkflowBindingValue> =>
|
|
140
131
|
Predicate.hasProperty(value, "create") &&
|
|
141
132
|
Predicate.isFunction(value.create) &&
|
|
142
133
|
Predicate.hasProperty(value, "createBatch") &&
|
|
@@ -146,18 +137,15 @@ const WorkflowBindingSchema = S.declare(
|
|
|
146
137
|
);
|
|
147
138
|
const decodeWorkflowBinding = S.decodeUnknownOption(WorkflowBindingSchema);
|
|
148
139
|
|
|
149
|
-
export const isWorkflow = <Payload>(
|
|
150
|
-
value
|
|
151
|
-
): value is CloudflareWorkflow<Payload> => Option.isSome(decodeWorkflowBinding(value));
|
|
140
|
+
export const isWorkflow = <Payload>(value: WorkflowBindingValue): value is Workflow<Payload> =>
|
|
141
|
+
Option.isSome(decodeWorkflowBinding(value));
|
|
152
142
|
|
|
153
143
|
export const makeClient = <
|
|
154
144
|
Payload extends RpcDefinition.ServiceFreeSchema,
|
|
155
145
|
Result extends RpcDefinition.ServiceFreeSchema,
|
|
156
146
|
>(
|
|
157
147
|
definition: WorkflowBindingDefinition<Payload, Result>,
|
|
158
|
-
): ((
|
|
159
|
-
workflow: CloudflareWorkflow<S.Codec.Encoded<Payload>>,
|
|
160
|
-
) => WorkflowBindingClient<Payload, Result>) => {
|
|
148
|
+
): ((workflow: Workflow<S.Codec.Encoded<Payload>>) => WorkflowBindingClient<Payload, Result>) => {
|
|
161
149
|
type PayloadValue = S.Schema.Type<Payload>;
|
|
162
150
|
type EncodedPayload = S.Codec.Encoded<Payload>;
|
|
163
151
|
type ResultValue = S.Schema.Type<Result>;
|
|
@@ -165,7 +153,7 @@ export const makeClient = <
|
|
|
165
153
|
const encodePayload = S.encodeEffect(definition.payload);
|
|
166
154
|
const decodeResult = S.decodeUnknownEffect(definition.result);
|
|
167
155
|
|
|
168
|
-
const wrapInstance = (raw:
|
|
156
|
+
const wrapInstance = (raw: globalThis.WorkflowInstance): WorkflowInstance<ResultValue> => {
|
|
169
157
|
const operation = <A>(name: string, evaluate: () => Promise<A>) =>
|
|
170
158
|
tryWorkflowPromise(definition.binding, name, evaluate);
|
|
171
159
|
|
|
@@ -229,7 +217,7 @@ export const makeClient = <
|
|
|
229
217
|
createBatch: Effect.fn("WorkflowBinding.createBatch", {
|
|
230
218
|
attributes: { binding: definition.binding, operation: "createBatch" },
|
|
231
219
|
})(function* (batch: WorkflowInstanceCreateBatchOptions<PayloadValue, EncodedPayload>) {
|
|
232
|
-
const encodedBatch: Array<
|
|
220
|
+
const encodedBatch: Array<globalThis.WorkflowInstanceCreateOptions<EncodedPayload>> = [];
|
|
233
221
|
|
|
234
222
|
for (const item of batch) {
|
|
235
223
|
const { payload, ...options } = item;
|
|
@@ -265,7 +253,7 @@ export const layer = <
|
|
|
265
253
|
Binding.layer(
|
|
266
254
|
tag,
|
|
267
255
|
definition.binding,
|
|
268
|
-
(value): value is
|
|
256
|
+
(value): value is Workflow<S.Codec.Encoded<Payload>> =>
|
|
269
257
|
isWorkflow<S.Codec.Encoded<Payload>>(value),
|
|
270
258
|
makeClient(definition),
|
|
271
259
|
{ expected: expectedWorkflow },
|
package/src/internal/Runtime.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as Cause from "effect/Cause";
|
|
1
2
|
import * as ConfigProvider from "effect/ConfigProvider";
|
|
2
3
|
import * as Effect from "effect/Effect";
|
|
3
4
|
import * as Layer from "effect/Layer";
|
|
@@ -8,6 +9,44 @@ import { WorkerConfig, WorkerEnvironment, type WorkerEnv } from "../Environment"
|
|
|
8
9
|
import * as RpcTargets from "../RpcTargets";
|
|
9
10
|
import { provideEntrypointServices } from "./Entrypoint";
|
|
10
11
|
|
|
12
|
+
export interface RunOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Observes a failed event's complete cause, including interruption, after its
|
|
15
|
+
* scope closes and before the native Promise rejects. Also observes runtime
|
|
16
|
+
* acquisition failures. Called once per failed invocation, never on success.
|
|
17
|
+
* Returned Promises are awaited; throws and rejections are ignored. The
|
|
18
|
+
* observer must settle and cannot use resources from the closed event scope.
|
|
19
|
+
* Reporting, filtering and privacy remain the caller's responsibility.
|
|
20
|
+
*/
|
|
21
|
+
readonly onFailure?: (cause: Cause.Cause<unknown>) => void | Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const runPromise = <A, E, R, LayerError>(
|
|
25
|
+
runtime: ManagedRuntime.ManagedRuntime<R, LayerError>,
|
|
26
|
+
effect: Effect.Effect<A, E, R>,
|
|
27
|
+
onFailure: RunOptions["onFailure"],
|
|
28
|
+
): Promise<A> => {
|
|
29
|
+
if (onFailure === undefined) {
|
|
30
|
+
return runtime.runPromise(effect);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return runtime.runPromiseExit(effect).then(async (exit) => {
|
|
34
|
+
if (exit._tag === "Success") {
|
|
35
|
+
return exit.value;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const rejection = Cause.squash(exit.cause);
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
await onFailure(exit.cause);
|
|
42
|
+
} catch {
|
|
43
|
+
// An observer cannot change the event's outcome.
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
throw rejection;
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
|
|
11
50
|
/**
|
|
12
51
|
* Assembles the shared `ManagedRuntime` used by the Cloudflare entrypoint
|
|
13
52
|
* classes (Worker, Durable Object, Workflow).
|
|
@@ -36,6 +75,7 @@ export function runEventPromise<A, E, R, LayerError>(
|
|
|
36
75
|
effect: Effect.Effect<A, E, NoInfer<R> | Scope.Scope>,
|
|
37
76
|
eventLayer?: undefined,
|
|
38
77
|
parent?: Tracer.AnySpan,
|
|
78
|
+
onFailure?: RunOptions["onFailure"],
|
|
39
79
|
): Promise<A>;
|
|
40
80
|
/** Builds and provides an event layer inside the event effect's scope. */
|
|
41
81
|
export function runEventPromise<A, E, R, REvent, EventLayerError, LayerError>(
|
|
@@ -43,6 +83,7 @@ export function runEventPromise<A, E, R, REvent, EventLayerError, LayerError>(
|
|
|
43
83
|
effect: Effect.Effect<A, E, NoInfer<R> | REvent | Scope.Scope>,
|
|
44
84
|
eventLayer: Layer.Layer<REvent, EventLayerError, NoInfer<R>>,
|
|
45
85
|
parent?: Tracer.AnySpan,
|
|
86
|
+
onFailure?: RunOptions["onFailure"],
|
|
46
87
|
): Promise<A>;
|
|
47
88
|
export function runEventPromise<A, E, R, REvent, EventLayerError, LayerError>(
|
|
48
89
|
...args:
|
|
@@ -51,25 +92,35 @@ export function runEventPromise<A, E, R, REvent, EventLayerError, LayerError>(
|
|
|
51
92
|
effect: Effect.Effect<A, E, R | Scope.Scope>,
|
|
52
93
|
eventLayer?: undefined,
|
|
53
94
|
parent?: Tracer.AnySpan,
|
|
95
|
+
onFailure?: RunOptions["onFailure"],
|
|
54
96
|
]
|
|
55
97
|
| readonly [
|
|
56
98
|
runtime: ManagedRuntime.ManagedRuntime<R, LayerError>,
|
|
57
99
|
effect: Effect.Effect<A, E, R | REvent | Scope.Scope>,
|
|
58
100
|
eventLayer: Layer.Layer<REvent, EventLayerError, R>,
|
|
59
101
|
parent?: Tracer.AnySpan,
|
|
102
|
+
onFailure?: RunOptions["onFailure"],
|
|
60
103
|
]
|
|
61
104
|
): Promise<A> {
|
|
62
|
-
const [runtime, effect, eventLayer, parent] = args;
|
|
105
|
+
const [runtime, effect, eventLayer, parent, onFailure] = args;
|
|
63
106
|
|
|
64
107
|
if (eventLayer === undefined) {
|
|
65
108
|
const event = Effect.scoped(RpcTargets.withScope(effect));
|
|
66
109
|
|
|
67
|
-
return
|
|
110
|
+
return runPromise(
|
|
111
|
+
runtime,
|
|
112
|
+
parent === undefined ? event : Effect.withParentSpan(event, parent),
|
|
113
|
+
onFailure,
|
|
114
|
+
);
|
|
68
115
|
}
|
|
69
116
|
|
|
70
117
|
const event = Effect.scoped(
|
|
71
118
|
RpcTargets.withScope(effect.pipe(Effect.provide(eventLayer, { local: true }))),
|
|
72
119
|
);
|
|
73
120
|
|
|
74
|
-
return
|
|
121
|
+
return runPromise(
|
|
122
|
+
runtime,
|
|
123
|
+
parent === undefined ? event : Effect.withParentSpan(event, parent),
|
|
124
|
+
onFailure,
|
|
125
|
+
);
|
|
75
126
|
}
|