effect-cf 0.35.0 → 0.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/Mcp.mjs ADDED
@@ -0,0 +1,270 @@
1
+ import { r as runNativeCallback } from "./WorkerContext-Yobnfw-K.mjs";
2
+ import { n as NativeRequest } from "./Worker-XsGJsCJX.mjs";
3
+ import { Cause, Context, Effect, Exit, Option, Predicate, Schema, Sink, Stream } from "effect";
4
+ import { McpServer, createMcpHandler, hostHeaderValidationResponse, localhostAllowedHostnames, localhostAllowedOrigins, originValidationResponse } from "@modelcontextprotocol/server";
5
+ import { AiError, Tool } from "effect/unstable/ai";
6
+ //#region src/Mcp.ts
7
+ const DEFAULT_CORS_OPTIONS = {
8
+ origin: "*",
9
+ headers: "Content-Type, Accept, Authorization, mcp-session-id, MCP-Protocol-Version, Mcp-Method, Mcp-Name",
10
+ methods: "GET, POST, DELETE, OPTIONS",
11
+ exposeHeaders: "mcp-session-id",
12
+ maxAge: 86400
13
+ };
14
+ const corsHeaders = (options) => {
15
+ const merged = {
16
+ ...DEFAULT_CORS_OPTIONS,
17
+ ...options
18
+ };
19
+ return new Headers({
20
+ "Access-Control-Allow-Headers": merged.headers,
21
+ "Access-Control-Allow-Methods": merged.methods,
22
+ "Access-Control-Allow-Origin": merged.origin,
23
+ "Access-Control-Expose-Headers": merged.exposeHeaders,
24
+ "Access-Control-Max-Age": String(merged.maxAge)
25
+ });
26
+ };
27
+ const withCors = (response, options) => {
28
+ if (options === false) return response;
29
+ const headers = new Headers(response.headers);
30
+ for (const [headerName, value] of corsHeaders(options ?? {})) headers.set(headerName, value);
31
+ return new Response(response.body, {
32
+ status: response.status,
33
+ statusText: response.statusText,
34
+ headers
35
+ });
36
+ };
37
+ const corsOriginHostname = (corsOptions) => {
38
+ const origin = corsOptions === false ? void 0 : corsOptions?.origin;
39
+ if (origin === void 0 || !URL.canParse(origin)) return;
40
+ const url = new URL(origin);
41
+ return (url.protocol === "http:" || url.protocol === "https:") && url.hostname !== "" ? url.hostname : void 0;
42
+ };
43
+ /**
44
+ * `Host` and `Origin` validation for the MCP route, using the MCP SDK's
45
+ * validation primitives with the same defaults Cloudflare applies: localhost
46
+ * and `workers.dev` endpoints validate the `Host` header against themselves,
47
+ * and present browser `Origin` headers must match localhost-class Origins, the
48
+ * endpoint's `workers.dev` hostname, or a concrete configured CORS origin.
49
+ */
50
+ const edgeGuardResponse = (request, requestUrl, options) => {
51
+ const localEndpoint = localhostAllowedHostnames().includes(requestUrl.hostname);
52
+ const workersDevEndpoint = requestUrl.hostname.endsWith(".workers.dev");
53
+ const acceptedHostnames = options.allowedHostnames ?? (localEndpoint ? localhostAllowedHostnames() : workersDevEndpoint ? [requestUrl.hostname] : void 0);
54
+ if (acceptedHostnames !== void 0) {
55
+ const hostRejection = hostHeaderValidationResponse(request, [...acceptedHostnames]);
56
+ if (hostRejection !== void 0) return hostRejection;
57
+ }
58
+ if (options.allowedOriginHostnames === "*") return;
59
+ let acceptedOriginHostnames = options.allowedOriginHostnames;
60
+ if (acceptedOriginHostnames === void 0) {
61
+ const defaults = new Set(localhostAllowedOrigins());
62
+ if (workersDevEndpoint) defaults.add(requestUrl.hostname);
63
+ const configuredOriginHostname = corsOriginHostname(options.corsOptions);
64
+ if (configuredOriginHostname !== void 0) defaults.add(configuredOriginHostname);
65
+ acceptedOriginHostnames = [...defaults];
66
+ }
67
+ return originValidationResponse(request, [...acceptedOriginHostnames]);
68
+ };
69
+ const INTERNAL_TOOL_ERROR_MESSAGE = "Tool execution failed due to an internal server error.";
70
+ const toolErrorResult = (message) => ({
71
+ isError: true,
72
+ content: [{
73
+ type: "text",
74
+ text: message
75
+ }]
76
+ });
77
+ /**
78
+ * Wraps a JSON Schema produced by Effect `Schema` as the Standard Schema shape
79
+ * accepted by MCP SDK v2 `registerTool`, with a passthrough `validate`.
80
+ *
81
+ * Used for output schemas and for dynamic tools whose parameters are already a
82
+ * JSON Schema: the toolkit performs its own decoding, so there is nothing
83
+ * additional to validate here.
84
+ */
85
+ const standardSchemaFromJsonSchema = (jsonSchema) => ({ "~standard": {
86
+ version: 1,
87
+ vendor: "effect-cf",
88
+ validate: (value) => ({ value }),
89
+ jsonSchema: {
90
+ input: () => jsonSchema,
91
+ output: () => jsonSchema
92
+ }
93
+ } });
94
+ /**
95
+ * Builds the tool input schema registered with the MCP SDK.
96
+ *
97
+ * The SDK validates incoming `tools/call` arguments with `~standard.validate`
98
+ * and answers validation failures with an MCP invalid-params error, so the
99
+ * tool's Effect parameters `Schema` backs `validate`. On success the original
100
+ * encoded arguments are kept: the toolkit decodes them itself when the tool
101
+ * handler executes.
102
+ */
103
+ const standardInputSchema = (tool) => {
104
+ const jsonSchema = Tool.getJsonSchema(tool);
105
+ if (!Schema.isSchema(tool.parametersSchema)) return standardSchemaFromJsonSchema(jsonSchema);
106
+ const parametersSchema = tool.parametersSchema;
107
+ const validate = Schema.toStandardSchemaV1(parametersSchema)["~standard"].validate;
108
+ return { "~standard": {
109
+ version: 1,
110
+ vendor: "effect-cf",
111
+ validate: (value) => {
112
+ const result = validate(value);
113
+ if (result instanceof Promise) return result.then((awaited) => awaited.issues === void 0 ? { value } : awaited);
114
+ return result.issues === void 0 ? { value } : result;
115
+ },
116
+ jsonSchema: {
117
+ input: () => jsonSchema,
118
+ output: () => jsonSchema
119
+ }
120
+ } };
121
+ };
122
+ const handleToolCall = (built, tool, params) => {
123
+ const isDeclaredFailure = Schema.is(tool.failureSchema);
124
+ return built.handle(tool.name, params).pipe(Stream.unwrap, Stream.run(Sink.last()), Effect.flatMap(Effect.fromOption), Effect.map((result) => {
125
+ if (result.isFailure) return toolErrorResult(JSON.stringify(result.encodedResult));
126
+ const structuredContent = Predicate.isObject(result.encodedResult) ? result.encodedResult : void 0;
127
+ const content = result.encodedResult === void 0 ? [] : [{
128
+ type: "text",
129
+ text: JSON.stringify(result.encodedResult)
130
+ }];
131
+ if (structuredContent === void 0) return {
132
+ isError: false,
133
+ content
134
+ };
135
+ return {
136
+ isError: false,
137
+ structuredContent,
138
+ content
139
+ };
140
+ }), Effect.tapCause(Effect.logError), Effect.catch((error) => {
141
+ if (AiError.isAiError(error)) {
142
+ const reason = error.reason;
143
+ return Effect.succeed(toolErrorResult(reason._tag === "ToolParameterValidationError" ? reason.message : INTERNAL_TOOL_ERROR_MESSAGE));
144
+ }
145
+ if (isDeclaredFailure(error)) {
146
+ const message = error instanceof Error ? error.message : INTERNAL_TOOL_ERROR_MESSAGE;
147
+ return Effect.succeed(toolErrorResult(message));
148
+ }
149
+ return Effect.succeed(toolErrorResult(INTERNAL_TOOL_ERROR_MESSAGE));
150
+ }), Effect.catchDefect(() => Effect.succeed(toolErrorResult(INTERNAL_TOOL_ERROR_MESSAGE))));
151
+ };
152
+ const registerToolkitTool = (server, built, tool, run) => {
153
+ const outputJsonSchema = Tool.getJsonSchemaFromSchema(tool.successSchema);
154
+ const outputSchema = outputJsonSchema.type === "object" ? standardSchemaFromJsonSchema(outputJsonSchema) : void 0;
155
+ const title = Context.getOrUndefined(tool.annotations, Tool.Title);
156
+ const toolMeta = Context.getOrUndefined(tool.annotations, Tool.Meta);
157
+ server.registerTool(tool.name, {
158
+ title,
159
+ description: Tool.getDescription(tool),
160
+ inputSchema: standardInputSchema(tool),
161
+ outputSchema,
162
+ annotations: {
163
+ title,
164
+ readOnlyHint: Context.get(tool.annotations, Tool.Readonly),
165
+ destructiveHint: Context.get(tool.annotations, Tool.Destructive),
166
+ idempotentHint: Context.get(tool.annotations, Tool.Idempotent),
167
+ openWorldHint: Context.get(tool.annotations, Tool.OpenWorld)
168
+ },
169
+ _meta: toolMeta
170
+ }, async (args) => {
171
+ const exit = await run(handleToolCall(built, tool, args ?? {}));
172
+ if (Exit.isSuccess(exit)) return exit.value;
173
+ throw Cause.squash(exit.cause);
174
+ });
175
+ };
176
+ /**
177
+ * Creates an Effect that serves a toolkit over MCP with the MCP SDK's
178
+ * stateless Streamable HTTP handler (`createMcpHandler` from
179
+ * `@modelcontextprotocol/server`), plus the Worker edge concerns Cloudflare's
180
+ * remote MCP deployments expect: CORS, `Host` header validation, and browser
181
+ * `Origin` validation.
182
+ *
183
+ * **Details**
184
+ *
185
+ * Yield the returned Effect inside a `Worker.make` fetch handler before other
186
+ * routing. When the request pathname matches `route` (default `"/mcp"`), the
187
+ * request is served by a fresh MCP server exposing every tool in the toolkit
188
+ * and the Effect succeeds with `Option.some(response)`. Any other pathname
189
+ * succeeds with `Option.none()` so the request can fall through to the rest of
190
+ * the fetch handler.
191
+ *
192
+ * Tool calls run through the caller's Effect context: provide the toolkit
193
+ * handlers (`toolkit.toLayer(...)`) and their services in the Worker layer or
194
+ * event layer. Tool parameters are decoded and results encoded with each
195
+ * tool's Effect `Schema`; parameter validation failures become MCP
196
+ * invalid-params errors, declared tool failures become tool results with
197
+ * `isError: true`, and unexpected errors are logged and reported to the client
198
+ * as an internal tool error.
199
+ *
200
+ * In-flight tool calls are awaited before the HTTP response is returned, so
201
+ * tool handlers always run to completion inside the fetch event, including on
202
+ * transport lanes that stream results into the response body.
203
+ *
204
+ * **Example**
205
+ *
206
+ * ```ts
207
+ * import { Effect, Layer, Option } from "effect"
208
+ * import { HttpRouter } from "effect/unstable/http"
209
+ * import { Worker } from "effect-cf"
210
+ * import * as Mcp from "effect-cf/mcp"
211
+ *
212
+ * const mcp = Mcp.fromToolkit(ActivityToolkit, {
213
+ * name: "strava-ingestor",
214
+ * version: "1.0.0",
215
+ * route: "/mcp",
216
+ * })
217
+ *
218
+ * const fetch = Effect.gen(function* () {
219
+ * const response = yield* mcp
220
+ * if (Option.isSome(response)) return response.value
221
+ * const router = yield* HttpRouter.HttpRouter
222
+ * return yield* router.asHttpEffect()
223
+ * })
224
+ *
225
+ * export default Worker.make(
226
+ * Layer.mergeAll(ApplicationLive, ActivityToolkitLive),
227
+ * { fetch },
228
+ * )
229
+ * ```
230
+ */
231
+ const fromToolkit = (toolkit, options) => {
232
+ const { name, version, title, serverOptions, route = "/mcp", corsOptions, allowedHostnames, allowedOriginHostnames, ...handlerOptions } = options;
233
+ const serverInfo = {
234
+ name,
235
+ version,
236
+ title
237
+ };
238
+ return Effect.gen(function* () {
239
+ const request = yield* NativeRequest;
240
+ const requestUrl = new URL(request.url);
241
+ if (requestUrl.pathname !== route) return Option.none();
242
+ const rejection = edgeGuardResponse(request, requestUrl, {
243
+ corsOptions,
244
+ allowedHostnames,
245
+ allowedOriginHostnames
246
+ });
247
+ if (rejection !== void 0) return Option.some(withCors(rejection, corsOptions));
248
+ if (request.method === "OPTIONS" && corsOptions !== false) return Option.some(new Response(null, { headers: corsHeaders(corsOptions ?? {}) }));
249
+ const built = yield* toolkit;
250
+ const response = yield* runNativeCallback(async (run) => {
251
+ const pending = /* @__PURE__ */ new Set();
252
+ const trackedRun = (effect) => {
253
+ const promise = run(effect);
254
+ pending.add(promise);
255
+ promise.finally(() => pending.delete(promise));
256
+ return promise;
257
+ };
258
+ const response = await createMcpHandler(() => {
259
+ const server = new McpServer(serverInfo, serverOptions);
260
+ for (const tool of Object.values(built.tools)) registerToolkitTool(server, built, tool, trackedRun);
261
+ return server;
262
+ }, handlerOptions).fetch(request);
263
+ while (pending.size > 0) await Promise.allSettled([...pending]);
264
+ return response;
265
+ });
266
+ return Option.some(withCors(response, corsOptions));
267
+ });
268
+ };
269
+ //#endregion
270
+ export { fromToolkit };
package/dist/Vitest.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { c as WorkerEnvironment, s as WorkerEnv } from "./Binding-DKcLrQCM.mjs";
2
- import { n as DurableObjectStateService, t as DurableObjectState } from "./DurableObjectState-DpYdNZgT.mjs";
3
- import { o as WorkflowInstanceStatusName } from "./WorkflowBinding-Cn3AuUyP.mjs";
2
+ import { n as DurableObjectStateService, t as DurableObjectState } from "./DurableObjectState-CpgAmFqo.mjs";
3
+ import { o as WorkflowInstanceStatusName } from "./WorkflowBinding-CvJT9hB5.mjs";
4
4
  import { Effect, Layer, Schema } from "effect";
5
5
  import { DurableObject } from "cloudflare:workers";
6
6
  import { adminSecretsStore as adminSecretsStore$1, getQueueResult, introspectWorkflow as introspectWorkflow$1, introspectWorkflowInstance as introspectWorkflowInstance$1 } from "cloudflare:test";
package/dist/Vitest.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  import { a as WorkerEnvironment, i as WorkerConfig } from "./ErrorMessage-Byx2OgNd.mjs";
2
- import { l as runNativeCallback, r as fromDurableObjectState, t as DurableObjectState } from "./DurableObjectState-DcqElJ4e.mjs";
2
+ import { r as runNativeCallback } from "./WorkerContext-Yobnfw-K.mjs";
3
+ import { r as fromDurableObjectState, t as DurableObjectState } from "./DurableObjectState-DLL0YgBd.mjs";
3
4
  import { ConfigProvider, Effect, Exit, Layer } from "effect";
4
5
  import { env } from "cloudflare:workers";
5
6
  import { abortAllDurableObjects as abortAllDurableObjects$1, adminSecretsStore as adminSecretsStore$1, applyD1Migrations as applyD1Migrations$1, createExecutionContext, createMessageBatch, createPagesEventContext, createScheduledController, evictAllDurableObjects as evictAllDurableObjects$1, evictDurableObject as evictDurableObject$1, getQueueResult, introspectWorkflow as introspectWorkflow$1, introspectWorkflowInstance as introspectWorkflowInstance$1, listDurableObjectIds as listDurableObjectIds$1, reset as reset$1, runDurableObjectAlarm as runDurableObjectAlarm$1, runInDurableObject as runInDurableObject$1, waitOnExecutionContext } from "cloudflare:test";
@@ -1,189 +1,7 @@
1
1
  import { c as WorkerEnvironment, n as BindingService, r as BindingValidationError, s as WorkerEnv, t as BindingNotFoundError } from "./Binding-DKcLrQCM.mjs";
2
- import { Cause, Context, Duration, Effect, Layer, Option, Predicate, Schema, Scope, Tracer } from "effect";
2
+ import { Cause, Context, Effect, Layer, Predicate, Schema, Scope, Tracer } from "effect";
3
3
  import { HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
4
4
  import { RpcStub, RpcTarget, WorkerEntrypoint } from "cloudflare:workers";
5
- declare namespace DurableObjectStorage_d_exports {
6
- export { DurableObjectStorage, DurableObjectTransaction, SchemaBackedSyncKvStorage, SqlCursor, SqlStorage, SqlStorageValue, StorageOperationError, SyncKvDefinition, SyncKvStorage, fromDurableObjectStorage };
7
- }
8
- type SqlStorageValue = globalThis.SqlStorageValue;
9
- declare const StorageOperationError_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]; }>) => Cause.YieldableError & {
10
- readonly _tag: "StorageOperationError";
11
- } & Readonly<A>;
12
- declare class StorageOperationError extends StorageOperationError_base<{
13
- readonly operation: string;
14
- readonly cause: unknown;
15
- }> {
16
- get message(): string;
17
- }
18
- type StorageEffect<A> = Effect.Effect<A, StorageOperationError>;
19
- interface SqlCursor<T extends Record<string, SqlStorageValue>> {
20
- next(): StorageEffect<{
21
- done?: false;
22
- value: T;
23
- } | {
24
- done: true;
25
- value?: never;
26
- }>;
27
- toArray(): StorageEffect<Array<T>>;
28
- one(): StorageEffect<T>;
29
- raw<U extends Array<SqlStorageValue>>(): StorageEffect<IterableIterator<U>>;
30
- readonly columnNames: Array<string>;
31
- readonly rowsRead: StorageEffect<number>;
32
- readonly rowsWritten: StorageEffect<number>;
33
- }
34
- interface SqlStorage {
35
- exec<T extends Record<string, SqlStorageValue>>(query: string, ...bindings: Array<SqlStorageValue>): StorageEffect<SqlCursor<T>>;
36
- readonly databaseSize: number;
37
- }
38
- interface SyncKvDefinition<Key, Value, EncodedValue> {
39
- readonly key: Schema.Codec<Key, string>;
40
- readonly value: Schema.Codec<Value, EncodedValue>;
41
- }
42
- /**
43
- * Sync KV wrapper that transparently encodes keys/values through Effect Schema.
44
- */
45
- interface SchemaBackedSyncKvStorage<Key, Value> {
46
- get(key: Key): Effect.Effect<Option.Option<Value>, unknown>;
47
- put(key: Key, value: Value): Effect.Effect<void, unknown>;
48
- delete(key: Key): Effect.Effect<boolean, unknown>;
49
- list(options?: globalThis.SyncKvListOptions): Effect.Effect<Array<[Key, Value]>, unknown>;
50
- }
51
- interface SyncKvStorage {
52
- get<T = unknown>(key: string): StorageEffect<T | undefined>;
53
- put<T>(key: string, value: T): StorageEffect<void>;
54
- delete(key: string): StorageEffect<boolean>;
55
- list<T = unknown>(options?: globalThis.SyncKvListOptions): StorageEffect<Array<[string, T]>>;
56
- schema<Key, Value, EncodedValue>(definition: SyncKvDefinition<Key, Value, EncodedValue>): SchemaBackedSyncKvStorage<Key, Value>;
57
- }
58
- /**
59
- * Effect wrapper around Cloudflare transaction callbacks.
60
- */
61
- interface DurableObjectTransaction {
62
- get<T = unknown>(key: string, options?: globalThis.DurableObjectGetOptions): StorageEffect<T | undefined>;
63
- get<T = unknown>(keys: Array<string>, options?: globalThis.DurableObjectGetOptions): StorageEffect<Map<string, T>>;
64
- list<T = unknown>(options?: globalThis.DurableObjectListOptions): StorageEffect<Map<string, T>>;
65
- put<T>(key: string, value: T, options?: globalThis.DurableObjectPutOptions): StorageEffect<void>;
66
- put<T>(entries: Record<string, T>, options?: globalThis.DurableObjectPutOptions): StorageEffect<void>;
67
- delete(key: string, options?: globalThis.DurableObjectPutOptions): StorageEffect<boolean>;
68
- delete(keys: Array<string>, options?: globalThis.DurableObjectPutOptions): StorageEffect<number>;
69
- rollback(): StorageEffect<void>;
70
- getAlarm(options?: globalThis.DurableObjectGetAlarmOptions): StorageEffect<number | null>;
71
- setAlarm(scheduledTime: number | Date, options?: globalThis.DurableObjectSetAlarmOptions): StorageEffect<void>;
72
- setAlarmAfter(delay: Duration.Input, options?: globalThis.DurableObjectSetAlarmOptions): StorageEffect<void>;
73
- deleteAlarm(options?: globalThis.DurableObjectSetAlarmOptions): StorageEffect<void>;
74
- }
75
- interface DurableObjectStorage {
76
- get<T = unknown>(key: string, options?: globalThis.DurableObjectGetOptions): StorageEffect<T | undefined>;
77
- put<T>(key: string, value: T, options?: globalThis.DurableObjectPutOptions): StorageEffect<void>;
78
- delete(key: string, options?: globalThis.DurableObjectPutOptions): StorageEffect<boolean>;
79
- /**
80
- * Deletes all stored data. On compatibility dates before 2026-02-24, Cloudflare
81
- * documents that active alarms must be deleted separately with `deleteAlarm()`.
82
- */
83
- deleteAll(options?: globalThis.DurableObjectPutOptions): StorageEffect<void>;
84
- getAlarm(options?: globalThis.DurableObjectGetAlarmOptions): StorageEffect<number | null>;
85
- setAlarm(scheduledTime: number | Date, options?: globalThis.DurableObjectSetAlarmOptions): StorageEffect<void>;
86
- setAlarmAfter(delay: Duration.Input, options?: globalThis.DurableObjectSetAlarmOptions): StorageEffect<void>;
87
- deleteAlarm(options?: globalThis.DurableObjectSetAlarmOptions): StorageEffect<void>;
88
- /**
89
- * SQLite-backed Durable Object storage only.
90
- *
91
- * The callback Effect must complete synchronously. If it requires asynchronous
92
- * work, use `transaction` instead so Cloudflare can run the async transaction
93
- * callback under the platform's transaction contract.
94
- */
95
- transactionSync<A, E, R>(closure: () => Effect.Effect<A, E, R>): Effect.Effect<A, E | StorageOperationError, R>;
96
- /**
97
- * Runs an async transaction and exposes a typed transaction wrapper.
98
- */
99
- transaction<A, E, R>(closure: (txn: DurableObjectTransaction) => Effect.Effect<A, E, R>): Effect.Effect<A, E | StorageOperationError, R>;
100
- /** Flushes pending writes to disk. */
101
- sync(): StorageEffect<void>;
102
- /** Requires SQLite-backed Durable Object storage. */
103
- getCurrentBookmark(): StorageEffect<string>;
104
- /** Requires SQLite-backed Durable Object storage. */
105
- onNextSessionRestoreBookmark(bookmark: string): StorageEffect<string>;
106
- readonly sql: SqlStorage;
107
- readonly kv: SyncKvStorage;
108
- }
109
- declare const fromDurableObjectStorage: (storage: globalThis.DurableObjectStorage) => DurableObjectStorage;
110
- declare namespace DurableObjectWebSocket_d_exports {
111
- export { AcceptUpgradeOptions, AcceptedUpgrade, AttachmentInvalidPolicy, AttachmentRehydrateOptions, DurableWebSocket, DurableWebSocketAttachment, DurableWebSocketAttachmentError, DurableWebSocketCloseError, DurableWebSocketHandlers, DurableWebSocketSendData, DurableWebSocketSendError, RehydratedDurableWebSocket, acceptUpgrade, attachment, fromWebSocket, handlers };
112
- }
113
- type DurableWebSocketSendData = string | ArrayBuffer | ArrayBufferView;
114
- declare const DurableWebSocketSendError_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 & {
115
- readonly _tag: "DurableWebSocketSendError";
116
- } & Readonly<A>;
117
- declare class DurableWebSocketSendError extends DurableWebSocketSendError_base<{
118
- readonly cause: unknown;
119
- }> {
120
- get message(): string;
121
- }
122
- declare const DurableWebSocketCloseError_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 & {
123
- readonly _tag: "DurableWebSocketCloseError";
124
- } & Readonly<A>;
125
- declare class DurableWebSocketCloseError extends DurableWebSocketCloseError_base<{
126
- readonly cause: unknown;
127
- }> {
128
- get message(): string;
129
- }
130
- declare const DurableWebSocketAttachmentError_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 & {
131
- readonly _tag: "DurableWebSocketAttachmentError";
132
- } & Readonly<A>;
133
- /** Error raised when serializing or deserializing a websocket attachment fails. */
134
- declare class DurableWebSocketAttachmentError extends DurableWebSocketAttachmentError_base<{
135
- readonly operation: "serialize" | "deserialize";
136
- readonly cause: unknown;
137
- }> {
138
- get message(): string;
139
- }
140
- interface DurableWebSocket<Attachment = unknown> {
141
- readonly raw: WebSocket;
142
- send(data: DurableWebSocketSendData): Effect.Effect<void, DurableWebSocketSendError>;
143
- close(code?: number, reason?: string): Effect.Effect<void, DurableWebSocketCloseError>;
144
- /** Serializes hibernation attachment metadata onto the socket. */
145
- serializeAttachment<A extends Attachment = Attachment>(value: A): Effect.Effect<void, DurableWebSocketAttachmentError>;
146
- /** Deserializes hibernation attachment metadata from the socket. */
147
- readonly deserializeAttachment: Effect.Effect<unknown, DurableWebSocketAttachmentError>;
148
- }
149
- declare const fromWebSocket: <Attachment = unknown>(raw: WebSocket) => DurableWebSocket<Attachment>;
150
- interface AcceptUpgradeOptions<Attachment = unknown> {
151
- readonly tags?: ReadonlyArray<string> | undefined;
152
- /** Optional attachment serialized onto the server socket. */
153
- readonly attachment?: Attachment | undefined;
154
- }
155
- interface AcceptedUpgrade<Attachment = unknown> {
156
- readonly client: WebSocket;
157
- readonly server: DurableWebSocket<Attachment>;
158
- readonly response: Response;
159
- }
160
- declare const acceptUpgrade: <Attachment = unknown>(options?: AcceptUpgradeOptions<Attachment> | undefined) => Effect.Effect<AcceptedUpgrade<Attachment>, DurableWebSocketAttachmentError, DurableObjectState>;
161
- type AttachmentInvalidPolicy = "ignore" | "ignore-and-close" | "fail";
162
- interface AttachmentRehydrateOptions {
163
- readonly tag?: string | undefined;
164
- readonly onInvalid?: AttachmentInvalidPolicy | undefined;
165
- }
166
- interface RehydratedDurableWebSocket<Attachment> {
167
- readonly socket: DurableWebSocket<Attachment>;
168
- readonly attachment: Attachment;
169
- }
170
- interface DurableWebSocketAttachment<Attachment, Encoded> {
171
- serialize(socket: DurableWebSocket<unknown>, value: Attachment): Effect.Effect<void, DurableWebSocketAttachmentError>;
172
- deserialize(socket: DurableWebSocket<unknown>): Effect.Effect<Option.Option<Attachment>, DurableWebSocketAttachmentError>;
173
- rehydrate(options?: AttachmentRehydrateOptions): Effect.Effect<Array<RehydratedDurableWebSocket<Attachment>>, DurableWebSocketAttachmentError, DurableObjectState>;
174
- readonly schema: Schema.Codec<Attachment, Encoded, never, never>;
175
- }
176
- declare const attachment: <const AttachmentSchema extends Schema.Codec<any, any, never, never>>(schema: AttachmentSchema) => DurableWebSocketAttachment<Schema.Schema.Type<AttachmentSchema>, Schema.Codec.Encoded<AttachmentSchema>>;
177
- interface DurableWebSocketHandlers<R = never, E = unknown> {
178
- readonly message?: (socket: DurableWebSocket, message: string | ArrayBuffer) => Effect.Effect<void, E, R>;
179
- readonly close?: (socket: DurableWebSocket, code: number, reason: string, wasClean: boolean) => Effect.Effect<void, E, R>;
180
- readonly error?: (socket: DurableWebSocket, cause: unknown) => Effect.Effect<void, E, R>;
181
- }
182
- declare const handlers: <R = never, E = unknown>(options: DurableWebSocketHandlers<R, E>) => {
183
- webSocketMessage: ((socket: DurableWebSocket, message: string | ArrayBuffer) => Effect.Effect<void, E, R>) | undefined;
184
- webSocketClose: ((socket: DurableWebSocket, code: number, reason: string, wasClean: boolean) => Effect.Effect<void, E, R>) | undefined;
185
- webSocketError: ((socket: DurableWebSocket, cause: unknown) => Effect.Effect<void, E, R>) | undefined;
186
- };
187
5
  declare namespace Rpc_d_exports {
188
6
  export { DisposableValue, MethodArgs, MethodKey, MethodReturn, Provider, Result$1 as Result, RpcStub, RpcTarget, Serializable, Stub, Stubable, Stubify, dispose, isDisposable, resolve, scoped };
189
7
  }
@@ -819,63 +637,5 @@ declare function make<ROut, LayerError, REvent extends never = never, EventLayer
819
637
  */
820
638
  declare function makeFetchHandler<ROut, LayerError, REvent, EventLayerError = never, Env extends WorkerEnv = WorkerEnv>(layer: Layer.Layer<ROut, LayerError, ExecutionContext | WorkerContext | WorkerEnvironment>, options: FetchWorkerOptionsWithEventLayer<ROut, REvent, EventLayerError>): FetchHandler<Env>;
821
639
  declare function makeFetchHandler<ROut, LayerError, REvent extends never = never, EventLayerError = never, Env extends WorkerEnv = WorkerEnv>(layer: Layer.Layer<ROut, LayerError, ExecutionContext | WorkerContext | WorkerEnvironment>, options: FetchWorkerOptions<ROut, REvent, EventLayerError>): FetchHandler<Env>;
822
- declare namespace DurableObjectState_d_exports {
823
- export { DurableObjectState, DurableObjectStateService, fromDurableObjectState };
824
- }
825
- /**
826
- * Effect-friendly wrapper around Cloudflare `DurableObjectState`.
827
- */
828
- interface DurableObjectStateService {
829
- readonly raw: globalThis.DurableObjectState;
830
- readonly id: globalThis.DurableObjectId;
831
- readonly storage: DurableObjectStorage;
832
- waitUntil(promise: Promise<unknown>): Effect.Effect<void>;
833
- /**
834
- * Runs a background Effect via Cloudflare's `waitUntil` with the caller's
835
- * Effect context, mirroring `WorkerContext.waitUntil` failure modes:
836
- * `"observe"` (default) logs or routes failures to `onFailure`, while
837
- * `"propagate"` also rejects the native `waitUntil` promise.
838
- */
839
- waitUntil<A, E, R, R2 = never>(effect: Effect.Effect<A, E, R>, options?: WorkerContextWaitUntilOptions<E, R2>): Effect.Effect<void, never, R | R2>;
840
- /**
841
- * Runs an Effect inside Cloudflare's `blockConcurrencyWhile` gate.
842
- *
843
- * Cloudflare resets a Durable Object if the callback throws/rejects, or if the
844
- * callback exceeds the platform timeout (currently documented as 30 seconds).
845
- * This safe default resolves the callback with the Effect `Exit` for typed
846
- * Effect failures and resumes that `Exit` afterward, so typed failures remain
847
- * ordinary Effect failures instead of resetting the Durable Object. Defects
848
- * and interruptions still reject the callback.
849
- */
850
- blockConcurrencyWhile<A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R>;
851
- /**
852
- * Runs an Effect inside Cloudflare's `blockConcurrencyWhile` gate and lets
853
- * Effect failures reject the callback.
854
- *
855
- * Use this only when Cloudflare's reset-on-throw behavior is intentional. The
856
- * platform also resets the Durable Object if the callback exceeds the
857
- * documented timeout (currently 30 seconds).
858
- */
859
- blockConcurrencyWhileOrReset<A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R>;
860
- acceptWebSocket(ws: DurableWebSocket, tags?: Array<string>): Effect.Effect<void>;
861
- getWebSockets(tag?: string): Effect.Effect<Array<DurableWebSocket>>;
862
- setWebSocketAutoResponse(pair?: WebSocketRequestResponsePair): Effect.Effect<void>;
863
- getWebSocketAutoResponse: Effect.Effect<WebSocketRequestResponsePair | null>;
864
- getWebSocketAutoResponseTimestamp(ws: DurableWebSocket): Effect.Effect<Date | null>;
865
- setHibernatableWebSocketEventTimeout(timeoutMs?: number): Effect.Effect<void>;
866
- getHibernatableWebSocketEventTimeout: Effect.Effect<number | null>;
867
- getTags(ws: DurableWebSocket): Effect.Effect<Array<string>>;
868
- /**
869
- * Forcibly resets the Durable Object. Cloudflare logs an uncaught Error using
870
- * the optional reason, and the method is not available in `wrangler dev` local
871
- * development according to the Durable Object State docs. Set
872
- * `retryAlarm: false` to prevent the current alarm invocation from retrying;
873
- * this option has no effect outside an alarm handler.
874
- */
875
- abort(reason?: string, options?: globalThis.DurableObjectAbortOptions): Effect.Effect<void>;
876
- }
877
- declare const DurableObjectState_base: Context.ServiceClass<DurableObjectState, "effect-cf/DurableObjectState", DurableObjectStateService>;
878
- declare class DurableObjectState extends DurableObjectState_base {}
879
- declare const fromDurableObjectState: (state: globalThis.DurableObjectState) => DurableObjectStateService;
880
640
  //#endregion
881
- export { DurableWebSocket as A, RpcDefinition_d_exports as C, AcceptUpgradeOptions as D, Rpc_d_exports as E, DurableObjectStorage_d_exports as M, StorageOperationError as N, AcceptedUpgrade as O, ReservedMethodName$3 as S, Provider as T, Queue_d_exports as _, NativeRequest as a, Definition$3 as b, WorkerDefinition_d_exports as c, AsyncMethodCloudflareReturn as d, AsyncMethodKey as f, RpcTracing_d_exports as g, RpcInvocationInfo as h, ExecutionContext as i, DurableWebSocketAttachmentError as j, DurableObjectWebSocket_d_exports as k, ServiceBinding_d_exports as l, ReceiverOptions as m, DurableObjectStateService as n, WorkerContext as o, AsyncMethodSuccess as p, DurableObjectState_d_exports as r, Worker_d_exports as s, DurableObjectState as t, AsyncMethodArgs as u, QueueDefinition_d_exports as v, ServiceFreeSchema$1 as w, Method$2 as x, QueueBinding_d_exports as y };
641
+ export { Provider as C, ServiceFreeSchema$1 as S, QueueBinding_d_exports as _, Worker_d_exports as a, ReservedMethodName$3 as b, AsyncMethodArgs as c, AsyncMethodSuccess as d, ReceiverOptions as f, QueueDefinition_d_exports as g, Queue_d_exports as h, WorkerContextWaitUntilOptions as i, AsyncMethodCloudflareReturn as l, RpcTracing_d_exports as m, NativeRequest as n, WorkerDefinition_d_exports as o, RpcInvocationInfo as p, WorkerContext as r, ServiceBinding_d_exports as s, ExecutionContext as t, AsyncMethodKey as u, Definition$3 as v, Rpc_d_exports as w, RpcDefinition_d_exports as x, Method$2 as y };