effect-cf 0.41.1 → 0.42.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 +24 -0
- package/README.md +28 -0
- package/dist/AiGateway.d.mts +2 -2
- package/dist/AnalyticsEngine.d.mts +2 -2
- package/dist/Artifacts.d.mts +2 -2
- package/dist/BrowserRendering.d.mts +2 -2
- package/dist/ContainerNamespace.d.mts +2 -2
- package/dist/D1.d.mts +9 -12
- package/dist/DurableObject.d.mts +9 -5
- package/dist/DurableObject.mjs +9 -4
- package/dist/DurableObjectDefinition.d.mts +15 -12
- package/dist/DurableObjectDefinition.mjs +5 -3
- package/dist/DurableObjectNamespace.d.mts +10 -8
- package/dist/DurableObjectSqlite.mjs +1 -1
- package/dist/Email.d.mts +2 -2
- package/dist/Hyperdrive.d.mts +2 -2
- package/dist/Images.d.mts +2 -2
- package/dist/Kv.d.mts +2 -2
- package/dist/Queue.d.mts +5 -4
- package/dist/QueueDefinition.d.mts +4 -4
- package/dist/R2.d.mts +2 -2
- package/dist/RpcDefinition.d.mts +26 -12
- package/dist/RpcDefinition.mjs +22 -5
- package/dist/Sandbox.d.mts +1 -1
- package/dist/ServiceBinding.d.mts +17 -18
- package/dist/Vectorize.d.mts +2 -2
- package/dist/Worker.d.mts +5 -3
- package/dist/Worker.mjs +4 -3
- package/dist/WorkerDefinition.d.mts +15 -11
- package/dist/WorkerDefinition.mjs +5 -3
- package/dist/WorkersAi.d.mts +2 -2
- package/dist/Workflow.d.mts +5 -4
- package/dist/WorkflowDefinition.d.mts +4 -4
- package/dist/index.d.mts +2 -2
- package/dist/internal/NativeCallback.mjs +5 -2
- package/package.json +1 -1
- package/src/AiGateway.ts +2 -0
- package/src/AnalyticsEngine.ts +2 -0
- package/src/Artifacts.ts +2 -0
- package/src/BrowserRendering.ts +2 -0
- package/src/ContainerNamespace.ts +2 -0
- package/src/D1.ts +16 -8
- package/src/DurableObject.ts +30 -4
- package/src/DurableObjectDefinition.ts +33 -17
- package/src/DurableObjectNamespace.ts +19 -35
- package/src/Email.ts +2 -0
- package/src/Hyperdrive.ts +2 -0
- package/src/Images.ts +2 -0
- package/src/Kv.ts +2 -0
- package/src/Queue.ts +4 -7
- package/src/QueueDefinition.ts +7 -4
- package/src/R2.ts +2 -0
- package/src/RpcDefinition.ts +64 -25
- package/src/Sandbox.ts +2 -0
- package/src/ServiceBinding.ts +39 -34
- package/src/Vectorize.ts +2 -0
- package/src/Worker.ts +12 -1
- package/src/WorkerDefinition.ts +28 -17
- package/src/WorkersAi.ts +2 -0
- package/src/Workflow.ts +9 -8
- package/src/WorkflowDefinition.ts +12 -4
- package/src/internal/NativeCallback.ts +13 -2
package/package.json
CHANGED
package/src/AiGateway.ts
CHANGED
|
@@ -10,6 +10,8 @@ import type { WorkerEnvironment } from "./Environment";
|
|
|
10
10
|
import { isWorkersAiBinding, type WorkersAiBinding } from "./WorkersAi";
|
|
11
11
|
import * as ErrorMessage from "./internal/ErrorMessage";
|
|
12
12
|
|
|
13
|
+
export type { BindingNotFoundError, BindingValidationError } from "./Binding";
|
|
14
|
+
|
|
13
15
|
const expectedAiGatewayBinding = "Workers AI binding with gateway()";
|
|
14
16
|
|
|
15
17
|
export class AiGatewayOperationError extends Data.TaggedError("AiGatewayOperationError")<{
|
package/src/AnalyticsEngine.ts
CHANGED
|
@@ -21,6 +21,8 @@ import * as Binding from "./Binding";
|
|
|
21
21
|
import type { WorkerEnvironment } from "./Environment";
|
|
22
22
|
import * as ErrorMessage from "./internal/ErrorMessage";
|
|
23
23
|
|
|
24
|
+
export type { BindingNotFoundError, BindingValidationError } from "./Binding";
|
|
25
|
+
|
|
24
26
|
const expectedAnalyticsEngineDataset = "Analytics Engine dataset binding with writeDataPoint()";
|
|
25
27
|
const defaultQueryApiBaseUrl = "https://api.cloudflare.com/client/v4";
|
|
26
28
|
const textEncoder = new TextEncoder();
|
package/src/Artifacts.ts
CHANGED
|
@@ -17,6 +17,8 @@ import * as Binding from "./Binding";
|
|
|
17
17
|
import type { WorkerEnvironment } from "./Environment";
|
|
18
18
|
import * as ErrorMessage from "./internal/ErrorMessage";
|
|
19
19
|
|
|
20
|
+
export type { BindingNotFoundError, BindingValidationError } from "./Binding";
|
|
21
|
+
|
|
20
22
|
const expectedArtifactsBinding =
|
|
21
23
|
"Artifacts binding with create(), get(), import(), list(), and delete()";
|
|
22
24
|
|
package/src/BrowserRendering.ts
CHANGED
|
@@ -8,6 +8,8 @@ import * as Binding from "./Binding";
|
|
|
8
8
|
import type { WorkerEnvironment } from "./Environment";
|
|
9
9
|
import * as ErrorMessage from "./internal/ErrorMessage";
|
|
10
10
|
|
|
11
|
+
export type { BindingNotFoundError, BindingValidationError } from "./Binding";
|
|
12
|
+
|
|
11
13
|
const expectedBrowserRenderingBinding = "Browser Rendering binding resource";
|
|
12
14
|
|
|
13
15
|
export class BrowserRenderingOperationError extends Data.TaggedError(
|
|
@@ -10,6 +10,8 @@ import * as RpcTargets from "./RpcTargets";
|
|
|
10
10
|
import type { WorkerEnvironment } from "./Environment";
|
|
11
11
|
import * as ErrorMessage from "./internal/ErrorMessage";
|
|
12
12
|
|
|
13
|
+
export type { BindingNotFoundError, BindingValidationError } from "./Binding";
|
|
14
|
+
|
|
13
15
|
const expectedContainerNamespace = "Container namespace binding with getByName()";
|
|
14
16
|
|
|
15
17
|
export type ContainerSignal = "SIGKILL" | "SIGINT" | "SIGTERM";
|
package/src/D1.ts
CHANGED
|
@@ -8,6 +8,8 @@ import type { SqlClient } from "effect/unstable/sql";
|
|
|
8
8
|
import * as Binding from "./Binding";
|
|
9
9
|
import type { WorkerEnvironment } from "./Environment";
|
|
10
10
|
|
|
11
|
+
export type { BindingNotFoundError, BindingValidationError } from "./Binding";
|
|
12
|
+
|
|
11
13
|
const TypeId = "~effect-cf/D1" as const;
|
|
12
14
|
|
|
13
15
|
export type TypeId = typeof TypeId;
|
|
@@ -19,6 +21,18 @@ export interface D1Definition {
|
|
|
19
21
|
|
|
20
22
|
export type D1SqlLayerOptions = Omit<D1Client.D1ClientConfig, "db">;
|
|
21
23
|
|
|
24
|
+
export type ServiceClass<Self, Id extends string> = Binding.BindingService<Self, Id, D1Database> & {
|
|
25
|
+
[TypeId]: typeof TypeId;
|
|
26
|
+
definition: D1Definition;
|
|
27
|
+
sqlLayer: (
|
|
28
|
+
options?: D1SqlLayerOptions,
|
|
29
|
+
) => Layer.Layer<
|
|
30
|
+
D1Client.D1Client | SqlClient.SqlClient,
|
|
31
|
+
Config.ConfigError | Binding.BindingNotFoundError | Binding.BindingValidationError,
|
|
32
|
+
WorkerEnvironment
|
|
33
|
+
>;
|
|
34
|
+
};
|
|
35
|
+
|
|
22
36
|
declare const D1ServiceTypeId: unique symbol;
|
|
23
37
|
|
|
24
38
|
export interface D1Service<Id extends string> {
|
|
@@ -40,18 +54,12 @@ export const make = <Id extends string>(id: Id, definition: D1Definition) =>
|
|
|
40
54
|
|
|
41
55
|
export const Service =
|
|
42
56
|
<Self>() =>
|
|
43
|
-
<Id extends string>(id: Id, definition: D1Definition) => {
|
|
57
|
+
<Id extends string>(id: Id, definition: D1Definition): ServiceClass<Self, Id> => {
|
|
44
58
|
const tag = Binding.Service<Self>()(id, definition.binding, isD1Database, undefined, {
|
|
45
59
|
expected: expectedD1Database,
|
|
46
60
|
});
|
|
47
61
|
|
|
48
|
-
const sqlLayer = (
|
|
49
|
-
options?: D1SqlLayerOptions,
|
|
50
|
-
): Layer.Layer<
|
|
51
|
-
D1Client.D1Client | SqlClient.SqlClient,
|
|
52
|
-
Config.ConfigError | Binding.BindingNotFoundError | Binding.BindingValidationError,
|
|
53
|
-
WorkerEnvironment
|
|
54
|
-
> =>
|
|
62
|
+
const sqlLayer: ServiceClass<Self, Id>["sqlLayer"] = (options) =>
|
|
55
63
|
Layer.unwrap(
|
|
56
64
|
Effect.gen(function* () {
|
|
57
65
|
const db = yield* tag;
|
package/src/DurableObject.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DurableObject as CloudflareDurableObject } from "cloudflare:workers";
|
|
2
2
|
import * as Effect from "effect/Effect";
|
|
3
3
|
import * as Layer from "effect/Layer";
|
|
4
|
+
import * as Scheduler from "effect/Scheduler";
|
|
4
5
|
import * as Tracer from "effect/Tracer";
|
|
5
6
|
import type { ManagedRuntime, Scope } from "effect";
|
|
6
7
|
|
|
@@ -19,6 +20,17 @@ import * as Runtime from "./internal/Runtime";
|
|
|
19
20
|
import * as Telemetry from "./internal/Telemetry";
|
|
20
21
|
import type { ReceiverOptions, RpcInvocationInfo } from "./RpcTracing";
|
|
21
22
|
|
|
23
|
+
export type { BindingNotFoundError, BindingValidationError } from "./Binding";
|
|
24
|
+
export type {
|
|
25
|
+
DurableObjectFetchError,
|
|
26
|
+
DurableObjectNamespaceClient,
|
|
27
|
+
DurableObjectRpcError,
|
|
28
|
+
DurableObjectStubClient,
|
|
29
|
+
StubCall,
|
|
30
|
+
StubRpc,
|
|
31
|
+
StubScopedCall,
|
|
32
|
+
} from "./DurableObjectNamespace";
|
|
33
|
+
|
|
22
34
|
const reservedMethodNames: ReadonlySet<string> = RpcDefinition.reservedMethodNames;
|
|
23
35
|
|
|
24
36
|
export type RuntimeContext<ROut> =
|
|
@@ -114,8 +126,10 @@ interface DurableObjectOptionsBase<
|
|
|
114
126
|
/**
|
|
115
127
|
* Effect run when Cloudflare loads this Durable Object instance into memory.
|
|
116
128
|
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
129
|
+
* The base layer is acquired before incoming events are admitted. The hook
|
|
130
|
+
* itself runs in the background; start it with
|
|
131
|
+
* `DurableObjectState.blockConcurrencyWhile` when incoming events should
|
|
132
|
+
* wait for setup to finish. Cloudflare may construct
|
|
119
133
|
* the same Durable Object id again after eviction or restart; use Durable
|
|
120
134
|
* Object storage if work must happen only once per id.
|
|
121
135
|
*/
|
|
@@ -287,7 +301,17 @@ export function make<
|
|
|
287
301
|
const initialize = options.initialize;
|
|
288
302
|
|
|
289
303
|
if (initialize !== undefined) {
|
|
290
|
-
state.waitUntil(
|
|
304
|
+
state.waitUntil(
|
|
305
|
+
state.blockConcurrencyWhile(async () => {
|
|
306
|
+
// Build services before admitting the first event, then let the
|
|
307
|
+
// hook synchronously install its own gate if it needs one. Its
|
|
308
|
+
// background work and failure reporting keep their waitUntil owner.
|
|
309
|
+
await Effect.runPromise(this.runtime.contextEffect, {
|
|
310
|
+
scheduler: new Scheduler.MixedScheduler("sync"),
|
|
311
|
+
});
|
|
312
|
+
state.waitUntil(this[RunSymbol](initialize, { eventLayer: false }));
|
|
313
|
+
}),
|
|
314
|
+
);
|
|
291
315
|
}
|
|
292
316
|
}
|
|
293
317
|
|
|
@@ -403,15 +427,17 @@ export type {
|
|
|
403
427
|
LayerOptions,
|
|
404
428
|
Method,
|
|
405
429
|
Methods,
|
|
430
|
+
NativeSchema,
|
|
406
431
|
NoReservedMethods,
|
|
407
432
|
Options,
|
|
408
433
|
ReservedMethodName,
|
|
434
|
+
RpcSchema,
|
|
409
435
|
ServerApi,
|
|
410
436
|
ServiceFreeSchema,
|
|
411
437
|
TagClass,
|
|
412
438
|
} from "./DurableObjectDefinition";
|
|
413
439
|
|
|
414
|
-
export { implement, method, Tag } from "./DurableObjectDefinition";
|
|
440
|
+
export { implement, method, native, Tag } from "./DurableObjectDefinition";
|
|
415
441
|
|
|
416
442
|
// Preserve the original public type export while using a domain-role name internally.
|
|
417
443
|
export type { DurableObjectRpcApi as "DurableObjectRpcShape" };
|
|
@@ -11,41 +11,55 @@ import * as RpcDefinition from "./RpcDefinition";
|
|
|
11
11
|
import { recordDecodedArgs } from "./internal/RpcInvocation";
|
|
12
12
|
import type { WorkerEnvironment } from "./Environment";
|
|
13
13
|
|
|
14
|
+
export type { BindingNotFoundError, BindingValidationError } from "./Binding";
|
|
15
|
+
export type {
|
|
16
|
+
DurableObjectFetchError,
|
|
17
|
+
DurableObjectNamespaceClient,
|
|
18
|
+
DurableObjectRpcError,
|
|
19
|
+
DurableObjectStubClient,
|
|
20
|
+
StubCall,
|
|
21
|
+
StubRpc,
|
|
22
|
+
StubScopedCall,
|
|
23
|
+
} from "./DurableObjectNamespace";
|
|
24
|
+
|
|
14
25
|
type ErasedInvoke<E> = (...args: ReadonlyArray<unknown>) => Effect.Effect<unknown, E>;
|
|
15
26
|
|
|
16
27
|
export type ServiceFreeSchema = S.Codec<any, any, never, never>;
|
|
28
|
+
export type NativeSchema<Schema extends ServiceFreeSchema = ServiceFreeSchema> =
|
|
29
|
+
RpcDefinition.NativeSchema<Schema>;
|
|
30
|
+
export type RpcSchema = RpcDefinition.RpcSchema;
|
|
17
31
|
|
|
18
32
|
export interface Method<
|
|
19
|
-
Args extends ReadonlyArray<
|
|
20
|
-
Success extends
|
|
33
|
+
Args extends ReadonlyArray<RpcSchema> = ReadonlyArray<RpcSchema>,
|
|
34
|
+
Success extends RpcSchema = RpcSchema,
|
|
21
35
|
> {
|
|
22
36
|
readonly args: Args;
|
|
23
37
|
readonly success: Success;
|
|
24
38
|
}
|
|
25
39
|
|
|
26
40
|
export namespace Method {
|
|
27
|
-
export type Any = Method<ReadonlyArray<
|
|
41
|
+
export type Any = Method<ReadonlyArray<RpcSchema>, RpcSchema>;
|
|
28
42
|
|
|
29
|
-
type ArgsFromSchemas<Args extends ReadonlyArray<
|
|
43
|
+
type ArgsFromSchemas<Args extends ReadonlyArray<RpcSchema>> = Args extends readonly []
|
|
30
44
|
? []
|
|
31
45
|
: Args extends readonly [
|
|
32
|
-
infer Head extends
|
|
33
|
-
...infer Tail extends ReadonlyArray<
|
|
46
|
+
infer Head extends RpcSchema,
|
|
47
|
+
...infer Tail extends ReadonlyArray<RpcSchema>,
|
|
34
48
|
]
|
|
35
|
-
? [
|
|
36
|
-
: Array<
|
|
49
|
+
? [RpcDefinition.SchemaType<Head>, ...ArgsFromSchemas<Tail>]
|
|
50
|
+
: Array<RpcDefinition.SchemaType<Args[number]>>;
|
|
37
51
|
|
|
38
|
-
type EncodedArgsFromSchemas<Args extends ReadonlyArray<
|
|
39
|
-
[Index in keyof Args]:
|
|
52
|
+
type EncodedArgsFromSchemas<Args extends ReadonlyArray<RpcSchema>> = {
|
|
53
|
+
[Index in keyof Args]: RpcDefinition.WireEncoded<Args[Index]>;
|
|
40
54
|
};
|
|
41
55
|
|
|
42
56
|
export type Args<Self extends Any> = ArgsFromSchemas<Self["args"]>;
|
|
43
57
|
|
|
44
58
|
export type EncodedArgs<Self extends Any> = EncodedArgsFromSchemas<Self["args"]>;
|
|
45
59
|
|
|
46
|
-
export type Success<Self extends Any> =
|
|
60
|
+
export type Success<Self extends Any> = RpcDefinition.SchemaType<Self["success"]>;
|
|
47
61
|
|
|
48
|
-
export type EncodedSuccess<
|
|
62
|
+
export type EncodedSuccess<Self extends Any> = RpcDefinition.WireEncoded<Self["success"]>;
|
|
49
63
|
}
|
|
50
64
|
|
|
51
65
|
export type Methods = Record<string, Method.Any>;
|
|
@@ -178,20 +192,22 @@ export type TagClass<
|
|
|
178
192
|
/**
|
|
179
193
|
* Defines a single RPC method schema in a Durable Object definition.
|
|
180
194
|
*/
|
|
181
|
-
export function method<Success extends
|
|
195
|
+
export function method<Success extends RpcSchema>(definition: {
|
|
182
196
|
readonly success: Success;
|
|
183
197
|
}): Method<readonly [], Success>;
|
|
184
198
|
export function method<
|
|
185
|
-
const Args extends ReadonlyArray<
|
|
186
|
-
Success extends
|
|
199
|
+
const Args extends ReadonlyArray<RpcSchema>,
|
|
200
|
+
Success extends RpcSchema,
|
|
187
201
|
>(definition: { readonly args: Args; readonly success: Success }): Method<Args, Success>;
|
|
188
202
|
export function method(definition: {
|
|
189
|
-
readonly args?: ReadonlyArray<
|
|
190
|
-
readonly success:
|
|
203
|
+
readonly args?: ReadonlyArray<RpcSchema>;
|
|
204
|
+
readonly success: RpcSchema;
|
|
191
205
|
}): Method {
|
|
192
206
|
return RpcDefinition.method(definition);
|
|
193
207
|
}
|
|
194
208
|
|
|
209
|
+
export const native = RpcDefinition.native;
|
|
210
|
+
|
|
195
211
|
const makeDefinition = <Id extends string, const MethodDefinitions extends Methods>(
|
|
196
212
|
id: Id,
|
|
197
213
|
methods: MethodDefinitions & NoReservedMethods<MethodDefinitions>,
|
|
@@ -120,12 +120,24 @@ type StubMethodCloudflareReturn<
|
|
|
120
120
|
Method extends keyof Api,
|
|
121
121
|
> = RpcInvocation.AsyncMethodCloudflareReturn<Api, Method>;
|
|
122
122
|
|
|
123
|
-
type StubCall<R, Api extends object> = <Method extends StubMethodKey<Api>>(
|
|
123
|
+
export type StubCall<R, Api extends object> = <Method extends StubMethodKey<Api>>(
|
|
124
124
|
stub: DurableObjectStubClient<Api>,
|
|
125
125
|
method: Method,
|
|
126
126
|
...args: StubMethodArgs<Api, Method>
|
|
127
127
|
) => Effect.Effect<StubMethodSuccess<Api, Method>, DurableObjectRpcError, R>;
|
|
128
128
|
|
|
129
|
+
export type StubRpc<R, Api extends object> = <Method extends StubMethodKey<Api>>(
|
|
130
|
+
stub: DurableObjectStubClient<Api>,
|
|
131
|
+
method: Method,
|
|
132
|
+
...args: StubMethodArgs<Api, Method>
|
|
133
|
+
) => Effect.Effect<StubMethodCloudflareReturn<Api, Method>, DurableObjectRpcError, R>;
|
|
134
|
+
|
|
135
|
+
export type StubScopedCall<R, Api extends object> = <Method extends StubMethodKey<Api>>(
|
|
136
|
+
stub: DurableObjectStubClient<Api>,
|
|
137
|
+
method: Method,
|
|
138
|
+
...args: StubMethodArgs<Api, Method>
|
|
139
|
+
) => Effect.Effect<Awaited<StubMethodSuccess<Api, Method>>, DurableObjectRpcError, Scope.Scope | R>;
|
|
140
|
+
|
|
129
141
|
type DurableObjectDirectClient<R, Api extends object> = {
|
|
130
142
|
readonly fetch: (
|
|
131
143
|
input: RequestInfo | URL,
|
|
@@ -227,22 +239,14 @@ export type DurableObjectNamespaceEffectClient<
|
|
|
227
239
|
*
|
|
228
240
|
* Most application code should use {@link call} instead.
|
|
229
241
|
*/
|
|
230
|
-
readonly rpc: <
|
|
231
|
-
stub: DurableObjectStubClient<Api>,
|
|
232
|
-
method: Method,
|
|
233
|
-
...args: StubMethodArgs<Api, Method>
|
|
234
|
-
) => Effect.Effect<StubMethodCloudflareReturn<Api, Method>, DurableObjectRpcError>;
|
|
242
|
+
readonly rpc: StubRpc<never, Api>;
|
|
235
243
|
/**
|
|
236
244
|
* Invokes a Durable Object RPC method, resolves Cloudflare's RPC result, and
|
|
237
245
|
* decodes the success value when the namespace was created from a definition.
|
|
238
246
|
*
|
|
239
247
|
* This is the normal choice when application code wants the final typed value.
|
|
240
248
|
*/
|
|
241
|
-
readonly call: <
|
|
242
|
-
stub: DurableObjectStubClient<Api>,
|
|
243
|
-
method: Method,
|
|
244
|
-
...args: StubMethodArgs<Api, Method>
|
|
245
|
-
) => Effect.Effect<StubMethodSuccess<Api, Method>, DurableObjectRpcError>;
|
|
249
|
+
readonly call: StubCall<never, Api>;
|
|
246
250
|
/**
|
|
247
251
|
* Invokes a Durable Object RPC method in the current `Scope`, resolves
|
|
248
252
|
* Cloudflare's RPC result, decodes definition-backed success values, and
|
|
@@ -252,11 +256,7 @@ export type DurableObjectNamespaceEffectClient<
|
|
|
252
256
|
* Use this for RPC methods that return Cloudflare RPC resources or other
|
|
253
257
|
* disposable objects whose lifetime should be tied to an Effect scope.
|
|
254
258
|
*/
|
|
255
|
-
readonly scopedCall: <
|
|
256
|
-
stub: DurableObjectStubClient<Api>,
|
|
257
|
-
method: Method,
|
|
258
|
-
...args: StubMethodArgs<Api, Method>
|
|
259
|
-
) => Effect.Effect<Awaited<StubMethodSuccess<Api, Method>>, DurableObjectRpcError, Scope.Scope>;
|
|
259
|
+
readonly scopedCall: StubScopedCall<never, Api>;
|
|
260
260
|
/**
|
|
261
261
|
* Exposes the underlying native Durable Object namespace binding.
|
|
262
262
|
*
|
|
@@ -292,25 +292,9 @@ export type DurableObjectNamespaceStaticClient<
|
|
|
292
292
|
input: RequestInfo | URL,
|
|
293
293
|
init?: RequestInit,
|
|
294
294
|
) => Effect.Effect<globalThis.Response, DurableObjectFetchError, R>;
|
|
295
|
-
readonly rpc: <
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
...args: StubMethodArgs<Api, Method>
|
|
299
|
-
) => Effect.Effect<StubMethodCloudflareReturn<Api, Method>, DurableObjectRpcError, R>;
|
|
300
|
-
readonly call: <Method extends StubMethodKey<Api>>(
|
|
301
|
-
stub: DurableObjectStubClient<Api>,
|
|
302
|
-
method: Method,
|
|
303
|
-
...args: StubMethodArgs<Api, Method>
|
|
304
|
-
) => Effect.Effect<StubMethodSuccess<Api, Method>, DurableObjectRpcError, R>;
|
|
305
|
-
readonly scopedCall: <Method extends StubMethodKey<Api>>(
|
|
306
|
-
stub: DurableObjectStubClient<Api>,
|
|
307
|
-
method: Method,
|
|
308
|
-
...args: StubMethodArgs<Api, Method>
|
|
309
|
-
) => Effect.Effect<
|
|
310
|
-
Awaited<StubMethodSuccess<Api, Method>>,
|
|
311
|
-
DurableObjectRpcError,
|
|
312
|
-
Scope.Scope | R
|
|
313
|
-
>;
|
|
295
|
+
readonly rpc: StubRpc<R, Api>;
|
|
296
|
+
readonly call: StubCall<R, Api>;
|
|
297
|
+
readonly scopedCall: StubScopedCall<R, Api>;
|
|
314
298
|
readonly rawUnsafe: () => Effect.Effect<DurableObjectNamespaceClient<Api>, never, R>;
|
|
315
299
|
};
|
|
316
300
|
|
package/src/Email.ts
CHANGED
|
@@ -14,6 +14,8 @@ import * as Binding from "./Binding";
|
|
|
14
14
|
import type { WorkerEnvironment } from "./Environment";
|
|
15
15
|
import * as ErrorMessage from "./internal/ErrorMessage";
|
|
16
16
|
|
|
17
|
+
export type { BindingNotFoundError, BindingValidationError } from "./Binding";
|
|
18
|
+
|
|
17
19
|
const expectedSendEmailBinding = "Send Email binding with send()";
|
|
18
20
|
const textEncoder = new TextEncoder();
|
|
19
21
|
|
package/src/Hyperdrive.ts
CHANGED
|
@@ -6,6 +6,8 @@ import type { Layer } from "effect";
|
|
|
6
6
|
import * as Binding from "./Binding";
|
|
7
7
|
import type { WorkerEnvironment } from "./Environment";
|
|
8
8
|
|
|
9
|
+
export type { BindingNotFoundError, BindingValidationError } from "./Binding";
|
|
10
|
+
|
|
9
11
|
const expectedHyperdrive = "Hyperdrive binding with connectionString";
|
|
10
12
|
|
|
11
13
|
export interface HyperdriveDefinition {
|
package/src/Images.ts
CHANGED
|
@@ -33,6 +33,8 @@ import * as Binding from "./Binding";
|
|
|
33
33
|
import type { WorkerEnvironment } from "./Environment";
|
|
34
34
|
import * as ErrorMessage from "./internal/ErrorMessage";
|
|
35
35
|
|
|
36
|
+
export type { BindingNotFoundError, BindingValidationError } from "./Binding";
|
|
37
|
+
|
|
36
38
|
const TypeId = "~effect-cf/Images/Steps" as const;
|
|
37
39
|
|
|
38
40
|
export type TypeId = typeof TypeId;
|
package/src/Kv.ts
CHANGED
|
@@ -14,6 +14,8 @@ import * as Binding from "./Binding";
|
|
|
14
14
|
import type { WorkerEnvironment } from "./Environment";
|
|
15
15
|
import * as ErrorMessage from "./internal/ErrorMessage";
|
|
16
16
|
|
|
17
|
+
export type { BindingNotFoundError, BindingValidationError } from "./Binding";
|
|
18
|
+
|
|
17
19
|
const expectedKvNamespace =
|
|
18
20
|
"KV namespace binding with get(), put(), delete(), getWithMetadata(), and list()";
|
|
19
21
|
|
package/src/Queue.ts
CHANGED
|
@@ -7,6 +7,9 @@ import type { WorkerEnvironment } from "./Environment";
|
|
|
7
7
|
import type * as QueueDefinition from "./QueueDefinition";
|
|
8
8
|
import * as ErrorMessage from "./internal/ErrorMessage";
|
|
9
9
|
|
|
10
|
+
export type { BindingNotFoundError, BindingValidationError } from "./Binding";
|
|
11
|
+
export type { QueueOperationError, QueueProducer } from "./QueueBinding";
|
|
12
|
+
|
|
10
13
|
export interface QueueMessage<Body> {
|
|
11
14
|
readonly raw: globalThis.Message<unknown>;
|
|
12
15
|
readonly id: string;
|
|
@@ -111,13 +114,7 @@ export namespace Definition {
|
|
|
111
114
|
|
|
112
115
|
export type LayerOptions = QueueDefinition.LayerOptions;
|
|
113
116
|
|
|
114
|
-
export type TagClass
|
|
115
|
-
Self,
|
|
116
|
-
Id extends string,
|
|
117
|
-
Message extends QueueDefinition.Definition.Any["message"],
|
|
118
|
-
> = QueueDefinition.TagClass<Self, Id, Message>;
|
|
119
|
-
|
|
120
|
-
export { implement, Tag } from "./QueueDefinition";
|
|
117
|
+
export { implement, Tag, type TagClass } from "./QueueDefinition";
|
|
121
118
|
|
|
122
119
|
export type Handler<ROut, Self extends QueueDefinition.Definition.Any> = QueueDefinition.Handler<
|
|
123
120
|
ROut,
|
package/src/QueueDefinition.ts
CHANGED
|
@@ -11,6 +11,9 @@ import type { ExecutionContext, WorkerContext } from "./Worker";
|
|
|
11
11
|
import * as WorkerEntrypoint from "./Worker";
|
|
12
12
|
import type * as RpcDefinition from "./RpcDefinition";
|
|
13
13
|
|
|
14
|
+
export type { BindingNotFoundError, BindingValidationError } from "./Binding";
|
|
15
|
+
export type { QueueOperationError, QueueProducer } from "./QueueBinding";
|
|
16
|
+
|
|
14
17
|
export interface Definition<
|
|
15
18
|
Id extends string = string,
|
|
16
19
|
Message extends RpcDefinition.ServiceFreeSchema = RpcDefinition.ServiceFreeSchema,
|
|
@@ -43,15 +46,15 @@ export type LayerOptions = {
|
|
|
43
46
|
readonly binding: string;
|
|
44
47
|
};
|
|
45
48
|
|
|
46
|
-
export
|
|
49
|
+
export type TagClass<
|
|
47
50
|
Self,
|
|
48
51
|
Id extends string,
|
|
49
52
|
Message extends RpcDefinition.ServiceFreeSchema,
|
|
50
|
-
>
|
|
53
|
+
> = Context.ServiceClass<
|
|
51
54
|
Self,
|
|
52
55
|
`effect-cf/Queue/${Id}`,
|
|
53
56
|
QueueBinding.QueueBindingClient<Message>
|
|
54
|
-
> {
|
|
57
|
+
> & {
|
|
55
58
|
readonly id: Id;
|
|
56
59
|
readonly message: Message;
|
|
57
60
|
readonly make: <ROut, LayerError>(
|
|
@@ -83,7 +86,7 @@ export interface TagClass<
|
|
|
83
86
|
never,
|
|
84
87
|
Self
|
|
85
88
|
>;
|
|
86
|
-
}
|
|
89
|
+
};
|
|
87
90
|
|
|
88
91
|
const makeDefinition = <Id extends string, Message extends RpcDefinition.ServiceFreeSchema>(
|
|
89
92
|
id: Id,
|
package/src/R2.ts
CHANGED
|
@@ -24,6 +24,8 @@ import * as Binding from "./Binding";
|
|
|
24
24
|
import type { WorkerEnvironment } from "./Environment";
|
|
25
25
|
import * as ErrorMessage from "./internal/ErrorMessage";
|
|
26
26
|
|
|
27
|
+
export type { BindingNotFoundError, BindingValidationError } from "./Binding";
|
|
28
|
+
|
|
27
29
|
const expectedR2Bucket =
|
|
28
30
|
"R2 bucket binding with head(), get(), put(), createMultipartUpload(), resumeMultipartUpload(), delete(), and list()";
|
|
29
31
|
|
package/src/RpcDefinition.ts
CHANGED
|
@@ -148,45 +148,86 @@ export type ReservedMethodName = (typeof reservedMethodNameValues)[number];
|
|
|
148
148
|
|
|
149
149
|
export type ServiceFreeSchema = S.Codec<any, any, never, never>;
|
|
150
150
|
|
|
151
|
+
export const NativeSchemaTypeId: unique symbol = Symbol.for("effect-cf/RpcDefinition/NativeSchema");
|
|
152
|
+
|
|
153
|
+
/** A schema whose encoded value is passed directly to Workers RPC. */
|
|
154
|
+
export interface NativeSchema<Schema extends ServiceFreeSchema = ServiceFreeSchema> {
|
|
155
|
+
readonly [NativeSchemaTypeId]: typeof NativeSchemaTypeId;
|
|
156
|
+
readonly schema: Schema;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export type RpcSchema = ServiceFreeSchema | NativeSchema;
|
|
160
|
+
|
|
161
|
+
export type SchemaType<Schema extends RpcSchema> =
|
|
162
|
+
Schema extends NativeSchema<infer Native extends ServiceFreeSchema>
|
|
163
|
+
? S.Schema.Type<Native>
|
|
164
|
+
: Schema extends ServiceFreeSchema
|
|
165
|
+
? S.Schema.Type<Schema>
|
|
166
|
+
: never;
|
|
167
|
+
|
|
168
|
+
export type WireEncoded<Schema extends RpcSchema> =
|
|
169
|
+
Schema extends NativeSchema<infer Native extends ServiceFreeSchema>
|
|
170
|
+
? S.Codec.Encoded<Native>
|
|
171
|
+
: S.Json;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Marks a schema to use its declared encoded form directly at the Workers RPC
|
|
175
|
+
* boundary instead of lowering it to canonical JSON.
|
|
176
|
+
*/
|
|
177
|
+
export const native = <Schema extends ServiceFreeSchema>(schema: Schema): NativeSchema<Schema> => {
|
|
178
|
+
const nativeSchema: NativeSchema<Schema> = {
|
|
179
|
+
[NativeSchemaTypeId]: NativeSchemaTypeId,
|
|
180
|
+
schema,
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
return Object.freeze(nativeSchema);
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const isNativeSchema = (schema: RpcSchema): schema is NativeSchema =>
|
|
187
|
+
Predicate.hasProperty(schema, NativeSchemaTypeId) &&
|
|
188
|
+
schema[NativeSchemaTypeId] === NativeSchemaTypeId;
|
|
189
|
+
|
|
151
190
|
/**
|
|
152
191
|
* Workers RPC structured-clones every value that crosses an isolate boundary
|
|
153
192
|
* and rejects class instances. Declaration schemas such as `Schema.Result`
|
|
154
193
|
* keep their container instance in their `Encoded` form, so the declared
|
|
155
|
-
* schemas are lowered to their canonical JSON codec before touching the wire
|
|
194
|
+
* schemas are lowered to their canonical JSON codec before touching the wire,
|
|
195
|
+
* unless explicitly wrapped with `native`.
|
|
156
196
|
*/
|
|
157
|
-
const wireCodec =
|
|
197
|
+
const wireCodec = (schema: RpcSchema): ServiceFreeSchema =>
|
|
198
|
+
isNativeSchema(schema) ? schema.schema : S.toCodecJson(schema);
|
|
158
199
|
|
|
159
200
|
export interface Method<
|
|
160
|
-
Args extends ReadonlyArray<
|
|
161
|
-
Success extends
|
|
201
|
+
Args extends ReadonlyArray<RpcSchema> = ReadonlyArray<RpcSchema>,
|
|
202
|
+
Success extends RpcSchema = RpcSchema,
|
|
162
203
|
> {
|
|
163
204
|
readonly args: Args;
|
|
164
205
|
readonly success: Success;
|
|
165
206
|
}
|
|
166
207
|
|
|
167
208
|
export namespace Method {
|
|
168
|
-
export type Any = Method<ReadonlyArray<
|
|
209
|
+
export type Any = Method<ReadonlyArray<RpcSchema>, RpcSchema>;
|
|
169
210
|
|
|
170
|
-
type ArgsFromSchemas<Args extends ReadonlyArray<
|
|
211
|
+
type ArgsFromSchemas<Args extends ReadonlyArray<RpcSchema>> = Args extends readonly []
|
|
171
212
|
? []
|
|
172
213
|
: Args extends readonly [
|
|
173
|
-
infer Head extends
|
|
174
|
-
...infer Tail extends ReadonlyArray<
|
|
214
|
+
infer Head extends RpcSchema,
|
|
215
|
+
...infer Tail extends ReadonlyArray<RpcSchema>,
|
|
175
216
|
]
|
|
176
|
-
? [
|
|
177
|
-
: Array<
|
|
217
|
+
? [SchemaType<Head>, ...ArgsFromSchemas<Tail>]
|
|
218
|
+
: Array<SchemaType<Args[number]>>;
|
|
178
219
|
|
|
179
|
-
type EncodedArgsFromSchemas<Args extends ReadonlyArray<
|
|
180
|
-
[Index in keyof Args]:
|
|
220
|
+
type EncodedArgsFromSchemas<Args extends ReadonlyArray<RpcSchema>> = {
|
|
221
|
+
[Index in keyof Args]: WireEncoded<Args[Index]>;
|
|
181
222
|
};
|
|
182
223
|
|
|
183
224
|
export type Args<Self extends Any> = ArgsFromSchemas<Self["args"]>;
|
|
184
225
|
|
|
185
226
|
export type EncodedArgs<Self extends Any> = EncodedArgsFromSchemas<Self["args"]>;
|
|
186
227
|
|
|
187
|
-
export type Success<Self extends Any> =
|
|
228
|
+
export type Success<Self extends Any> = SchemaType<Self["success"]>;
|
|
188
229
|
|
|
189
|
-
export type EncodedSuccess<
|
|
230
|
+
export type EncodedSuccess<Self extends Any> = WireEncoded<Self["success"]>;
|
|
190
231
|
}
|
|
191
232
|
|
|
192
233
|
export type Methods = Record<string, Method.Any>;
|
|
@@ -237,16 +278,16 @@ export const assertNoReservedMethods = <
|
|
|
237
278
|
}
|
|
238
279
|
};
|
|
239
280
|
|
|
240
|
-
export function method<Success extends
|
|
281
|
+
export function method<Success extends RpcSchema>(definition: {
|
|
241
282
|
readonly success: Success;
|
|
242
283
|
}): Method<readonly [], Success>;
|
|
243
284
|
export function method<
|
|
244
|
-
const Args extends ReadonlyArray<
|
|
245
|
-
Success extends
|
|
285
|
+
const Args extends ReadonlyArray<RpcSchema>,
|
|
286
|
+
Success extends RpcSchema,
|
|
246
287
|
>(definition: { readonly args: Args; readonly success: Success }): Method<Args, Success>;
|
|
247
288
|
export function method(definition: {
|
|
248
|
-
readonly args?: ReadonlyArray<
|
|
249
|
-
readonly success:
|
|
289
|
+
readonly args?: ReadonlyArray<RpcSchema>;
|
|
290
|
+
readonly success: RpcSchema;
|
|
250
291
|
}) {
|
|
251
292
|
return {
|
|
252
293
|
args: definition.args ?? [],
|
|
@@ -276,9 +317,8 @@ export const decodeArgs = Effect.fnUntraced(function* <
|
|
|
276
317
|
});
|
|
277
318
|
}
|
|
278
319
|
|
|
279
|
-
const
|
|
280
|
-
|
|
281
|
-
).pipe(
|
|
320
|
+
const codecs = methodDefinition.args.map((schema) => wireCodec(schema));
|
|
321
|
+
const decoded = yield* S.decodeUnknownEffect(S.Tuple(codecs))(args).pipe(
|
|
282
322
|
Effect.mapError(
|
|
283
323
|
(cause) =>
|
|
284
324
|
new RpcArgumentDecodeError({
|
|
@@ -315,9 +355,8 @@ export const encodeArgs = Effect.fnUntraced(function* <
|
|
|
315
355
|
});
|
|
316
356
|
}
|
|
317
357
|
|
|
318
|
-
const
|
|
319
|
-
|
|
320
|
-
).pipe(
|
|
358
|
+
const codecs = methodDefinition.args.map((schema) => wireCodec(schema));
|
|
359
|
+
const encoded = yield* S.encodeUnknownEffect(S.Tuple(codecs))(args).pipe(
|
|
321
360
|
Effect.mapError(
|
|
322
361
|
(cause) =>
|
|
323
362
|
new RpcArgumentEncodeError({
|
package/src/Sandbox.ts
CHANGED
|
@@ -47,6 +47,8 @@ import * as ErrorMessage from "./internal/ErrorMessage";
|
|
|
47
47
|
import { CurrentTargets } from "./internal/RpcTargets";
|
|
48
48
|
import * as RpcTargets from "./RpcTargets";
|
|
49
49
|
|
|
50
|
+
export type { BindingNotFoundError, BindingValidationError } from "./Binding";
|
|
51
|
+
|
|
50
52
|
export type {
|
|
51
53
|
BackupOptions,
|
|
52
54
|
CheckChangesOptions,
|