effect-cf 0.39.1 → 0.40.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 +18 -0
- package/README.md +9 -1
- package/dist/AiGateway.d.mts +86 -0
- package/dist/AiGateway.mjs +178 -0
- package/dist/AnalyticsEngine.d.mts +170 -0
- package/dist/AnalyticsEngine.mjs +275 -0
- package/dist/{Artifacts-B3r3RuTB.d.mts → Artifacts.d.mts} +8 -5
- package/dist/{Artifacts-CBxWGeZB.mjs → Artifacts.mjs} +9 -5
- package/dist/Binding.d.mts +45 -0
- package/dist/{Binding-C82jRhdr.mjs → Binding.mjs} +8 -4
- package/dist/BrowserRendering.d.mts +85 -0
- package/dist/BrowserRendering.mjs +81 -0
- package/dist/Cache.d.mts +40 -0
- package/dist/Cache.mjs +51 -0
- package/dist/CloudflareOtlp.d.mts +95 -0
- package/dist/CloudflareOtlp.mjs +125 -0
- package/dist/CloudflareTracer.d.mts +20 -0
- package/dist/CloudflareTracer.mjs +69 -0
- package/dist/ComputerArtifacts.d.mts +2 -2
- package/dist/ComputerArtifacts.mjs +3 -2
- package/dist/ComputerWorkspace.d.mts +36 -31
- package/dist/ComputerWorkspace.mjs +8 -3
- package/dist/ComputerWorkspaceHost.d.mts +1 -1
- package/dist/ComputerWorkspaceHost.mjs +1 -1
- package/dist/{ContainerNamespace-DbLaeFhN.d.mts → ContainerNamespace.d.mts} +16 -12
- package/dist/ContainerNamespace.mjs +165 -0
- package/dist/D1.d.mts +33 -0
- package/dist/D1.mjs +32 -0
- package/dist/DurableObject.d.mts +103 -0
- package/dist/DurableObject.mjs +77 -0
- package/dist/DurableObjectAlarm.d.mts +187 -0
- package/dist/DurableObjectAlarm.mjs +344 -0
- package/dist/DurableObjectDefinition.d.mts +87 -0
- package/dist/DurableObjectDefinition.mjs +125 -0
- package/dist/DurableObjectNamespace.d.mts +154 -0
- package/dist/DurableObjectNamespace.mjs +144 -0
- package/dist/DurableObjectRpcWebSocket.d.mts +112 -0
- package/dist/DurableObjectRpcWebSocket.mjs +547 -0
- package/dist/DurableObjectSqlite.d.mts +11 -0
- package/dist/DurableObjectSqlite.mjs +16 -0
- package/dist/DurableObjectState.d.mts +65 -0
- package/dist/DurableObjectState.mjs +47 -0
- package/dist/DurableObjectStorage.d.mts +112 -0
- package/dist/{DurableObjectState-DLL0YgBd.mjs → DurableObjectStorage.mjs} +19 -157
- package/dist/DurableObjectWebSocket.d.mts +83 -0
- package/dist/DurableObjectWebSocket.mjs +120 -0
- package/dist/Email.d.mts +106 -0
- package/dist/Email.mjs +247 -0
- package/dist/Environment.d.mts +59 -0
- package/dist/{ErrorMessage-Byx2OgNd.mjs → Environment.mjs} +7 -18
- package/dist/{Hyperdrive-HrwFlZ6x.d.mts → Hyperdrive.d.mts} +8 -5
- package/dist/Hyperdrive.mjs +32 -0
- package/dist/HyperdrivePg.d.mts +4 -3
- package/dist/HyperdrivePg.mjs +3 -1
- package/dist/Images.d.mts +191 -0
- package/dist/Images.mjs +112 -0
- package/dist/Kv.d.mts +84 -0
- package/dist/Kv.mjs +132 -0
- package/dist/Mcp.d.mts +5 -3
- package/dist/Mcp.mjs +13 -4
- package/dist/Queue.d.mts +68 -0
- package/dist/Queue.mjs +54 -0
- package/dist/QueueBinding.d.mts +42 -0
- package/dist/QueueBinding.mjs +69 -0
- package/dist/QueueDefinition.d.mts +48 -0
- package/dist/QueueDefinition.mjs +63 -0
- package/dist/R2.d.mts +89 -0
- package/dist/R2.mjs +117 -0
- package/dist/Rpc.d.mts +29 -0
- package/dist/Rpc.mjs +28 -0
- package/dist/RpcDefinition.d.mts +116 -0
- package/dist/RpcDefinition.mjs +184 -0
- package/dist/RpcTracing.d.mts +52 -0
- package/dist/RpcTracing.mjs +77 -0
- package/dist/Sandbox.d.mts +10 -5
- package/dist/Sandbox.mjs +9 -3
- package/dist/ServiceBinding.d.mts +112 -0
- package/dist/ServiceBinding.mjs +145 -0
- package/dist/Vectorize.d.mts +68 -0
- package/dist/Vectorize.mjs +76 -0
- package/dist/Vitest.d.mts +6 -4
- package/dist/Vitest.mjs +8 -4
- package/dist/WebTransport.d.mts +66 -0
- package/dist/WebTransport.mjs +63 -0
- package/dist/Worker.d.mts +139 -0
- package/dist/Worker.mjs +141 -0
- package/dist/WorkerDefinition.d.mts +100 -0
- package/dist/WorkerDefinition.mjs +103 -0
- package/dist/WorkersAi.d.mts +84 -0
- package/dist/WorkersAi.mjs +84 -0
- package/dist/Workflow.d.mts +91 -0
- package/dist/Workflow.mjs +139 -0
- package/dist/{WorkflowBinding-DtVykUCz.d.mts → WorkflowBinding.d.mts} +14 -10
- package/dist/WorkflowBinding.mjs +100 -0
- package/dist/WorkflowDefinition.d.mts +51 -0
- package/dist/WorkflowDefinition.mjs +69 -0
- package/dist/{rolldown-runtime-D7D4PA-g.mjs → _virtual/_rolldown/runtime.mjs} +1 -1
- package/dist/index.d.mts +40 -1800
- package/dist/index.mjs +40 -3123
- package/dist/{ComputerWorkspaceHostRegistry-CY5Fv4Ng.mjs → internal/ComputerWorkspaceHostRegistry.mjs} +1 -1
- package/dist/internal/Entrypoint.mjs +37 -0
- package/dist/internal/ErrorMessage.mjs +17 -0
- package/dist/internal/NativeCallback.mjs +33 -0
- package/dist/internal/RpcInvocation.d.mts +13 -0
- package/dist/internal/RpcInvocation.mjs +34 -0
- package/dist/internal/Runtime.mjs +31 -0
- package/dist/internal/Telemetry.mjs +20 -0
- package/dist/{WorkerContext-Yobnfw-K.mjs → internal/WorkerContext.mjs} +4 -31
- package/package.json +1 -1
- package/src/AiGateway.ts +5 -1
- package/src/AnalyticsEngine.ts +14 -19
- package/src/Artifacts.ts +6 -1
- package/src/Binding.ts +5 -1
- package/src/BrowserRendering.ts +5 -1
- package/src/Cache.ts +5 -1
- package/src/CloudflareOtlp.ts +12 -10
- package/src/CloudflareTracer.ts +7 -1
- package/src/ComputerArtifacts.ts +2 -1
- package/src/ComputerWorkspace.ts +7 -1
- package/src/ContainerNamespace.ts +6 -1
- package/src/D1.ts +4 -1
- package/src/DurableObject.ts +122 -29
- package/src/DurableObjectAlarm.ts +185 -52
- package/src/DurableObjectDefinition.ts +22 -22
- package/src/DurableObjectNamespace.ts +4 -1
- package/src/DurableObjectRpcWebSocket.ts +7 -1
- package/src/DurableObjectSqlite.ts +2 -1
- package/src/DurableObjectState.ts +4 -1
- package/src/DurableObjectStorage.ts +11 -13
- package/src/DurableObjectWebSocket.ts +5 -1
- package/src/Email.ts +5 -1
- package/src/Environment.ts +6 -1
- package/src/Hyperdrive.ts +4 -1
- package/src/HyperdrivePg.ts +3 -1
- package/src/Images.ts +7 -1
- package/src/Kv.ts +7 -1
- package/src/Mcp.ts +13 -13
- package/src/Queue.ts +3 -1
- package/src/QueueBinding.ts +5 -1
- package/src/QueueDefinition.ts +4 -1
- package/src/R2.ts +7 -1
- package/src/Rpc.ts +4 -1
- package/src/RpcDefinition.ts +4 -1
- package/src/RpcTracing.ts +9 -1
- package/src/Sandbox.ts +7 -1
- package/src/ServiceBinding.ts +6 -1
- package/src/Vectorize.ts +7 -1
- package/src/Vitest.ts +5 -1
- package/src/WebTransport.ts +6 -1
- package/src/Worker.ts +10 -16
- package/src/WorkerDefinition.ts +3 -1
- package/src/WorkersAi.ts +7 -1
- package/src/Workflow.ts +8 -11
- package/src/WorkflowBinding.ts +6 -1
- package/src/WorkflowDefinition.ts +4 -1
- package/src/internal/Entrypoint.ts +3 -1
- package/src/internal/ErrorMessage.ts +1 -1
- package/src/internal/NativeCallback.ts +3 -1
- package/src/internal/RpcInvocation.ts +5 -1
- package/src/internal/Runtime.ts +5 -1
- package/src/internal/Telemetry.ts +4 -3
- package/src/internal/WorkerContext.ts +3 -1
- package/dist/Binding-DKcLrQCM.d.mts +0 -94
- package/dist/DurableObjectState-DJ0K-zyd.d.mts +0 -244
- package/dist/Worker-XsGJsCJX.mjs +0 -885
- package/dist/Worker-gV4mDqIs.d.mts +0 -641
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as S from "effect/Schema";
|
|
3
|
+
import * as Option from "effect/Option";
|
|
4
|
+
declare namespace WebTransport_d_exports {
|
|
5
|
+
export { Capabilities, InboundTransport, WebTransportCapability, WebTransportUnsupportedError, capabilities, inboundSessionsUnsupported, inboundTransport, isHttp3 };
|
|
6
|
+
}
|
|
7
|
+
declare const InboundTransport_base: S.Class<InboundTransport, S.Struct<{
|
|
8
|
+
readonly httpProtocol: S.String;
|
|
9
|
+
readonly clientQuicRtt: S.optional<S.Number>;
|
|
10
|
+
readonly clientTcpRtt: S.optional<S.Number>;
|
|
11
|
+
}>, {}>;
|
|
12
|
+
/**
|
|
13
|
+
* Metadata Cloudflare's edge reports about the inbound client connection.
|
|
14
|
+
*
|
|
15
|
+
* `httpProtocol` and `clientTcpRtt` are declared in
|
|
16
|
+
* `@cloudflare/workers-types`; `clientQuicRtt` is documented by Cloudflare
|
|
17
|
+
* ("only present when the client connected over QUIC (HTTP/3)") but not yet
|
|
18
|
+
* present in the published types, so it is decoded from the open
|
|
19
|
+
* `Record<string, unknown>` side of `request.cf`.
|
|
20
|
+
*/
|
|
21
|
+
declare class InboundTransport extends InboundTransport_base {}
|
|
22
|
+
/**
|
|
23
|
+
* Decodes the inbound transport metadata from `request.cf`.
|
|
24
|
+
*
|
|
25
|
+
* Returns `None` when the metadata is absent (for example in local `wrangler
|
|
26
|
+
* dev` or when a Worker invokes another Worker directly) or does not match
|
|
27
|
+
* the expected shape.
|
|
28
|
+
*/
|
|
29
|
+
declare const inboundTransport: (request: Pick<CloudflareRequest, "cf">) => Option.Option<InboundTransport>;
|
|
30
|
+
declare const isHttp3: (transport: InboundTransport) => boolean;
|
|
31
|
+
interface Capabilities {
|
|
32
|
+
/**
|
|
33
|
+
* Whether Worker code can accept inbound WebTransport sessions. Typed as
|
|
34
|
+
* literally `false`: no such runtime API exists (cloudflare/workerd#6451),
|
|
35
|
+
* so this can only change through a breaking, deliberate update when
|
|
36
|
+
* Cloudflare ships one.
|
|
37
|
+
*/
|
|
38
|
+
readonly inboundSessions: false;
|
|
39
|
+
/**
|
|
40
|
+
* Whether the runtime exposes a client `WebTransport` constructor global.
|
|
41
|
+
* Feature-detected at runtime; `false` in workerd today, which has no
|
|
42
|
+
* QUIC stack.
|
|
43
|
+
*/
|
|
44
|
+
readonly outboundSessions: boolean;
|
|
45
|
+
}
|
|
46
|
+
declare const capabilities: Effect.Effect<Capabilities>;
|
|
47
|
+
type WebTransportCapability = "inbound-sessions" | "outbound-sessions";
|
|
48
|
+
declare const WebTransportUnsupportedError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
49
|
+
readonly _tag: "WebTransportUnsupportedError";
|
|
50
|
+
} & Readonly<A>;
|
|
51
|
+
declare class WebTransportUnsupportedError extends WebTransportUnsupportedError_base<{
|
|
52
|
+
readonly capability: WebTransportCapability;
|
|
53
|
+
}> {
|
|
54
|
+
get message(): string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The explicit typed boundary for inbound WebTransport sessions.
|
|
58
|
+
*
|
|
59
|
+
* Always fails with {@link WebTransportUnsupportedError} today. Route the
|
|
60
|
+
* code path that would accept a session through this effect so the
|
|
61
|
+
* limitation is visible in the type system and greppable when Cloudflare
|
|
62
|
+
* ships a real API.
|
|
63
|
+
*/
|
|
64
|
+
declare const inboundSessionsUnsupported: Effect.Effect<never, WebTransportUnsupportedError>;
|
|
65
|
+
//#endregion
|
|
66
|
+
export { Capabilities, InboundTransport, WebTransportCapability, WebTransportUnsupportedError, WebTransport_d_exports, capabilities, inboundSessionsUnsupported, inboundTransport, isHttp3 };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { __exportAll } from "./_virtual/_rolldown/runtime.mjs";
|
|
2
|
+
import * as Data from "effect/Data";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
import * as S from "effect/Schema";
|
|
5
|
+
import * as Predicate from "effect/Predicate";
|
|
6
|
+
import "effect/Option";
|
|
7
|
+
import * as Result from "effect/Result";
|
|
8
|
+
//#region src/WebTransport.ts
|
|
9
|
+
var WebTransport_exports = /* @__PURE__ */ __exportAll({
|
|
10
|
+
InboundTransport: () => InboundTransport,
|
|
11
|
+
WebTransportUnsupportedError: () => WebTransportUnsupportedError,
|
|
12
|
+
capabilities: () => capabilities,
|
|
13
|
+
inboundSessionsUnsupported: () => inboundSessionsUnsupported,
|
|
14
|
+
inboundTransport: () => inboundTransport,
|
|
15
|
+
isHttp3: () => isHttp3
|
|
16
|
+
});
|
|
17
|
+
/**
|
|
18
|
+
* Metadata Cloudflare's edge reports about the inbound client connection.
|
|
19
|
+
*
|
|
20
|
+
* `httpProtocol` and `clientTcpRtt` are declared in
|
|
21
|
+
* `@cloudflare/workers-types`; `clientQuicRtt` is documented by Cloudflare
|
|
22
|
+
* ("only present when the client connected over QUIC (HTTP/3)") but not yet
|
|
23
|
+
* present in the published types, so it is decoded from the open
|
|
24
|
+
* `Record<string, unknown>` side of `request.cf`.
|
|
25
|
+
*/
|
|
26
|
+
var InboundTransport = class extends S.Class("InboundTransport")({
|
|
27
|
+
httpProtocol: S.String,
|
|
28
|
+
clientQuicRtt: S.optional(S.Number),
|
|
29
|
+
clientTcpRtt: S.optional(S.Number)
|
|
30
|
+
}) {};
|
|
31
|
+
const decodeInboundTransport = S.decodeUnknownResult(InboundTransport);
|
|
32
|
+
/**
|
|
33
|
+
* Decodes the inbound transport metadata from `request.cf`.
|
|
34
|
+
*
|
|
35
|
+
* Returns `None` when the metadata is absent (for example in local `wrangler
|
|
36
|
+
* dev` or when a Worker invokes another Worker directly) or does not match
|
|
37
|
+
* the expected shape.
|
|
38
|
+
*/
|
|
39
|
+
const inboundTransport = (request) => Result.getSuccess(decodeInboundTransport(request.cf));
|
|
40
|
+
const isHttp3 = (transport) => transport.clientQuicRtt !== void 0 || transport.httpProtocol === "HTTP/3";
|
|
41
|
+
const capabilities = Effect.sync(() => {
|
|
42
|
+
const runtime = globalThis;
|
|
43
|
+
return {
|
|
44
|
+
inboundSessions: false,
|
|
45
|
+
outboundSessions: Predicate.hasProperty(runtime, "WebTransport") && Predicate.isFunction(runtime["WebTransport"])
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
var WebTransportUnsupportedError = class extends Data.TaggedError("WebTransportUnsupportedError") {
|
|
49
|
+
get message() {
|
|
50
|
+
return this.capability === "inbound-sessions" ? "Cloudflare Workers cannot accept inbound WebTransport sessions: the edge terminates QUIC and no runtime session API exists (cloudflare/workerd#6451). Use Durable Object WebSockets for bidirectional push." : "This Workers runtime provides no WebTransport client: workerd has no QUIC stack and cloudflare:sockets is TCP-only.";
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* The explicit typed boundary for inbound WebTransport sessions.
|
|
55
|
+
*
|
|
56
|
+
* Always fails with {@link WebTransportUnsupportedError} today. Route the
|
|
57
|
+
* code path that would accept a session through this effect so the
|
|
58
|
+
* limitation is visible in the type system and greppable when Cloudflare
|
|
59
|
+
* ships a real API.
|
|
60
|
+
*/
|
|
61
|
+
const inboundSessionsUnsupported = Effect.fail(new WebTransportUnsupportedError({ capability: "inbound-sessions" }));
|
|
62
|
+
//#endregion
|
|
63
|
+
export { InboundTransport, WebTransportUnsupportedError, WebTransport_exports, capabilities, inboundSessionsUnsupported, inboundTransport, isHttp3 };
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { WorkerEnv, WorkerEnvironment } from "./Environment.mjs";
|
|
2
|
+
import { ReservedMethodName as ReservedMethodName$1 } from "./RpcDefinition.mjs";
|
|
3
|
+
import { QueueHandler } from "./Queue.mjs";
|
|
4
|
+
import { ReceiverOptions, RpcInvocationInfo } from "./RpcTracing.mjs";
|
|
5
|
+
import { Api, Definition, HandlerEffect, Handlers, LayerOptions, Method, Methods, NoReservedMethods, Options, ServerApi, ServiceFreeSchema, Tag, TagClass, implement, method } from "./WorkerDefinition.mjs";
|
|
6
|
+
import * as Context$1 from "effect/Context";
|
|
7
|
+
import * as Effect from "effect/Effect";
|
|
8
|
+
import * as Layer$1 from "effect/Layer";
|
|
9
|
+
import { WorkerEntrypoint } from "cloudflare:workers";
|
|
10
|
+
import * as HttpServerRequest from "effect/unstable/http/HttpServerRequest";
|
|
11
|
+
import * as HttpServerResponse from "effect/unstable/http/HttpServerResponse";
|
|
12
|
+
import { Cause, Scope } from "effect";
|
|
13
|
+
declare namespace Worker_d_exports {
|
|
14
|
+
export { Api, Definition, ExecutionContext, FetchHandler, FetchWorkerOptions, HandlerEffect, Handlers, LayerOptions, Method, Methods, NativeRequest, NoReservedMethods, Options, ReservedMethodName, RpcHandlers, RunOptions, RunSymbol, ServerApi, ServiceFreeSchema, Tag, TagClass, WorkerClass, WorkerContext, WorkerContextService, WorkerContextWaitUntilOptions, WorkerFetchSuccess, WorkerHandler, WorkerOptions, WorkerRpc, WorkerRpcContract, WorkerRpcHandler, WorkerRpcContract as WorkerRpcShape, implement, isWebSocketUpgrade, make, makeFetchHandler, method };
|
|
15
|
+
}
|
|
16
|
+
declare const ExecutionContext_base: Context$1.ServiceClass<ExecutionContext, "effect-cf/ExecutionContext", globalThis.ExecutionContext<unknown>>;
|
|
17
|
+
declare class ExecutionContext extends ExecutionContext_base {}
|
|
18
|
+
interface WorkerContextWaitUntilOptions<E, R> {
|
|
19
|
+
/**
|
|
20
|
+
* Failure mode for the background effect: `"observe"` (default) logs or
|
|
21
|
+
* routes the failure to `onFailure`, while `"propagate"` also rejects the
|
|
22
|
+
* native `waitUntil` promise.
|
|
23
|
+
*/
|
|
24
|
+
readonly mode?: "observe" | "propagate";
|
|
25
|
+
readonly onFailure?: (cause: Cause.Cause<E>) => Effect.Effect<void, never, R>;
|
|
26
|
+
}
|
|
27
|
+
interface WorkerContextService {
|
|
28
|
+
readonly raw: globalThis.ExecutionContext;
|
|
29
|
+
waitUntil<A, E, R, R2 = never>(effect: Effect.Effect<A, E, R>, options?: WorkerContextWaitUntilOptions<E, R2>): Effect.Effect<void, never, R | R2>;
|
|
30
|
+
waitUntilPropagating<A, E, R, R2 = never>(effect: Effect.Effect<A, E, R>, options?: Omit<WorkerContextWaitUntilOptions<E, R2>, "mode">): Effect.Effect<void, never, R | R2>;
|
|
31
|
+
readonly passThroughOnException: Effect.Effect<void>;
|
|
32
|
+
abort(reason?: string): Effect.Effect<void>;
|
|
33
|
+
}
|
|
34
|
+
declare const WorkerContext_base: Context$1.ServiceClass<WorkerContext, "effect-cf/WorkerContext", WorkerContextService>;
|
|
35
|
+
declare class WorkerContext extends WorkerContext_base {}
|
|
36
|
+
declare const NativeRequest_base: Context$1.ServiceClass<NativeRequest, "effect-cf/NativeRequest", Request<unknown, CfProperties<unknown>>>;
|
|
37
|
+
declare class NativeRequest extends NativeRequest_base {}
|
|
38
|
+
declare const isWebSocketUpgrade: (request: Request) => boolean;
|
|
39
|
+
type ReservedMethodName = ReservedMethodName$1 | "fetch" | "connect" | "queue" | "scheduled" | "tail" | "tailStream" | "test" | "trace" | "alarm" | "webSocketMessage" | "webSocketClose" | "webSocketError";
|
|
40
|
+
type WorkerBaseContext<ROut> = ExecutionContext | WorkerContext | WorkerEnvironment | ROut;
|
|
41
|
+
type WorkerFetchContext<ROut> = WorkerBaseContext<ROut> | NativeRequest | HttpServerRequest.HttpServerRequest | Scope.Scope;
|
|
42
|
+
type WorkerRpcContext<ROut> = WorkerBaseContext<ROut> | Scope.Scope;
|
|
43
|
+
/** Override to instrument the whole event, then call super[RunSymbol]. */
|
|
44
|
+
declare const RunSymbol: unique symbol;
|
|
45
|
+
declare const FetchSymbol: unique symbol;
|
|
46
|
+
/** Metadata available before an event effect or its event layer starts. */
|
|
47
|
+
interface RunOptions {
|
|
48
|
+
readonly event?: "fetch" | "rpc" | "queue";
|
|
49
|
+
readonly rpc?: RpcInvocationInfo;
|
|
50
|
+
}
|
|
51
|
+
type WorkerFetchSuccess = Response | HttpServerResponse.HttpServerResponse;
|
|
52
|
+
/**
|
|
53
|
+
* Effect type for `fetch` handlers executed by {@link make}.
|
|
54
|
+
*/
|
|
55
|
+
type WorkerHandler<ROut, A = WorkerFetchSuccess> = Effect.Effect<A, unknown, WorkerFetchContext<ROut>>;
|
|
56
|
+
/**
|
|
57
|
+
* Effect type for worker RPC handlers.
|
|
58
|
+
*/
|
|
59
|
+
type WorkerRpcHandler<ROut, A = unknown> = Effect.Effect<A, unknown, WorkerRpcContext<ROut>>;
|
|
60
|
+
/**
|
|
61
|
+
* Shape of worker RPC handlers passed to {@link make}.
|
|
62
|
+
*/
|
|
63
|
+
type WorkerRpc<ROut> = Record<string, (...args: Array<any>) => WorkerRpcHandler<ROut>>;
|
|
64
|
+
type WorkerRpcContract<Rpc extends WorkerRpc<ROut>, ROut> = { readonly [Key in keyof Rpc]: Rpc[Key] extends ((...args: infer Args) => Effect.Effect<infer A, unknown, WorkerRpcContext<ROut>>) ? (...args: Args) => Promise<A> : never; };
|
|
65
|
+
type RpcHandlers<ROut, Api> = { readonly [Key in keyof Api as Key extends keyof WorkerEntrypoint ? never : Key extends string ? Key extends ReservedMethodName ? never : [Api[Key]] extends [never] ? never : Api[Key] extends ((...args: Array<any>) => Promise<any>) ? Key : never : never]: Api[Key] extends ((...args: infer Args) => Promise<infer A>) ? (...args: Args) => WorkerRpcHandler<ROut, A> : never; };
|
|
66
|
+
interface WorkerOptions<RRuntime, REvent = never, EventLayerError = never, Rpc extends WorkerRpc<RRuntime | REvent> = Record<never, never>> {
|
|
67
|
+
/**
|
|
68
|
+
* Layer provided around each Cloudflare event handled by this Worker.
|
|
69
|
+
*
|
|
70
|
+
* The layer is built inside the event's Effect scope. For fetch handlers that
|
|
71
|
+
* return an Effect `HttpServerResponse` stream, its scope remains open until
|
|
72
|
+
* the response body finishes or is canceled. Native `Response` values pass
|
|
73
|
+
* through unchanged, so their body streams do not carry this scoped-lifetime
|
|
74
|
+
* guarantee. Fetch, queue, and RPC handlers schedule a best-effort telemetry
|
|
75
|
+
* flush capped at two seconds.
|
|
76
|
+
*/
|
|
77
|
+
readonly eventLayer?: Layer$1.Layer<REvent, EventLayerError, WorkerBaseContext<RRuntime>>;
|
|
78
|
+
readonly fetch?: Effect.Effect<WorkerFetchSuccess, unknown, WorkerFetchContext<RRuntime | REvent>>;
|
|
79
|
+
readonly queue?: QueueHandler<RRuntime | REvent>;
|
|
80
|
+
/**
|
|
81
|
+
* Optional RPC methods exposed as class instance methods.
|
|
82
|
+
*
|
|
83
|
+
* After every invocation, the configured OTLP flusher is scheduled through
|
|
84
|
+
* `WorkerContext.waitUntil`, including when the handler fails. The scheduled
|
|
85
|
+
* flush silently settles within two seconds even if the exporter does not.
|
|
86
|
+
*/
|
|
87
|
+
readonly rpc?: Rpc;
|
|
88
|
+
/** Accept live native trace metadata. The client must also enable rpcTracing. */
|
|
89
|
+
readonly rpcTracing?: ReceiverOptions;
|
|
90
|
+
}
|
|
91
|
+
type WorkerOptionsWithEventLayer<RRuntime, REvent, EventLayerError, Rpc extends WorkerRpc<RRuntime | REvent> = Record<never, never>> = Omit<WorkerOptions<RRuntime, REvent, EventLayerError, Rpc>, "eventLayer"> & {
|
|
92
|
+
readonly eventLayer: Layer$1.Layer<REvent, EventLayerError, WorkerBaseContext<RRuntime>>;
|
|
93
|
+
};
|
|
94
|
+
type FetchWorkerOptions<RRuntime, REvent = never, EventLayerError = never> = Omit<WorkerOptions<RRuntime, REvent, EventLayerError, Record<never, never>>, "rpc"> & {
|
|
95
|
+
readonly rpc?: never;
|
|
96
|
+
};
|
|
97
|
+
type FetchWorkerOptionsWithEventLayer<RRuntime, REvent, EventLayerError> = Omit<FetchWorkerOptions<RRuntime, REvent, EventLayerError>, "eventLayer"> & {
|
|
98
|
+
readonly eventLayer: Layer$1.Layer<REvent, EventLayerError, WorkerBaseContext<RRuntime>>;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Cloudflare `WorkerEntrypoint` constructor produced by {@link make}.
|
|
102
|
+
*/
|
|
103
|
+
type WorkerClass<Rpc extends WorkerRpc<ROut>, ROut> = new (ctx: globalThis.ExecutionContext, env: WorkerEnv) => WorkerEntrypoint<WorkerEnv> & {
|
|
104
|
+
fetch(request: Request): Promise<Response>;
|
|
105
|
+
queue(batch: globalThis.MessageBatch): Promise<void>;
|
|
106
|
+
[RunSymbol]<A, E>(effect: Effect.Effect<A, E, WorkerRpcContext<ROut>>, options?: RunOptions): Promise<A>;
|
|
107
|
+
[FetchSymbol](request: Request, requestContext: globalThis.ExecutionContext): Promise<Response>;
|
|
108
|
+
} & WorkerRpcContract<Rpc, ROut>;
|
|
109
|
+
/**
|
|
110
|
+
* `ExportedHandler`-compatible fetch object produced by {@link makeFetchHandler}.
|
|
111
|
+
*/
|
|
112
|
+
interface FetchHandler<Env extends WorkerEnv = WorkerEnv> {
|
|
113
|
+
readonly fetch: (request: Request, env: Env, ctx: globalThis.ExecutionContext) => Promise<Response>;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Cloudflare creates a new `WorkerEntrypoint` instance for each native
|
|
117
|
+
* invocation, so this base layer is not shared across invocations. Its managed
|
|
118
|
+
* runtime has no deterministic disposal point in this adapter; use
|
|
119
|
+
* `eventLayer` for resources whose finalizers must run with an event.
|
|
120
|
+
*/
|
|
121
|
+
declare function make<ROut, LayerError>(layer: Layer$1.Layer<ROut, LayerError, ExecutionContext | WorkerContext | WorkerEnvironment>, fetch: WorkerHandler<ROut>): WorkerClass<Record<never, never>, ROut>;
|
|
122
|
+
declare function make<ROut, LayerError, REvent, EventLayerError = never, const Rpc extends WorkerRpc<ROut | REvent> = Record<never, never>>(layer: Layer$1.Layer<ROut, LayerError, ExecutionContext | WorkerContext | WorkerEnvironment>, options: WorkerOptionsWithEventLayer<ROut, REvent, EventLayerError, Rpc>): WorkerClass<Rpc, ROut | REvent>;
|
|
123
|
+
declare function make<ROut, LayerError, REvent extends never = never, EventLayerError = never, const Rpc extends WorkerRpc<ROut | REvent> = Record<never, never>>(layer: Layer$1.Layer<ROut, LayerError, ExecutionContext | WorkerContext | WorkerEnvironment>, options: WorkerOptions<ROut, REvent, EventLayerError, Rpc>): WorkerClass<Rpc, ROut | REvent>;
|
|
124
|
+
/**
|
|
125
|
+
* Creates an `ExportedHandler`-compatible `{ fetch }` object backed by
|
|
126
|
+
* {@link make}.
|
|
127
|
+
*
|
|
128
|
+
* The Effect runtime is cached per `env` identity, so the base layer builds
|
|
129
|
+
* once for that cached handler. Request handlers and `eventLayer` receive fresh
|
|
130
|
+
* `ExecutionContext` and `WorkerContext` services. A service constructed by the
|
|
131
|
+
* cached base layer from either context instead captures the first request's
|
|
132
|
+
* value, so construct invocation-bound services in `eventLayer`. Cloudflare
|
|
133
|
+
* provides no isolate shutdown hook, so cached base-layer finalizers are not
|
|
134
|
+
* guaranteed to run.
|
|
135
|
+
*/
|
|
136
|
+
declare function makeFetchHandler<ROut, LayerError, REvent, EventLayerError = never, Env extends WorkerEnv = WorkerEnv>(layer: Layer$1.Layer<ROut, LayerError, ExecutionContext | WorkerContext | WorkerEnvironment>, options: FetchWorkerOptionsWithEventLayer<ROut, REvent, EventLayerError>): FetchHandler<Env>;
|
|
137
|
+
declare function makeFetchHandler<ROut, LayerError, REvent extends never = never, EventLayerError = never, Env extends WorkerEnv = WorkerEnv>(layer: Layer$1.Layer<ROut, LayerError, ExecutionContext | WorkerContext | WorkerEnvironment>, options: FetchWorkerOptions<ROut, REvent, EventLayerError>): FetchHandler<Env>;
|
|
138
|
+
//#endregion
|
|
139
|
+
export { type Api, type Definition, ExecutionContext, FetchHandler, FetchWorkerOptions, type HandlerEffect, type Handlers, type LayerOptions, type Method, type Methods, NativeRequest, type NoReservedMethods, type Options, ReservedMethodName, RpcHandlers, RunOptions, RunSymbol, type ServerApi, type ServiceFreeSchema, Tag, type TagClass, WorkerClass, WorkerContext, WorkerContextService, WorkerContextWaitUntilOptions, WorkerFetchSuccess, WorkerHandler, WorkerOptions, WorkerRpc, WorkerRpcContract, type WorkerRpcContract as WorkerRpcShape, WorkerRpcHandler, Worker_d_exports, implement, isWebSocketUpgrade, make, makeFetchHandler, method };
|
package/dist/Worker.mjs
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { __exportAll } from "./_virtual/_rolldown/runtime.mjs";
|
|
2
|
+
import { fromExecutionContext } from "./internal/WorkerContext.mjs";
|
|
3
|
+
import { fromMessage, fromMessageBatch } from "./Queue.mjs";
|
|
4
|
+
import { reservedMethodNames as reservedMethodNames$1 } from "./RpcDefinition.mjs";
|
|
5
|
+
import { assumeEntrypointClass, defineEntrypointRpcMethods } from "./internal/Entrypoint.mjs";
|
|
6
|
+
import { makeEntrypointRuntime, runEventPromise } from "./internal/Runtime.mjs";
|
|
7
|
+
import { scheduleTelemetryFlush as scheduleTelemetryFlush$1 } from "./internal/Telemetry.mjs";
|
|
8
|
+
import { Tag, implement, method } from "./WorkerDefinition.mjs";
|
|
9
|
+
import * as Context from "effect/Context";
|
|
10
|
+
import * as Effect from "effect/Effect";
|
|
11
|
+
import * as Layer from "effect/Layer";
|
|
12
|
+
import { WorkerEntrypoint } from "cloudflare:workers";
|
|
13
|
+
import * as Tracer from "effect/Tracer";
|
|
14
|
+
import * as References from "effect/References";
|
|
15
|
+
import * as HttpEffect from "effect/unstable/http/HttpEffect";
|
|
16
|
+
import * as HttpMiddleware from "effect/unstable/http/HttpMiddleware";
|
|
17
|
+
import * as HttpServerRequest from "effect/unstable/http/HttpServerRequest";
|
|
18
|
+
import * as HttpServerResponse from "effect/unstable/http/HttpServerResponse";
|
|
19
|
+
//#region src/Worker.ts
|
|
20
|
+
var Worker_exports = /* @__PURE__ */ __exportAll({
|
|
21
|
+
ExecutionContext: () => ExecutionContext,
|
|
22
|
+
NativeRequest: () => NativeRequest,
|
|
23
|
+
RunSymbol: () => RunSymbol,
|
|
24
|
+
Tag: () => Tag,
|
|
25
|
+
WorkerContext: () => WorkerContext,
|
|
26
|
+
implement: () => implement,
|
|
27
|
+
isWebSocketUpgrade: () => isWebSocketUpgrade,
|
|
28
|
+
make: () => make,
|
|
29
|
+
makeFetchHandler: () => makeFetchHandler,
|
|
30
|
+
method: () => method
|
|
31
|
+
});
|
|
32
|
+
var ExecutionContext = class extends Context.Service()("effect-cf/ExecutionContext") {};
|
|
33
|
+
var WorkerContext = class extends Context.Service()("effect-cf/WorkerContext") {};
|
|
34
|
+
var NativeRequest = class extends Context.Service()("effect-cf/NativeRequest") {};
|
|
35
|
+
const isWebSocketUpgrade = (request) => request.headers.get("Upgrade")?.toLowerCase() === "websocket";
|
|
36
|
+
const reservedMethodNames = /* @__PURE__ */ new Set([
|
|
37
|
+
...reservedMethodNames$1,
|
|
38
|
+
"queue",
|
|
39
|
+
"scheduled",
|
|
40
|
+
"tail",
|
|
41
|
+
"tailStream",
|
|
42
|
+
"test",
|
|
43
|
+
"trace"
|
|
44
|
+
]);
|
|
45
|
+
/** Override to instrument the whole event, then call super[RunSymbol]. */
|
|
46
|
+
const RunSymbol = Symbol.for("effect-cf/Worker/run");
|
|
47
|
+
const FetchSymbol = Symbol.for("effect-cf/Worker/fetch");
|
|
48
|
+
const renderFetchSuccess = (effect, eventLayer) => Effect.suspend(() => {
|
|
49
|
+
let nativeResponse;
|
|
50
|
+
let webResponse;
|
|
51
|
+
const httpApp = Effect.flatMap(effect, (response) => {
|
|
52
|
+
if (response instanceof Response) {
|
|
53
|
+
nativeResponse = response;
|
|
54
|
+
return Effect.succeed(HttpServerResponse.empty());
|
|
55
|
+
}
|
|
56
|
+
return Effect.succeed(response);
|
|
57
|
+
});
|
|
58
|
+
const handleResponse = (request, response) => nativeResponse !== void 0 ? Effect.void : Effect.map(Effect.context(), (context) => {
|
|
59
|
+
webResponse = HttpServerResponse.toWeb(HttpEffect.scopeTransferToStream(response), {
|
|
60
|
+
withoutBody: request.method === "HEAD",
|
|
61
|
+
context
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
const telemetryMiddleware = HttpMiddleware.make((self) => Effect.gen(function* () {
|
|
65
|
+
yield* Effect.addFinalizer(() => scheduleTelemetryFlush);
|
|
66
|
+
return yield* self;
|
|
67
|
+
}));
|
|
68
|
+
const handled = eventLayer === void 0 ? HttpEffect.toHandled(httpApp, handleResponse, telemetryMiddleware) : Effect.flatMap(References.TracerEnabled, (tracerEnabled) => HttpEffect.toHandled(httpApp, handleResponse, HttpMiddleware.make((self) => Effect.provideService(Effect.gen(function* () {
|
|
69
|
+
const context = yield* Layer.build(Layer.fresh(eventLayer));
|
|
70
|
+
yield* Effect.addFinalizer(() => Effect.provideContext(scheduleTelemetryFlush, context));
|
|
71
|
+
return yield* HttpMiddleware.tracer(self).pipe(Effect.onExit(() => Effect.yieldNow), Effect.provideContext(context));
|
|
72
|
+
}), References.TracerEnabled, tracerEnabled))).pipe(Effect.withTracerEnabled(false)));
|
|
73
|
+
const captured = () => nativeResponse ?? webResponse ?? new Response(null, { status: 500 });
|
|
74
|
+
return Effect.matchCause(handled, {
|
|
75
|
+
onFailure: captured,
|
|
76
|
+
onSuccess: captured
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
const isWorkerOptions = (options) => !Effect.isEffect(options);
|
|
80
|
+
/**
|
|
81
|
+
* Drains buffered OTLP telemetry when the fetch Effect scope closes. Effect
|
|
82
|
+
* response streams transfer that scope to the body and schedule the flush when
|
|
83
|
+
* the body finishes or is canceled.
|
|
84
|
+
*
|
|
85
|
+
* The flush is handed to `ctx.waitUntil` instead of being awaited by the
|
|
86
|
+
* handler. It is a no-op when the context does not contain an
|
|
87
|
+
* `OtlpExporter.Flusher`, and silently settles within two seconds.
|
|
88
|
+
*/
|
|
89
|
+
const scheduleTelemetryFlush = scheduleTelemetryFlush$1((flush) => Effect.flatMap(WorkerContext, (workerContext) => workerContext.waitUntil(flush)));
|
|
90
|
+
function make(layer, optionsOrFetch) {
|
|
91
|
+
const options = isWorkerOptions(optionsOrFetch) ? optionsOrFetch : { fetch: optionsOrFetch };
|
|
92
|
+
class EffectWorker extends WorkerEntrypoint {
|
|
93
|
+
runtime;
|
|
94
|
+
constructor(ctx, env) {
|
|
95
|
+
super(ctx, env);
|
|
96
|
+
this.runtime = makeEntrypointRuntime(layer, env, Layer.mergeAll(Layer.succeed(ExecutionContext, ctx), Layer.succeed(WorkerContext, fromExecutionContext(ctx))));
|
|
97
|
+
}
|
|
98
|
+
[RunSymbol](effect, runOptions = {}) {
|
|
99
|
+
const eventLayer = runOptions.event === "fetch" ? void 0 : options.eventLayer;
|
|
100
|
+
const parent = runOptions.rpc?.parent;
|
|
101
|
+
const parentSpan = parent === void 0 ? void 0 : Tracer.externalSpan(parent);
|
|
102
|
+
if (eventLayer === void 0) return runEventPromise(this.runtime, effect, void 0, parentSpan);
|
|
103
|
+
return runEventPromise(this.runtime, effect, eventLayer, parentSpan);
|
|
104
|
+
}
|
|
105
|
+
fetch(request) {
|
|
106
|
+
return this[FetchSymbol](request);
|
|
107
|
+
}
|
|
108
|
+
[FetchSymbol](request, requestContext) {
|
|
109
|
+
const fetchHandler = options.fetch;
|
|
110
|
+
if (fetchHandler === void 0) return Promise.resolve(new Response("Not Found", { status: 404 }));
|
|
111
|
+
const ctx = requestContext ?? this.ctx;
|
|
112
|
+
const requestServices = Layer.mergeAll(Layer.succeed(NativeRequest, request), Layer.succeed(HttpServerRequest.HttpServerRequest, HttpServerRequest.fromWeb(request)), Layer.succeed(ExecutionContext, ctx), Layer.succeed(WorkerContext, fromExecutionContext(ctx)));
|
|
113
|
+
return this[RunSymbol](renderFetchSuccess(fetchHandler, options.eventLayer).pipe(Effect.provide(requestServices)), { event: "fetch" });
|
|
114
|
+
}
|
|
115
|
+
queue(batch) {
|
|
116
|
+
const queueHandler = options.queue;
|
|
117
|
+
if (queueHandler === void 0) return Promise.resolve();
|
|
118
|
+
const messages = batch.messages.map((message) => fromMessage(message, message.body));
|
|
119
|
+
return this[RunSymbol](queueHandler(fromMessageBatch(batch, messages)).pipe(Effect.onExit(() => scheduleTelemetryFlush)), { event: "queue" });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
defineEntrypointRpcMethods("Worker", EffectWorker.prototype, options.rpc, reservedMethodNames, (self, effect, rpc) => self[RunSymbol](effect, {
|
|
123
|
+
event: "rpc",
|
|
124
|
+
rpc
|
|
125
|
+
}), () => scheduleTelemetryFlush, options.rpcTracing);
|
|
126
|
+
return assumeEntrypointClass(EffectWorker);
|
|
127
|
+
}
|
|
128
|
+
function makeFetchHandler(layer, options) {
|
|
129
|
+
const WorkerClass = options.eventLayer === void 0 ? make(layer, options) : make(layer, options);
|
|
130
|
+
const instances = /* @__PURE__ */ new WeakMap();
|
|
131
|
+
return { fetch: (request, env, ctx) => {
|
|
132
|
+
let instance = instances.get(env);
|
|
133
|
+
if (instance === void 0) {
|
|
134
|
+
instance = new WorkerClass(ctx, env);
|
|
135
|
+
instances.set(env, instance);
|
|
136
|
+
}
|
|
137
|
+
return instance[FetchSymbol](request, ctx);
|
|
138
|
+
} };
|
|
139
|
+
}
|
|
140
|
+
//#endregion
|
|
141
|
+
export { ExecutionContext, NativeRequest, RunSymbol, Tag, WorkerContext, Worker_exports, implement, isWebSocketUpgrade, make, makeFetchHandler, method };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { WorkerEnvironment } from "./Environment.mjs";
|
|
2
|
+
import { BindingNotFoundError, BindingValidationError } from "./Binding.mjs";
|
|
3
|
+
import { Provider } from "./Rpc.mjs";
|
|
4
|
+
import { ServiceBindingEffectClient, ServiceBindingStaticClient } from "./ServiceBinding.mjs";
|
|
5
|
+
import { ExecutionContext, ReservedMethodName as ReservedMethodName$1, WorkerClass, WorkerContext, WorkerOptions, WorkerRpcHandler } from "./Worker.mjs";
|
|
6
|
+
import * as Context$1 from "effect/Context";
|
|
7
|
+
import { Layer, Schema } from "effect";
|
|
8
|
+
declare namespace WorkerDefinition_d_exports {
|
|
9
|
+
export { Api, Definition, HandlerEffect, Handlers, LayerOptions, Method, Methods, NoReservedMethods, Options, ReservedMethodName, ServerApi, ServiceFreeSchema, Tag, TagClass, Worker, implement, make, method };
|
|
10
|
+
}
|
|
11
|
+
type ServiceFreeSchema = Schema.Codec<any, any, never, never>;
|
|
12
|
+
interface Method<Args extends ReadonlyArray<ServiceFreeSchema> = ReadonlyArray<ServiceFreeSchema>, Success extends ServiceFreeSchema = ServiceFreeSchema> {
|
|
13
|
+
readonly args: Args;
|
|
14
|
+
readonly success: Success;
|
|
15
|
+
}
|
|
16
|
+
declare namespace Method {
|
|
17
|
+
export type Any = Method<ReadonlyArray<ServiceFreeSchema>, ServiceFreeSchema>;
|
|
18
|
+
type ArgsFromSchemas<Args extends ReadonlyArray<ServiceFreeSchema>> = Args extends readonly [] ? [] : Args extends readonly [infer Head extends ServiceFreeSchema, ...infer Tail extends ReadonlyArray<ServiceFreeSchema>] ? [Schema.Schema.Type<Head>, ...ArgsFromSchemas<Tail>] : Array<Schema.Schema.Type<Args[number]>>;
|
|
19
|
+
type EncodedArgsFromSchemas<Args extends ReadonlyArray<ServiceFreeSchema>> = { [Index in keyof Args]: Schema.Json; };
|
|
20
|
+
export type Args<Self extends Any> = ArgsFromSchemas<Self["args"]>;
|
|
21
|
+
export type EncodedArgs<Self extends Any> = EncodedArgsFromSchemas<Self["args"]>;
|
|
22
|
+
export type Success<Self extends Any> = Schema.Schema.Type<Self["success"]>;
|
|
23
|
+
export type EncodedSuccess<_Self extends Any> = Schema.Json;
|
|
24
|
+
export {};
|
|
25
|
+
}
|
|
26
|
+
type Methods = Record<string, Method.Any>;
|
|
27
|
+
/**
|
|
28
|
+
* RPC contract for a Worker service.
|
|
29
|
+
*
|
|
30
|
+
* Create with {@link make} and reuse to type both worker implementations and
|
|
31
|
+
* service bindings in other workers.
|
|
32
|
+
*/
|
|
33
|
+
interface Definition<Id extends string = string, MethodDefinitions extends Methods = Methods> {
|
|
34
|
+
readonly id: Id;
|
|
35
|
+
readonly methods: MethodDefinitions;
|
|
36
|
+
}
|
|
37
|
+
declare namespace Definition {
|
|
38
|
+
type Any = Definition<string, Methods>;
|
|
39
|
+
}
|
|
40
|
+
type ReservedMethodName = ReservedMethodName$1;
|
|
41
|
+
type NoReservedMethods<MethodDefinitions extends Methods> = Extract<keyof MethodDefinitions, ReservedMethodName> extends never ? MethodDefinitions : never;
|
|
42
|
+
/**
|
|
43
|
+
* Promise-based client API derived from a {@link Definition}.
|
|
44
|
+
*/
|
|
45
|
+
type ServerApi<Self extends Definition.Any> = { readonly [Key in keyof Self["methods"]]: (...args: Method.Args<Self["methods"][Key]>) => Promise<Method.Success<Self["methods"][Key]>>; };
|
|
46
|
+
type Api<Self extends Definition.Any> = Provider<ServerApi<Self>, ReservedMethodName>;
|
|
47
|
+
/**
|
|
48
|
+
* Effect handlers for each RPC method in a worker definition.
|
|
49
|
+
*/
|
|
50
|
+
type Handlers<ROut, Self extends Definition.Any> = { readonly [Key in keyof Self["methods"]]: (...args: Method.Args<Self["methods"][Key]>) => WorkerRpcHandler<ROut, Method.Success<Self["methods"][Key]>>; };
|
|
51
|
+
type BaseOptions<ROut, Self extends Definition.Any, REvent, EventLayerError> = Omit<WorkerOptions<ROut, REvent, EventLayerError, Handlers<ROut | REvent, Self>>, "eventLayer" | "rpc"> & {
|
|
52
|
+
readonly rpc: Handlers<ROut | REvent, Self>;
|
|
53
|
+
};
|
|
54
|
+
type EventLayerOptions<ROut, REvent, EventLayerError> = [REvent] extends [never] ? Pick<WorkerOptions<ROut, never, EventLayerError>, "eventLayer"> : {
|
|
55
|
+
readonly eventLayer: NonNullable<WorkerOptions<ROut, REvent, EventLayerError>["eventLayer"]>;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Worker constructor options for a specific RPC definition.
|
|
59
|
+
*/
|
|
60
|
+
type Options<ROut, Self extends Definition.Any, REvent = never, EventLayerError = never> = BaseOptions<ROut, Self, REvent, EventLayerError> & EventLayerOptions<ROut, REvent, EventLayerError>;
|
|
61
|
+
type LayerOptions = {
|
|
62
|
+
readonly binding: string;
|
|
63
|
+
readonly rpcTracing?: boolean;
|
|
64
|
+
};
|
|
65
|
+
type TagClass<Self, Id extends string, MethodDefinitions extends Methods> = Context$1.ServiceClass<Self, Id, ServiceBindingEffectClient<Api<Definition<Id, MethodDefinitions>>, Definition<Id, MethodDefinitions>>> & ServiceBindingStaticClient<Self, Api<Definition<Id, MethodDefinitions>>, Definition<Id, MethodDefinitions>> & {
|
|
66
|
+
readonly id: Id;
|
|
67
|
+
readonly methods: MethodDefinitions;
|
|
68
|
+
readonly make: {
|
|
69
|
+
<ROut, LayerError, REvent, EventLayerError = never>(layer: Layer.Layer<ROut, LayerError, ExecutionContext | WorkerContext | WorkerEnvironment>, options: Options<ROut, Definition<Id, MethodDefinitions>, REvent, EventLayerError> & {
|
|
70
|
+
readonly eventLayer: NonNullable<WorkerOptions<ROut, REvent, EventLayerError>["eventLayer"]>;
|
|
71
|
+
}): WorkerClass<Handlers<ROut | REvent, Definition<Id, MethodDefinitions>>, ROut | REvent>;
|
|
72
|
+
<ROut, LayerError, REvent extends never = never, EventLayerError = never>(layer: Layer.Layer<ROut, LayerError, ExecutionContext | WorkerContext | WorkerEnvironment>, options: Options<ROut, Definition<Id, MethodDefinitions>, REvent, EventLayerError>): WorkerClass<Handlers<ROut | REvent, Definition<Id, MethodDefinitions>>, ROut | REvent>;
|
|
73
|
+
};
|
|
74
|
+
readonly layer: (options: LayerOptions) => Layer.Layer<Self, BindingNotFoundError | BindingValidationError, WorkerEnvironment>;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Defines a single RPC method schema in a worker definition.
|
|
78
|
+
*/
|
|
79
|
+
declare const method: {
|
|
80
|
+
<Success extends ServiceFreeSchema>(definition: {
|
|
81
|
+
readonly success: Success;
|
|
82
|
+
}): Method<readonly [], Success>;
|
|
83
|
+
<const Args extends ReadonlyArray<ServiceFreeSchema>, Success extends ServiceFreeSchema>(definition: {
|
|
84
|
+
readonly args: Args;
|
|
85
|
+
readonly success: Success;
|
|
86
|
+
}): Method<Args, Success>;
|
|
87
|
+
};
|
|
88
|
+
declare const make: <Id extends string, const MethodDefinitions extends Methods>(id: Id, methods: MethodDefinitions & NoReservedMethods<MethodDefinitions>) => TagClass<Definition<Id, MethodDefinitions>, Id, MethodDefinitions>;
|
|
89
|
+
declare const Tag: <Self>() => <Id extends string, const MethodDefinitions extends Methods>(id: Id, methods: MethodDefinitions & NoReservedMethods<MethodDefinitions>) => TagClass<Self, Id, MethodDefinitions>;
|
|
90
|
+
declare const Worker: typeof Tag;
|
|
91
|
+
/**
|
|
92
|
+
* Helper for implementing handlers with the exact method shape of a definition.
|
|
93
|
+
*/
|
|
94
|
+
declare const implement: <ROut, const Self extends Definition.Any>(_definition: Self, handlers: Handlers<ROut, Self>) => Handlers<ROut, Self>;
|
|
95
|
+
/**
|
|
96
|
+
* Convenience alias for a single worker RPC handler Effect.
|
|
97
|
+
*/
|
|
98
|
+
type HandlerEffect<ROut, Self extends Definition.Any, Key extends keyof Self["methods"]> = WorkerRpcHandler<ROut, Method.Success<Self["methods"][Key]>>;
|
|
99
|
+
//#endregion
|
|
100
|
+
export { Api, Definition, HandlerEffect, Handlers, LayerOptions, Method, Methods, NoReservedMethods, Options, ReservedMethodName, ServerApi, ServiceFreeSchema, Tag, TagClass, Worker, WorkerDefinition_d_exports, implement, make, method };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { __exportAll } from "./_virtual/_rolldown/runtime.mjs";
|
|
2
|
+
import { assertNoReservedMethods, decodeArgs, encodeSuccess, make as make$1, method as method$1 } from "./RpcDefinition.mjs";
|
|
3
|
+
import { recordDecodedArgs } from "./internal/RpcInvocation.mjs";
|
|
4
|
+
import { layer, makeDirectMethods } from "./ServiceBinding.mjs";
|
|
5
|
+
import { make as make$2 } from "./Worker.mjs";
|
|
6
|
+
import * as Context from "effect/Context";
|
|
7
|
+
import * as Effect from "effect/Effect";
|
|
8
|
+
//#region src/WorkerDefinition.ts
|
|
9
|
+
var WorkerDefinition_exports = /* @__PURE__ */ __exportAll({
|
|
10
|
+
Tag: () => Tag,
|
|
11
|
+
Worker: () => Worker,
|
|
12
|
+
implement: () => implement,
|
|
13
|
+
make: () => make,
|
|
14
|
+
method: () => method
|
|
15
|
+
});
|
|
16
|
+
const reservedMethodNames = /* @__PURE__ */ new Set([
|
|
17
|
+
"constructor",
|
|
18
|
+
"dup",
|
|
19
|
+
"fetch",
|
|
20
|
+
"connect",
|
|
21
|
+
"queue",
|
|
22
|
+
"scheduled",
|
|
23
|
+
"tail",
|
|
24
|
+
"tailStream",
|
|
25
|
+
"test",
|
|
26
|
+
"trace",
|
|
27
|
+
"alarm",
|
|
28
|
+
"webSocketMessage",
|
|
29
|
+
"webSocketClose",
|
|
30
|
+
"webSocketError"
|
|
31
|
+
]);
|
|
32
|
+
const assumeTagClass = (value) => {
|
|
33
|
+
return value;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Defines a single RPC method schema in a worker definition.
|
|
37
|
+
*/
|
|
38
|
+
const method = method$1;
|
|
39
|
+
const makeDefinition = (id, methods) => {
|
|
40
|
+
assertNoReservedMethods("Worker", methods, reservedMethodNames);
|
|
41
|
+
const definition = make$1(id, methods);
|
|
42
|
+
return Object.assign(definition, { make: (layer, options) => {
|
|
43
|
+
const workerOptions = {
|
|
44
|
+
...options,
|
|
45
|
+
rpc: wrapHandlers(definition, options.rpc)
|
|
46
|
+
};
|
|
47
|
+
if (workerOptions.eventLayer === void 0) return make$2(layer, workerOptions);
|
|
48
|
+
return make$2(layer, workerOptions);
|
|
49
|
+
} });
|
|
50
|
+
};
|
|
51
|
+
const make = (id, methods) => Tag()(id, methods);
|
|
52
|
+
const Tag = () => (id, methods) => {
|
|
53
|
+
const definition = makeDefinition(id, methods);
|
|
54
|
+
const tag = Context.Service()(id);
|
|
55
|
+
const bindingDefinition = (binding) => ({
|
|
56
|
+
...binding,
|
|
57
|
+
definition
|
|
58
|
+
});
|
|
59
|
+
const layer$1 = (binding) => layer(tag, bindingDefinition(binding));
|
|
60
|
+
const fetch = (input, init) => Effect.gen(function* () {
|
|
61
|
+
return yield* (yield* tag).fetch(input, init);
|
|
62
|
+
});
|
|
63
|
+
const rpc = (method, ...args) => Effect.gen(function* () {
|
|
64
|
+
return yield* (yield* tag).rpc(method, ...args);
|
|
65
|
+
});
|
|
66
|
+
const call = (method, ...args) => Effect.gen(function* () {
|
|
67
|
+
return yield* (yield* tag).call(method, ...args);
|
|
68
|
+
});
|
|
69
|
+
const scopedCall = (method, ...args) => Effect.gen(function* () {
|
|
70
|
+
return yield* (yield* tag).scopedCall(method, ...args);
|
|
71
|
+
});
|
|
72
|
+
const directMethods = makeDirectMethods(definition, call);
|
|
73
|
+
return assumeTagClass(Object.assign(tag, directMethods, {
|
|
74
|
+
id: definition.id,
|
|
75
|
+
methods: definition.methods,
|
|
76
|
+
make: definition.make,
|
|
77
|
+
layer: layer$1,
|
|
78
|
+
fetch,
|
|
79
|
+
rpc,
|
|
80
|
+
call,
|
|
81
|
+
scopedCall
|
|
82
|
+
}));
|
|
83
|
+
};
|
|
84
|
+
const Worker = Tag;
|
|
85
|
+
const wrapHandlers = (definition, handlers) => {
|
|
86
|
+
const wrapped = Object.create(null);
|
|
87
|
+
for (const key of Object.keys(definition.methods)) {
|
|
88
|
+
const handler = handlers[key];
|
|
89
|
+
wrapped[key] = (...args) => Effect.gen(function* () {
|
|
90
|
+
const decodedArgs = yield* decodeArgs(definition, key, args);
|
|
91
|
+
yield* recordDecodedArgs(decodedArgs);
|
|
92
|
+
const value = yield* handler(...decodedArgs);
|
|
93
|
+
return yield* encodeSuccess(definition, key, value);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return wrapped;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Helper for implementing handlers with the exact method shape of a definition.
|
|
100
|
+
*/
|
|
101
|
+
const implement = (_definition, handlers) => handlers;
|
|
102
|
+
//#endregion
|
|
103
|
+
export { Tag, Worker, WorkerDefinition_exports, implement, make, method };
|