effect-cf 0.18.0 → 0.20.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,5 +1,4 @@
1
- import { t as __exportAll } from "./chunk-CfYAbeIz.mjs";
2
- import { a as WorkerConfig, i as layer$19, n as Binding_exports, o as WorkerEnvironment, r as Service$2, t as Hyperdrive_exports } from "./Hyperdrive-89hg_Fck.mjs";
1
+ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
3
2
  import { Cause, Clock, Config, ConfigProvider, Context, Data, DateTime, Duration, Effect, Exit, Layer, ManagedRuntime, Option, Queue, Result, Schema } from "effect";
4
3
  import { FetchHttpClient, HttpClient, HttpClientRequest, HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
5
4
  import { OtlpLogger, OtlpMetrics, OtlpSerialization, OtlpTracer } from "effect/unstable/observability";
@@ -9,15 +8,140 @@ import * as RpcMessage from "effect/unstable/rpc/RpcMessage";
9
8
  import * as RpcSerialization from "effect/unstable/rpc/RpcSerialization";
10
9
  import * as RpcServer from "effect/unstable/rpc/RpcServer";
11
10
  import { SqliteClient } from "@effect/sql-sqlite-do";
11
+ //#region src/Environment.ts
12
+ /**
13
+ * Context service for reading worker bindings from the current `env` object.
14
+ */
15
+ var WorkerEnvironment = class extends Context.Service()("effect-cf/WorkerEnvironment") {};
16
+ let WorkerConfig;
17
+ (function(_WorkerConfig) {
18
+ _WorkerConfig.string = (name) => Config.string(name);
19
+ _WorkerConfig.redacted = (name) => Config.redacted(name);
20
+ _WorkerConfig.number = (name) => Config.number(name);
21
+ _WorkerConfig.integer = (name) => Config.int(name);
22
+ _WorkerConfig.boolean = (name) => Config.boolean(name);
23
+ const providerFromEnv = _WorkerConfig.providerFromEnv = (env) => ConfigProvider.fromUnknown(env);
24
+ const providerWith = _WorkerConfig.providerWith = (makeProvider) => Effect.map(WorkerEnvironment, makeProvider);
25
+ const provider = _WorkerConfig.provider = providerWith(providerFromEnv);
26
+ _WorkerConfig.layer = _WorkerConfig.providerLayer = ConfigProvider.layer(provider);
27
+ _WorkerConfig.layerWith = (makeProvider) => ConfigProvider.layer(providerWith(makeProvider));
28
+ })(WorkerConfig || (WorkerConfig = {}));
29
+ //#endregion
30
+ //#region src/Binding.ts
31
+ var Binding_exports = /* @__PURE__ */ __exportAll({
32
+ BindingNotFoundError: () => BindingNotFoundError,
33
+ BindingValidationError: () => BindingValidationError,
34
+ Service: () => Service$2,
35
+ TypeId: () => TypeId$3,
36
+ layer: () => layer$20
37
+ });
38
+ /** Internal type id marker used by binding helper services. */
39
+ const TypeId$3 = "effect-cf/Binding";
40
+ /** Error raised when a configured binding does not exist on `env`. */
41
+ var BindingNotFoundError = class extends Data.TaggedError("BindingNotFoundError") {};
42
+ /** Error raised when a binding exists but does not match the expected shape. */
43
+ var BindingValidationError = class extends Data.TaggedError("BindingValidationError") {};
44
+ const defaultExpected = "Cloudflare binding resource";
45
+ const isPropertyTarget$1 = (value) => (typeof value === "object" || typeof value === "function") && value !== null;
46
+ const getObjectName = (value) => {
47
+ const tag = (() => {
48
+ try {
49
+ return Object.prototype.toString.call(value).slice(8, -1);
50
+ } catch {
51
+ return typeof value;
52
+ }
53
+ })();
54
+ const constructorName = (() => {
55
+ try {
56
+ return "constructor" in value && typeof value.constructor === "function" && typeof value.constructor.name === "string" ? value.constructor.name : void 0;
57
+ } catch {
58
+ return;
59
+ }
60
+ })();
61
+ if (tag !== "Object") return tag;
62
+ if (constructorName !== void 0 && constructorName !== "" && constructorName !== "Object") return constructorName;
63
+ return tag;
64
+ };
65
+ const propertyNames = (value) => {
66
+ const names = /* @__PURE__ */ new Set();
67
+ for (const target of [value, Object.getPrototypeOf(value)]) {
68
+ if (target === null || target === Object.prototype || target === Function.prototype) continue;
69
+ try {
70
+ for (const name of Object.getOwnPropertyNames(target)) names.add(name);
71
+ } catch {
72
+ continue;
73
+ }
74
+ }
75
+ return [...names].filter((name) => name !== "constructor").sort();
76
+ };
77
+ const isMethod = (value, name) => {
78
+ try {
79
+ return typeof Reflect.get(value, name) === "function";
80
+ } catch {
81
+ return false;
82
+ }
83
+ };
84
+ const describeActual = (value) => {
85
+ if (value === null) return "null";
86
+ if (typeof value !== "object" && typeof value !== "function") return typeof value;
87
+ const names = propertyNames(value);
88
+ const methods = names.filter((name) => isMethod(value, name));
89
+ const properties = names.filter((name) => !methods.includes(name));
90
+ const details = [methods.length > 0 ? `methods ${methods.join(", ")}` : void 0, properties.length > 0 ? `properties ${properties.join(", ")}` : void 0].filter((detail) => detail !== void 0);
91
+ if (details.length === 0) return getObjectName(value);
92
+ return `${getObjectName(value)} with ${details.join("; ")}`;
93
+ };
94
+ const getBinding = (env, binding, isResource, options) => Effect.gen(function* () {
95
+ if (!isPropertyTarget$1(env)) {
96
+ const actual = describeActual(env);
97
+ return yield* Effect.fail(new BindingValidationError({
98
+ binding,
99
+ expected: "WorkerEnvironment object",
100
+ actual,
101
+ message: `Cloudflare binding "${binding}" failed validation. Expected WorkerEnvironment object; got ${actual}`
102
+ }));
103
+ }
104
+ const resource = Reflect.get(env, binding);
105
+ if (resource === void 0) return yield* Effect.fail(new BindingNotFoundError({
106
+ binding,
107
+ message: `Cloudflare binding "${binding}" was not found in WorkerEnvironment`
108
+ }));
109
+ if (!isResource(resource)) {
110
+ const expected = options?.expected ?? defaultExpected;
111
+ const actual = describeActual(resource);
112
+ return yield* Effect.fail(new BindingValidationError({
113
+ binding,
114
+ expected,
115
+ actual,
116
+ message: `Cloudflare binding "${binding}" failed validation. Expected ${expected}; got ${actual}`
117
+ }));
118
+ }
119
+ return resource;
120
+ });
121
+ const layer$20 = (tag, binding, isResource, wrap, options) => Layer.effect(tag, Effect.gen(function* () {
122
+ const env = yield* WorkerEnvironment;
123
+ const resource = yield* getBinding(env, binding, isResource, options);
124
+ return wrap === void 0 ? resource : wrap(resource);
125
+ }));
126
+ const Service$2 = () => (id, binding, isResource, wrap, options) => {
127
+ const tag = Context.Service()(id);
128
+ const serviceLayer = layer$20(tag, binding, isResource, wrap, options);
129
+ return Object.assign(tag, {
130
+ [TypeId$3]: TypeId$3,
131
+ binding,
132
+ layer: serviceLayer
133
+ });
134
+ };
135
+ //#endregion
12
136
  //#region src/WorkersAi.ts
13
137
  var WorkersAi_exports = /* @__PURE__ */ __exportAll({
14
- Tag: () => Tag$17,
138
+ Tag: () => Tag$18,
15
139
  WorkersAiOperationError: () => WorkersAiOperationError,
16
140
  embeddingResponse: () => embeddingResponse,
17
141
  isWorkersAiBinding: () => isWorkersAiBinding,
18
- layer: () => layer$18,
19
- make: () => make$17,
20
- makeClient: () => makeClient$14
142
+ layer: () => layer$19,
143
+ make: () => make$18,
144
+ makeClient: () => makeClient$15
21
145
  });
22
146
  const expectedWorkersAiBinding = "Workers AI binding with run(), gateway(), and models()";
23
147
  /** Error raised when a Workers AI operation fails. */
@@ -41,7 +165,7 @@ const embeddingResponse = (value) => ({
41
165
  data: value.data ?? [],
42
166
  shape: value.shape ?? []
43
167
  });
44
- const makeClient$14 = (definition) => (ai) => {
168
+ const makeClient$15 = (definition) => (ai) => {
45
169
  const run = ((model, input, options) => tryWorkersAiPromise(definition.binding, "run", () => ai.run(model, input, options)));
46
170
  return {
47
171
  definition,
@@ -53,11 +177,11 @@ const makeClient$14 = (definition) => (ai) => {
53
177
  unsafeRaw: Effect.succeed(ai)
54
178
  };
55
179
  };
56
- const layer$18 = (tag, definition) => layer$19(tag, definition.binding, (value) => isWorkersAiBinding(value), makeClient$14(definition), { expected: expectedWorkersAiBinding });
57
- const make$17 = (id) => Tag$17()(id);
58
- const Tag$17 = () => (id) => {
180
+ const layer$19 = (tag, definition) => layer$20(tag, definition.binding, (value) => isWorkersAiBinding(value), makeClient$15(definition), { expected: expectedWorkersAiBinding });
181
+ const make$18 = (id) => Tag$18()(id);
182
+ const Tag$18 = () => (id) => {
59
183
  const tag = Context.Service()(id);
60
- const makeLayer = (definition) => layer$18(tag, definition);
184
+ const makeLayer = (definition) => layer$19(tag, definition);
61
185
  return Object.assign(tag, {
62
186
  id,
63
187
  layer: makeLayer
@@ -67,11 +191,11 @@ const Tag$17 = () => (id) => {
67
191
  //#region src/AiGateway.ts
68
192
  var AiGateway_exports = /* @__PURE__ */ __exportAll({
69
193
  AiGatewayOperationError: () => AiGatewayOperationError,
70
- Tag: () => Tag$16,
194
+ Tag: () => Tag$17,
71
195
  isAiGatewayBinding: () => isAiGatewayBinding,
72
- layer: () => layer$17,
73
- make: () => make$16,
74
- makeClient: () => makeClient$13,
196
+ layer: () => layer$18,
197
+ make: () => make$17,
198
+ makeClient: () => makeClient$14,
75
199
  makeClientFromAi: () => makeClientFromAi,
76
200
  makeHttpClient: () => makeHttpClient
77
201
  });
@@ -98,7 +222,7 @@ const providerUrl = (baseUrl, path = "") => {
98
222
  };
99
223
  const gatewayUrl = (definition) => `https://gateway.ai.cloudflare.com/v1/${definition.accountId}/${definition.gatewayId}/`;
100
224
  const isAiGatewayBinding = (value) => isWorkersAiBinding(value);
101
- const makeClient$13 = (definition, gateway) => ({
225
+ const makeClient$14 = (definition, gateway) => ({
102
226
  definition,
103
227
  run: (data, options) => tryAiGatewayPromise(definition.binding, "run", () => gateway.run(Array.isArray(data) ? [...data] : data, options)),
104
228
  getUrl: (provider) => tryAiGatewayPromise(definition.binding, "getUrl", () => gateway.getUrl(provider)),
@@ -115,11 +239,11 @@ const makeClientFromAi = (definition, ai) => {
115
239
  const withGateway = (operation) => gateway.pipe(Effect.flatMap(operation));
116
240
  return {
117
241
  definition,
118
- run: (data, options) => withGateway((raw) => makeClient$13(definition, raw).run(data, options)),
119
- getUrl: (provider) => withGateway((raw) => makeClient$13(definition, raw).getUrl(provider)),
120
- fetch: (options) => withGateway((raw) => makeClient$13(definition, raw).fetch(options)),
121
- patchLog: (logId, data) => withGateway((raw) => makeClient$13(definition, raw).patchLog(logId, data)),
122
- getLog: (logId) => withGateway((raw) => makeClient$13(definition, raw).getLog(logId)),
242
+ run: (data, options) => withGateway((raw) => makeClient$14(definition, raw).run(data, options)),
243
+ getUrl: (provider) => withGateway((raw) => makeClient$14(definition, raw).getUrl(provider)),
244
+ fetch: (options) => withGateway((raw) => makeClient$14(definition, raw).fetch(options)),
245
+ patchLog: (logId, data) => withGateway((raw) => makeClient$14(definition, raw).patchLog(logId, data)),
246
+ getLog: (logId) => withGateway((raw) => makeClient$14(definition, raw).getLog(logId)),
123
247
  unsafeRaw: gateway
124
248
  };
125
249
  };
@@ -159,11 +283,11 @@ const makeHttpClient = (definition, request = fetch) => {
159
283
  unsafeRaw: Effect.fail(aiGatewayError(binding, "unsafeRaw", /* @__PURE__ */ new TypeError("HTTP AI Gateway clients have no raw binding")))
160
284
  };
161
285
  };
162
- const layer$17 = (tag, definition) => layer$19(tag, definition.binding, isAiGatewayBinding, (ai) => makeClientFromAi(definition, ai), { expected: expectedAiGatewayBinding });
163
- const make$16 = (id) => Tag$16()(id);
164
- const Tag$16 = () => (id) => {
286
+ const layer$18 = (tag, definition) => layer$20(tag, definition.binding, isAiGatewayBinding, (ai) => makeClientFromAi(definition, ai), { expected: expectedAiGatewayBinding });
287
+ const make$17 = (id) => Tag$17()(id);
288
+ const Tag$17 = () => (id) => {
165
289
  const tag = Context.Service()(id);
166
- const makeLayer = (definition) => layer$17(tag, definition);
290
+ const makeLayer = (definition) => layer$18(tag, definition);
167
291
  return Object.assign(tag, {
168
292
  id,
169
293
  layer: makeLayer
@@ -178,11 +302,11 @@ var AnalyticsEngine_exports = /* @__PURE__ */ __exportAll({
178
302
  AnalyticsEngineQueryError: () => AnalyticsEngineQueryError,
179
303
  AnalyticsEngineWriteValidationError: () => AnalyticsEngineWriteValidationError,
180
304
  QueryTag: () => QueryTag,
181
- Tag: () => Tag$15,
305
+ Tag: () => Tag$16,
182
306
  isAnalyticsEngineDataset: () => isAnalyticsEngineDataset,
183
- layer: () => layer$16,
184
- make: () => make$15,
185
- makeClient: () => makeClient$12,
307
+ layer: () => layer$17,
308
+ make: () => make$16,
309
+ makeClient: () => makeClient$13,
186
310
  makeQuery: () => makeQuery,
187
311
  makeQueryClient: () => makeQueryClient,
188
312
  queryConfig: () => queryConfig,
@@ -194,7 +318,7 @@ var AnalyticsEngine_exports = /* @__PURE__ */ __exportAll({
194
318
  });
195
319
  const expectedAnalyticsEngineDataset = "Analytics Engine dataset binding with writeDataPoint()";
196
320
  const defaultQueryApiBaseUrl = "https://api.cloudflare.com/client/v4";
197
- const textEncoder = new TextEncoder();
321
+ const textEncoder$1 = new TextEncoder();
198
322
  const writeLimits = {
199
323
  maxBlobs: 20,
200
324
  maxDoubles: 20,
@@ -260,9 +384,9 @@ const resolveWritePolicy = (defaults, options) => ({
260
384
  });
261
385
  const fieldPath = (prefix, field) => prefix === "" ? field : `${prefix}.${field}`;
262
386
  const indexedPath = (prefix, field, index) => `${fieldPath(prefix, field)}[${index}]`;
263
- const byteLength = (value) => {
387
+ const byteLength$1 = (value) => {
264
388
  if (value === null) return 0;
265
- return typeof value === "string" ? textEncoder.encode(value).byteLength : value.byteLength;
389
+ return typeof value === "string" ? textEncoder$1.encode(value).byteLength : value.byteLength;
266
390
  };
267
391
  const lengthViolation = (path, label, actual, limit) => ({
268
392
  path,
@@ -276,11 +400,11 @@ const validateDataPointLimits = (dataPoint, pathPrefix = "") => {
276
400
  if (dataPoint.doubles !== void 0 && dataPoint.doubles.length > writeLimits.maxDoubles) violations.push(lengthViolation(fieldPath(pathPrefix, "doubles"), "doubles", dataPoint.doubles.length, writeLimits.maxDoubles));
277
401
  if (dataPoint.indexes !== void 0 && dataPoint.indexes.length > writeLimits.maxIndexes) violations.push(lengthViolation(fieldPath(pathPrefix, "indexes"), "indexes", dataPoint.indexes.length, writeLimits.maxIndexes));
278
402
  if (dataPoint.blobs !== void 0) {
279
- const blobBytes = dataPoint.blobs.reduce((total, value) => total + byteLength(value), 0);
403
+ const blobBytes = dataPoint.blobs.reduce((total, value) => total + byteLength$1(value), 0);
280
404
  if (blobBytes > writeLimits.maxBlobBytes) violations.push(lengthViolation(fieldPath(pathPrefix, "blobs"), "blob bytes", blobBytes, writeLimits.maxBlobBytes));
281
405
  }
282
406
  if (dataPoint.indexes !== void 0) for (let index = 0; index < dataPoint.indexes.length; index++) {
283
- const indexBytes = byteLength(dataPoint.indexes[index] ?? null);
407
+ const indexBytes = byteLength$1(dataPoint.indexes[index] ?? null);
284
408
  if (indexBytes > writeLimits.maxIndexBytes) violations.push(lengthViolation(indexedPath(pathPrefix, "indexes", index), "index bytes", indexBytes, writeLimits.maxIndexBytes));
285
409
  }
286
410
  return violations;
@@ -295,7 +419,8 @@ const toAnalyticsEngineDataPoint = (dataPoint) => ({
295
419
  ...dataPoint.blobs === void 0 ? {} : { blobs: [...dataPoint.blobs] }
296
420
  });
297
421
  const validateDataPoint = (binding, operation, dataPoint, pathPrefix = "") => Effect.gen(function* () {
298
- const validated = toAnalyticsEngineDataPoint(yield* decodeDataPoint(dataPoint).pipe(Effect.mapError((cause) => analyticsEngineWriteValidationError(binding, operation, [schemaViolation(pathPrefix, cause)], cause))));
422
+ const decoded = yield* decodeDataPoint(dataPoint).pipe(Effect.mapError((cause) => analyticsEngineWriteValidationError(binding, operation, [schemaViolation(pathPrefix, cause)], cause)));
423
+ const validated = toAnalyticsEngineDataPoint(decoded);
299
424
  const violations = validateDataPointLimits(validated, pathPrefix);
300
425
  if (violations.length > 0) return yield* Effect.fail(analyticsEngineWriteValidationError(binding, operation, violations));
301
426
  return validated;
@@ -347,7 +472,8 @@ const executeQueryRequest = (definition, httpClient, sql, options) => Effect.gen
347
472
  const makeQueryClientWith = (definition, httpClient) => {
348
473
  const raw = (sql, options) => executeQueryRequest(definition, httpClient, sql, options);
349
474
  const query = (sql, options) => Effect.gen(function* () {
350
- return yield* decodeQueryResponse(yield* (yield* raw(sql, options)).json.pipe(Effect.catch((cause) => Effect.fail(analyticsEngineQueryError(definition, "json", "Failed to read Analytics Engine SQL API JSON response body", { cause })))));
475
+ const json = yield* (yield* raw(sql, options)).json.pipe(Effect.catch((cause) => Effect.fail(analyticsEngineQueryError(definition, "json", "Failed to read Analytics Engine SQL API JSON response body", { cause }))));
476
+ return yield* decodeQueryResponse(json);
351
477
  });
352
478
  const queryResult = (row, sql, options) => Effect.gen(function* () {
353
479
  const result = yield* query(sql, options);
@@ -375,7 +501,7 @@ const isAnalyticsEngineDataset = (value) => {
375
501
  if (typeof value !== "object" || value === null) return false;
376
502
  return typeof Reflect.get(value, "writeDataPoint") === "function";
377
503
  };
378
- const makeClient$12 = (definition, defaults) => (dataset) => {
504
+ const makeClient$13 = (definition, defaults) => (dataset) => {
379
505
  const writeDataPoint = (dataPoint, options) => {
380
506
  const policy = resolveWritePolicy(defaults, options);
381
507
  return validateOptionalDataPoint(definition.binding, "writeDataPoint", dataPoint).pipe(Effect.matchEffect({
@@ -407,15 +533,16 @@ const queryConfig = (options) => Config.all({
407
533
  const queryLayer = (tag, definition) => Layer.effect(tag, makeQueryClient(definition));
408
534
  const queryFetchLayer = (tag, definition) => queryLayer(tag, definition).pipe(Layer.provide(FetchHttpClient.layer));
409
535
  const queryLayerConfig = (tag, config = queryConfig()) => Layer.effect(tag, Effect.gen(function* () {
410
- return yield* makeQueryClient(yield* config);
536
+ const definition = yield* config;
537
+ return yield* makeQueryClient(definition);
411
538
  }));
412
539
  const queryFetchLayerConfig = (tag, config = queryConfig()) => queryLayerConfig(tag, config).pipe(Layer.provide(FetchHttpClient.layer));
413
- const layer$16 = (tag, definition) => layer$19(tag, definition.binding, isAnalyticsEngineDataset, makeClient$12(definition, definition.write), { expected: expectedAnalyticsEngineDataset });
414
- const make$15 = (id) => Tag$15()(id);
540
+ const layer$17 = (tag, definition) => layer$20(tag, definition.binding, isAnalyticsEngineDataset, makeClient$13(definition, definition.write), { expected: expectedAnalyticsEngineDataset });
541
+ const make$16 = (id) => Tag$16()(id);
415
542
  const makeQuery = (id) => QueryTag()(id);
416
- const Tag$15 = () => (id) => {
543
+ const Tag$16 = () => (id) => {
417
544
  const tag = Context.Service()(id);
418
- const makeLayer = (definition) => layer$16(tag, definition);
545
+ const makeLayer = (definition) => layer$17(tag, definition);
419
546
  return Object.assign(tag, {
420
547
  id,
421
548
  layer: makeLayer
@@ -439,11 +566,11 @@ const QueryTag = () => (id) => {
439
566
  //#region src/BrowserRendering.ts
440
567
  var BrowserRendering_exports = /* @__PURE__ */ __exportAll({
441
568
  BrowserRenderingOperationError: () => BrowserRenderingOperationError,
442
- Tag: () => Tag$14,
569
+ Tag: () => Tag$15,
443
570
  isBrowserRenderingBinding: () => isBrowserRenderingBinding,
444
- layer: () => layer$15,
445
- make: () => make$14,
446
- makeClient: () => makeClient$11
571
+ layer: () => layer$16,
572
+ make: () => make$15,
573
+ makeClient: () => makeClient$12
447
574
  });
448
575
  const expectedBrowserRenderingBinding = "Browser Rendering binding resource";
449
576
  /** Error raised when a Browser Rendering operation fails. */
@@ -480,17 +607,17 @@ const wrapBrowser = (binding, browser) => ({
480
607
  disconnect: browser.disconnect === void 0 ? Effect.void : tryBrowserRenderingSync(binding, "disconnect", () => browser.disconnect())
481
608
  });
482
609
  const isBrowserRenderingBinding = (value) => (typeof value === "object" || typeof value === "function") && value !== null;
483
- const makeClient$11 = (definition) => (binding) => ({
610
+ const makeClient$12 = (definition) => (binding) => ({
484
611
  definition,
485
612
  launchWith: (launch, options) => tryBrowserRenderingPromise(definition.binding, "launch", () => launch(binding, options)).pipe(Effect.map((browser) => wrapBrowser(definition.binding, browser))),
486
613
  connectWith: (connect, options) => tryBrowserRenderingPromise(definition.binding, "connect", () => connect(binding, options)).pipe(Effect.map((browser) => wrapBrowser(definition.binding, browser))),
487
614
  unsafeRaw: Effect.succeed(binding)
488
615
  });
489
- const layer$15 = (tag, definition) => layer$19(tag, definition.binding, isBrowserRenderingBinding, makeClient$11(definition), { expected: expectedBrowserRenderingBinding });
490
- const make$14 = (id) => Tag$14()(id);
491
- const Tag$14 = () => (id) => {
616
+ const layer$16 = (tag, definition) => layer$20(tag, definition.binding, isBrowserRenderingBinding, makeClient$12(definition), { expected: expectedBrowserRenderingBinding });
617
+ const make$15 = (id) => Tag$15()(id);
618
+ const Tag$15 = () => (id) => {
492
619
  const tag = Context.Service()(id);
493
- const makeLayer = (definition) => layer$15(tag, definition);
620
+ const makeLayer = (definition) => layer$16(tag, definition);
494
621
  return Object.assign(tag, {
495
622
  id,
496
623
  layer: makeLayer
@@ -501,10 +628,10 @@ const Tag$14 = () => (id) => {
501
628
  var Cache_exports = /* @__PURE__ */ __exportAll({
502
629
  CacheOperationError: () => CacheOperationError,
503
630
  CacheStorage: () => CacheStorage,
504
- layer: () => layer$14,
631
+ layer: () => layer$15,
505
632
  layerFrom: () => layerFrom,
506
633
  makeCacheClient: () => makeCacheClient,
507
- makeClient: () => makeClient$10
634
+ makeClient: () => makeClient$11
508
635
  });
509
636
  /** Error raised when a Cloudflare Cache API operation fails. */
510
637
  var CacheOperationError = class extends Data.TaggedError("CacheOperationError") {};
@@ -528,15 +655,15 @@ const makeCacheClient = (cache, name = "default") => ({
528
655
  unsafeRaw: Effect.succeed(cache)
529
656
  });
530
657
  /** Wraps a native Cloudflare `CacheStorage` instance. */
531
- const makeClient$10 = (storage) => ({
658
+ const makeClient$11 = (storage) => ({
532
659
  default: makeCacheClient(storage.default),
533
660
  open: (name) => tryCachePromise(name, "open", () => storage.open(name)).pipe(Effect.map((cache) => makeCacheClient(cache, name))),
534
661
  unsafeRaw: Effect.succeed(storage)
535
662
  });
536
663
  /** Provides Cache API services from an explicit native `CacheStorage` instance. */
537
- const layerFrom = (storage) => Layer.succeed(CacheStorage, makeClient$10(storage));
664
+ const layerFrom = (storage) => Layer.succeed(CacheStorage, makeClient$11(storage));
538
665
  /** Provides Cache API services from Cloudflare's global `caches` object. */
539
- const layer$14 = Layer.sync(CacheStorage, () => makeClient$10(caches));
666
+ const layer$15 = Layer.sync(CacheStorage, () => makeClient$11(caches));
540
667
  //#endregion
541
668
  //#region src/DurableObjectStorage.ts
542
669
  var DurableObjectStorage_exports = /* @__PURE__ */ __exportAll({
@@ -745,7 +872,7 @@ const attachment = (schema) => {
745
872
  })), Effect.flatMap((encoded) => socket.serializeAttachment(encoded)));
746
873
  const deserialize = (socket) => Effect.gen(function* () {
747
874
  const value = yield* socket.deserializeAttachment;
748
- if (value == null) return Option.none();
875
+ if (value === null || value === void 0) return Option.none();
749
876
  return Option.some(yield* Schema.decodeUnknownEffect(schema)(value).pipe(Effect.mapError((cause) => new DurableWebSocketAttachmentError({
750
877
  operation: "deserialize",
751
878
  cause
@@ -830,7 +957,7 @@ const runPromiseExitPreservingTypedFailures = async (effect) => {
830
957
  //#region src/CloudflareOtlp.ts
831
958
  var CloudflareOtlp_exports = /* @__PURE__ */ __exportAll({
832
959
  durableObjectLayer: () => durableObjectLayer,
833
- layer: () => layer$13,
960
+ layer: () => layer$14,
834
961
  layerJson: () => layerJson,
835
962
  layerProtobuf: () => layerProtobuf,
836
963
  workerLayer: () => workerLayer
@@ -857,8 +984,8 @@ const makeResource = (options, runtimeAttributes) => ({
857
984
  }
858
985
  });
859
986
  const serializationLayer = (serialization) => serialization === "json" ? OtlpSerialization.layerJson : OtlpSerialization.layerProtobuf;
987
+ /** Merges a non-empty signal layer list; callers handle the empty case. */
860
988
  const mergeSignalLayers = (layers) => {
861
- if (layers.length === 0) return Layer.empty;
862
989
  let merged = layers[0];
863
990
  for (let index = 1; index < layers.length; index++) merged = Layer.mergeAll(merged, layers[index]);
864
991
  return merged;
@@ -882,6 +1009,7 @@ const makeLayer = (options = {}, runtimeAttributes = {}) => {
882
1009
  resource,
883
1010
  headers: options.headers
884
1011
  }));
1012
+ if (layers.length === 0) return Layer.empty;
885
1013
  return mergeSignalLayers(layers).pipe(Layer.provide(cloudflareConfigProviderLayer), Layer.provide(serializationLayer(options.serialization)), Layer.provide(FetchHttpClient.layer));
886
1014
  };
887
1015
  /**
@@ -892,14 +1020,14 @@ const makeLayer = (options = {}, runtimeAttributes = {}) => {
892
1020
  * installed as the primary `ConfigProvider`; outside Cloudflare, the ambient
893
1021
  * Effect `ConfigProvider` remains the fallback.
894
1022
  */
895
- const layer$13 = (options = {}) => makeLayer(options);
1023
+ const layer$14 = (options = {}) => makeLayer(options);
896
1024
  /** Base OTLP telemetry layer forced to JSON serialization. */
897
- const layerJson = (options = {}) => layer$13({
1025
+ const layerJson = (options = {}) => layer$14({
898
1026
  ...options,
899
1027
  serialization: "json"
900
1028
  });
901
1029
  /** Base OTLP telemetry layer forced to protobuf serialization. */
902
- const layerProtobuf = (options = {}) => layer$13({
1030
+ const layerProtobuf = (options = {}) => layer$14({
903
1031
  ...options,
904
1032
  serialization: "protobuf"
905
1033
  });
@@ -931,11 +1059,11 @@ var ContainerNamespace_exports = /* @__PURE__ */ __exportAll({
931
1059
  ContainerNamespace: () => ContainerNamespace,
932
1060
  ContainerOperationError: () => ContainerOperationError,
933
1061
  ContainerState: () => ContainerState,
934
- Tag: () => Tag$13,
1062
+ Tag: () => Tag$14,
935
1063
  isContainerNamespaceResource: () => isContainerNamespaceResource,
936
- layer: () => layer$12,
937
- make: () => make$13,
938
- makeClient: () => makeClient$9
1064
+ layer: () => layer$13,
1065
+ make: () => make$14,
1066
+ makeClient: () => makeClient$10
939
1067
  });
940
1068
  const expectedContainerNamespace = "Container namespace binding with getByName()";
941
1069
  /** Serializable state reported by a Cloudflare Container instance. */
@@ -978,7 +1106,7 @@ const makeInstanceClient = (definition, instance, stub) => ({
978
1106
  destroy: tryContainerPromise(definition, instance, "destroy", () => stub.destroy())
979
1107
  });
980
1108
  const isContainerNamespaceResource = (value) => typeof value === "object" && value !== null && typeof Reflect.get(value, "getByName") === "function";
981
- const makeClient$9 = (definition) => (namespace) => {
1109
+ const makeClient$10 = (definition) => (namespace) => {
982
1110
  const getByName = (name, options) => Effect.try({
983
1111
  try: () => makeInstanceClient(definition, name, namespace.getByName(name, options)),
984
1112
  catch: (cause) => new ContainerOperationError({
@@ -1007,12 +1135,12 @@ const makeClient$9 = (definition) => (namespace) => {
1007
1135
  unsafeRaw: Effect.succeed(namespace)
1008
1136
  };
1009
1137
  };
1010
- const layer$12 = (tag, definition) => layer$19(tag, definition.binding, isContainerNamespaceResource, makeClient$9(definition), { expected: expectedContainerNamespace });
1011
- const make$13 = (id) => Tag$13()(id);
1138
+ const layer$13 = (tag, definition) => layer$20(tag, definition.binding, isContainerNamespaceResource, makeClient$10(definition), { expected: expectedContainerNamespace });
1139
+ const make$14 = (id) => Tag$14()(id);
1012
1140
  /** Creates a typed Effect service for a Cloudflare Container namespace. */
1013
- const Tag$13 = () => (id) => {
1141
+ const Tag$14 = () => (id) => {
1014
1142
  const tag = Context.Service()(id);
1015
- const makeLayer = (definition) => layer$12(tag, definition);
1143
+ const makeLayer = (definition) => layer$13(tag, definition);
1016
1144
  const getByName = (name, options) => Effect.gen(function* () {
1017
1145
  return yield* (yield* tag).getByName(name, options);
1018
1146
  });
@@ -1036,12 +1164,12 @@ const Tag$13 = () => (id) => {
1036
1164
  unsafeRaw
1037
1165
  });
1038
1166
  };
1039
- const ContainerNamespace = Tag$13;
1167
+ const ContainerNamespace = Tag$14;
1040
1168
  //#endregion
1041
1169
  //#region src/D1.ts
1042
1170
  var D1_exports = /* @__PURE__ */ __exportAll({
1043
1171
  Service: () => Service$1,
1044
- make: () => make$12
1172
+ make: () => make$13
1045
1173
  });
1046
1174
  const TypeId$2 = "effect-cf/D1";
1047
1175
  const expectedD1Database = "D1 database binding with prepare(), batch(), and exec()";
@@ -1053,7 +1181,7 @@ const isD1Database = (value) => {
1053
1181
  /**
1054
1182
  * Creates a typed D1 service tag plus Effect helpers.
1055
1183
  */
1056
- const make$12 = (id, definition) => Service$1()(id, definition);
1184
+ const make$13 = (id, definition) => Service$1()(id, definition);
1057
1185
  /**
1058
1186
  * Builds a D1 service around a Cloudflare D1 database binding.
1059
1187
  *
@@ -1089,8 +1217,8 @@ const Service$1 = () => (id, definition) => {
1089
1217
  var QueueBinding_exports = /* @__PURE__ */ __exportAll({
1090
1218
  QueueOperationError: () => QueueOperationError,
1091
1219
  isQueue: () => isQueue,
1092
- layer: () => layer$11,
1093
- makeClient: () => makeClient$8
1220
+ layer: () => layer$12,
1221
+ makeClient: () => makeClient$9
1094
1222
  });
1095
1223
  const expectedQueueProducer = "Queue producer binding with send(); optional sendBatch()/metrics()";
1096
1224
  var QueueOperationError = class extends Data.TaggedError("QueueOperationError") {};
@@ -1107,7 +1235,7 @@ const isQueue = (value) => {
1107
1235
  if (typeof value !== "object" || value === null) return false;
1108
1236
  return typeof value.send === "function";
1109
1237
  };
1110
- const makeClient$8 = (definition) => {
1238
+ const makeClient$9 = (definition) => {
1111
1239
  const encodeMessage = Schema.encodeEffect(definition.message);
1112
1240
  return (queue) => ({
1113
1241
  send: Effect.fnUntraced(function* (message, options) {
@@ -1145,30 +1273,30 @@ const makeClient$8 = (definition) => {
1145
1273
  unsafeRaw: Effect.succeed(queue)
1146
1274
  });
1147
1275
  };
1148
- const layer$11 = (tag, definition) => layer$19(tag, definition.binding, (value) => isQueue(value), makeClient$8(definition), { expected: expectedQueueProducer });
1276
+ const layer$12 = (tag, definition) => layer$20(tag, definition.binding, (value) => isQueue(value), makeClient$9(definition), { expected: expectedQueueProducer });
1149
1277
  //#endregion
1150
1278
  //#region src/QueueDefinition.ts
1151
1279
  var QueueDefinition_exports = /* @__PURE__ */ __exportAll({
1152
1280
  Queue: () => Queue$1,
1153
- Tag: () => Tag$12,
1281
+ Tag: () => Tag$13,
1154
1282
  implement: () => implement$7,
1155
- make: () => make$11
1283
+ make: () => make$12
1156
1284
  });
1157
1285
  const makeDefinition$4 = (id, definition) => {
1158
1286
  const queueDefinition = {
1159
1287
  id,
1160
1288
  message: definition.message
1161
1289
  };
1162
- return Object.assign(queueDefinition, { make: (layer, options) => make$8(layer, {
1290
+ return Object.assign(queueDefinition, { make: (layer, options) => make$9(layer, {
1163
1291
  ...options,
1164
1292
  queue: wrapHandler$1(queueDefinition, options.queue)
1165
1293
  }) });
1166
1294
  };
1167
- const make$11 = (id, definition) => Tag$12()(id, definition);
1168
- const Tag$12 = () => (id, definition) => {
1295
+ const make$12 = (id, definition) => Tag$13()(id, definition);
1296
+ const Tag$13 = () => (id, definition) => {
1169
1297
  const queueDefinition = makeDefinition$4(id, definition);
1170
1298
  const tag = Context.Service()(id);
1171
- const layer = (binding) => layer$11(tag, {
1299
+ const layer = (binding) => layer$12(tag, {
1172
1300
  ...binding,
1173
1301
  message: definition.message
1174
1302
  });
@@ -1195,7 +1323,7 @@ const Tag$12 = () => (id, definition) => {
1195
1323
  unsafeRaw
1196
1324
  });
1197
1325
  };
1198
- const Queue$1 = Tag$12;
1326
+ const Queue$1 = Tag$13;
1199
1327
  const wrapHandler$1 = (definition, handler) => {
1200
1328
  const decodeBody = Schema.decodeUnknownEffect(definition.message);
1201
1329
  return (batch) => Effect.gen(function* () {
@@ -1207,7 +1335,7 @@ const implement$7 = (_definition, handler) => handler;
1207
1335
  //#region src/Queue.ts
1208
1336
  var Queue_exports = /* @__PURE__ */ __exportAll({
1209
1337
  QueueMessageDecodeError: () => QueueMessageDecodeError,
1210
- Tag: () => Tag$11,
1338
+ Tag: () => Tag$12,
1211
1339
  decodeBatch: () => decodeBatch,
1212
1340
  fromMessage: () => fromMessage,
1213
1341
  fromMessageBatch: () => fromMessageBatch,
@@ -1245,7 +1373,7 @@ const decodeBatch = (batch, decodeBody) => Effect.gen(function* () {
1245
1373
  }
1246
1374
  return fromMessageBatch(batch, messages);
1247
1375
  });
1248
- const Tag$11 = Tag$12;
1376
+ const Tag$12 = Tag$13;
1249
1377
  const implement$6 = implement$7;
1250
1378
  //#endregion
1251
1379
  //#region src/RpcDefinition.ts
@@ -1263,7 +1391,7 @@ var RpcDefinition_exports = /* @__PURE__ */ __exportAll({
1263
1391
  decodeSuccess: () => decodeSuccess,
1264
1392
  encodeArgs: () => encodeArgs,
1265
1393
  encodeSuccess: () => encodeSuccess,
1266
- make: () => make$10,
1394
+ make: () => make$11,
1267
1395
  method: () => method$4,
1268
1396
  reservedMethodNames: () => reservedMethodNames$4
1269
1397
  });
@@ -1273,7 +1401,7 @@ var RpcArgumentDecodeError = class extends Data.TaggedError("RpcArgumentDecodeEr
1273
1401
  var RpcArgumentEncodeError = class extends Data.TaggedError("RpcArgumentEncodeError") {};
1274
1402
  var RpcSuccessDecodeError = class extends Data.TaggedError("RpcSuccessDecodeError") {};
1275
1403
  var RpcSuccessEncodeError = class extends Data.TaggedError("RpcSuccessEncodeError") {};
1276
- const reservedMethodNames$4 = new Set([
1404
+ const reservedMethodNames$4 = /* @__PURE__ */ new Set([
1277
1405
  "constructor",
1278
1406
  "fetch",
1279
1407
  "connect",
@@ -1366,7 +1494,7 @@ const decodeSuccess = (definition, methodName, value) => {
1366
1494
  cause
1367
1495
  })));
1368
1496
  };
1369
- const make$10 = (id, methods) => {
1497
+ const make$11 = (id, methods) => {
1370
1498
  const definition = {
1371
1499
  id,
1372
1500
  methods
@@ -1424,8 +1552,8 @@ var ServiceBinding_exports = /* @__PURE__ */ __exportAll({
1424
1552
  ServiceBindingFetchError: () => ServiceBindingFetchError,
1425
1553
  ServiceBindingRpcError: () => ServiceBindingRpcError,
1426
1554
  isServiceBindingClient: () => isServiceBindingClient,
1427
- layer: () => layer$10,
1428
- makeClient: () => makeClient$7,
1555
+ layer: () => layer$11,
1556
+ makeClient: () => makeClient$8,
1429
1557
  makeDirectMethods: () => makeDirectMethods$1
1430
1558
  });
1431
1559
  const TypeId$1 = "effect-cf/ServiceBinding";
@@ -1439,7 +1567,7 @@ var ServiceBindingFetchError = class extends Data.TaggedError("ServiceBindingFet
1439
1567
  */
1440
1568
  var ServiceBindingRpcError = class extends Data.TaggedError("ServiceBindingRpcError") {};
1441
1569
  const isServiceBindingClient = (value) => typeof value === "object" && value !== null && typeof Reflect.get(value, "fetch") === "function";
1442
- const makeClient$7 = (definition) => {
1570
+ const makeClient$8 = (definition) => {
1443
1571
  return (service) => {
1444
1572
  const fetch = (input, init) => Effect.tryPromise({
1445
1573
  try: () => service.fetch(input, init),
@@ -1450,11 +1578,12 @@ const makeClient$7 = (definition) => {
1450
1578
  });
1451
1579
  const rpc = (method, ...args) => Effect.gen(function* () {
1452
1580
  const methodName = String(method);
1453
- return yield* invokeRpcMethod(service, method, definition.definition === void 0 ? args : yield* encodeArgs(definition.definition, methodName, args).pipe(Effect.mapError((cause) => new ServiceBindingRpcError({
1581
+ const encodedArgs = definition.definition === void 0 ? args : yield* encodeArgs(definition.definition, methodName, args).pipe(Effect.mapError((cause) => new ServiceBindingRpcError({
1454
1582
  binding: definition.binding,
1455
1583
  method: methodName,
1456
1584
  cause
1457
- }))), (cause) => new ServiceBindingRpcError({
1585
+ })));
1586
+ return yield* invokeRpcMethod(service, method, encodedArgs, (cause) => new ServiceBindingRpcError({
1458
1587
  binding: definition.binding,
1459
1588
  method: methodName,
1460
1589
  cause
@@ -1470,14 +1599,18 @@ const makeClient$7 = (definition) => {
1470
1599
  });
1471
1600
  const call = (method, ...args) => Effect.gen(function* () {
1472
1601
  const methodName = String(method);
1473
- return yield* decodeSuccess$2(methodName, yield* resolve(yield* rpc(method, ...args)).pipe(Effect.mapError((cause) => new ServiceBindingRpcError({
1602
+ const value = yield* resolve(yield* rpc(method, ...args)).pipe(Effect.mapError((cause) => new ServiceBindingRpcError({
1474
1603
  binding: definition.binding,
1475
1604
  method: methodName,
1476
1605
  cause
1477
- }))));
1606
+ })));
1607
+ return yield* decodeSuccess$2(methodName, value);
1478
1608
  });
1479
1609
  const scopedCall = (method, ...args) => Effect.gen(function* () {
1480
- return yield* decodeSuccess$2(String(method), yield* scoped(yield* rpc(method, ...args)));
1610
+ const methodName = String(method);
1611
+ const result = yield* rpc(method, ...args);
1612
+ const value = yield* scoped(result);
1613
+ return yield* decodeSuccess$2(methodName, value);
1481
1614
  });
1482
1615
  const directMethods = makeDirectMethods$1(definition.definition, call);
1483
1616
  return Object.assign(directMethods, {
@@ -1488,7 +1621,7 @@ const makeClient$7 = (definition) => {
1488
1621
  });
1489
1622
  };
1490
1623
  };
1491
- const layer$10 = (tag, definition) => layer$19(tag, definition.binding, (value) => isServiceBindingClient(value), makeClient$7(definition), { expected: expectedServiceBinding });
1624
+ const layer$11 = (tag, definition) => layer$20(tag, definition.binding, (value) => isServiceBindingClient(value), makeClient$8(definition), { expected: expectedServiceBinding });
1492
1625
  /**
1493
1626
  * Creates a typed Effect service for a Worker service binding.
1494
1627
  *
@@ -1519,7 +1652,7 @@ const layer$10 = (tag, definition) => layer$19(tag, definition.binding, (value)
1519
1652
  * ```
1520
1653
  */
1521
1654
  const Service = () => (id, definition) => {
1522
- const tag = Service$2()(id, definition.binding, (value) => isServiceBindingClient(value), makeClient$7(definition));
1655
+ const tag = Service$2()(id, definition.binding, (value) => isServiceBindingClient(value), makeClient$8(definition));
1523
1656
  const fetch = (input, init) => Effect.gen(function* () {
1524
1657
  return yield* (yield* tag).fetch(input, init);
1525
1658
  });
@@ -1550,13 +1683,13 @@ const makeDirectMethods$1 = (rpcDefinition, call) => {
1550
1683
  //#endregion
1551
1684
  //#region src/WorkerDefinition.ts
1552
1685
  var WorkerDefinition_exports = /* @__PURE__ */ __exportAll({
1553
- Tag: () => Tag$10,
1686
+ Tag: () => Tag$11,
1554
1687
  Worker: () => Worker,
1555
1688
  implement: () => implement$5,
1556
- make: () => make$9,
1689
+ make: () => make$10,
1557
1690
  method: () => method$3
1558
1691
  });
1559
- const reservedMethodNames$3 = new Set([
1692
+ const reservedMethodNames$3 = /* @__PURE__ */ new Set([
1560
1693
  "constructor",
1561
1694
  "dup",
1562
1695
  "fetch",
@@ -1591,21 +1724,21 @@ const method$3 = method$4;
1591
1724
  */
1592
1725
  const makeDefinition$3 = (id, methods) => {
1593
1726
  assertNoReservedMethods("Worker", methods, reservedMethodNames$3);
1594
- const definition = make$10(id, methods);
1595
- return Object.assign(definition, { make: (layer, options) => make$8(layer, {
1727
+ const definition = make$11(id, methods);
1728
+ return Object.assign(definition, { make: (layer, options) => make$9(layer, {
1596
1729
  ...options,
1597
1730
  rpc: wrapHandlers$1(definition, options.rpc)
1598
1731
  }) });
1599
1732
  };
1600
- const make$9 = (id, methods) => Tag$10()(id, methods);
1601
- const Tag$10 = () => (id, methods) => {
1733
+ const make$10 = (id, methods) => Tag$11()(id, methods);
1734
+ const Tag$11 = () => (id, methods) => {
1602
1735
  const definition = makeDefinition$3(id, methods);
1603
1736
  const tag = Context.Service()(id);
1604
1737
  const bindingDefinition = (binding) => ({
1605
1738
  ...binding,
1606
1739
  definition
1607
1740
  });
1608
- const layer = (binding) => layer$10(tag, bindingDefinition(binding));
1741
+ const layer = (binding) => layer$11(tag, bindingDefinition(binding));
1609
1742
  const fetch = (input, init) => Effect.gen(function* () {
1610
1743
  return yield* (yield* tag).fetch(input, init);
1611
1744
  });
@@ -1630,13 +1763,15 @@ const Tag$10 = () => (id, methods) => {
1630
1763
  scopedCall
1631
1764
  });
1632
1765
  };
1633
- const Worker = Tag$10;
1766
+ const Worker = Tag$11;
1634
1767
  const wrapHandlers$1 = (definition, handlers) => {
1635
1768
  const wrapped = {};
1636
1769
  for (const key of Object.keys(definition.methods)) {
1637
1770
  const handler = handlers[key];
1638
1771
  wrapped[key] = (...args) => Effect.gen(function* () {
1639
- return yield* encodeSuccess(definition, key, yield* handler(...yield* decodeArgs(definition, key, args)));
1772
+ const decodedArgs = yield* decodeArgs(definition, key, args);
1773
+ const value = yield* handler(...decodedArgs);
1774
+ return yield* encodeSuccess(definition, key, value);
1640
1775
  });
1641
1776
  }
1642
1777
  return wrapped;
@@ -1654,6 +1789,8 @@ const clock = {
1654
1789
  currentTimeMillis: Effect.sync(() => clock.currentTimeMillisUnsafe()),
1655
1790
  currentTimeNanosUnsafe: () => BigInt(Date.now()) * nanosPerMilli,
1656
1791
  currentTimeNanos: Effect.sync(() => clock.currentTimeNanosUnsafe()),
1792
+ monotonicTimeNanosUnsafe: () => typeof performance === "undefined" ? BigInt(Date.now()) * nanosPerMilli : BigInt(Math.round(performance.now() * 1e6)),
1793
+ monotonicTimeNanos: Effect.sync(() => clock.monotonicTimeNanosUnsafe()),
1657
1794
  sleep: (duration) => {
1658
1795
  const millis = Duration.toMillis(duration);
1659
1796
  if (millis <= 0) return Effect.yieldNow;
@@ -1664,7 +1801,7 @@ const clock = {
1664
1801
  });
1665
1802
  }
1666
1803
  };
1667
- const layer$9 = Layer.effect(Clock.Clock, Effect.succeed(clock));
1804
+ const layer$10 = Layer.effect(Clock.Clock, Effect.succeed(clock));
1668
1805
  //#endregion
1669
1806
  //#region src/internal/Entrypoint.ts
1670
1807
  const provideEntrypointServices = (layer, services) => layer.pipe(Layer.provideMerge(services));
@@ -1706,11 +1843,11 @@ const fromExecutionContext = (ctx, runPromiseExit) => {
1706
1843
  var Worker_exports = /* @__PURE__ */ __exportAll({
1707
1844
  ExecutionContext: () => ExecutionContext,
1708
1845
  NativeRequest: () => NativeRequest,
1709
- Tag: () => Tag$9,
1846
+ Tag: () => Tag$10,
1710
1847
  WorkerContext: () => WorkerContext,
1711
1848
  implement: () => implement$4,
1712
1849
  isWebSocketUpgrade: () => isWebSocketUpgrade,
1713
- make: () => make$8,
1850
+ make: () => make$9,
1714
1851
  makeFetchHandler: () => makeFetchHandler,
1715
1852
  method: () => method$2,
1716
1853
  renderHttpResponse: () => renderHttpResponse
@@ -1719,7 +1856,7 @@ var ExecutionContext = class extends Context.Service()("effect-cf/ExecutionConte
1719
1856
  var WorkerContext = class extends Context.Service()("effect-cf/WorkerContext") {};
1720
1857
  var NativeRequest = class extends Context.Service()("effect-cf/NativeRequest") {};
1721
1858
  const isWebSocketUpgrade = (request) => request.headers.get("Upgrade")?.toLowerCase() === "websocket";
1722
- const reservedMethodNames$2 = new Set([
1859
+ const reservedMethodNames$2 = /* @__PURE__ */ new Set([
1723
1860
  "constructor",
1724
1861
  "dup",
1725
1862
  "fetch",
@@ -1739,14 +1876,15 @@ const RunSymbol$1 = Symbol.for("effect-cf/Worker/run");
1739
1876
  const renderHttpResponse = (effect) => Effect.flatMap(effect, (response) => Effect.map(Effect.context(), (context) => HttpServerResponse.toWeb(response, { context })));
1740
1877
  const renderFetchSuccess = (effect) => Effect.flatMap(effect, (response) => response instanceof Response ? Effect.succeed(response) : Effect.map(Effect.context(), (context) => HttpServerResponse.toWeb(response, { context })));
1741
1878
  const isWorkerOptions = (options) => typeof options === "object" && options !== null && ("eventLayer" in options || "fetch" in options || "queue" in options || "rpc" in options);
1742
- function make$8(layer, optionsOrFetch) {
1879
+ function make$9(layer, optionsOrFetch) {
1743
1880
  const options = isWorkerOptions(optionsOrFetch) ? optionsOrFetch : { fetch: optionsOrFetch };
1744
1881
  class EffectWorker extends WorkerEntrypoint {
1745
1882
  runtime;
1746
1883
  constructor(ctx, env) {
1747
1884
  super(ctx, env);
1748
1885
  let runWaitUntilEffect = () => Promise.reject(/* @__PURE__ */ new Error("WorkerContext runtime is not initialized"));
1749
- const runtimeLayer = provideEntrypointServices(layer, Layer.mergeAll(layer$9, Layer.succeed(ExecutionContext, ctx), ConfigProvider.layer(Effect.succeed(WorkerConfig.providerFromEnv(env))), Layer.succeed(WorkerContext, fromExecutionContext(ctx, (effect) => runWaitUntilEffect(effect))), Layer.succeed(WorkerEnvironment, env)));
1886
+ const services = Layer.mergeAll(layer$10, Layer.succeed(ExecutionContext, ctx), ConfigProvider.layer(Effect.succeed(WorkerConfig.providerFromEnv(env))), Layer.succeed(WorkerContext, fromExecutionContext(ctx, (effect) => runWaitUntilEffect(effect))), Layer.succeed(WorkerEnvironment, env));
1887
+ const runtimeLayer = provideEntrypointServices(layer, services);
1750
1888
  this.runtime = ManagedRuntime.make(runtimeLayer);
1751
1889
  runWaitUntilEffect = (effect) => this.runtime.runPromiseExit(effect);
1752
1890
  }
@@ -1771,10 +1909,10 @@ function make$8(layer, optionsOrFetch) {
1771
1909
  return assumeEntrypointClass(EffectWorker);
1772
1910
  }
1773
1911
  const makeFetchHandler = (layer, options) => {
1774
- const WorkerClass = make$8(layer, options);
1912
+ const WorkerClass = make$9(layer, options);
1775
1913
  return { fetch: (request, env, ctx) => Promise.resolve(new WorkerClass(ctx, env).fetch(request)) };
1776
1914
  };
1777
- const Tag$9 = Tag$10;
1915
+ const Tag$10 = Tag$11;
1778
1916
  const method$2 = method$3;
1779
1917
  const implement$4 = implement$5;
1780
1918
  //#endregion
@@ -1783,8 +1921,8 @@ var DurableObjectNamespace_exports = /* @__PURE__ */ __exportAll({
1783
1921
  DurableObjectFetchError: () => DurableObjectFetchError,
1784
1922
  DurableObjectRpcError: () => DurableObjectRpcError,
1785
1923
  isDurableObjectNamespaceClient: () => isDurableObjectNamespaceClient,
1786
- layer: () => layer$8,
1787
- makeClient: () => makeClient$6,
1924
+ layer: () => layer$9,
1925
+ makeClient: () => makeClient$7,
1788
1926
  makeDirectMethods: () => makeDirectMethods
1789
1927
  });
1790
1928
  const expectedDurableObjectNamespace = "Durable Object namespace binding with getByName(), get(), idFromName(), idFromString(), newUniqueId(), and jurisdiction()";
@@ -1798,7 +1936,7 @@ var DurableObjectRpcError = class extends Data.TaggedError("DurableObjectRpcErro
1798
1936
  var DurableObjectFetchError = class extends Data.TaggedError("DurableObjectFetchError") {};
1799
1937
  const hasFunction$2 = (value, key) => typeof Reflect.get(value, key) === "function";
1800
1938
  const isDurableObjectNamespaceClient = (value) => typeof value === "object" && value !== null && hasFunction$2(value, "getByName") && hasFunction$2(value, "get") && hasFunction$2(value, "idFromName") && hasFunction$2(value, "idFromString") && hasFunction$2(value, "newUniqueId") && hasFunction$2(value, "jurisdiction");
1801
- const makeClient$6 = (definition) => {
1939
+ const makeClient$7 = (definition) => {
1802
1940
  return (namespace) => {
1803
1941
  const newUniqueId = (options) => Effect.sync(() => namespace.newUniqueId(options));
1804
1942
  const idFromName = (name) => Effect.sync(() => namespace.idFromName(name));
@@ -1815,11 +1953,12 @@ const makeClient$6 = (definition) => {
1815
1953
  });
1816
1954
  const rpc = (stub, method, ...args) => Effect.gen(function* () {
1817
1955
  const methodName = String(method);
1818
- return yield* invokeRpcMethod(stub, method, definition.definition === void 0 ? args : yield* encodeArgs(definition.definition, methodName, args).pipe(Effect.mapError((cause) => new DurableObjectRpcError({
1956
+ const encodedArgs = definition.definition === void 0 ? args : yield* encodeArgs(definition.definition, methodName, args).pipe(Effect.mapError((cause) => new DurableObjectRpcError({
1819
1957
  binding: definition.binding,
1820
1958
  method: methodName,
1821
1959
  cause
1822
- }))), (cause) => new DurableObjectRpcError({
1960
+ })));
1961
+ return yield* invokeRpcMethod(stub, method, encodedArgs, (cause) => new DurableObjectRpcError({
1823
1962
  binding: definition.binding,
1824
1963
  method: methodName,
1825
1964
  cause
@@ -1835,14 +1974,18 @@ const makeClient$6 = (definition) => {
1835
1974
  });
1836
1975
  const call = (stub, method, ...args) => Effect.gen(function* () {
1837
1976
  const methodName = String(method);
1838
- return yield* decodeSuccess$1(methodName, yield* resolve(yield* rpc(stub, method, ...args)).pipe(Effect.mapError((cause) => new DurableObjectRpcError({
1977
+ const value = yield* resolve(yield* rpc(stub, method, ...args)).pipe(Effect.mapError((cause) => new DurableObjectRpcError({
1839
1978
  binding: definition.binding,
1840
1979
  method: methodName,
1841
1980
  cause
1842
- }))));
1981
+ })));
1982
+ return yield* decodeSuccess$1(methodName, value);
1843
1983
  });
1844
1984
  const scopedCall = (stub, method, ...args) => Effect.gen(function* () {
1845
- return yield* decodeSuccess$1(String(method), yield* scoped(yield* rpc(stub, method, ...args)));
1985
+ const methodName = String(method);
1986
+ const result = yield* rpc(stub, method, ...args);
1987
+ const value = yield* scoped(result);
1988
+ return yield* decodeSuccess$1(methodName, value);
1846
1989
  });
1847
1990
  const directMethods = makeDirectMethods(definition.definition, {
1848
1991
  call,
@@ -1865,7 +2008,7 @@ const makeClient$6 = (definition) => {
1865
2008
  });
1866
2009
  };
1867
2010
  };
1868
- const layer$8 = (tag, definition) => layer$19(tag, definition.binding, (value) => isDurableObjectNamespaceClient(value), makeClient$6(definition), { expected: expectedDurableObjectNamespace });
2011
+ const layer$9 = (tag, definition) => layer$20(tag, definition.binding, (value) => isDurableObjectNamespaceClient(value), makeClient$7(definition), { expected: expectedDurableObjectNamespace });
1869
2012
  const makeDirectMethods = (rpcDefinition, helpers) => {
1870
2013
  const methods = {};
1871
2014
  if (rpcDefinition !== void 0) {
@@ -1890,12 +2033,12 @@ const makeDirectMethods = (rpcDefinition, helpers) => {
1890
2033
  //#region src/DurableObjectDefinition.ts
1891
2034
  var DurableObjectDefinition_exports = /* @__PURE__ */ __exportAll({
1892
2035
  DurableObject: () => DurableObject$1,
1893
- Tag: () => Tag$8,
2036
+ Tag: () => Tag$9,
1894
2037
  implement: () => implement$3,
1895
- make: () => make$7,
2038
+ make: () => make$8,
1896
2039
  method: () => method$1
1897
2040
  });
1898
- const reservedMethodNames$1 = new Set([
2041
+ const reservedMethodNames$1 = /* @__PURE__ */ new Set([
1899
2042
  "constructor",
1900
2043
  "dup",
1901
2044
  "fetch",
@@ -1923,21 +2066,21 @@ const method$1 = method$4;
1923
2066
  */
1924
2067
  const makeDefinition$2 = (id, methods) => {
1925
2068
  assertNoReservedMethods("Durable Object", methods, reservedMethodNames$1);
1926
- const definition = make$10(id, methods);
1927
- return Object.assign(definition, { make: (layer, options) => make$6(layer, {
2069
+ const definition = make$11(id, methods);
2070
+ return Object.assign(definition, { make: (layer, options) => make$7(layer, {
1928
2071
  ...options,
1929
2072
  rpc: wrapHandlers(definition, options.rpc)
1930
2073
  }) });
1931
2074
  };
1932
- const make$7 = (id, methods) => Tag$8()(id, methods);
1933
- const Tag$8 = () => (id, methods) => {
2075
+ const make$8 = (id, methods) => Tag$9()(id, methods);
2076
+ const Tag$9 = () => (id, methods) => {
1934
2077
  const definition = makeDefinition$2(id, methods);
1935
2078
  const tag = Context.Service()(id);
1936
2079
  const bindingDefinition = (binding) => ({
1937
2080
  ...binding,
1938
2081
  definition
1939
2082
  });
1940
- const layer = (binding) => layer$8(tag, bindingDefinition(binding));
2083
+ const layer = (binding) => layer$9(tag, bindingDefinition(binding));
1941
2084
  const newUniqueId = Effect.fnUntraced(function* (options) {
1942
2085
  return yield* (yield* tag).newUniqueId(options);
1943
2086
  });
@@ -1995,13 +2138,15 @@ const Tag$8 = () => (id, methods) => {
1995
2138
  unsafeRaw
1996
2139
  });
1997
2140
  };
1998
- const DurableObject$1 = Tag$8;
2141
+ const DurableObject$1 = Tag$9;
1999
2142
  const wrapHandlers = (definition, handlers) => {
2000
2143
  const wrapped = {};
2001
2144
  for (const key of Object.keys(definition.methods)) {
2002
2145
  const handler = handlers[key];
2003
2146
  wrapped[key] = (...args) => Effect.gen(function* () {
2004
- return yield* encodeSuccess(definition, key, yield* handler(...yield* decodeArgs(definition, key, args)));
2147
+ const decodedArgs = yield* decodeArgs(definition, key, args);
2148
+ const value = yield* handler(...decodedArgs);
2149
+ return yield* encodeSuccess(definition, key, value);
2005
2150
  });
2006
2151
  }
2007
2152
  return wrapped;
@@ -2013,12 +2158,12 @@ const implement$3 = (_definition, handlers) => handlers;
2013
2158
  //#endregion
2014
2159
  //#region src/DurableObject.ts
2015
2160
  var DurableObject_exports = /* @__PURE__ */ __exportAll({
2016
- Tag: () => Tag$7,
2161
+ Tag: () => Tag$8,
2017
2162
  implement: () => implement$2,
2018
- make: () => make$6,
2163
+ make: () => make$7,
2019
2164
  method: () => method
2020
2165
  });
2021
- const reservedMethodNames = new Set([
2166
+ const reservedMethodNames = /* @__PURE__ */ new Set([
2022
2167
  "constructor",
2023
2168
  "dup",
2024
2169
  "fetch",
@@ -2031,12 +2176,13 @@ const RunSymbol = Symbol.for("effect-cf/DurableObject/run");
2031
2176
  /**
2032
2177
  * Creates a Durable Object class backed by a single managed Effect runtime.
2033
2178
  */
2034
- const make$6 = (layer, options = {}) => {
2179
+ const make$7 = (layer, options = {}) => {
2035
2180
  class EffectDurableObject extends DurableObject {
2036
2181
  runtime;
2037
2182
  constructor(state, env) {
2038
2183
  super(state, env);
2039
- const runtimeLayer = provideEntrypointServices(layer, Layer.mergeAll(layer$9, ConfigProvider.layer(Effect.succeed(WorkerConfig.providerFromEnv(env))), Layer.succeed(DurableObjectState, fromDurableObjectState(state)), Layer.succeed(WorkerEnvironment, env)));
2184
+ const services = Layer.mergeAll(layer$10, ConfigProvider.layer(Effect.succeed(WorkerConfig.providerFromEnv(env))), Layer.succeed(DurableObjectState, fromDurableObjectState(state)), Layer.succeed(WorkerEnvironment, env));
2185
+ const runtimeLayer = provideEntrypointServices(layer, services);
2040
2186
  this.runtime = ManagedRuntime.make(runtimeLayer);
2041
2187
  const initialize = options.initialize;
2042
2188
  if (initialize !== void 0) state.waitUntil(this[RunSymbol](initialize, { eventLayer: false }));
@@ -2073,7 +2219,7 @@ const make$6 = (layer, options = {}) => {
2073
2219
  defineEntrypointRpcMethods("Durable Object", EffectDurableObject.prototype, options.rpc, reservedMethodNames, (self, effect) => self[RunSymbol](effect));
2074
2220
  return assumeEntrypointClass(EffectDurableObject);
2075
2221
  };
2076
- const Tag$7 = Tag$8;
2222
+ const Tag$8 = Tag$9;
2077
2223
  const method = method$1;
2078
2224
  const implement$2 = implement$3;
2079
2225
  //#endregion
@@ -2360,7 +2506,8 @@ var DurableObjectAlarm = class DurableObjectAlarm extends Context.Service()("eff
2360
2506
  const actionMode = failureAction === void 0 ? mode : getFailureActionMode(failureAction);
2361
2507
  if (actionMode === "retry" || actionMode === "isolated") {
2362
2508
  const actionRetryDelay = failureAction === void 0 ? void 0 : getFailureActionRetryDelay(failureAction);
2363
- yield* rescheduleFailedAlarm(row, actionRetryDelay === void 0 ? yield* getFailureRetryDelay(options) : yield* toFailureRescheduleMillis(actionRetryDelay));
2509
+ const retryDelay = actionRetryDelay === void 0 ? yield* getFailureRetryDelay(options) : yield* toFailureRescheduleMillis(actionRetryDelay);
2510
+ yield* rescheduleFailedAlarm(row, retryDelay);
2364
2511
  return "continue";
2365
2512
  }
2366
2513
  if (actionMode === "skip-and-advance-repeat") {
@@ -2402,7 +2549,7 @@ var DurableObjectAlarm = class DurableObjectAlarm extends Context.Service()("eff
2402
2549
  //#region src/DurableObjectRpcWebSocket.ts
2403
2550
  var DurableObjectRpcWebSocket_exports = /* @__PURE__ */ __exportAll({
2404
2551
  DurableObjectRpcWebSocket: () => DurableObjectRpcWebSocket,
2405
- layer: () => layer$7
2552
+ layer: () => layer$8
2406
2553
  });
2407
2554
  const defaultAttachmentKey = "effectCloudflareRpcClientId";
2408
2555
  const defaultTag = "effect-cf-rpc";
@@ -2413,7 +2560,7 @@ var DurableObjectRpcWebSocket = class extends Context.Service()("effect-cf/Durab
2413
2560
  /**
2414
2561
  * Builds a layer that bridges Durable Object websocket events to `RpcServer.Protocol`.
2415
2562
  */
2416
- const layer$7 = (options = {}) => Layer.effectContext(Effect.gen(function* () {
2563
+ const layer$8 = (options = {}) => Layer.effectContext(Effect.gen(function* () {
2417
2564
  const tag = options.tag ?? defaultTag;
2418
2565
  const attachmentKey = options.attachmentKey ?? defaultAttachmentKey;
2419
2566
  const durableObjectState = yield* DurableObjectState;
@@ -2501,7 +2648,8 @@ const layer$7 = (options = {}) => Layer.effectContext(Effect.gen(function* () {
2501
2648
  }
2502
2649
  for (const current of decoded) yield* run(connection.id, current);
2503
2650
  }).pipe(Effect.catch((error) => {
2504
- return send(register(socket), error);
2651
+ const connection = register(socket);
2652
+ return send(connection, error);
2505
2653
  })),
2506
2654
  close: unregister,
2507
2655
  error: (socket, error) => Effect.gen(function* () {
@@ -2526,7 +2674,7 @@ const writeAttachment = (socket, key, clientId) => {
2526
2674
  };
2527
2675
  //#endregion
2528
2676
  //#region src/DurableObjectSqlite.ts
2529
- var DurableObjectSqlite_exports = /* @__PURE__ */ __exportAll({ layer: () => layer$6 });
2677
+ var DurableObjectSqlite_exports = /* @__PURE__ */ __exportAll({ layer: () => layer$7 });
2530
2678
  /**
2531
2679
  * Provides `effect/unstable/sql` from the current Durable Object SQLite storage.
2532
2680
  *
@@ -2538,7 +2686,7 @@ var DurableObjectSqlite_exports = /* @__PURE__ */ __exportAll({ layer: () => lay
2538
2686
  * );
2539
2687
  * ```
2540
2688
  */
2541
- const layer$6 = (options) => Layer.unwrap(Effect.gen(function* () {
2689
+ const layer$7 = (options) => Layer.unwrap(Effect.gen(function* () {
2542
2690
  const state = yield* DurableObjectState;
2543
2691
  return SqliteClient.layer({
2544
2692
  ...options,
@@ -2549,38 +2697,269 @@ const layer$6 = (options) => Layer.unwrap(Effect.gen(function* () {
2549
2697
  //#region src/Email.ts
2550
2698
  var Email_exports = /* @__PURE__ */ __exportAll({
2551
2699
  EmailOperationError: () => EmailOperationError,
2552
- Tag: () => Tag$6,
2700
+ EmailValidationError: () => EmailValidationError,
2701
+ Tag: () => Tag$7,
2702
+ emailErrorCodes: () => emailErrorCodes,
2553
2703
  isEmailBinding: () => isEmailBinding,
2554
- layer: () => layer$5,
2555
- make: () => make$5,
2556
- makeClient: () => makeClient$5
2704
+ isEmailMessageBuilder: () => isEmailMessageBuilder,
2705
+ layer: () => layer$6,
2706
+ make: () => make$6,
2707
+ makeClient: () => makeClient$6,
2708
+ sendLimits: () => sendLimits,
2709
+ validateMessage: () => validateMessage
2557
2710
  });
2558
2711
  const expectedSendEmailBinding = "Send Email binding with send()";
2712
+ const textEncoder = new TextEncoder();
2713
+ /** Documented Cloudflare Email Sending limits. */
2714
+ const sendLimits = {
2715
+ /** Combined `to`, `cc`, and `bcc` addresses per message. */
2716
+ maxRecipients: 50,
2717
+ maxAttachments: 32,
2718
+ /** Total message size, including attachments. Not enforced client side. */
2719
+ maxMessageBytes: 5 * 1024 * 1024,
2720
+ maxHeaderNameBytes: 100,
2721
+ maxHeaderValueBytes: 2048,
2722
+ maxHeadersBytes: 16 * 1024,
2723
+ /** Allowlisted custom headers, excluding `X-` prefixed headers. */
2724
+ maxAllowlistHeaders: 20
2725
+ };
2726
+ /** Error codes reported by Cloudflare Email Sending. */
2727
+ const emailErrorCodes = [
2728
+ "E_VALIDATION_ERROR",
2729
+ "E_FIELD_MISSING",
2730
+ "E_TOO_MANY_RECIPIENTS",
2731
+ "E_TOO_MANY_ATTACHMENTS",
2732
+ "E_SENDER_NOT_VERIFIED",
2733
+ "E_RECIPIENT_NOT_ALLOWED",
2734
+ "E_RECIPIENT_SUPPRESSED",
2735
+ "E_SENDER_DOMAIN_NOT_AVAILABLE",
2736
+ "E_CONTENT_TOO_LARGE",
2737
+ "E_DELIVERY_FAILED",
2738
+ "E_RATE_LIMIT_EXCEEDED",
2739
+ "E_DAILY_LIMIT_EXCEEDED",
2740
+ "E_INTERNAL_SERVER_ERROR",
2741
+ "E_HEADER_NOT_ALLOWED",
2742
+ "E_HEADER_USE_API_FIELD",
2743
+ "E_HEADER_VALUE_INVALID",
2744
+ "E_HEADER_VALUE_TOO_LONG",
2745
+ "E_HEADER_NAME_INVALID",
2746
+ "E_HEADERS_TOO_LARGE",
2747
+ "E_HEADERS_TOO_MANY"
2748
+ ];
2559
2749
  /** Error raised when a Cloudflare Send Email operation fails. */
2560
2750
  var EmailOperationError = class extends Data.TaggedError("EmailOperationError") {};
2751
+ /** Error raised when a message violates documented Cloudflare Email Sending limits. */
2752
+ var EmailValidationError = class extends Data.TaggedError("EmailValidationError") {};
2753
+ const emailErrorCode = (cause) => {
2754
+ if (typeof cause !== "object" || cause === null) return;
2755
+ const code = Reflect.get(cause, "code");
2756
+ return typeof code === "string" ? code : void 0;
2757
+ };
2561
2758
  const emailError = (binding, operation, cause) => new EmailOperationError({
2562
2759
  binding,
2563
2760
  operation,
2564
- cause
2761
+ cause,
2762
+ code: emailErrorCode(cause)
2763
+ });
2764
+ const emailValidationError = (binding, operation, violations) => new EmailValidationError({
2765
+ binding,
2766
+ operation,
2767
+ violations
2565
2768
  });
2566
2769
  const tryEmailPromise = (binding, operation, evaluate) => Effect.tryPromise({
2567
2770
  try: evaluate,
2568
2771
  catch: (cause) => emailError(binding, operation, cause)
2569
2772
  });
2773
+ const builderFields = [
2774
+ "subject",
2775
+ "html",
2776
+ "text",
2777
+ "cc",
2778
+ "bcc",
2779
+ "replyTo",
2780
+ "attachments",
2781
+ "headers"
2782
+ ];
2783
+ /**
2784
+ * Distinguishes structured Email Sending messages from raw MIME `EmailMessage`
2785
+ * values, which only carry envelope `from` and `to` addresses.
2786
+ */
2787
+ const isEmailMessageBuilder = (message) => {
2788
+ if (typeof message !== "object" || message === null) return false;
2789
+ return builderFields.some((field) => Reflect.get(message, field) !== void 0);
2790
+ };
2791
+ const byteLength = (value) => textEncoder.encode(value).byteLength;
2792
+ const limitViolation = (path, label, actual, limit) => ({
2793
+ path,
2794
+ message: `${label} exceeds Cloudflare Email Sending limit`,
2795
+ actual,
2796
+ limit
2797
+ });
2798
+ const addressList = (value) => {
2799
+ if (value === void 0) return [];
2800
+ return Array.isArray(value) ? value : [value];
2801
+ };
2802
+ const addressViolations = (path, value) => {
2803
+ if (typeof value === "string") return value.includes("@") ? [] : [{
2804
+ path,
2805
+ message: "Email address must contain an @ symbol"
2806
+ }];
2807
+ if (typeof value !== "object" || value === null) return [{
2808
+ path,
2809
+ message: "Email address must be a string or { name, email } object"
2810
+ }];
2811
+ const email = Reflect.get(value, "email");
2812
+ if (typeof email !== "string" || !email.includes("@")) return [{
2813
+ path: `${path}.email`,
2814
+ message: "Email address must contain an @ symbol"
2815
+ }];
2816
+ return [];
2817
+ };
2818
+ const recipientViolations = (field, value) => addressList(value).flatMap((address, index) => addressViolations(`${field}[${index}]`, address));
2819
+ const attachmentViolations = (attachments) => {
2820
+ const violations = [];
2821
+ if (attachments.length > sendLimits.maxAttachments) violations.push(limitViolation("attachments", "attachments", attachments.length, sendLimits.maxAttachments));
2822
+ for (let index = 0; index < attachments.length; index++) {
2823
+ const attachment = attachments[index];
2824
+ const path = `attachments[${index}]`;
2825
+ if (typeof attachment !== "object" || attachment === null) {
2826
+ violations.push({
2827
+ path,
2828
+ message: "Attachment must be an object"
2829
+ });
2830
+ continue;
2831
+ }
2832
+ if (typeof attachment.filename !== "string" || attachment.filename === "") violations.push({
2833
+ path: `${path}.filename`,
2834
+ message: "Attachment filename is required"
2835
+ });
2836
+ if (typeof attachment.type !== "string" || attachment.type === "") violations.push({
2837
+ path: `${path}.type`,
2838
+ message: "Attachment MIME type is required"
2839
+ });
2840
+ if (attachment.content === void 0 || attachment.content === null) violations.push({
2841
+ path: `${path}.content`,
2842
+ message: "Attachment content is required"
2843
+ });
2844
+ if (attachment.disposition === "inline" && typeof attachment.contentId !== "string") violations.push({
2845
+ path: `${path}.contentId`,
2846
+ message: "Inline attachments require a contentId"
2847
+ });
2848
+ }
2849
+ return violations;
2850
+ };
2851
+ const headerViolations = (headers) => {
2852
+ const violations = [];
2853
+ const entries = Object.entries(headers);
2854
+ let totalBytes = 0;
2855
+ let allowlistHeaders = 0;
2856
+ for (const [name, value] of entries) {
2857
+ const path = `headers["${name}"]`;
2858
+ const nameBytes = byteLength(name);
2859
+ if (nameBytes > sendLimits.maxHeaderNameBytes) violations.push(limitViolation(path, "header name bytes", nameBytes, sendLimits.maxHeaderNameBytes));
2860
+ if (typeof value !== "string") {
2861
+ violations.push({
2862
+ path,
2863
+ message: "Header value must be a string"
2864
+ });
2865
+ continue;
2866
+ }
2867
+ const valueBytes = byteLength(value);
2868
+ if (valueBytes > sendLimits.maxHeaderValueBytes) violations.push(limitViolation(path, "header value bytes", valueBytes, sendLimits.maxHeaderValueBytes));
2869
+ totalBytes += nameBytes + valueBytes;
2870
+ if (!name.toLowerCase().startsWith("x-")) allowlistHeaders += 1;
2871
+ }
2872
+ if (totalBytes > sendLimits.maxHeadersBytes) violations.push(limitViolation("headers", "header bytes", totalBytes, sendLimits.maxHeadersBytes));
2873
+ if (allowlistHeaders > sendLimits.maxAllowlistHeaders) violations.push(limitViolation("headers", "allowlisted custom headers", allowlistHeaders, sendLimits.maxAllowlistHeaders));
2874
+ return violations;
2875
+ };
2876
+ /**
2877
+ * Validates a structured message against documented Cloudflare Email Sending
2878
+ * limits and returns every violation found. Total message size is not checked
2879
+ * because the encoded MIME size is only known once Cloudflare composes it.
2880
+ */
2881
+ const validateMessage = (message) => {
2882
+ const violations = [];
2883
+ const fields = message;
2884
+ if (fields.from === void 0) violations.push({
2885
+ path: "from",
2886
+ message: "A from address is required"
2887
+ });
2888
+ else violations.push(...addressViolations("from", fields.from));
2889
+ if (fields.replyTo !== void 0) violations.push(...addressViolations("replyTo", fields.replyTo));
2890
+ if (typeof fields.subject !== "string" || fields.subject === "") violations.push({
2891
+ path: "subject",
2892
+ message: "A subject is required"
2893
+ });
2894
+ if (typeof fields.text !== "string" && typeof fields.html !== "string") violations.push({
2895
+ path: "$",
2896
+ message: "A message requires either text or html content"
2897
+ });
2898
+ const recipients = addressList(fields.to).length + addressList(fields.cc).length + addressList(fields.bcc).length;
2899
+ if (recipients === 0) violations.push({
2900
+ path: "$",
2901
+ message: "A message requires at least one to, cc, or bcc address"
2902
+ });
2903
+ if (recipients > sendLimits.maxRecipients) violations.push(limitViolation("$", "combined to, cc, and bcc addresses", recipients, sendLimits.maxRecipients));
2904
+ violations.push(...recipientViolations("to", fields.to));
2905
+ violations.push(...recipientViolations("cc", fields.cc));
2906
+ violations.push(...recipientViolations("bcc", fields.bcc));
2907
+ if (fields.attachments !== void 0) violations.push(...attachmentViolations(fields.attachments));
2908
+ if (fields.headers !== void 0) violations.push(...headerViolations(fields.headers));
2909
+ return violations;
2910
+ };
2911
+ const validateSendInput = (binding, operation, message) => {
2912
+ const violations = validateMessage(message);
2913
+ return violations.length > 0 ? Effect.fail(emailValidationError(binding, operation, violations)) : Effect.succeed(message);
2914
+ };
2570
2915
  const isEmailBinding = (value) => {
2571
2916
  if (typeof value !== "object" || value === null) return false;
2572
2917
  return typeof value.send === "function";
2573
2918
  };
2574
- const makeClient$5 = (definition) => (email) => {
2919
+ const makeClient$6 = (definition, options) => (email) => {
2575
2920
  const runtime = email;
2576
- const send = ((message) => tryEmailPromise(definition.binding, "send", () => runtime.send(message)));
2921
+ const validate = options?.validate ?? true;
2922
+ const send = ((message) => {
2923
+ const dispatch = () => tryEmailPromise(definition.binding, "send", () => runtime.send(message));
2924
+ if (!validate || !isEmailMessageBuilder(message)) return dispatch();
2925
+ return validateSendInput(definition.binding, "send", message).pipe(Effect.flatMap(dispatch));
2926
+ });
2577
2927
  return {
2578
2928
  definition,
2579
2929
  send,
2580
2930
  unsafeRaw: Effect.succeed(email)
2581
2931
  };
2582
2932
  };
2583
- const layer$5 = (tag, definition) => layer$19(tag, definition.binding, isEmailBinding, makeClient$5(definition), { expected: expectedSendEmailBinding });
2933
+ const layer$6 = (tag, definition) => layer$20(tag, definition.binding, isEmailBinding, makeClient$6(definition, definition.send), { expected: expectedSendEmailBinding });
2934
+ const make$6 = (id) => Tag$7()(id);
2935
+ const Tag$7 = () => (id) => {
2936
+ const tag = Context.Service()(id);
2937
+ const makeLayer = (definition) => layer$6(tag, definition);
2938
+ return Object.assign(tag, {
2939
+ id,
2940
+ layer: makeLayer
2941
+ });
2942
+ };
2943
+ //#endregion
2944
+ //#region src/Hyperdrive.ts
2945
+ var Hyperdrive_exports = /* @__PURE__ */ __exportAll({
2946
+ Tag: () => Tag$6,
2947
+ isHyperdrive: () => isHyperdrive,
2948
+ layer: () => layer$5,
2949
+ make: () => make$5,
2950
+ makeClient: () => makeClient$5
2951
+ });
2952
+ const expectedHyperdrive = "Hyperdrive binding with connectionString";
2953
+ const isHyperdrive = (value) => {
2954
+ if (typeof value !== "object" || value === null) return false;
2955
+ return typeof value.connectionString === "string";
2956
+ };
2957
+ const makeClient$5 = (definition) => (hyperdrive) => ({
2958
+ definition,
2959
+ connectionString: hyperdrive.connectionString,
2960
+ unsafeRaw: Effect.succeed(hyperdrive)
2961
+ });
2962
+ const layer$5 = (tag, definition) => layer$20(tag, definition.binding, isHyperdrive, makeClient$5(definition), { expected: expectedHyperdrive });
2584
2963
  const make$5 = (id) => Tag$6()(id);
2585
2964
  const Tag$6 = () => (id) => {
2586
2965
  const tag = Context.Service()(id);
@@ -2687,7 +3066,7 @@ const makeClient$4 = (definition) => (images) => {
2687
3066
  unsafeRaw: Effect.succeed(images)
2688
3067
  };
2689
3068
  };
2690
- const layer$4 = (tag, definition) => layer$19(tag, definition.binding, isImagesBinding, makeClient$4(definition), { expected: expectedImagesBinding });
3069
+ const layer$4 = (tag, definition) => layer$20(tag, definition.binding, isImagesBinding, makeClient$4(definition), { expected: expectedImagesBinding });
2691
3070
  const make$4 = (id) => Tag$5()(id);
2692
3071
  const Tag$5 = () => (id) => {
2693
3072
  const tag = Context.Service()(id);
@@ -2709,7 +3088,7 @@ var Kv_exports = /* @__PURE__ */ __exportAll({
2709
3088
  const expectedKvNamespace = "KV namespace binding with get(), put(), delete(), getWithMetadata(), and list()";
2710
3089
  /** Error raised when a KV operation fails. */
2711
3090
  var KvOperationError = class extends Data.TaggedError("KvOperationError") {};
2712
- const maybeString = (value) => value == null ? Option.none() : Option.some(value);
3091
+ const maybeString = (value) => value === null || value === void 0 ? Option.none() : Option.some(value);
2713
3092
  const maybeNumber = (value) => value === void 0 ? Option.none() : Option.some(value);
2714
3093
  const kvError = (binding, operation, cause) => new KvOperationError({
2715
3094
  binding,
@@ -2782,7 +3161,7 @@ const makeClient$3 = (definition) => {
2782
3161
  unsafeRaw: Effect.succeed(kv)
2783
3162
  });
2784
3163
  };
2785
- const layer$3 = (tag, definition) => layer$19(tag, definition.binding, isKvNamespace, makeClient$3(definition), { expected: expectedKvNamespace });
3164
+ const layer$3 = (tag, definition) => layer$20(tag, definition.binding, isKvNamespace, makeClient$3(definition), { expected: expectedKvNamespace });
2786
3165
  const makeDefinition$1 = (id, definition) => {
2787
3166
  const kvDefinition = {
2788
3167
  id,
@@ -2899,7 +3278,7 @@ const makeClient$2 = (definition) => {
2899
3278
  };
2900
3279
  };
2901
3280
  };
2902
- const layer$2 = (tag, definition) => layer$19(tag, definition.binding, isR2Bucket, makeClient$2(definition), { expected: expectedR2Bucket });
3281
+ const layer$2 = (tag, definition) => layer$20(tag, definition.binding, isR2Bucket, makeClient$2(definition), { expected: expectedR2Bucket });
2903
3282
  const make$3 = (id) => Tag$3()(id);
2904
3283
  const Tag$3 = () => (id) => {
2905
3284
  const tag = Context.Service()(id);
@@ -2956,7 +3335,7 @@ const makeClient$1 = (definition) => {
2956
3335
  return {
2957
3336
  status: status.status,
2958
3337
  output,
2959
- error: status.error == null ? Option.none() : Option.some(status.error)
3338
+ error: status.error === null || status.error === void 0 ? Option.none() : Option.some(status.error)
2960
3339
  };
2961
3340
  }))),
2962
3341
  sendEvent: (event) => operation("sendEvent", () => raw.sendEvent(event))
@@ -2965,10 +3344,11 @@ const makeClient$1 = (definition) => {
2965
3344
  return (workflow) => ({
2966
3345
  create: Effect.fnUntraced(function* (payload, options) {
2967
3346
  const encoded = yield* encodePayload(payload);
2968
- return wrapInstance(yield* tryWorkflowPromise(definition.binding, "create", () => workflow.create({
3347
+ const raw = yield* tryWorkflowPromise(definition.binding, "create", () => workflow.create({
2969
3348
  ...options,
2970
3349
  params: encoded
2971
- })));
3350
+ }));
3351
+ return wrapInstance(raw);
2972
3352
  }),
2973
3353
  createBatch: Effect.fnUntraced(function* (batch) {
2974
3354
  const encodedBatch = [];
@@ -2985,7 +3365,7 @@ const makeClient$1 = (definition) => {
2985
3365
  unsafeRaw: Effect.succeed(workflow)
2986
3366
  });
2987
3367
  };
2988
- const layer$1 = (tag, definition) => layer$19(tag, definition.binding, (value) => isWorkflow(value), makeClient$1(definition), { expected: expectedWorkflow });
3368
+ const layer$1 = (tag, definition) => layer$20(tag, definition.binding, (value) => isWorkflow(value), makeClient$1(definition), { expected: expectedWorkflow });
2989
3369
  //#endregion
2990
3370
  //#region src/WorkflowDefinition.ts
2991
3371
  var WorkflowDefinition_exports = /* @__PURE__ */ __exportAll({
@@ -3045,7 +3425,8 @@ const wrapHandler = (definition, handler) => {
3045
3425
  ...yield* WorkflowEvent$1,
3046
3426
  payload: decodedPayload
3047
3427
  };
3048
- return yield* encodeResult(yield* handler(decodedPayload).pipe(Effect.provideService(WorkflowEvent$1, decodedEvent)));
3428
+ const result = yield* handler(decodedPayload).pipe(Effect.provideService(WorkflowEvent$1, decodedEvent));
3429
+ return yield* encodeResult(result);
3049
3430
  });
3050
3431
  };
3051
3432
  const implement$1 = (_definition, handler) => handler;
@@ -3102,7 +3483,8 @@ const make$1 = (layer, options) => {
3102
3483
  constructor(ctx, env) {
3103
3484
  super(ctx, env);
3104
3485
  let runWaitUntilEffect = () => Promise.reject(/* @__PURE__ */ new Error("WorkerContext runtime is not initialized"));
3105
- 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)));
3486
+ const services = 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));
3487
+ const runtimeLayer = provideEntrypointServices(layer, services);
3106
3488
  this.runtime = ManagedRuntime.make(runtimeLayer);
3107
3489
  runWaitUntilEffect = (effect) => this.runtime.runPromiseExit(effect);
3108
3490
  }
@@ -3159,7 +3541,7 @@ const makeClient = (definition) => (index) => {
3159
3541
  unsafeRaw: Effect.succeed(index)
3160
3542
  };
3161
3543
  };
3162
- const layer = (tag, definition) => layer$19(tag, definition.binding, isVectorizeBinding, makeClient(definition), { expected: expectedVectorizeBinding });
3544
+ const layer = (tag, definition) => layer$20(tag, definition.binding, isVectorizeBinding, makeClient(definition), { expected: expectedVectorizeBinding });
3163
3545
  const make = (id) => Tag()(id);
3164
3546
  const Tag = () => (id) => {
3165
3547
  const tag = Context.Service()(id);