effect-cf 0.11.0 → 0.13.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/index.mjs CHANGED
@@ -1,13 +1,576 @@
1
1
  import { t as __exportAll } from "./chunk-CfYAbeIz.mjs";
2
- import { a as WorkerConfig, i as layer$9, n as Binding_exports, o as WorkerEnvironment, r as Service$2, t as Hyperdrive_exports } from "./Hyperdrive-89hg_Fck.mjs";
3
- import { Cause, Clock, ConfigProvider, Context, Data, DateTime, Duration, Effect, Exit, Layer, ManagedRuntime, Option, Queue, Schema } from "effect";
2
+ import { a as WorkerConfig, i as layer$10, n as Binding_exports, o as WorkerEnvironment, r as Service$2, t as Hyperdrive_exports } from "./Hyperdrive-89hg_Fck.mjs";
3
+ import { Cause, Clock, Config, ConfigProvider, Context, Data, DateTime, Duration, Effect, Exit, Layer, ManagedRuntime, Option, Queue, Schema } from "effect";
4
+ import { FetchHttpClient, HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
5
+ import { Otlp, OtlpLogger, OtlpMetrics, OtlpSerialization, OtlpTracer } from "effect/unstable/observability";
4
6
  import { D1Client } from "@effect/sql-d1";
5
7
  import { DurableObject, RpcStub, RpcTarget, WorkerEntrypoint, WorkflowEntrypoint } from "cloudflare:workers";
6
- import { HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
7
8
  import * as RpcMessage from "effect/unstable/rpc/RpcMessage";
8
9
  import * as RpcSerialization from "effect/unstable/rpc/RpcSerialization";
9
10
  import * as RpcServer from "effect/unstable/rpc/RpcServer";
10
11
  import { SqliteClient } from "@effect/sql-sqlite-do";
12
+ //#region src/DurableObjectStorage.ts
13
+ var DurableObjectStorage_exports = /* @__PURE__ */ __exportAll({
14
+ StorageOperationError: () => StorageOperationError,
15
+ fromDurableObjectStorage: () => fromDurableObjectStorage
16
+ });
17
+ /** Error type used when a storage operation throws or rejects. */
18
+ var StorageOperationError = class extends Data.TaggedError("StorageOperationError") {};
19
+ const storageError = (operation, cause) => new StorageOperationError({
20
+ operation,
21
+ cause
22
+ });
23
+ const tryStorageSync = (operation, evaluate) => Effect.try({
24
+ try: evaluate,
25
+ catch: (cause) => storageError(operation, cause)
26
+ });
27
+ const tryStoragePromise = (operation, evaluate) => Effect.tryPromise({
28
+ try: evaluate,
29
+ catch: (cause) => storageError(operation, cause)
30
+ });
31
+ const fromSqlCursor = (cursor) => ({
32
+ next: () => tryStorageSync("sql.next", () => cursor.next()),
33
+ toArray: () => tryStorageSync("sql.toArray", () => cursor.toArray()),
34
+ one: () => tryStorageSync("sql.one", () => cursor.one()),
35
+ raw: () => tryStorageSync("sql.raw", () => cursor.raw()),
36
+ get columnNames() {
37
+ return cursor.columnNames;
38
+ },
39
+ rowsRead: tryStorageSync("sql.rowsRead", () => cursor.rowsRead),
40
+ rowsWritten: tryStorageSync("sql.rowsWritten", () => cursor.rowsWritten)
41
+ });
42
+ const fromSqlStorage = (sql) => ({
43
+ exec: (query, ...bindings) => tryStorageSync("sql.exec", () => fromSqlCursor(sql.exec(query, ...bindings))),
44
+ get databaseSize() {
45
+ return sql.databaseSize;
46
+ }
47
+ });
48
+ const schemaBackedSyncKvStorage = (kv, definition) => {
49
+ const encodeKey = Schema.encodeEffect(definition.key);
50
+ const decodeKey = Schema.decodeUnknownEffect(definition.key);
51
+ const encodeValue = Schema.encodeEffect(definition.value);
52
+ const decodeValue = Schema.decodeUnknownEffect(definition.value);
53
+ return {
54
+ get: (key) => Effect.gen(function* () {
55
+ const encodedKey = yield* encodeKey(key);
56
+ const encodedValue = yield* tryStorageSync("kv.get", () => kv.get(encodedKey));
57
+ if (encodedValue === void 0) return Option.none();
58
+ return yield* decodeValue(encodedValue).pipe(Effect.map(Option.some));
59
+ }),
60
+ put: (key, value) => Effect.gen(function* () {
61
+ const encodedKey = yield* encodeKey(key);
62
+ const encodedValue = yield* encodeValue(value);
63
+ yield* tryStorageSync("kv.put", () => kv.put(encodedKey, encodedValue));
64
+ }),
65
+ delete: (key) => Effect.gen(function* () {
66
+ const encodedKey = yield* encodeKey(key);
67
+ return yield* tryStorageSync("kv.delete", () => kv.delete(encodedKey));
68
+ }),
69
+ list: (options) => Effect.gen(function* () {
70
+ const entries = Array.from(yield* tryStorageSync("kv.list", () => kv.list(options)));
71
+ const decoded = [];
72
+ for (const [key, value] of entries) decoded.push([yield* decodeKey(key), yield* decodeValue(value)]);
73
+ return decoded;
74
+ })
75
+ };
76
+ };
77
+ const fromSyncKvStorage = (kv) => ({
78
+ get: (key) => tryStorageSync("kv.get", () => kv.get(key)),
79
+ put: (key, value) => tryStorageSync("kv.put", () => kv.put(key, value)),
80
+ delete: (key) => tryStorageSync("kv.delete", () => kv.delete(key)),
81
+ list: (options) => tryStorageSync("kv.list", () => Array.from(kv.list(options))),
82
+ schema: (definition) => schemaBackedSyncKvStorage(kv, definition)
83
+ });
84
+ const fromDurableObjectTransaction = (txn) => ({
85
+ get: (keyOrKeys, options) => Array.isArray(keyOrKeys) ? tryStoragePromise("transaction.get", () => txn.get(keyOrKeys, options)) : tryStoragePromise("transaction.get", () => txn.get(keyOrKeys, options)),
86
+ list: (options) => tryStoragePromise("transaction.list", () => txn.list(options)),
87
+ put: (keyOrEntries, valueOrOptions, maybeOptions) => tryStoragePromise("transaction.put", () => typeof keyOrEntries === "string" ? txn.put(keyOrEntries, valueOrOptions, maybeOptions) : txn.put(keyOrEntries, valueOrOptions)),
88
+ delete: (keyOrKeys, options) => Array.isArray(keyOrKeys) ? tryStoragePromise("transaction.delete", () => txn.delete(keyOrKeys, options)) : tryStoragePromise("transaction.delete", () => txn.delete(keyOrKeys, options)),
89
+ rollback: () => tryStorageSync("transaction.rollback", () => txn.rollback()),
90
+ getAlarm: (options) => tryStoragePromise("transaction.getAlarm", () => txn.getAlarm(options)),
91
+ setAlarm: (scheduledTime, options) => tryStoragePromise("transaction.setAlarm", () => txn.setAlarm(scheduledTime, options)),
92
+ deleteAlarm: (options) => tryStoragePromise("transaction.deleteAlarm", () => txn.deleteAlarm(options))
93
+ });
94
+ /**
95
+ * Wraps native Cloudflare storage APIs as Effect-returning helpers.
96
+ */
97
+ const fromDurableObjectStorage = (storage) => ({
98
+ get: (key, options) => tryStoragePromise("get", () => storage.get(key, options)),
99
+ put: (key, value, options) => tryStoragePromise("put", () => storage.put(key, value, options)),
100
+ delete: (key, options) => tryStoragePromise("delete", () => storage.delete(key, options)),
101
+ deleteAll: (options) => tryStoragePromise("deleteAll", () => storage.deleteAll(options)),
102
+ getAlarm: (options) => tryStoragePromise("getAlarm", () => storage.getAlarm(options)),
103
+ setAlarm: (scheduledTime, options) => tryStoragePromise("setAlarm", () => storage.setAlarm(scheduledTime, options)),
104
+ deleteAlarm: (options) => tryStoragePromise("deleteAlarm", () => storage.deleteAlarm(options)),
105
+ transactionSync: (closure) => Effect.context().pipe(Effect.flatMap((context) => Effect.suspend(() => {
106
+ try {
107
+ return Effect.succeed(storage.transactionSync(() => {
108
+ const exit = Effect.runSyncExitWith(context)(closure());
109
+ if (Exit.isSuccess(exit)) return exit.value;
110
+ throw exit;
111
+ }));
112
+ } catch (cause) {
113
+ if (Exit.isExit(cause) && Exit.isFailure(cause)) return Effect.failCause(cause.cause);
114
+ return Effect.fail(storageError("transactionSync", cause));
115
+ }
116
+ }))),
117
+ transaction: (closure) => Effect.context().pipe(Effect.flatMap((context) => Effect.callback((resume) => {
118
+ storage.transaction(async (txn) => {
119
+ const exit = await Effect.runPromiseExitWith(context)(closure(fromDurableObjectTransaction(txn)));
120
+ if (Exit.isSuccess(exit)) return exit.value;
121
+ throw exit;
122
+ }).then((value) => resume(Effect.succeed(value)), (cause) => {
123
+ if (Exit.isExit(cause) && Exit.isFailure(cause)) resume(Effect.failCause(cause.cause));
124
+ else resume(Effect.fail(storageError("transaction", cause)));
125
+ });
126
+ }))),
127
+ sync: () => tryStoragePromise("sync", () => storage.sync()),
128
+ getCurrentBookmark: () => tryStoragePromise("getCurrentBookmark", () => storage.getCurrentBookmark()),
129
+ onNextSessionRestoreBookmark: (bookmark) => tryStoragePromise("onNextSessionRestoreBookmark", () => storage.onNextSessionRestoreBookmark(bookmark)),
130
+ sql: fromSqlStorage(storage.sql),
131
+ kv: fromSyncKvStorage(storage.kv)
132
+ });
133
+ //#endregion
134
+ //#region src/DurableObjectWebSocket.ts
135
+ var DurableObjectWebSocket_exports = /* @__PURE__ */ __exportAll({
136
+ DurableWebSocketAttachmentError: () => DurableWebSocketAttachmentError,
137
+ DurableWebSocketCloseError: () => DurableWebSocketCloseError,
138
+ DurableWebSocketSendError: () => DurableWebSocketSendError,
139
+ acceptUpgrade: () => acceptUpgrade,
140
+ attachment: () => attachment,
141
+ fromWebSocket: () => fromWebSocket,
142
+ handlers: () => handlers
143
+ });
144
+ /** Error raised when sending on a Durable Object websocket fails. */
145
+ var DurableWebSocketSendError = class extends Data.TaggedError("DurableWebSocketSendError") {};
146
+ /** Error raised when closing a Durable Object websocket fails. */
147
+ var DurableWebSocketCloseError = class extends Data.TaggedError("DurableWebSocketCloseError") {};
148
+ /** Error raised when serializing or deserializing a websocket attachment fails. */
149
+ var DurableWebSocketAttachmentError = class extends Data.TaggedError("DurableWebSocketAttachmentError") {};
150
+ const wrappers = /* @__PURE__ */ new WeakMap();
151
+ /** Wraps a native Cloudflare websocket in the Effect-native Durable Object API. */
152
+ const fromWebSocket = (raw) => {
153
+ const existing = wrappers.get(raw);
154
+ if (existing !== void 0) return existing;
155
+ const socket = {
156
+ raw,
157
+ send: (data) => Effect.try({
158
+ try: () => raw.send(data),
159
+ catch: (cause) => new DurableWebSocketSendError({ cause })
160
+ }),
161
+ close: (code, reason) => Effect.try({
162
+ try: () => raw.close(code, reason),
163
+ catch: (cause) => new DurableWebSocketCloseError({ cause })
164
+ }),
165
+ serializeAttachment: (value) => Effect.try({
166
+ try: () => raw.serializeAttachment(value),
167
+ catch: (cause) => new DurableWebSocketAttachmentError({
168
+ operation: "serialize",
169
+ cause
170
+ })
171
+ }),
172
+ deserializeAttachment: Effect.try({
173
+ try: () => raw.deserializeAttachment(),
174
+ catch: (cause) => new DurableWebSocketAttachmentError({
175
+ operation: "deserialize",
176
+ cause
177
+ })
178
+ })
179
+ };
180
+ wrappers.set(raw, socket);
181
+ return socket;
182
+ };
183
+ /**
184
+ * Accepts a websocket upgrade and registers the server socket on `DurableObjectState`.
185
+ *
186
+ * @example
187
+ * ```ts
188
+ * const response = yield* DurableObjectWebSocket.acceptUpgrade({
189
+ * tags: ["room:general"],
190
+ * });
191
+ *
192
+ * return response.response;
193
+ * ```
194
+ */
195
+ const acceptUpgrade = (options = {}) => Effect.gen(function* () {
196
+ const state = yield* DurableObjectState;
197
+ const pair = new WebSocketPair();
198
+ const client = pair[0];
199
+ const server = fromWebSocket(pair[1]);
200
+ if (options.attachment !== void 0) server.raw.serializeAttachment(options.attachment);
201
+ yield* state.acceptWebSocket(server, options.tags === void 0 ? void 0 : [...options.tags]);
202
+ return {
203
+ client,
204
+ server,
205
+ response: new Response(null, {
206
+ status: 101,
207
+ webSocket: client
208
+ })
209
+ };
210
+ });
211
+ /** Creates typed attachment helpers for accepted and rehydrated sockets. */
212
+ const attachment = (schema) => {
213
+ const serialize = (socket, value) => Schema.encodeEffect(schema)(value).pipe(Effect.mapError((cause) => new DurableWebSocketAttachmentError({
214
+ operation: "serialize",
215
+ cause
216
+ })), Effect.flatMap((encoded) => socket.serializeAttachment(encoded)));
217
+ const deserialize = (socket) => Effect.gen(function* () {
218
+ const value = yield* socket.deserializeAttachment;
219
+ if (value == null) return Option.none();
220
+ return Option.some(yield* Schema.decodeUnknownEffect(schema)(value).pipe(Effect.mapError((cause) => new DurableWebSocketAttachmentError({
221
+ operation: "deserialize",
222
+ cause
223
+ }))));
224
+ });
225
+ const rehydrate = (options = {}) => Effect.gen(function* () {
226
+ const sockets = yield* (yield* DurableObjectState).getWebSockets(options.tag);
227
+ const restored = [];
228
+ const onInvalid = options.onInvalid ?? "ignore";
229
+ for (const socket of sockets) {
230
+ const decoded = yield* deserialize(socket).pipe(Effect.match({
231
+ onFailure: (error) => ({
232
+ _tag: "Failure",
233
+ error
234
+ }),
235
+ onSuccess: (value) => ({
236
+ _tag: "Success",
237
+ value
238
+ })
239
+ }));
240
+ if (decoded._tag === "Success" && Option.isSome(decoded.value)) {
241
+ restored.push({
242
+ socket,
243
+ attachment: decoded.value.value
244
+ });
245
+ continue;
246
+ }
247
+ if (decoded._tag === "Failure" && onInvalid === "fail") return yield* Effect.fail(decoded.error);
248
+ if (decoded._tag === "Failure" && onInvalid === "ignore-and-close") yield* socket.close(1008, "invalid websocket attachment").pipe(Effect.ignore);
249
+ }
250
+ return restored;
251
+ });
252
+ return {
253
+ serialize,
254
+ deserialize,
255
+ rehydrate,
256
+ schema
257
+ };
258
+ };
259
+ /** Maps compact websocket lifecycle handler names to `DurableObject.make` options. */
260
+ const handlers = (options) => ({
261
+ webSocketMessage: options.message,
262
+ webSocketClose: options.close,
263
+ webSocketError: options.error
264
+ });
265
+ //#endregion
266
+ //#region src/DurableObjectState.ts
267
+ var DurableObjectState_exports = /* @__PURE__ */ __exportAll({
268
+ DurableObjectState: () => DurableObjectState,
269
+ fromDurableObjectState: () => fromDurableObjectState
270
+ });
271
+ /**
272
+ * Context tag for accessing the current Durable Object state service.
273
+ */
274
+ var DurableObjectState = class extends Context.Service()("effect-cf/DurableObjectState") {};
275
+ /**
276
+ * Wraps a native Cloudflare `DurableObjectState` as a {@link DurableObjectStateService}.
277
+ */
278
+ const fromDurableObjectState = (state) => ({
279
+ raw: state,
280
+ id: state.id,
281
+ storage: fromDurableObjectStorage(state.storage),
282
+ waitUntil: (promise) => Effect.sync(() => state.waitUntil(promise)),
283
+ blockConcurrencyWhile: (effect) => Effect.context().pipe(Effect.flatMap((context) => Effect.promise(() => state.blockConcurrencyWhile(() => runPromiseExitPreservingTypedFailures(Effect.provideContext(effect, context))))), Effect.flatten),
284
+ blockConcurrencyWhileOrReset: (effect) => Effect.context().pipe(Effect.flatMap((context) => Effect.promise(() => state.blockConcurrencyWhile(() => Effect.runPromise(Effect.provideContext(effect, context)))))),
285
+ acceptWebSocket: (ws, tags) => Effect.sync(() => state.acceptWebSocket(ws.raw, tags)),
286
+ getWebSockets: (tag) => Effect.sync(() => state.getWebSockets(tag).map((socket) => fromWebSocket(socket))),
287
+ setWebSocketAutoResponse: (pair) => Effect.sync(() => state.setWebSocketAutoResponse(pair)),
288
+ getWebSocketAutoResponse: Effect.sync(() => state.getWebSocketAutoResponse()),
289
+ getWebSocketAutoResponseTimestamp: (ws) => Effect.sync(() => state.getWebSocketAutoResponseTimestamp(ws.raw)),
290
+ setHibernatableWebSocketEventTimeout: (timeoutMs) => Effect.sync(() => state.setHibernatableWebSocketEventTimeout(timeoutMs)),
291
+ getHibernatableWebSocketEventTimeout: Effect.sync(() => state.getHibernatableWebSocketEventTimeout()),
292
+ getTags: (ws) => Effect.sync(() => state.getTags(ws.raw)),
293
+ abort: (reason) => Effect.sync(() => state.abort(reason))
294
+ });
295
+ const runPromiseExitPreservingTypedFailures = async (effect) => {
296
+ const exit = await Effect.runPromiseExit(effect);
297
+ if (Exit.isFailure(exit) && (Cause.hasDies(exit.cause) || Cause.hasInterrupts(exit.cause))) throw Cause.squash(exit.cause);
298
+ return exit;
299
+ };
300
+ //#endregion
301
+ //#region src/CloudflareOtlp.ts
302
+ var CloudflareOtlp_exports = /* @__PURE__ */ __exportAll({
303
+ CloudflareOtlpSettings: () => CloudflareOtlpSettings,
304
+ durableObjectLayer: () => durableObjectLayer,
305
+ layer: () => layer$9,
306
+ layerJson: () => layerJson,
307
+ layerProtobuf: () => layerProtobuf,
308
+ settingsConfig: () => settingsConfig,
309
+ settingsLayer: () => settingsLayer,
310
+ workerLayer: () => workerLayer
311
+ });
312
+ /**
313
+ * Supported OpenTelemetry environment configuration for Cloudflare OTLP export.
314
+ *
315
+ * This config intentionally uses the conventional `OTEL_*` variable names so
316
+ * deployments can share the same settings used by other OpenTelemetry SDKs.
317
+ * It covers the OTLP HTTP settings supported by the Effect OTLP layers:
318
+ *
319
+ * - `OTEL_EXPORTER_OTLP_ENDPOINT`
320
+ * - `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT`
321
+ * - `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`
322
+ * - `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`
323
+ * - `OTEL_EXPORTER_OTLP_HEADERS`
324
+ * - `OTEL_EXPORTER_OTLP_LOGS_HEADERS`
325
+ * - `OTEL_EXPORTER_OTLP_TRACES_HEADERS`
326
+ * - `OTEL_EXPORTER_OTLP_METRICS_HEADERS`
327
+ * - `OTEL_SERVICE_NAME`
328
+ * - `OTEL_RESOURCE_ATTRIBUTES`
329
+ *
330
+ * `OTEL_SERVICE_VERSION` is also accepted as an effect-cf convenience alias.
331
+ * The standard OpenTelemetry way to configure service version is
332
+ * `OTEL_RESOURCE_ATTRIBUTES=service.version=...`.
333
+ *
334
+ * Consumers with non-standard binding names should map those names into
335
+ * {@link CloudflareOtlpSettings} rather than changing this config globally.
336
+ */
337
+ const settingsConfig = Config.all({
338
+ endpoint: Config.string("OTEL_EXPORTER_OTLP_ENDPOINT").pipe(Config.option),
339
+ logsEndpoint: Config.string("OTEL_EXPORTER_OTLP_LOGS_ENDPOINT").pipe(Config.option),
340
+ tracesEndpoint: Config.string("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT").pipe(Config.option),
341
+ metricsEndpoint: Config.string("OTEL_EXPORTER_OTLP_METRICS_ENDPOINT").pipe(Config.option),
342
+ headers: Config.string("OTEL_EXPORTER_OTLP_HEADERS").pipe(Config.option),
343
+ logsHeaders: Config.string("OTEL_EXPORTER_OTLP_LOGS_HEADERS").pipe(Config.option),
344
+ tracesHeaders: Config.string("OTEL_EXPORTER_OTLP_TRACES_HEADERS").pipe(Config.option),
345
+ metricsHeaders: Config.string("OTEL_EXPORTER_OTLP_METRICS_HEADERS").pipe(Config.option),
346
+ serviceName: Config.string("OTEL_SERVICE_NAME").pipe(Config.option),
347
+ serviceVersion: Config.string("OTEL_SERVICE_VERSION").pipe(Config.option),
348
+ resourceAttributes: Config.schema(Config.Record(Schema.String, Schema.String), "OTEL_RESOURCE_ATTRIBUTES").pipe(Config.option)
349
+ });
350
+ /**
351
+ * Service carrying already-resolved Cloudflare OTLP settings.
352
+ *
353
+ * Provide this service directly when an application needs to map custom
354
+ * Cloudflare binding names, compute settings dynamically, or override settings
355
+ * in tests. When this service is present, the OTLP layers use it instead of
356
+ * reading {@link settingsConfig}.
357
+ *
358
+ * @example
359
+ * ```ts
360
+ * const CustomOtlpSettings = Layer.effect(
361
+ * CloudflareOtlp.CloudflareOtlpSettings,
362
+ * Config.all({
363
+ * ...CloudflareOtlp.settingsConfig,
364
+ * endpoint: Config.string("MY_OTLP_ENDPOINT").pipe(Config.option),
365
+ * }),
366
+ * ).pipe(Layer.provide(WorkerConfig.layer));
367
+ * ```
368
+ */
369
+ var CloudflareOtlpSettings = class extends Context.Service()("effect-cf/CloudflareOtlpSettings") {};
370
+ const allSignals = [
371
+ "logs",
372
+ "traces",
373
+ "metrics"
374
+ ];
375
+ const optionToUndefined = (option) => Option.isSome(option) ? option.value : void 0;
376
+ const nonEmptyStringOption = (option) => Option.flatMap(option, (value) => {
377
+ const trimmed = value.trim();
378
+ return trimmed === "" ? Option.none() : Option.some(trimmed);
379
+ });
380
+ const nonEmptyRecordOption = (option) => Option.filter(option, (value) => Object.keys(value).length > 0);
381
+ const normalizeSettings = (settings) => ({
382
+ endpoint: nonEmptyStringOption(settings.endpoint),
383
+ logsEndpoint: nonEmptyStringOption(settings.logsEndpoint),
384
+ tracesEndpoint: nonEmptyStringOption(settings.tracesEndpoint),
385
+ metricsEndpoint: nonEmptyStringOption(settings.metricsEndpoint),
386
+ headers: nonEmptyStringOption(settings.headers),
387
+ logsHeaders: nonEmptyStringOption(settings.logsHeaders),
388
+ tracesHeaders: nonEmptyStringOption(settings.tracesHeaders),
389
+ metricsHeaders: nonEmptyStringOption(settings.metricsHeaders),
390
+ serviceName: nonEmptyStringOption(settings.serviceName),
391
+ serviceVersion: nonEmptyStringOption(settings.serviceVersion),
392
+ resourceAttributes: nonEmptyRecordOption(settings.resourceAttributes)
393
+ });
394
+ /**
395
+ * Layer that reads standard OpenTelemetry settings from the current Cloudflare
396
+ * `env` object.
397
+ *
398
+ * The layer depends on {@link WorkerEnvironment} and installs a
399
+ * Cloudflare-backed Effect `ConfigProvider`, so `settingsConfig` reads from
400
+ * Worker vars/secrets instead of Node process environment variables.
401
+ */
402
+ const settingsLayer = Layer.effect(CloudflareOtlpSettings, settingsConfig.pipe(Config.map(normalizeSettings))).pipe(Layer.provide(WorkerConfig.layer));
403
+ const selectedSignals = (signals) => new Set(signals ?? allSignals);
404
+ const withDefinedAttributes = (attributes) => {
405
+ const out = {};
406
+ for (const [key, value] of Object.entries(attributes)) if (value !== void 0) out[key] = value;
407
+ return out;
408
+ };
409
+ const parseHeaders = (input) => {
410
+ if (Option.isNone(input) || input.value.trim() === "") return;
411
+ const headers = {};
412
+ for (const part of input.value.split(",")) {
413
+ const index = part.indexOf("=");
414
+ if (index <= 0) continue;
415
+ const key = part.slice(0, index).trim();
416
+ const value = part.slice(index + 1).trim();
417
+ if (key !== "") headers[decodeHeaderComponent(key)] = decodeHeaderComponent(value);
418
+ }
419
+ return headers;
420
+ };
421
+ const mergeHeaders = (common, signalSpecific) => {
422
+ const commonHeaders = parseHeaders(common);
423
+ const signalHeaders = parseHeaders(signalSpecific);
424
+ if (commonHeaders === void 0 && signalHeaders === void 0) return;
425
+ return {
426
+ ...commonHeaders,
427
+ ...signalHeaders
428
+ };
429
+ };
430
+ const decodeHeaderComponent = (value) => {
431
+ try {
432
+ return decodeURIComponent(value);
433
+ } catch {
434
+ return value;
435
+ }
436
+ };
437
+ const appendOtlpPath = (baseUrl, path) => `${baseUrl.replace(/\/+$/, "")}${path}`;
438
+ const makeResource = (settings, options, runtimeAttributes) => ({
439
+ serviceName: options.serviceName ?? optionToUndefined(settings.serviceName),
440
+ serviceVersion: options.serviceVersion ?? optionToUndefined(settings.serviceVersion),
441
+ attributes: {
442
+ ...optionToUndefined(settings.resourceAttributes),
443
+ ...withDefinedAttributes(runtimeAttributes),
444
+ ...options.attributes
445
+ }
446
+ });
447
+ const commonOtlpOptions = (settings, options, runtimeAttributes) => ({
448
+ resource: makeResource(settings, options, runtimeAttributes),
449
+ maxBatchSize: options.maxBatchSize,
450
+ loggerExportInterval: options.loggerExportInterval,
451
+ loggerExcludeLogSpans: options.loggerExcludeLogSpans,
452
+ loggerMergeWithExisting: options.loggerMergeWithExisting,
453
+ tracerExportInterval: options.tracerExportInterval,
454
+ tracerContext: options.tracerContext,
455
+ metricsExportInterval: options.metricsExportInterval,
456
+ metricsTemporality: options.metricsTemporality,
457
+ shutdownTimeout: options.shutdownTimeout
458
+ });
459
+ const serializationLayer = (serialization) => serialization === "json" ? OtlpSerialization.layerJson : OtlpSerialization.layerProtobuf;
460
+ const resolveSettings = Effect.gen(function* () {
461
+ const settings = yield* Effect.serviceOption(CloudflareOtlpSettings);
462
+ if (Option.isSome(settings)) return normalizeSettings(settings.value);
463
+ const env = yield* Effect.serviceOption(WorkerEnvironment);
464
+ if (Option.isSome(env)) return normalizeSettings(yield* settingsConfig.pipe(Effect.provide(ConfigProvider.layer(Effect.succeed(WorkerConfig.providerFromEnv(env.value))))));
465
+ return normalizeSettings(yield* settingsConfig);
466
+ });
467
+ const mergeSignalLayers = (layers) => {
468
+ if (layers.length === 0) return Layer.empty;
469
+ let merged = layers[0];
470
+ for (let index = 1; index < layers.length; index++) merged = Layer.mergeAll(merged, layers[index]);
471
+ return merged;
472
+ };
473
+ const emptyLayer = Layer.empty;
474
+ const makeLayerFromSettings = (options = {}, runtimeAttributes = {}) => Layer.unwrap(Effect.map(resolveSettings, (settings) => {
475
+ const signals = selectedSignals(options.signals);
476
+ const endpoint = optionToUndefined(settings.endpoint);
477
+ const logsEndpoint = optionToUndefined(settings.logsEndpoint);
478
+ const tracesEndpoint = optionToUndefined(settings.tracesEndpoint);
479
+ const metricsEndpoint = optionToUndefined(settings.metricsEndpoint);
480
+ const hasSpecificEndpoint = logsEndpoint !== void 0 || tracesEndpoint !== void 0 || metricsEndpoint !== void 0;
481
+ const hasSpecificHeaders = Option.isSome(settings.logsHeaders) || Option.isSome(settings.tracesHeaders) || Option.isSome(settings.metricsHeaders);
482
+ const common = commonOtlpOptions(settings, options, runtimeAttributes);
483
+ if (endpoint !== void 0 && !hasSpecificEndpoint && !hasSpecificHeaders && signals.size === 3) return Otlp.layer({
484
+ baseUrl: endpoint,
485
+ headers: parseHeaders(settings.headers),
486
+ ...common
487
+ }).pipe(Layer.provide(serializationLayer(options.serialization)), Layer.provide(FetchHttpClient.layer));
488
+ const layers = [];
489
+ if (signals.has("logs")) {
490
+ const url = logsEndpoint ?? (endpoint === void 0 ? void 0 : appendOtlpPath(endpoint, "/v1/logs"));
491
+ if (url !== void 0) layers.push(OtlpLogger.layer({
492
+ url,
493
+ resource: common.resource,
494
+ headers: mergeHeaders(settings.headers, settings.logsHeaders),
495
+ exportInterval: common.loggerExportInterval,
496
+ maxBatchSize: common.maxBatchSize,
497
+ shutdownTimeout: common.shutdownTimeout,
498
+ excludeLogSpans: common.loggerExcludeLogSpans,
499
+ mergeWithExisting: common.loggerMergeWithExisting
500
+ }).pipe(Layer.provide(serializationLayer(options.serialization)), Layer.provide(FetchHttpClient.layer)));
501
+ }
502
+ if (signals.has("traces")) {
503
+ const url = tracesEndpoint ?? (endpoint === void 0 ? void 0 : appendOtlpPath(endpoint, "/v1/traces"));
504
+ if (url !== void 0) layers.push(OtlpTracer.layer({
505
+ url,
506
+ resource: common.resource,
507
+ headers: mergeHeaders(settings.headers, settings.tracesHeaders),
508
+ exportInterval: common.tracerExportInterval,
509
+ maxBatchSize: common.maxBatchSize,
510
+ context: common.tracerContext,
511
+ shutdownTimeout: common.shutdownTimeout
512
+ }).pipe(Layer.provide(serializationLayer(options.serialization)), Layer.provide(FetchHttpClient.layer)));
513
+ }
514
+ if (signals.has("metrics")) {
515
+ const url = metricsEndpoint ?? (endpoint === void 0 ? void 0 : appendOtlpPath(endpoint, "/v1/metrics"));
516
+ if (url !== void 0) layers.push(OtlpMetrics.layer({
517
+ url,
518
+ resource: common.resource,
519
+ headers: mergeHeaders(settings.headers, settings.metricsHeaders),
520
+ exportInterval: common.metricsExportInterval,
521
+ shutdownTimeout: common.shutdownTimeout,
522
+ temporality: common.metricsTemporality
523
+ }).pipe(Layer.provide(serializationLayer(options.serialization)), Layer.provide(FetchHttpClient.layer)));
524
+ }
525
+ return mergeSignalLayers(layers);
526
+ }).pipe(Effect.catch((error) => Effect.logWarning("CloudflareOtlp disabled because OTLP configuration is invalid", { error: String(error) }).pipe(Effect.as(emptyLayer)))));
527
+ const makeLayer = (options = {}, runtimeAttributes = {}) => makeLayerFromSettings(options, runtimeAttributes);
528
+ /**
529
+ * Base OTLP telemetry layer for Cloudflare-compatible runtimes.
530
+ *
531
+ * The layer reads {@link CloudflareOtlpSettings} when provided. Otherwise it
532
+ * reads standard OpenTelemetry config from `WorkerEnvironment` when available,
533
+ * then falls back to the ambient Effect `ConfigProvider`.
534
+ *
535
+ * When only `OTEL_EXPORTER_OTLP_ENDPOINT` is configured, per-signal paths are
536
+ * derived by appending `/v1/logs`, `/v1/traces`, and `/v1/metrics`. Signal
537
+ * specific endpoints are used as-is, matching the OpenTelemetry OTLP exporter
538
+ * convention.
539
+ */
540
+ const layer$9 = (options = {}) => makeLayer(options);
541
+ /** Base OTLP telemetry layer forced to JSON serialization. */
542
+ const layerJson = (options = {}) => layer$9({
543
+ ...options,
544
+ serialization: "json"
545
+ });
546
+ /** Base OTLP telemetry layer forced to protobuf serialization. */
547
+ const layerProtobuf = (options = {}) => layer$9({
548
+ ...options,
549
+ serialization: "protobuf"
550
+ });
551
+ /**
552
+ * OTLP layer with Cloudflare Worker resource attributes.
553
+ *
554
+ * Provide this layer at runtime scope for long-lived metrics aggregation, or at
555
+ * handler scope when traces/logs should flush as the Cloudflare event finishes.
556
+ */
557
+ const workerLayer = (options = {}) => makeLayer(options, {
558
+ "cloudflare.resource_type": "worker",
559
+ "cloudflare.worker.name": options.workerName
560
+ });
561
+ /**
562
+ * OTLP layer with Cloudflare Durable Object resource attributes.
563
+ *
564
+ * The layer reads {@link DurableObjectState} so it can optionally include the
565
+ * Durable Object id. Prefer leaving `includeObjectId` disabled unless the
566
+ * backend can tolerate high-cardinality resource attributes.
567
+ */
568
+ const durableObjectLayer = (options = {}) => Layer.unwrap(Effect.map(DurableObjectState, (state) => makeLayer(options, {
569
+ "cloudflare.resource_type": "durable_object",
570
+ "cloudflare.durable_object.class": options.className,
571
+ "cloudflare.durable_object.id": options.includeObjectId ? state.id.toString() : void 0
572
+ })));
573
+ //#endregion
11
574
  //#region src/D1.ts
12
575
  var D1_exports = /* @__PURE__ */ __exportAll({
13
576
  Service: () => Service$1,
@@ -115,7 +678,7 @@ const makeClient$6 = (definition) => {
115
678
  unsafeRaw: Effect.succeed(queue)
116
679
  });
117
680
  };
118
- const layer$8 = (tag, definition) => layer$9(tag, definition.binding, (value) => isQueue(value), makeClient$6(definition), { expected: expectedQueueProducer });
681
+ const layer$8 = (tag, definition) => layer$10(tag, definition.binding, (value) => isQueue(value), makeClient$6(definition), { expected: expectedQueueProducer });
119
682
  //#endregion
120
683
  //#region src/QueueDefinition.ts
121
684
  var QueueDefinition_exports = /* @__PURE__ */ __exportAll({
@@ -458,7 +1021,7 @@ const makeClient$5 = (definition) => {
458
1021
  });
459
1022
  };
460
1023
  };
461
- const layer$7 = (tag, definition) => layer$9(tag, definition.binding, (value) => isServiceBindingClient(value), makeClient$5(definition), { expected: expectedServiceBinding });
1024
+ const layer$7 = (tag, definition) => layer$10(tag, definition.binding, (value) => isServiceBindingClient(value), makeClient$5(definition), { expected: expectedServiceBinding });
462
1025
  /**
463
1026
  * Creates a typed Effect service for a Worker service binding.
464
1027
  *
@@ -501,175 +1064,32 @@ const Service = () => (id, definition) => {
501
1064
  });
502
1065
  const scopedCall = (method, ...args) => Effect.gen(function* () {
503
1066
  return yield* (yield* tag).scopedCall(method, ...args);
504
- });
505
- const directMethods = makeDirectMethods$1(definition.definition, call);
506
- return Object.assign(tag, directMethods, {
507
- [TypeId$1]: TypeId$1,
508
- definition,
509
- fetch,
510
- rpc,
511
- call,
512
- scopedCall
513
- });
514
- };
515
- const makeDirectMethods$1 = (rpcDefinition, call) => {
516
- const methods = {};
517
- if (rpcDefinition !== void 0) for (const methodName of Object.keys(rpcDefinition.methods)) methods[methodName] = (...args) => call(methodName, ...args);
518
- return methods;
519
- };
520
- //#endregion
521
- //#region src/WorkerDefinition.ts
522
- var WorkerDefinition_exports = /* @__PURE__ */ __exportAll({
523
- Tag: () => Tag$8,
524
- Worker: () => Worker,
525
- implement: () => implement$5,
526
- make: () => make$7,
527
- method: () => method$3
528
- });
529
- const reservedMethodNames$3 = new Set([
530
- "constructor",
531
- "dup",
532
- "fetch",
533
- "connect",
534
- "queue",
535
- "scheduled",
536
- "tail",
537
- "tailStream",
538
- "test",
539
- "trace",
540
- "alarm",
541
- "webSocketMessage",
542
- "webSocketClose",
543
- "webSocketError"
544
- ]);
545
- /**
546
- * Defines a single RPC method schema in a worker definition.
547
- */
548
- const method$3 = method$4;
549
- /**
550
- * Creates a typed worker RPC definition plus helpers for implementation and bindings.
551
- *
552
- * @example
553
- * ```ts
554
- * const CounterWorker = WorkerDefinition.make("CounterWorker", {
555
- * increment: WorkerDefinition.method({
556
- * args: [Schema.Number],
557
- * success: Schema.Number,
558
- * }),
559
- * });
560
- * ```
561
- */
562
- const makeDefinition$3 = (id, methods) => {
563
- assertNoReservedMethods("Worker", methods, reservedMethodNames$3);
564
- const definition = make$8(id, methods);
565
- return Object.assign(definition, { make: (layer, options) => make$6(layer, {
566
- ...options,
567
- rpc: wrapHandlers$1(definition, options.rpc)
568
- }) });
569
- };
570
- const make$7 = (id, methods) => Tag$8()(id, methods);
571
- const Tag$8 = () => (id, methods) => {
572
- const definition = makeDefinition$3(id, methods);
573
- const tag = Context.Service()(id);
574
- const bindingDefinition = (binding) => ({
575
- ...binding,
576
- definition
577
- });
578
- const layer = (binding) => layer$7(tag, bindingDefinition(binding));
579
- const fetch = (input, init) => Effect.gen(function* () {
580
- return yield* (yield* tag).fetch(input, init);
581
- });
582
- const rpc = (method, ...args) => Effect.gen(function* () {
583
- return yield* (yield* tag).rpc(method, ...args);
584
- });
585
- const call = (method, ...args) => Effect.gen(function* () {
586
- return yield* (yield* tag).call(method, ...args);
587
- });
588
- const scopedCall = (method, ...args) => Effect.gen(function* () {
589
- return yield* (yield* tag).scopedCall(method, ...args);
590
- });
591
- const directMethods = makeDirectMethods$1(definition, call);
592
- return Object.assign(tag, directMethods, {
593
- id: definition.id,
594
- methods: definition.methods,
595
- make: definition.make,
596
- layer,
597
- fetch,
598
- rpc,
599
- call,
600
- scopedCall
601
- });
602
- };
603
- const Worker = Tag$8;
604
- const wrapHandlers$1 = (definition, handlers) => {
605
- const wrapped = {};
606
- for (const key of Object.keys(definition.methods)) {
607
- const handler = handlers[key];
608
- wrapped[key] = (...args) => Effect.gen(function* () {
609
- return yield* encodeSuccess(definition, key, yield* handler(...yield* decodeArgs(definition, key, args)));
610
- });
611
- }
612
- return wrapped;
613
- };
614
- /**
615
- * Helper for implementing handlers with the exact method shape of a definition.
616
- */
617
- const implement$5 = (_definition, handlers) => handlers;
618
- //#endregion
619
- //#region src/internal/Entrypoint.ts
620
- const provideEntrypointServices = (layer, services) => layer.pipe(Layer.provideMerge(services));
621
- const defineEntrypointRpcMethods = (target, prototype, rpc, reservedMethodNames, run) => {
622
- const methods = rpc ?? {};
623
- assertNoReservedMethods(target, methods, reservedMethodNames);
624
- for (const [key, method] of Object.entries(methods)) Object.defineProperty(prototype, key, {
625
- enumerable: true,
626
- value(...args) {
627
- return run(this, Effect.suspend(() => method(...args)));
628
- }
629
- });
630
- };
631
- const assumeEntrypointClass = (entrypoint) => entrypoint;
632
- //#endregion
633
- //#region src/internal/WorkerContext.ts
634
- const causeError = (cause) => new Error(Cause.pretty(cause));
635
- const failureHandler = (cause, options) => (options?.onFailure?.(cause) ?? Effect.logError("WorkerContext.waitUntil failed", Cause.pretty(cause))).pipe(Effect.catchCause((handlerCause) => Effect.logError("WorkerContext.waitUntil failure handler failed", Cause.pretty(cause), Cause.pretty(handlerCause))));
636
- const fromExecutionContext = (ctx, runPromiseExit) => {
637
- const schedule = (effect, options, mode) => Effect.context().pipe(Effect.flatMap((context) => Effect.sync(() => {
638
- const runHandler = (cause) => runPromiseExit(Effect.scoped(Effect.provideContext(failureHandler(cause, options), context))).then((exit) => {
639
- if (Exit.isFailure(exit)) console.error("WorkerContext.waitUntil failure handler failed", Cause.pretty(exit.cause));
640
- });
641
- ctx.waitUntil(runPromiseExit(Effect.scoped(Effect.provideContext(effect, context))).then(async (exit) => {
642
- if (Exit.isSuccess(exit)) return;
643
- await runHandler(exit.cause);
644
- if (mode === "propagate") throw causeError(exit.cause);
645
- }));
646
- })));
647
- return {
648
- raw: ctx,
649
- waitUntil: (effect, options) => schedule(effect, options, options?.mode ?? "observe"),
650
- waitUntilPropagating: (effect, options) => schedule(effect, options, "propagate"),
651
- passThroughOnException: Effect.sync(() => ctx.passThroughOnException())
652
- };
1067
+ });
1068
+ const directMethods = makeDirectMethods$1(definition.definition, call);
1069
+ return Object.assign(tag, directMethods, {
1070
+ [TypeId$1]: TypeId$1,
1071
+ definition,
1072
+ fetch,
1073
+ rpc,
1074
+ call,
1075
+ scopedCall
1076
+ });
1077
+ };
1078
+ const makeDirectMethods$1 = (rpcDefinition, call) => {
1079
+ const methods = {};
1080
+ if (rpcDefinition !== void 0) for (const methodName of Object.keys(rpcDefinition.methods)) methods[methodName] = (...args) => call(methodName, ...args);
1081
+ return methods;
653
1082
  };
654
1083
  //#endregion
655
- //#region src/Worker.ts
656
- var Worker_exports = /* @__PURE__ */ __exportAll({
657
- ExecutionContext: () => ExecutionContext,
658
- NativeRequest: () => NativeRequest,
659
- Tag: () => Tag$7,
660
- WorkerContext: () => WorkerContext,
661
- implement: () => implement$4,
662
- isWebSocketUpgrade: () => isWebSocketUpgrade,
663
- make: () => make$6,
664
- makeFetchHandler: () => makeFetchHandler,
665
- method: () => method$2,
666
- renderHttpResponse: () => renderHttpResponse
1084
+ //#region src/WorkerDefinition.ts
1085
+ var WorkerDefinition_exports = /* @__PURE__ */ __exportAll({
1086
+ Tag: () => Tag$8,
1087
+ Worker: () => Worker,
1088
+ implement: () => implement$5,
1089
+ make: () => make$7,
1090
+ method: () => method$3
667
1091
  });
668
- var ExecutionContext = class extends Context.Service()("effect-cf/ExecutionContext") {};
669
- var WorkerContext = class extends Context.Service()("effect-cf/WorkerContext") {};
670
- var NativeRequest = class extends Context.Service()("effect-cf/NativeRequest") {};
671
- const isWebSocketUpgrade = (request) => request.headers.get("Upgrade")?.toLowerCase() === "websocket";
672
- const reservedMethodNames$2 = new Set([
1092
+ const reservedMethodNames$3 = new Set([
673
1093
  "constructor",
674
1094
  "dup",
675
1095
  "fetch",
@@ -685,336 +1105,191 @@ const reservedMethodNames$2 = new Set([
685
1105
  "webSocketClose",
686
1106
  "webSocketError"
687
1107
  ]);
688
- const RunSymbol$1 = Symbol.for("effect-cf/Worker/run");
689
- const renderHttpResponse = (effect) => Effect.flatMap(effect, (response) => Effect.map(Effect.context(), (context) => HttpServerResponse.toWeb(response, { context })));
690
- const renderFetchSuccess = (effect) => Effect.flatMap(effect, (response) => response instanceof Response ? Effect.succeed(response) : Effect.map(Effect.context(), (context) => HttpServerResponse.toWeb(response, { context })));
691
- const isWorkerOptions = (options) => typeof options === "object" && options !== null && ("fetch" in options || "queue" in options || "rpc" in options);
692
- function make$6(layer, optionsOrFetch) {
693
- const options = isWorkerOptions(optionsOrFetch) ? optionsOrFetch : { fetch: optionsOrFetch };
694
- class EffectWorker extends WorkerEntrypoint {
695
- runtime;
696
- constructor(ctx, env) {
697
- super(ctx, env);
698
- let runWaitUntilEffect = () => Promise.reject(/* @__PURE__ */ new Error("WorkerContext runtime is not initialized"));
699
- const runtimeLayer = provideEntrypointServices(layer, Layer.mergeAll(Layer.succeed(ExecutionContext, ctx), ConfigProvider.layer(Effect.succeed(WorkerConfig.providerFromEnv(env))), Layer.succeed(WorkerContext, fromExecutionContext(ctx, (effect) => runWaitUntilEffect(effect))), Layer.succeed(WorkerEnvironment, env)));
700
- this.runtime = ManagedRuntime.make(runtimeLayer);
701
- runWaitUntilEffect = (effect) => this.runtime.runPromiseExit(effect);
702
- }
703
- [RunSymbol$1](effect) {
704
- return this.runtime.runPromise(Effect.scoped(effect));
705
- }
706
- fetch(request) {
707
- const fetchHandler = options.fetch;
708
- if (fetchHandler === void 0) return Promise.resolve(new Response("Not Found", { status: 404 }));
709
- const requestServices = Layer.mergeAll(Layer.succeed(NativeRequest, request), Layer.succeed(HttpServerRequest.HttpServerRequest, HttpServerRequest.fromWeb(request)));
710
- return this[RunSymbol$1](renderFetchSuccess(fetchHandler).pipe(Effect.provide(requestServices)));
711
- }
712
- queue(batch) {
713
- const queueHandler = options.queue;
714
- if (queueHandler === void 0) return Promise.resolve();
715
- const messages = batch.messages.map((message) => fromMessage(message, message.body));
716
- return this[RunSymbol$1](queueHandler(fromMessageBatch(batch, messages)));
717
- }
718
- }
719
- defineEntrypointRpcMethods("Worker", EffectWorker.prototype, options.rpc, reservedMethodNames$2, (self, effect) => self[RunSymbol$1](effect));
720
- return assumeEntrypointClass(EffectWorker);
721
- }
722
- const makeFetchHandler = (layer, options) => {
723
- const WorkerClass = make$6(layer, options);
724
- return { fetch: (request, env, ctx) => Promise.resolve(new WorkerClass(ctx, env).fetch(request)) };
725
- };
726
- const Tag$7 = Tag$8;
727
- const method$2 = method$3;
728
- const implement$4 = implement$5;
729
- //#endregion
730
- //#region src/DurableObjectStorage.ts
731
- var DurableObjectStorage_exports = /* @__PURE__ */ __exportAll({
732
- StorageOperationError: () => StorageOperationError,
733
- fromDurableObjectStorage: () => fromDurableObjectStorage
734
- });
735
- /** Error type used when a storage operation throws or rejects. */
736
- var StorageOperationError = class extends Data.TaggedError("StorageOperationError") {};
737
- const storageError = (operation, cause) => new StorageOperationError({
738
- operation,
739
- cause
740
- });
741
- const tryStorageSync = (operation, evaluate) => Effect.try({
742
- try: evaluate,
743
- catch: (cause) => storageError(operation, cause)
744
- });
745
- const tryStoragePromise = (operation, evaluate) => Effect.tryPromise({
746
- try: evaluate,
747
- catch: (cause) => storageError(operation, cause)
748
- });
749
- const fromSqlCursor = (cursor) => ({
750
- next: () => tryStorageSync("sql.next", () => cursor.next()),
751
- toArray: () => tryStorageSync("sql.toArray", () => cursor.toArray()),
752
- one: () => tryStorageSync("sql.one", () => cursor.one()),
753
- raw: () => tryStorageSync("sql.raw", () => cursor.raw()),
754
- get columnNames() {
755
- return cursor.columnNames;
756
- },
757
- rowsRead: tryStorageSync("sql.rowsRead", () => cursor.rowsRead),
758
- rowsWritten: tryStorageSync("sql.rowsWritten", () => cursor.rowsWritten)
759
- });
760
- const fromSqlStorage = (sql) => ({
761
- exec: (query, ...bindings) => tryStorageSync("sql.exec", () => fromSqlCursor(sql.exec(query, ...bindings))),
762
- get databaseSize() {
763
- return sql.databaseSize;
764
- }
765
- });
766
- const schemaBackedSyncKvStorage = (kv, definition) => {
767
- const encodeKey = Schema.encodeEffect(definition.key);
768
- const decodeKey = Schema.decodeUnknownEffect(definition.key);
769
- const encodeValue = Schema.encodeEffect(definition.value);
770
- const decodeValue = Schema.decodeUnknownEffect(definition.value);
771
- return {
772
- get: (key) => Effect.gen(function* () {
773
- const encodedKey = yield* encodeKey(key);
774
- const encodedValue = yield* tryStorageSync("kv.get", () => kv.get(encodedKey));
775
- if (encodedValue === void 0) return Option.none();
776
- return yield* decodeValue(encodedValue).pipe(Effect.map(Option.some));
777
- }),
778
- put: (key, value) => Effect.gen(function* () {
779
- const encodedKey = yield* encodeKey(key);
780
- const encodedValue = yield* encodeValue(value);
781
- yield* tryStorageSync("kv.put", () => kv.put(encodedKey, encodedValue));
782
- }),
783
- delete: (key) => Effect.gen(function* () {
784
- const encodedKey = yield* encodeKey(key);
785
- return yield* tryStorageSync("kv.delete", () => kv.delete(encodedKey));
786
- }),
787
- list: (options) => Effect.gen(function* () {
788
- const entries = Array.from(yield* tryStorageSync("kv.list", () => kv.list(options)));
789
- const decoded = [];
790
- for (const [key, value] of entries) decoded.push([yield* decodeKey(key), yield* decodeValue(value)]);
791
- return decoded;
792
- })
793
- };
794
- };
795
- const fromSyncKvStorage = (kv) => ({
796
- get: (key) => tryStorageSync("kv.get", () => kv.get(key)),
797
- put: (key, value) => tryStorageSync("kv.put", () => kv.put(key, value)),
798
- delete: (key) => tryStorageSync("kv.delete", () => kv.delete(key)),
799
- list: (options) => tryStorageSync("kv.list", () => Array.from(kv.list(options))),
800
- schema: (definition) => schemaBackedSyncKvStorage(kv, definition)
801
- });
802
- const fromDurableObjectTransaction = (txn) => ({
803
- get: (keyOrKeys, options) => Array.isArray(keyOrKeys) ? tryStoragePromise("transaction.get", () => txn.get(keyOrKeys, options)) : tryStoragePromise("transaction.get", () => txn.get(keyOrKeys, options)),
804
- list: (options) => tryStoragePromise("transaction.list", () => txn.list(options)),
805
- put: (keyOrEntries, valueOrOptions, maybeOptions) => tryStoragePromise("transaction.put", () => typeof keyOrEntries === "string" ? txn.put(keyOrEntries, valueOrOptions, maybeOptions) : txn.put(keyOrEntries, valueOrOptions)),
806
- delete: (keyOrKeys, options) => Array.isArray(keyOrKeys) ? tryStoragePromise("transaction.delete", () => txn.delete(keyOrKeys, options)) : tryStoragePromise("transaction.delete", () => txn.delete(keyOrKeys, options)),
807
- rollback: () => tryStorageSync("transaction.rollback", () => txn.rollback()),
808
- getAlarm: (options) => tryStoragePromise("transaction.getAlarm", () => txn.getAlarm(options)),
809
- setAlarm: (scheduledTime, options) => tryStoragePromise("transaction.setAlarm", () => txn.setAlarm(scheduledTime, options)),
810
- deleteAlarm: (options) => tryStoragePromise("transaction.deleteAlarm", () => txn.deleteAlarm(options))
811
- });
812
1108
  /**
813
- * Wraps native Cloudflare storage APIs as Effect-returning helpers.
1109
+ * Defines a single RPC method schema in a worker definition.
814
1110
  */
815
- const fromDurableObjectStorage = (storage) => ({
816
- get: (key, options) => tryStoragePromise("get", () => storage.get(key, options)),
817
- put: (key, value, options) => tryStoragePromise("put", () => storage.put(key, value, options)),
818
- delete: (key, options) => tryStoragePromise("delete", () => storage.delete(key, options)),
819
- deleteAll: (options) => tryStoragePromise("deleteAll", () => storage.deleteAll(options)),
820
- getAlarm: (options) => tryStoragePromise("getAlarm", () => storage.getAlarm(options)),
821
- setAlarm: (scheduledTime, options) => tryStoragePromise("setAlarm", () => storage.setAlarm(scheduledTime, options)),
822
- deleteAlarm: (options) => tryStoragePromise("deleteAlarm", () => storage.deleteAlarm(options)),
823
- transactionSync: (closure) => Effect.context().pipe(Effect.flatMap((context) => Effect.suspend(() => {
824
- try {
825
- return Effect.succeed(storage.transactionSync(() => {
826
- const exit = Effect.runSyncExitWith(context)(closure());
827
- if (Exit.isSuccess(exit)) return exit.value;
828
- throw exit;
829
- }));
830
- } catch (cause) {
831
- if (Exit.isExit(cause) && Exit.isFailure(cause)) return Effect.failCause(cause.cause);
832
- return Effect.fail(storageError("transactionSync", cause));
833
- }
834
- }))),
835
- transaction: (closure) => Effect.context().pipe(Effect.flatMap((context) => Effect.callback((resume) => {
836
- storage.transaction(async (txn) => {
837
- const exit = await Effect.runPromiseExitWith(context)(closure(fromDurableObjectTransaction(txn)));
838
- if (Exit.isSuccess(exit)) return exit.value;
839
- throw exit;
840
- }).then((value) => resume(Effect.succeed(value)), (cause) => {
841
- if (Exit.isExit(cause) && Exit.isFailure(cause)) resume(Effect.failCause(cause.cause));
842
- else resume(Effect.fail(storageError("transaction", cause)));
843
- });
844
- }))),
845
- sync: () => tryStoragePromise("sync", () => storage.sync()),
846
- getCurrentBookmark: () => tryStoragePromise("getCurrentBookmark", () => storage.getCurrentBookmark()),
847
- onNextSessionRestoreBookmark: (bookmark) => tryStoragePromise("onNextSessionRestoreBookmark", () => storage.onNextSessionRestoreBookmark(bookmark)),
848
- sql: fromSqlStorage(storage.sql),
849
- kv: fromSyncKvStorage(storage.kv)
850
- });
851
- //#endregion
852
- //#region src/DurableObjectWebSocket.ts
853
- var DurableObjectWebSocket_exports = /* @__PURE__ */ __exportAll({
854
- DurableWebSocketAttachmentError: () => DurableWebSocketAttachmentError,
855
- DurableWebSocketCloseError: () => DurableWebSocketCloseError,
856
- DurableWebSocketSendError: () => DurableWebSocketSendError,
857
- acceptUpgrade: () => acceptUpgrade,
858
- attachment: () => attachment,
859
- fromWebSocket: () => fromWebSocket,
860
- handlers: () => handlers
861
- });
862
- /** Error raised when sending on a Durable Object websocket fails. */
863
- var DurableWebSocketSendError = class extends Data.TaggedError("DurableWebSocketSendError") {};
864
- /** Error raised when closing a Durable Object websocket fails. */
865
- var DurableWebSocketCloseError = class extends Data.TaggedError("DurableWebSocketCloseError") {};
866
- /** Error raised when serializing or deserializing a websocket attachment fails. */
867
- var DurableWebSocketAttachmentError = class extends Data.TaggedError("DurableWebSocketAttachmentError") {};
868
- const wrappers = /* @__PURE__ */ new WeakMap();
869
- /** Wraps a native Cloudflare websocket in the Effect-native Durable Object API. */
870
- const fromWebSocket = (raw) => {
871
- const existing = wrappers.get(raw);
872
- if (existing !== void 0) return existing;
873
- const socket = {
874
- raw,
875
- send: (data) => Effect.try({
876
- try: () => raw.send(data),
877
- catch: (cause) => new DurableWebSocketSendError({ cause })
878
- }),
879
- close: (code, reason) => Effect.try({
880
- try: () => raw.close(code, reason),
881
- catch: (cause) => new DurableWebSocketCloseError({ cause })
882
- }),
883
- serializeAttachment: (value) => Effect.try({
884
- try: () => raw.serializeAttachment(value),
885
- catch: (cause) => new DurableWebSocketAttachmentError({
886
- operation: "serialize",
887
- cause
888
- })
889
- }),
890
- deserializeAttachment: Effect.try({
891
- try: () => raw.deserializeAttachment(),
892
- catch: (cause) => new DurableWebSocketAttachmentError({
893
- operation: "deserialize",
894
- cause
895
- })
896
- })
897
- };
898
- wrappers.set(raw, socket);
899
- return socket;
900
- };
1111
+ const method$3 = method$4;
901
1112
  /**
902
- * Accepts a websocket upgrade and registers the server socket on `DurableObjectState`.
1113
+ * Creates a typed worker RPC definition plus helpers for implementation and bindings.
903
1114
  *
904
1115
  * @example
905
1116
  * ```ts
906
- * const response = yield* DurableObjectWebSocket.acceptUpgrade({
907
- * tags: ["room:general"],
1117
+ * const CounterWorker = WorkerDefinition.make("CounterWorker", {
1118
+ * increment: WorkerDefinition.method({
1119
+ * args: [Schema.Number],
1120
+ * success: Schema.Number,
1121
+ * }),
908
1122
  * });
909
- *
910
- * return response.response;
911
1123
  * ```
912
1124
  */
913
- const acceptUpgrade = (options = {}) => Effect.gen(function* () {
914
- const state = yield* DurableObjectState;
915
- const pair = new WebSocketPair();
916
- const client = pair[0];
917
- const server = fromWebSocket(pair[1]);
918
- if (options.attachment !== void 0) server.raw.serializeAttachment(options.attachment);
919
- yield* state.acceptWebSocket(server, options.tags === void 0 ? void 0 : [...options.tags]);
920
- return {
921
- client,
922
- server,
923
- response: new Response(null, {
924
- status: 101,
925
- webSocket: client
926
- })
927
- };
928
- });
929
- /** Creates typed attachment helpers for accepted and rehydrated sockets. */
930
- const attachment = (schema) => {
931
- const serialize = (socket, value) => Schema.encodeEffect(schema)(value).pipe(Effect.mapError((cause) => new DurableWebSocketAttachmentError({
932
- operation: "serialize",
933
- cause
934
- })), Effect.flatMap((encoded) => socket.serializeAttachment(encoded)));
935
- const deserialize = (socket) => Effect.gen(function* () {
936
- const value = yield* socket.deserializeAttachment;
937
- if (value == null) return Option.none();
938
- return Option.some(yield* Schema.decodeUnknownEffect(schema)(value).pipe(Effect.mapError((cause) => new DurableWebSocketAttachmentError({
939
- operation: "deserialize",
940
- cause
941
- }))));
1125
+ const makeDefinition$3 = (id, methods) => {
1126
+ assertNoReservedMethods("Worker", methods, reservedMethodNames$3);
1127
+ const definition = make$8(id, methods);
1128
+ return Object.assign(definition, { make: (layer, options) => make$6(layer, {
1129
+ ...options,
1130
+ rpc: wrapHandlers$1(definition, options.rpc)
1131
+ }) });
1132
+ };
1133
+ const make$7 = (id, methods) => Tag$8()(id, methods);
1134
+ const Tag$8 = () => (id, methods) => {
1135
+ const definition = makeDefinition$3(id, methods);
1136
+ const tag = Context.Service()(id);
1137
+ const bindingDefinition = (binding) => ({
1138
+ ...binding,
1139
+ definition
942
1140
  });
943
- const rehydrate = (options = {}) => Effect.gen(function* () {
944
- const sockets = yield* (yield* DurableObjectState).getWebSockets(options.tag);
945
- const restored = [];
946
- const onInvalid = options.onInvalid ?? "ignore";
947
- for (const socket of sockets) {
948
- const decoded = yield* deserialize(socket).pipe(Effect.match({
949
- onFailure: (error) => ({
950
- _tag: "Failure",
951
- error
952
- }),
953
- onSuccess: (value) => ({
954
- _tag: "Success",
955
- value
956
- })
957
- }));
958
- if (decoded._tag === "Success" && Option.isSome(decoded.value)) {
959
- restored.push({
960
- socket,
961
- attachment: decoded.value.value
962
- });
963
- continue;
964
- }
965
- if (decoded._tag === "Failure" && onInvalid === "fail") return yield* Effect.fail(decoded.error);
966
- if (decoded._tag === "Failure" && onInvalid === "ignore-and-close") yield* socket.close(1008, "invalid websocket attachment").pipe(Effect.ignore);
1141
+ const layer = (binding) => layer$7(tag, bindingDefinition(binding));
1142
+ const fetch = (input, init) => Effect.gen(function* () {
1143
+ return yield* (yield* tag).fetch(input, init);
1144
+ });
1145
+ const rpc = (method, ...args) => Effect.gen(function* () {
1146
+ return yield* (yield* tag).rpc(method, ...args);
1147
+ });
1148
+ const call = (method, ...args) => Effect.gen(function* () {
1149
+ return yield* (yield* tag).call(method, ...args);
1150
+ });
1151
+ const scopedCall = (method, ...args) => Effect.gen(function* () {
1152
+ return yield* (yield* tag).scopedCall(method, ...args);
1153
+ });
1154
+ const directMethods = makeDirectMethods$1(definition, call);
1155
+ return Object.assign(tag, directMethods, {
1156
+ id: definition.id,
1157
+ methods: definition.methods,
1158
+ make: definition.make,
1159
+ layer,
1160
+ fetch,
1161
+ rpc,
1162
+ call,
1163
+ scopedCall
1164
+ });
1165
+ };
1166
+ const Worker = Tag$8;
1167
+ const wrapHandlers$1 = (definition, handlers) => {
1168
+ const wrapped = {};
1169
+ for (const key of Object.keys(definition.methods)) {
1170
+ const handler = handlers[key];
1171
+ wrapped[key] = (...args) => Effect.gen(function* () {
1172
+ return yield* encodeSuccess(definition, key, yield* handler(...yield* decodeArgs(definition, key, args)));
1173
+ });
1174
+ }
1175
+ return wrapped;
1176
+ };
1177
+ /**
1178
+ * Helper for implementing handlers with the exact method shape of a definition.
1179
+ */
1180
+ const implement$5 = (_definition, handlers) => handlers;
1181
+ //#endregion
1182
+ //#region src/internal/Entrypoint.ts
1183
+ const provideEntrypointServices = (layer, services) => layer.pipe(Layer.provideMerge(services));
1184
+ const defineEntrypointRpcMethods = (target, prototype, rpc, reservedMethodNames, run) => {
1185
+ const methods = rpc ?? {};
1186
+ assertNoReservedMethods(target, methods, reservedMethodNames);
1187
+ for (const [key, method] of Object.entries(methods)) Object.defineProperty(prototype, key, {
1188
+ enumerable: true,
1189
+ value(...args) {
1190
+ return run(this, Effect.suspend(() => method(...args)));
967
1191
  }
968
- return restored;
969
1192
  });
1193
+ };
1194
+ const assumeEntrypointClass = (entrypoint) => entrypoint;
1195
+ //#endregion
1196
+ //#region src/internal/WorkerContext.ts
1197
+ const causeError = (cause) => new Error(Cause.pretty(cause));
1198
+ const failureHandler = (cause, options) => (options?.onFailure?.(cause) ?? Effect.logError("WorkerContext.waitUntil failed", Cause.pretty(cause))).pipe(Effect.catchCause((handlerCause) => Effect.logError("WorkerContext.waitUntil failure handler failed", Cause.pretty(cause), Cause.pretty(handlerCause))));
1199
+ const fromExecutionContext = (ctx, runPromiseExit) => {
1200
+ const schedule = (effect, options, mode) => Effect.context().pipe(Effect.flatMap((context) => Effect.sync(() => {
1201
+ const runHandler = (cause) => runPromiseExit(Effect.scoped(Effect.provideContext(failureHandler(cause, options), context))).then((exit) => {
1202
+ if (Exit.isFailure(exit)) console.error("WorkerContext.waitUntil failure handler failed", Cause.pretty(exit.cause));
1203
+ });
1204
+ ctx.waitUntil(runPromiseExit(Effect.scoped(Effect.provideContext(effect, context))).then(async (exit) => {
1205
+ if (Exit.isSuccess(exit)) return;
1206
+ await runHandler(exit.cause);
1207
+ if (mode === "propagate") throw causeError(exit.cause);
1208
+ }));
1209
+ })));
970
1210
  return {
971
- serialize,
972
- deserialize,
973
- rehydrate,
974
- schema
1211
+ raw: ctx,
1212
+ waitUntil: (effect, options) => schedule(effect, options, options?.mode ?? "observe"),
1213
+ waitUntilPropagating: (effect, options) => schedule(effect, options, "propagate"),
1214
+ passThroughOnException: Effect.sync(() => ctx.passThroughOnException())
975
1215
  };
976
1216
  };
977
- /** Maps compact websocket lifecycle handler names to `DurableObject.make` options. */
978
- const handlers = (options) => ({
979
- webSocketMessage: options.message,
980
- webSocketClose: options.close,
981
- webSocketError: options.error
982
- });
983
1217
  //#endregion
984
- //#region src/DurableObjectState.ts
985
- var DurableObjectState_exports = /* @__PURE__ */ __exportAll({
986
- DurableObjectState: () => DurableObjectState,
987
- fromDurableObjectState: () => fromDurableObjectState
988
- });
989
- /**
990
- * Context tag for accessing the current Durable Object state service.
991
- */
992
- var DurableObjectState = class extends Context.Service()("effect-cf/DurableObjectState") {};
993
- /**
994
- * Wraps a native Cloudflare `DurableObjectState` as a {@link DurableObjectStateService}.
995
- */
996
- const fromDurableObjectState = (state) => ({
997
- raw: state,
998
- id: state.id,
999
- storage: fromDurableObjectStorage(state.storage),
1000
- waitUntil: (promise) => Effect.sync(() => state.waitUntil(promise)),
1001
- blockConcurrencyWhile: (effect) => Effect.context().pipe(Effect.flatMap((context) => Effect.promise(() => state.blockConcurrencyWhile(() => runPromiseExitPreservingTypedFailures(Effect.provideContext(effect, context))))), Effect.flatten),
1002
- blockConcurrencyWhileOrReset: (effect) => Effect.context().pipe(Effect.flatMap((context) => Effect.promise(() => state.blockConcurrencyWhile(() => Effect.runPromise(Effect.provideContext(effect, context)))))),
1003
- acceptWebSocket: (ws, tags) => Effect.sync(() => state.acceptWebSocket(ws.raw, tags)),
1004
- getWebSockets: (tag) => Effect.sync(() => state.getWebSockets(tag).map((socket) => fromWebSocket(socket))),
1005
- setWebSocketAutoResponse: (pair) => Effect.sync(() => state.setWebSocketAutoResponse(pair)),
1006
- getWebSocketAutoResponse: Effect.sync(() => state.getWebSocketAutoResponse()),
1007
- getWebSocketAutoResponseTimestamp: (ws) => Effect.sync(() => state.getWebSocketAutoResponseTimestamp(ws.raw)),
1008
- setHibernatableWebSocketEventTimeout: (timeoutMs) => Effect.sync(() => state.setHibernatableWebSocketEventTimeout(timeoutMs)),
1009
- getHibernatableWebSocketEventTimeout: Effect.sync(() => state.getHibernatableWebSocketEventTimeout()),
1010
- getTags: (ws) => Effect.sync(() => state.getTags(ws.raw)),
1011
- abort: (reason) => Effect.sync(() => state.abort(reason))
1218
+ //#region src/Worker.ts
1219
+ var Worker_exports = /* @__PURE__ */ __exportAll({
1220
+ ExecutionContext: () => ExecutionContext,
1221
+ NativeRequest: () => NativeRequest,
1222
+ Tag: () => Tag$7,
1223
+ WorkerContext: () => WorkerContext,
1224
+ implement: () => implement$4,
1225
+ isWebSocketUpgrade: () => isWebSocketUpgrade,
1226
+ make: () => make$6,
1227
+ makeFetchHandler: () => makeFetchHandler,
1228
+ method: () => method$2,
1229
+ renderHttpResponse: () => renderHttpResponse
1012
1230
  });
1013
- const runPromiseExitPreservingTypedFailures = async (effect) => {
1014
- const exit = await Effect.runPromiseExit(effect);
1015
- if (Exit.isFailure(exit) && (Cause.hasDies(exit.cause) || Cause.hasInterrupts(exit.cause))) throw Cause.squash(exit.cause);
1016
- return exit;
1231
+ var ExecutionContext = class extends Context.Service()("effect-cf/ExecutionContext") {};
1232
+ var WorkerContext = class extends Context.Service()("effect-cf/WorkerContext") {};
1233
+ var NativeRequest = class extends Context.Service()("effect-cf/NativeRequest") {};
1234
+ const isWebSocketUpgrade = (request) => request.headers.get("Upgrade")?.toLowerCase() === "websocket";
1235
+ const reservedMethodNames$2 = new Set([
1236
+ "constructor",
1237
+ "dup",
1238
+ "fetch",
1239
+ "connect",
1240
+ "queue",
1241
+ "scheduled",
1242
+ "tail",
1243
+ "tailStream",
1244
+ "test",
1245
+ "trace",
1246
+ "alarm",
1247
+ "webSocketMessage",
1248
+ "webSocketClose",
1249
+ "webSocketError"
1250
+ ]);
1251
+ const RunSymbol$1 = Symbol.for("effect-cf/Worker/run");
1252
+ const renderHttpResponse = (effect) => Effect.flatMap(effect, (response) => Effect.map(Effect.context(), (context) => HttpServerResponse.toWeb(response, { context })));
1253
+ const renderFetchSuccess = (effect) => Effect.flatMap(effect, (response) => response instanceof Response ? Effect.succeed(response) : Effect.map(Effect.context(), (context) => HttpServerResponse.toWeb(response, { context })));
1254
+ const isWorkerOptions = (options) => typeof options === "object" && options !== null && ("eventLayer" in options || "fetch" in options || "queue" in options || "rpc" in options);
1255
+ function make$6(layer, optionsOrFetch) {
1256
+ const options = isWorkerOptions(optionsOrFetch) ? optionsOrFetch : { fetch: optionsOrFetch };
1257
+ class EffectWorker extends WorkerEntrypoint {
1258
+ runtime;
1259
+ constructor(ctx, env) {
1260
+ super(ctx, env);
1261
+ let runWaitUntilEffect = () => Promise.reject(/* @__PURE__ */ new Error("WorkerContext runtime is not initialized"));
1262
+ const runtimeLayer = provideEntrypointServices(layer, Layer.mergeAll(Layer.succeed(ExecutionContext, ctx), ConfigProvider.layer(Effect.succeed(WorkerConfig.providerFromEnv(env))), Layer.succeed(WorkerContext, fromExecutionContext(ctx, (effect) => runWaitUntilEffect(effect))), Layer.succeed(WorkerEnvironment, env)));
1263
+ this.runtime = ManagedRuntime.make(runtimeLayer);
1264
+ runWaitUntilEffect = (effect) => this.runtime.runPromiseExit(effect);
1265
+ }
1266
+ [RunSymbol$1](effect, runOptions = {}) {
1267
+ const effectWithEventLayer = runOptions.eventLayer === false || options.eventLayer === void 0 ? effect : effect.pipe(Effect.provide(options.eventLayer, { local: true }));
1268
+ return this.runtime.runPromise(Effect.scoped(effectWithEventLayer));
1269
+ }
1270
+ fetch(request) {
1271
+ const fetchHandler = options.fetch;
1272
+ if (fetchHandler === void 0) return Promise.resolve(new Response("Not Found", { status: 404 }));
1273
+ const requestServices = Layer.mergeAll(Layer.succeed(NativeRequest, request), Layer.succeed(HttpServerRequest.HttpServerRequest, HttpServerRequest.fromWeb(request)));
1274
+ return this[RunSymbol$1](renderFetchSuccess(fetchHandler).pipe(Effect.provide(requestServices)));
1275
+ }
1276
+ queue(batch) {
1277
+ const queueHandler = options.queue;
1278
+ if (queueHandler === void 0) return Promise.resolve();
1279
+ const messages = batch.messages.map((message) => fromMessage(message, message.body));
1280
+ return this[RunSymbol$1](queueHandler(fromMessageBatch(batch, messages)));
1281
+ }
1282
+ }
1283
+ defineEntrypointRpcMethods("Worker", EffectWorker.prototype, options.rpc, reservedMethodNames$2, (self, effect) => self[RunSymbol$1](effect));
1284
+ return assumeEntrypointClass(EffectWorker);
1285
+ }
1286
+ const makeFetchHandler = (layer, options) => {
1287
+ const WorkerClass = make$6(layer, options);
1288
+ return { fetch: (request, env, ctx) => Promise.resolve(new WorkerClass(ctx, env).fetch(request)) };
1017
1289
  };
1290
+ const Tag$7 = Tag$8;
1291
+ const method$2 = method$3;
1292
+ const implement$4 = implement$5;
1018
1293
  //#endregion
1019
1294
  //#region src/DurableObjectNamespace.ts
1020
1295
  var DurableObjectNamespace_exports = /* @__PURE__ */ __exportAll({
@@ -1103,7 +1378,7 @@ const makeClient$4 = (definition) => {
1103
1378
  });
1104
1379
  };
1105
1380
  };
1106
- const layer$6 = (tag, definition) => layer$9(tag, definition.binding, (value) => isDurableObjectNamespaceClient(value), makeClient$4(definition), { expected: expectedDurableObjectNamespace });
1381
+ const layer$6 = (tag, definition) => layer$10(tag, definition.binding, (value) => isDurableObjectNamespaceClient(value), makeClient$4(definition), { expected: expectedDurableObjectNamespace });
1107
1382
  const makeDirectMethods = (rpcDefinition, helpers) => {
1108
1383
  const methods = {};
1109
1384
  if (rpcDefinition !== void 0) {
@@ -1277,10 +1552,11 @@ const make$4 = (layer, options = {}) => {
1277
1552
  const runtimeLayer = provideEntrypointServices(layer, Layer.mergeAll(Layer.succeed(DurableObjectState, fromDurableObjectState(state)), Layer.succeed(WorkerEnvironment, env)));
1278
1553
  this.runtime = ManagedRuntime.make(runtimeLayer);
1279
1554
  const initialize = options.initialize;
1280
- if (initialize !== void 0) state.waitUntil(this[RunSymbol](initialize));
1555
+ if (initialize !== void 0) state.waitUntil(this[RunSymbol](initialize, { eventLayer: false }));
1281
1556
  }
1282
- [RunSymbol](effect) {
1283
- return this.runtime.runPromise(Effect.scoped(effect));
1557
+ [RunSymbol](effect, runOptions = {}) {
1558
+ const effectWithEventLayer = runOptions.eventLayer === false || options.eventLayer === void 0 ? effect : effect.pipe(Effect.provide(options.eventLayer, { local: true }));
1559
+ return this.runtime.runPromise(Effect.scoped(effectWithEventLayer));
1284
1560
  }
1285
1561
  fetch(request) {
1286
1562
  const fetchHandler = options.fetch;
@@ -1879,7 +2155,7 @@ const makeClient$3 = (definition) => (images) => {
1879
2155
  unsafeRaw: Effect.succeed(images)
1880
2156
  };
1881
2157
  };
1882
- const layer$3 = (tag, definition) => layer$9(tag, definition.binding, isImagesBinding, makeClient$3(definition), { expected: expectedImagesBinding });
2158
+ const layer$3 = (tag, definition) => layer$10(tag, definition.binding, isImagesBinding, makeClient$3(definition), { expected: expectedImagesBinding });
1883
2159
  const make$3 = (id) => Tag$4()(id);
1884
2160
  const Tag$4 = () => (id) => {
1885
2161
  const tag = Context.Service()(id);
@@ -1974,7 +2250,7 @@ const makeClient$2 = (definition) => {
1974
2250
  unsafeRaw: Effect.succeed(kv)
1975
2251
  });
1976
2252
  };
1977
- const layer$2 = (tag, definition) => layer$9(tag, definition.binding, isKvNamespace, makeClient$2(definition), { expected: expectedKvNamespace });
2253
+ const layer$2 = (tag, definition) => layer$10(tag, definition.binding, isKvNamespace, makeClient$2(definition), { expected: expectedKvNamespace });
1978
2254
  const makeDefinition$1 = (id, definition) => {
1979
2255
  const kvDefinition = {
1980
2256
  id,
@@ -2091,7 +2367,7 @@ const makeClient$1 = (definition) => {
2091
2367
  };
2092
2368
  };
2093
2369
  };
2094
- const layer$1 = (tag, definition) => layer$9(tag, definition.binding, isR2Bucket, makeClient$1(definition), { expected: expectedR2Bucket });
2370
+ const layer$1 = (tag, definition) => layer$10(tag, definition.binding, isR2Bucket, makeClient$1(definition), { expected: expectedR2Bucket });
2095
2371
  const make$2 = (id) => Tag$2()(id);
2096
2372
  const Tag$2 = () => (id) => {
2097
2373
  const tag = Context.Service()(id);
@@ -2177,7 +2453,7 @@ const makeClient = (definition) => {
2177
2453
  unsafeRaw: Effect.succeed(workflow)
2178
2454
  });
2179
2455
  };
2180
- const layer = (tag, definition) => layer$9(tag, definition.binding, (value) => isWorkflow(value), makeClient(definition), { expected: expectedWorkflow });
2456
+ const layer = (tag, definition) => layer$10(tag, definition.binding, (value) => isWorkflow(value), makeClient(definition), { expected: expectedWorkflow });
2181
2457
  //#endregion
2182
2458
  //#region src/WorkflowDefinition.ts
2183
2459
  var WorkflowDefinition_exports = /* @__PURE__ */ __exportAll({
@@ -2198,7 +2474,7 @@ const make$1 = (id, definition) => Tag$1()(id, definition);
2198
2474
  const Tag$1 = () => (id, definition) => {
2199
2475
  const workflowDefinition = makeDefinition(id, definition);
2200
2476
  const tag = Context.Service()(id);
2201
- const layer$10 = (binding) => layer(tag, {
2477
+ const layer$11 = (binding) => layer(tag, {
2202
2478
  ...binding,
2203
2479
  payload: definition.payload,
2204
2480
  result: definition.result
@@ -2220,7 +2496,7 @@ const Tag$1 = () => (id, definition) => {
2220
2496
  payload: workflowDefinition.payload,
2221
2497
  result: workflowDefinition.result,
2222
2498
  make: workflowDefinition.make,
2223
- layer: layer$10,
2499
+ layer: layer$11,
2224
2500
  create,
2225
2501
  createBatch,
2226
2502
  get,
@@ -2311,4 +2587,4 @@ const waitForEvent = (name, options) => Effect.flatMap(WorkflowStep$1, (workflow
2311
2587
  const Tag = Tag$1;
2312
2588
  const implement = implement$1;
2313
2589
  //#endregion
2314
- export { Binding_exports as Binding, D1_exports as D1, DurableObject_exports as DurableObject, DurableObjectAlarm_exports as DurableObjectAlarm, DurableObjectDefinition_exports as DurableObjectDefinition, DurableObjectNamespace_exports as DurableObjectNamespace, DurableObjectRpcWebSocket_exports as DurableObjectRpcWebSocket, DurableObjectSqlite_exports as DurableObjectSqlite, DurableObjectState_exports as DurableObjectState, DurableObjectStorage_exports as DurableObjectStorage, DurableObjectWebSocket_exports as DurableObjectWebSocket, Hyperdrive_exports as Hyperdrive, Images_exports as Images, Kv_exports as Kv, Queue_exports as Queue, QueueBinding_exports as QueueBinding, QueueDefinition_exports as QueueDefinition, R2_exports as R2, Rpc_exports as Rpc, RpcDefinition_exports as RpcDefinition, ServiceBinding_exports as ServiceBinding, Worker_exports as Worker, WorkerConfig, WorkerDefinition_exports as WorkerDefinition, WorkerEnvironment, Workflow_exports as Workflow, WorkflowBinding_exports as WorkflowBinding, WorkflowDefinition_exports as WorkflowDefinition };
2590
+ export { Binding_exports as Binding, CloudflareOtlp_exports as CloudflareOtlp, D1_exports as D1, DurableObject_exports as DurableObject, DurableObjectAlarm_exports as DurableObjectAlarm, DurableObjectDefinition_exports as DurableObjectDefinition, DurableObjectNamespace_exports as DurableObjectNamespace, DurableObjectRpcWebSocket_exports as DurableObjectRpcWebSocket, DurableObjectSqlite_exports as DurableObjectSqlite, DurableObjectState_exports as DurableObjectState, DurableObjectStorage_exports as DurableObjectStorage, DurableObjectWebSocket_exports as DurableObjectWebSocket, Hyperdrive_exports as Hyperdrive, Images_exports as Images, Kv_exports as Kv, Queue_exports as Queue, QueueBinding_exports as QueueBinding, QueueDefinition_exports as QueueDefinition, R2_exports as R2, Rpc_exports as Rpc, RpcDefinition_exports as RpcDefinition, ServiceBinding_exports as ServiceBinding, Worker_exports as Worker, WorkerConfig, WorkerDefinition_exports as WorkerDefinition, WorkerEnvironment, Workflow_exports as Workflow, WorkflowBinding_exports as WorkflowBinding, WorkflowDefinition_exports as WorkflowDefinition };