effect-cf 0.11.0 → 0.12.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,65 +1,19 @@
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";
4
- import { D1Client } from "@effect/sql-d1";
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";
5
6
  import { DurableObject, RpcStub, RpcTarget, WorkerEntrypoint, WorkflowEntrypoint } from "cloudflare:workers";
6
- import { HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
7
+ import { D1Client } from "@effect/sql-d1";
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";
11
- //#region src/D1.ts
12
- var D1_exports = /* @__PURE__ */ __exportAll({
13
- Service: () => Service$1,
14
- make: () => make$10
15
- });
16
- const TypeId$2 = "effect-cf/D1";
17
- const expectedD1Database = "D1 database binding with prepare(), batch(), and exec()";
18
- const isD1Database = (value) => {
19
- if (typeof value !== "object" || value === null) return false;
20
- const resource = value;
21
- return typeof resource.prepare === "function" && typeof resource.batch === "function" && typeof resource.exec === "function";
22
- };
23
- /**
24
- * Creates a typed D1 service tag plus Effect helpers.
25
- */
26
- const make$10 = (id, definition) => Service$1()(id, definition);
27
- /**
28
- * Builds a D1 service around a Cloudflare D1 database binding.
29
- *
30
- * The returned service exposes the raw `D1Database` binding and `sqlLayer(...)`
31
- * for providing `effect/unstable/sql` via `@effect/sql-d1`.
32
- *
33
- * @example
34
- * ```ts
35
- * class TodoDatabase extends D1.Service<TodoDatabase>()("TodoDatabase", {
36
- * binding: "TODO_DB",
37
- * }) {}
38
- *
39
- * const SqlLive = TodoDatabase.sqlLayer();
40
- * ```
41
- */
42
- const Service$1 = () => (id, definition) => {
43
- const tag = Service$2()(id, definition.binding, isD1Database, void 0, { expected: expectedD1Database });
44
- const sqlLayer = (options) => Layer.unwrap(Effect.gen(function* () {
45
- const db = yield* tag;
46
- return D1Client.layer({
47
- ...options,
48
- db
49
- });
50
- })).pipe(Layer.provide(tag.layer));
51
- return Object.assign(tag, {
52
- [TypeId$2]: TypeId$2,
53
- definition,
54
- sqlLayer
55
- });
56
- };
57
- //#endregion
58
12
  //#region src/QueueBinding.ts
59
13
  var QueueBinding_exports = /* @__PURE__ */ __exportAll({
60
14
  QueueOperationError: () => QueueOperationError,
61
15
  isQueue: () => isQueue,
62
- layer: () => layer$8,
16
+ layer: () => layer$9,
63
17
  makeClient: () => makeClient$6
64
18
  });
65
19
  const expectedQueueProducer = "Queue producer binding with send(); optional sendBatch()/metrics()";
@@ -115,30 +69,30 @@ const makeClient$6 = (definition) => {
115
69
  unsafeRaw: Effect.succeed(queue)
116
70
  });
117
71
  };
118
- const layer$8 = (tag, definition) => layer$9(tag, definition.binding, (value) => isQueue(value), makeClient$6(definition), { expected: expectedQueueProducer });
72
+ const layer$9 = (tag, definition) => layer$10(tag, definition.binding, (value) => isQueue(value), makeClient$6(definition), { expected: expectedQueueProducer });
119
73
  //#endregion
120
74
  //#region src/QueueDefinition.ts
121
75
  var QueueDefinition_exports = /* @__PURE__ */ __exportAll({
122
76
  Queue: () => Queue$1,
123
77
  Tag: () => Tag$10,
124
78
  implement: () => implement$7,
125
- make: () => make$9
79
+ make: () => make$10
126
80
  });
127
81
  const makeDefinition$4 = (id, definition) => {
128
82
  const queueDefinition = {
129
83
  id,
130
84
  message: definition.message
131
85
  };
132
- return Object.assign(queueDefinition, { make: (layer, options) => make$6(layer, {
86
+ return Object.assign(queueDefinition, { make: (layer, options) => make$7(layer, {
133
87
  ...options,
134
88
  queue: wrapHandler$1(queueDefinition, options.queue)
135
89
  }) });
136
90
  };
137
- const make$9 = (id, definition) => Tag$10()(id, definition);
91
+ const make$10 = (id, definition) => Tag$10()(id, definition);
138
92
  const Tag$10 = () => (id, definition) => {
139
93
  const queueDefinition = makeDefinition$4(id, definition);
140
94
  const tag = Context.Service()(id);
141
- const layer = (binding) => layer$8(tag, {
95
+ const layer = (binding) => layer$9(tag, {
142
96
  ...binding,
143
97
  message: definition.message
144
98
  });
@@ -233,7 +187,7 @@ var RpcDefinition_exports = /* @__PURE__ */ __exportAll({
233
187
  decodeSuccess: () => decodeSuccess,
234
188
  encodeArgs: () => encodeArgs,
235
189
  encodeSuccess: () => encodeSuccess,
236
- make: () => make$8,
190
+ make: () => make$9,
237
191
  method: () => method$4,
238
192
  reservedMethodNames: () => reservedMethodNames$4
239
193
  });
@@ -336,7 +290,7 @@ const decodeSuccess = (definition, methodName, value) => {
336
290
  cause
337
291
  })));
338
292
  };
339
- const make$8 = (id, methods) => {
293
+ const make$9 = (id, methods) => {
340
294
  const definition = {
341
295
  id,
342
296
  methods
@@ -390,15 +344,15 @@ const invokeRpcMethod = (target, method, args, makeError) => Effect.gen(function
390
344
  //#endregion
391
345
  //#region src/ServiceBinding.ts
392
346
  var ServiceBinding_exports = /* @__PURE__ */ __exportAll({
393
- Service: () => Service,
347
+ Service: () => Service$1,
394
348
  ServiceBindingFetchError: () => ServiceBindingFetchError,
395
349
  ServiceBindingRpcError: () => ServiceBindingRpcError,
396
350
  isServiceBindingClient: () => isServiceBindingClient,
397
- layer: () => layer$7,
351
+ layer: () => layer$8,
398
352
  makeClient: () => makeClient$5,
399
353
  makeDirectMethods: () => makeDirectMethods$1
400
354
  });
401
- const TypeId$1 = "effect-cf/ServiceBinding";
355
+ const TypeId$2 = "effect-cf/ServiceBinding";
402
356
  const expectedServiceBinding = "Worker service binding with fetch()";
403
357
  /**
404
358
  * Failure raised when calling `fetch` on a service binding.
@@ -458,7 +412,7 @@ const makeClient$5 = (definition) => {
458
412
  });
459
413
  };
460
414
  };
461
- const layer$7 = (tag, definition) => layer$9(tag, definition.binding, (value) => isServiceBindingClient(value), makeClient$5(definition), { expected: expectedServiceBinding });
415
+ const layer$8 = (tag, definition) => layer$10(tag, definition.binding, (value) => isServiceBindingClient(value), makeClient$5(definition), { expected: expectedServiceBinding });
462
416
  /**
463
417
  * Creates a typed Effect service for a Worker service binding.
464
418
  *
@@ -488,7 +442,7 @@ const layer$7 = (tag, definition) => layer$9(tag, definition.binding, (value) =>
488
442
  * });
489
443
  * ```
490
444
  */
491
- const Service = () => (id, definition) => {
445
+ const Service$1 = () => (id, definition) => {
492
446
  const tag = Service$2()(id, definition.binding, (value) => isServiceBindingClient(value), makeClient$5(definition));
493
447
  const fetch = (input, init) => Effect.gen(function* () {
494
448
  return yield* (yield* tag).fetch(input, init);
@@ -504,7 +458,7 @@ const Service = () => (id, definition) => {
504
458
  });
505
459
  const directMethods = makeDirectMethods$1(definition.definition, call);
506
460
  return Object.assign(tag, directMethods, {
507
- [TypeId$1]: TypeId$1,
461
+ [TypeId$2]: TypeId$2,
508
462
  definition,
509
463
  fetch,
510
464
  rpc,
@@ -523,7 +477,7 @@ var WorkerDefinition_exports = /* @__PURE__ */ __exportAll({
523
477
  Tag: () => Tag$8,
524
478
  Worker: () => Worker,
525
479
  implement: () => implement$5,
526
- make: () => make$7,
480
+ make: () => make$8,
527
481
  method: () => method$3
528
482
  });
529
483
  const reservedMethodNames$3 = new Set([
@@ -561,13 +515,13 @@ const method$3 = method$4;
561
515
  */
562
516
  const makeDefinition$3 = (id, methods) => {
563
517
  assertNoReservedMethods("Worker", methods, reservedMethodNames$3);
564
- const definition = make$8(id, methods);
565
- return Object.assign(definition, { make: (layer, options) => make$6(layer, {
518
+ const definition = make$9(id, methods);
519
+ return Object.assign(definition, { make: (layer, options) => make$7(layer, {
566
520
  ...options,
567
521
  rpc: wrapHandlers$1(definition, options.rpc)
568
522
  }) });
569
523
  };
570
- const make$7 = (id, methods) => Tag$8()(id, methods);
524
+ const make$8 = (id, methods) => Tag$8()(id, methods);
571
525
  const Tag$8 = () => (id, methods) => {
572
526
  const definition = makeDefinition$3(id, methods);
573
527
  const tag = Context.Service()(id);
@@ -575,7 +529,7 @@ const Tag$8 = () => (id, methods) => {
575
529
  ...binding,
576
530
  definition
577
531
  });
578
- const layer = (binding) => layer$7(tag, bindingDefinition(binding));
532
+ const layer = (binding) => layer$8(tag, bindingDefinition(binding));
579
533
  const fetch = (input, init) => Effect.gen(function* () {
580
534
  return yield* (yield* tag).fetch(input, init);
581
535
  });
@@ -660,7 +614,7 @@ var Worker_exports = /* @__PURE__ */ __exportAll({
660
614
  WorkerContext: () => WorkerContext,
661
615
  implement: () => implement$4,
662
616
  isWebSocketUpgrade: () => isWebSocketUpgrade,
663
- make: () => make$6,
617
+ make: () => make$7,
664
618
  makeFetchHandler: () => makeFetchHandler,
665
619
  method: () => method$2,
666
620
  renderHttpResponse: () => renderHttpResponse
@@ -689,7 +643,7 @@ const RunSymbol$1 = Symbol.for("effect-cf/Worker/run");
689
643
  const renderHttpResponse = (effect) => Effect.flatMap(effect, (response) => Effect.map(Effect.context(), (context) => HttpServerResponse.toWeb(response, { context })));
690
644
  const renderFetchSuccess = (effect) => Effect.flatMap(effect, (response) => response instanceof Response ? Effect.succeed(response) : Effect.map(Effect.context(), (context) => HttpServerResponse.toWeb(response, { context })));
691
645
  const isWorkerOptions = (options) => typeof options === "object" && options !== null && ("fetch" in options || "queue" in options || "rpc" in options);
692
- function make$6(layer, optionsOrFetch) {
646
+ function make$7(layer, optionsOrFetch) {
693
647
  const options = isWorkerOptions(optionsOrFetch) ? optionsOrFetch : { fetch: optionsOrFetch };
694
648
  class EffectWorker extends WorkerEntrypoint {
695
649
  runtime;
@@ -720,7 +674,7 @@ function make$6(layer, optionsOrFetch) {
720
674
  return assumeEntrypointClass(EffectWorker);
721
675
  }
722
676
  const makeFetchHandler = (layer, options) => {
723
- const WorkerClass = make$6(layer, options);
677
+ const WorkerClass = make$7(layer, options);
724
678
  return { fetch: (request, env, ctx) => Promise.resolve(new WorkerClass(ctx, env).fetch(request)) };
725
679
  };
726
680
  const Tag$7 = Tag$8;
@@ -1021,7 +975,7 @@ var DurableObjectNamespace_exports = /* @__PURE__ */ __exportAll({
1021
975
  DurableObjectFetchError: () => DurableObjectFetchError,
1022
976
  DurableObjectRpcError: () => DurableObjectRpcError,
1023
977
  isDurableObjectNamespaceClient: () => isDurableObjectNamespaceClient,
1024
- layer: () => layer$6,
978
+ layer: () => layer$7,
1025
979
  makeClient: () => makeClient$4,
1026
980
  makeDirectMethods: () => makeDirectMethods
1027
981
  });
@@ -1103,7 +1057,7 @@ const makeClient$4 = (definition) => {
1103
1057
  });
1104
1058
  };
1105
1059
  };
1106
- const layer$6 = (tag, definition) => layer$9(tag, definition.binding, (value) => isDurableObjectNamespaceClient(value), makeClient$4(definition), { expected: expectedDurableObjectNamespace });
1060
+ const layer$7 = (tag, definition) => layer$10(tag, definition.binding, (value) => isDurableObjectNamespaceClient(value), makeClient$4(definition), { expected: expectedDurableObjectNamespace });
1107
1061
  const makeDirectMethods = (rpcDefinition, helpers) => {
1108
1062
  const methods = {};
1109
1063
  if (rpcDefinition !== void 0) {
@@ -1130,7 +1084,7 @@ var DurableObjectDefinition_exports = /* @__PURE__ */ __exportAll({
1130
1084
  DurableObject: () => DurableObject$1,
1131
1085
  Tag: () => Tag$6,
1132
1086
  implement: () => implement$3,
1133
- make: () => make$5,
1087
+ make: () => make$6,
1134
1088
  method: () => method$1
1135
1089
  });
1136
1090
  const reservedMethodNames$1 = new Set([
@@ -1161,13 +1115,13 @@ const method$1 = method$4;
1161
1115
  */
1162
1116
  const makeDefinition$2 = (id, methods) => {
1163
1117
  assertNoReservedMethods("Durable Object", methods, reservedMethodNames$1);
1164
- const definition = make$8(id, methods);
1165
- return Object.assign(definition, { make: (layer, options) => make$4(layer, {
1118
+ const definition = make$9(id, methods);
1119
+ return Object.assign(definition, { make: (layer, options) => make$5(layer, {
1166
1120
  ...options,
1167
1121
  rpc: wrapHandlers(definition, options.rpc)
1168
1122
  }) });
1169
1123
  };
1170
- const make$5 = (id, methods) => Tag$6()(id, methods);
1124
+ const make$6 = (id, methods) => Tag$6()(id, methods);
1171
1125
  const Tag$6 = () => (id, methods) => {
1172
1126
  const definition = makeDefinition$2(id, methods);
1173
1127
  const tag = Context.Service()(id);
@@ -1175,7 +1129,7 @@ const Tag$6 = () => (id, methods) => {
1175
1129
  ...binding,
1176
1130
  definition
1177
1131
  });
1178
- const layer = (binding) => layer$6(tag, bindingDefinition(binding));
1132
+ const layer = (binding) => layer$7(tag, bindingDefinition(binding));
1179
1133
  const newUniqueId = Effect.fnUntraced(function* (options) {
1180
1134
  return yield* (yield* tag).newUniqueId(options);
1181
1135
  });
@@ -1253,7 +1207,7 @@ const implement$3 = (_definition, handlers) => handlers;
1253
1207
  var DurableObject_exports = /* @__PURE__ */ __exportAll({
1254
1208
  Tag: () => Tag$5,
1255
1209
  implement: () => implement$2,
1256
- make: () => make$4,
1210
+ make: () => make$5,
1257
1211
  method: () => method
1258
1212
  });
1259
1213
  const reservedMethodNames = new Set([
@@ -1269,7 +1223,7 @@ const RunSymbol = Symbol.for("effect-cf/DurableObject/run");
1269
1223
  /**
1270
1224
  * Creates a Durable Object class backed by a single managed Effect runtime.
1271
1225
  */
1272
- const make$4 = (layer, options = {}) => {
1226
+ const make$5 = (layer, options = {}) => {
1273
1227
  class EffectDurableObject extends DurableObject {
1274
1228
  runtime;
1275
1229
  constructor(state, env) {
@@ -1314,6 +1268,378 @@ const Tag$5 = Tag$6;
1314
1268
  const method = method$1;
1315
1269
  const implement$2 = implement$3;
1316
1270
  //#endregion
1271
+ //#region src/CloudflareOtlp.ts
1272
+ var CloudflareOtlp_exports = /* @__PURE__ */ __exportAll({
1273
+ CloudflareOtlpSettings: () => CloudflareOtlpSettings,
1274
+ durableObjectLayer: () => durableObjectLayer,
1275
+ instrumentDurableObjectOptions: () => instrumentDurableObjectOptions,
1276
+ instrumentWorkerOptions: () => instrumentWorkerOptions,
1277
+ layer: () => layer$6,
1278
+ layerJson: () => layerJson,
1279
+ layerProtobuf: () => layerProtobuf,
1280
+ settingsConfig: () => settingsConfig,
1281
+ settingsLayer: () => settingsLayer,
1282
+ workerLayer: () => workerLayer
1283
+ });
1284
+ /**
1285
+ * Supported OpenTelemetry environment configuration for Cloudflare OTLP export.
1286
+ *
1287
+ * This config intentionally uses the conventional `OTEL_*` variable names so
1288
+ * deployments can share the same settings used by other OpenTelemetry SDKs.
1289
+ * It covers the OTLP HTTP settings supported by the Effect OTLP layers:
1290
+ *
1291
+ * - `OTEL_EXPORTER_OTLP_ENDPOINT`
1292
+ * - `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT`
1293
+ * - `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`
1294
+ * - `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`
1295
+ * - `OTEL_EXPORTER_OTLP_HEADERS`
1296
+ * - `OTEL_EXPORTER_OTLP_LOGS_HEADERS`
1297
+ * - `OTEL_EXPORTER_OTLP_TRACES_HEADERS`
1298
+ * - `OTEL_EXPORTER_OTLP_METRICS_HEADERS`
1299
+ * - `OTEL_SERVICE_NAME`
1300
+ * - `OTEL_RESOURCE_ATTRIBUTES`
1301
+ *
1302
+ * `OTEL_SERVICE_VERSION` is also accepted as an effect-cf convenience alias.
1303
+ * The standard OpenTelemetry way to configure service version is
1304
+ * `OTEL_RESOURCE_ATTRIBUTES=service.version=...`.
1305
+ *
1306
+ * Consumers with non-standard binding names should map those names into
1307
+ * {@link CloudflareOtlpSettings} rather than changing this config globally.
1308
+ */
1309
+ const settingsConfig = Config.all({
1310
+ endpoint: Config.string("OTEL_EXPORTER_OTLP_ENDPOINT").pipe(Config.option),
1311
+ logsEndpoint: Config.string("OTEL_EXPORTER_OTLP_LOGS_ENDPOINT").pipe(Config.option),
1312
+ tracesEndpoint: Config.string("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT").pipe(Config.option),
1313
+ metricsEndpoint: Config.string("OTEL_EXPORTER_OTLP_METRICS_ENDPOINT").pipe(Config.option),
1314
+ headers: Config.string("OTEL_EXPORTER_OTLP_HEADERS").pipe(Config.option),
1315
+ logsHeaders: Config.string("OTEL_EXPORTER_OTLP_LOGS_HEADERS").pipe(Config.option),
1316
+ tracesHeaders: Config.string("OTEL_EXPORTER_OTLP_TRACES_HEADERS").pipe(Config.option),
1317
+ metricsHeaders: Config.string("OTEL_EXPORTER_OTLP_METRICS_HEADERS").pipe(Config.option),
1318
+ serviceName: Config.string("OTEL_SERVICE_NAME").pipe(Config.option),
1319
+ serviceVersion: Config.string("OTEL_SERVICE_VERSION").pipe(Config.option),
1320
+ resourceAttributes: Config.schema(Config.Record(Schema.String, Schema.String), "OTEL_RESOURCE_ATTRIBUTES").pipe(Config.option)
1321
+ });
1322
+ /**
1323
+ * Service carrying already-resolved Cloudflare OTLP settings.
1324
+ *
1325
+ * Provide this service directly when an application needs to map custom
1326
+ * Cloudflare binding names, compute settings dynamically, or override settings
1327
+ * in tests. When this service is present, the OTLP layers use it instead of
1328
+ * reading {@link settingsConfig}.
1329
+ *
1330
+ * @example
1331
+ * ```ts
1332
+ * const CustomOtlpSettings = Layer.effect(
1333
+ * CloudflareOtlp.CloudflareOtlpSettings,
1334
+ * Config.all({
1335
+ * ...CloudflareOtlp.settingsConfig,
1336
+ * endpoint: Config.string("MY_OTLP_ENDPOINT").pipe(Config.option),
1337
+ * }),
1338
+ * ).pipe(Layer.provide(WorkerConfig.layer));
1339
+ * ```
1340
+ */
1341
+ var CloudflareOtlpSettings = class extends Context.Service()("effect-cf/CloudflareOtlpSettings") {};
1342
+ const allSignals = [
1343
+ "logs",
1344
+ "traces",
1345
+ "metrics"
1346
+ ];
1347
+ const optionToUndefined = (option) => Option.isSome(option) ? option.value : void 0;
1348
+ const nonEmptyStringOption = (option) => Option.flatMap(option, (value) => {
1349
+ const trimmed = value.trim();
1350
+ return trimmed === "" ? Option.none() : Option.some(trimmed);
1351
+ });
1352
+ const nonEmptyRecordOption = (option) => Option.filter(option, (value) => Object.keys(value).length > 0);
1353
+ const normalizeSettings = (settings) => ({
1354
+ endpoint: nonEmptyStringOption(settings.endpoint),
1355
+ logsEndpoint: nonEmptyStringOption(settings.logsEndpoint),
1356
+ tracesEndpoint: nonEmptyStringOption(settings.tracesEndpoint),
1357
+ metricsEndpoint: nonEmptyStringOption(settings.metricsEndpoint),
1358
+ headers: nonEmptyStringOption(settings.headers),
1359
+ logsHeaders: nonEmptyStringOption(settings.logsHeaders),
1360
+ tracesHeaders: nonEmptyStringOption(settings.tracesHeaders),
1361
+ metricsHeaders: nonEmptyStringOption(settings.metricsHeaders),
1362
+ serviceName: nonEmptyStringOption(settings.serviceName),
1363
+ serviceVersion: nonEmptyStringOption(settings.serviceVersion),
1364
+ resourceAttributes: nonEmptyRecordOption(settings.resourceAttributes)
1365
+ });
1366
+ /**
1367
+ * Layer that reads standard OpenTelemetry settings from the current Cloudflare
1368
+ * `env` object.
1369
+ *
1370
+ * The layer depends on {@link WorkerEnvironment} and installs a
1371
+ * Cloudflare-backed Effect `ConfigProvider`, so `settingsConfig` reads from
1372
+ * Worker vars/secrets instead of Node process environment variables.
1373
+ */
1374
+ const settingsLayer = Layer.effect(CloudflareOtlpSettings, settingsConfig.pipe(Config.map(normalizeSettings))).pipe(Layer.provide(WorkerConfig.layer));
1375
+ const selectedSignals = (signals) => new Set(signals ?? allSignals);
1376
+ const withDefinedAttributes = (attributes) => {
1377
+ const out = {};
1378
+ for (const [key, value] of Object.entries(attributes)) if (value !== void 0) out[key] = value;
1379
+ return out;
1380
+ };
1381
+ const parseHeaders = (input) => {
1382
+ if (Option.isNone(input) || input.value.trim() === "") return;
1383
+ const headers = {};
1384
+ for (const part of input.value.split(",")) {
1385
+ const index = part.indexOf("=");
1386
+ if (index <= 0) continue;
1387
+ const key = part.slice(0, index).trim();
1388
+ const value = part.slice(index + 1).trim();
1389
+ if (key !== "") headers[decodeHeaderComponent(key)] = decodeHeaderComponent(value);
1390
+ }
1391
+ return headers;
1392
+ };
1393
+ const mergeHeaders = (common, signalSpecific) => {
1394
+ const commonHeaders = parseHeaders(common);
1395
+ const signalHeaders = parseHeaders(signalSpecific);
1396
+ if (commonHeaders === void 0 && signalHeaders === void 0) return;
1397
+ return {
1398
+ ...commonHeaders,
1399
+ ...signalHeaders
1400
+ };
1401
+ };
1402
+ const decodeHeaderComponent = (value) => {
1403
+ try {
1404
+ return decodeURIComponent(value);
1405
+ } catch {
1406
+ return value;
1407
+ }
1408
+ };
1409
+ const appendOtlpPath = (baseUrl, path) => `${baseUrl.replace(/\/+$/, "")}${path}`;
1410
+ const makeResource = (settings, options, runtimeAttributes) => ({
1411
+ serviceName: options.serviceName ?? optionToUndefined(settings.serviceName),
1412
+ serviceVersion: options.serviceVersion ?? optionToUndefined(settings.serviceVersion),
1413
+ attributes: {
1414
+ ...optionToUndefined(settings.resourceAttributes),
1415
+ ...withDefinedAttributes(runtimeAttributes),
1416
+ ...options.attributes
1417
+ }
1418
+ });
1419
+ const commonOtlpOptions = (settings, options, runtimeAttributes) => ({
1420
+ resource: makeResource(settings, options, runtimeAttributes),
1421
+ maxBatchSize: options.maxBatchSize,
1422
+ loggerExportInterval: options.loggerExportInterval,
1423
+ loggerExcludeLogSpans: options.loggerExcludeLogSpans,
1424
+ loggerMergeWithExisting: options.loggerMergeWithExisting,
1425
+ tracerExportInterval: options.tracerExportInterval,
1426
+ tracerContext: options.tracerContext,
1427
+ metricsExportInterval: options.metricsExportInterval,
1428
+ metricsTemporality: options.metricsTemporality,
1429
+ shutdownTimeout: options.shutdownTimeout
1430
+ });
1431
+ const serializationLayer = (serialization) => serialization === "json" ? OtlpSerialization.layerJson : OtlpSerialization.layerProtobuf;
1432
+ const resolveSettings = Effect.gen(function* () {
1433
+ const settings = yield* Effect.serviceOption(CloudflareOtlpSettings);
1434
+ if (Option.isSome(settings)) return normalizeSettings(settings.value);
1435
+ const env = yield* Effect.serviceOption(WorkerEnvironment);
1436
+ if (Option.isSome(env)) return normalizeSettings(yield* settingsConfig.pipe(Effect.provide(ConfigProvider.layer(Effect.succeed(WorkerConfig.providerFromEnv(env.value))))));
1437
+ return normalizeSettings(yield* settingsConfig);
1438
+ });
1439
+ const mergeSignalLayers = (layers) => {
1440
+ if (layers.length === 0) return Layer.empty;
1441
+ let merged = layers[0];
1442
+ for (let index = 1; index < layers.length; index++) merged = Layer.mergeAll(merged, layers[index]);
1443
+ return merged;
1444
+ };
1445
+ const emptyLayer = Layer.empty;
1446
+ const makeLayerFromSettings = (options = {}, runtimeAttributes = {}) => Layer.unwrap(Effect.map(resolveSettings, (settings) => {
1447
+ const signals = selectedSignals(options.signals);
1448
+ const endpoint = optionToUndefined(settings.endpoint);
1449
+ const logsEndpoint = optionToUndefined(settings.logsEndpoint);
1450
+ const tracesEndpoint = optionToUndefined(settings.tracesEndpoint);
1451
+ const metricsEndpoint = optionToUndefined(settings.metricsEndpoint);
1452
+ const hasSpecificEndpoint = logsEndpoint !== void 0 || tracesEndpoint !== void 0 || metricsEndpoint !== void 0;
1453
+ const hasSpecificHeaders = Option.isSome(settings.logsHeaders) || Option.isSome(settings.tracesHeaders) || Option.isSome(settings.metricsHeaders);
1454
+ const common = commonOtlpOptions(settings, options, runtimeAttributes);
1455
+ if (endpoint !== void 0 && !hasSpecificEndpoint && !hasSpecificHeaders && signals.size === 3) return Otlp.layer({
1456
+ baseUrl: endpoint,
1457
+ headers: parseHeaders(settings.headers),
1458
+ ...common
1459
+ }).pipe(Layer.provide(serializationLayer(options.serialization)), Layer.provide(FetchHttpClient.layer));
1460
+ const layers = [];
1461
+ if (signals.has("logs")) {
1462
+ const url = logsEndpoint ?? (endpoint === void 0 ? void 0 : appendOtlpPath(endpoint, "/v1/logs"));
1463
+ if (url !== void 0) layers.push(OtlpLogger.layer({
1464
+ url,
1465
+ resource: common.resource,
1466
+ headers: mergeHeaders(settings.headers, settings.logsHeaders),
1467
+ exportInterval: common.loggerExportInterval,
1468
+ maxBatchSize: common.maxBatchSize,
1469
+ shutdownTimeout: common.shutdownTimeout,
1470
+ excludeLogSpans: common.loggerExcludeLogSpans,
1471
+ mergeWithExisting: common.loggerMergeWithExisting
1472
+ }).pipe(Layer.provide(serializationLayer(options.serialization)), Layer.provide(FetchHttpClient.layer)));
1473
+ }
1474
+ if (signals.has("traces")) {
1475
+ const url = tracesEndpoint ?? (endpoint === void 0 ? void 0 : appendOtlpPath(endpoint, "/v1/traces"));
1476
+ if (url !== void 0) layers.push(OtlpTracer.layer({
1477
+ url,
1478
+ resource: common.resource,
1479
+ headers: mergeHeaders(settings.headers, settings.tracesHeaders),
1480
+ exportInterval: common.tracerExportInterval,
1481
+ maxBatchSize: common.maxBatchSize,
1482
+ context: common.tracerContext,
1483
+ shutdownTimeout: common.shutdownTimeout
1484
+ }).pipe(Layer.provide(serializationLayer(options.serialization)), Layer.provide(FetchHttpClient.layer)));
1485
+ }
1486
+ if (signals.has("metrics")) {
1487
+ const url = metricsEndpoint ?? (endpoint === void 0 ? void 0 : appendOtlpPath(endpoint, "/v1/metrics"));
1488
+ if (url !== void 0) layers.push(OtlpMetrics.layer({
1489
+ url,
1490
+ resource: common.resource,
1491
+ headers: mergeHeaders(settings.headers, settings.metricsHeaders),
1492
+ exportInterval: common.metricsExportInterval,
1493
+ shutdownTimeout: common.shutdownTimeout,
1494
+ temporality: common.metricsTemporality
1495
+ }).pipe(Layer.provide(serializationLayer(options.serialization)), Layer.provide(FetchHttpClient.layer)));
1496
+ }
1497
+ return mergeSignalLayers(layers);
1498
+ }).pipe(Effect.catch((error) => Effect.logWarning("CloudflareOtlp disabled because OTLP configuration is invalid", { error: String(error) }).pipe(Effect.as(emptyLayer)))));
1499
+ const makeLayer = (options = {}, runtimeAttributes = {}) => makeLayerFromSettings(options, runtimeAttributes);
1500
+ /**
1501
+ * Base OTLP telemetry layer for Cloudflare-compatible runtimes.
1502
+ *
1503
+ * The layer reads {@link CloudflareOtlpSettings} when provided. Otherwise it
1504
+ * reads standard OpenTelemetry config from `WorkerEnvironment` when available,
1505
+ * then falls back to the ambient Effect `ConfigProvider`.
1506
+ *
1507
+ * When only `OTEL_EXPORTER_OTLP_ENDPOINT` is configured, per-signal paths are
1508
+ * derived by appending `/v1/logs`, `/v1/traces`, and `/v1/metrics`. Signal
1509
+ * specific endpoints are used as-is, matching the OpenTelemetry OTLP exporter
1510
+ * convention.
1511
+ */
1512
+ const layer$6 = (options = {}) => makeLayer(options);
1513
+ /** Base OTLP telemetry layer forced to JSON serialization. */
1514
+ const layerJson = (options = {}) => layer$6({
1515
+ ...options,
1516
+ serialization: "json"
1517
+ });
1518
+ /** Base OTLP telemetry layer forced to protobuf serialization. */
1519
+ const layerProtobuf = (options = {}) => layer$6({
1520
+ ...options,
1521
+ serialization: "protobuf"
1522
+ });
1523
+ /**
1524
+ * OTLP layer with Cloudflare Worker resource attributes.
1525
+ *
1526
+ * Provide this layer at runtime scope for long-lived metrics aggregation, or at
1527
+ * handler scope when traces/logs should flush as the Cloudflare event finishes.
1528
+ */
1529
+ const workerLayer = (options = {}) => makeLayer(options, {
1530
+ "cloudflare.resource_type": "worker",
1531
+ "cloudflare.worker.name": options.workerName
1532
+ });
1533
+ /**
1534
+ * OTLP layer with Cloudflare Durable Object resource attributes.
1535
+ *
1536
+ * The layer reads {@link DurableObjectState} so it can optionally include the
1537
+ * Durable Object id. Prefer leaving `includeObjectId` disabled unless the
1538
+ * backend can tolerate high-cardinality resource attributes.
1539
+ */
1540
+ const durableObjectLayer = (options = {}) => Layer.unwrap(Effect.map(DurableObjectState, (state) => makeLayer(options, {
1541
+ "cloudflare.resource_type": "durable_object",
1542
+ "cloudflare.durable_object.class": options.className,
1543
+ "cloudflare.durable_object.id": options.includeObjectId ? state.id.toString() : void 0
1544
+ })));
1545
+ const provideRpcLayer = (rpc, layer) => {
1546
+ if (rpc === void 0) return;
1547
+ return new Proxy(rpc, { get(target, property, receiver) {
1548
+ const handler = Reflect.get(target, property, receiver);
1549
+ if (typeof handler !== "function") return handler;
1550
+ return (...args) => Effect.suspend(() => Reflect.apply(handler, receiver, args)).pipe(Effect.provide(layer));
1551
+ } });
1552
+ };
1553
+ /**
1554
+ * Instrument Worker lifecycle handlers with event-scoped OTLP telemetry.
1555
+ *
1556
+ * Each defined handler is provided with {@link workerLayer}. Because Worker
1557
+ * handlers run inside `Effect.scoped`, the exporter scope closes and flushes at
1558
+ * the end of each Cloudflare event.
1559
+ */
1560
+ const instrumentWorkerOptions = (options) => (handlers) => {
1561
+ const telemetryLayer = workerLayer(options);
1562
+ const queue = handlers.queue;
1563
+ return {
1564
+ ...handlers,
1565
+ fetch: handlers.fetch === void 0 ? void 0 : handlers.fetch.pipe(Effect.provide(telemetryLayer)),
1566
+ queue: queue === void 0 ? void 0 : (batch) => queue(batch).pipe(Effect.provide(telemetryLayer)),
1567
+ rpc: provideRpcLayer(handlers.rpc, telemetryLayer)
1568
+ };
1569
+ };
1570
+ /**
1571
+ * Instrument Durable Object lifecycle handlers with event-scoped OTLP telemetry.
1572
+ *
1573
+ * Each defined handler is provided with {@link durableObjectLayer}. Because
1574
+ * Durable Object handlers run inside `Effect.scoped`, the exporter scope closes
1575
+ * and flushes at the end of each Cloudflare event.
1576
+ */
1577
+ const instrumentDurableObjectOptions = (options) => (handlers) => {
1578
+ const telemetryLayer = durableObjectLayer(options);
1579
+ const alarm = handlers.alarm;
1580
+ const webSocketMessage = handlers.webSocketMessage;
1581
+ const webSocketClose = handlers.webSocketClose;
1582
+ const webSocketError = handlers.webSocketError;
1583
+ return {
1584
+ ...handlers,
1585
+ initialize: handlers.initialize === void 0 ? void 0 : handlers.initialize.pipe(Effect.provide(telemetryLayer)),
1586
+ fetch: handlers.fetch === void 0 ? void 0 : handlers.fetch.pipe(Effect.provide(telemetryLayer)),
1587
+ alarms: handlers.alarms === void 0 ? void 0 : handlers.alarms.pipe(Effect.provide(telemetryLayer)),
1588
+ alarm: alarm === void 0 ? void 0 : (alarmInfo) => alarm(alarmInfo).pipe(Effect.provide(telemetryLayer)),
1589
+ webSocketMessage: webSocketMessage === void 0 ? void 0 : (socket, message) => webSocketMessage(socket, message).pipe(Effect.provide(telemetryLayer)),
1590
+ webSocketClose: webSocketClose === void 0 ? void 0 : (socket, code, reason, wasClean) => webSocketClose(socket, code, reason, wasClean).pipe(Effect.provide(telemetryLayer)),
1591
+ webSocketError: webSocketError === void 0 ? void 0 : (socket, error) => webSocketError(socket, error).pipe(Effect.provide(telemetryLayer)),
1592
+ rpc: provideRpcLayer(handlers.rpc, telemetryLayer)
1593
+ };
1594
+ };
1595
+ //#endregion
1596
+ //#region src/D1.ts
1597
+ var D1_exports = /* @__PURE__ */ __exportAll({
1598
+ Service: () => Service,
1599
+ make: () => make$4
1600
+ });
1601
+ const TypeId$1 = "effect-cf/D1";
1602
+ const expectedD1Database = "D1 database binding with prepare(), batch(), and exec()";
1603
+ const isD1Database = (value) => {
1604
+ if (typeof value !== "object" || value === null) return false;
1605
+ const resource = value;
1606
+ return typeof resource.prepare === "function" && typeof resource.batch === "function" && typeof resource.exec === "function";
1607
+ };
1608
+ /**
1609
+ * Creates a typed D1 service tag plus Effect helpers.
1610
+ */
1611
+ const make$4 = (id, definition) => Service()(id, definition);
1612
+ /**
1613
+ * Builds a D1 service around a Cloudflare D1 database binding.
1614
+ *
1615
+ * The returned service exposes the raw `D1Database` binding and `sqlLayer(...)`
1616
+ * for providing `effect/unstable/sql` via `@effect/sql-d1`.
1617
+ *
1618
+ * @example
1619
+ * ```ts
1620
+ * class TodoDatabase extends D1.Service<TodoDatabase>()("TodoDatabase", {
1621
+ * binding: "TODO_DB",
1622
+ * }) {}
1623
+ *
1624
+ * const SqlLive = TodoDatabase.sqlLayer();
1625
+ * ```
1626
+ */
1627
+ const Service = () => (id, definition) => {
1628
+ const tag = Service$2()(id, definition.binding, isD1Database, void 0, { expected: expectedD1Database });
1629
+ const sqlLayer = (options) => Layer.unwrap(Effect.gen(function* () {
1630
+ const db = yield* tag;
1631
+ return D1Client.layer({
1632
+ ...options,
1633
+ db
1634
+ });
1635
+ })).pipe(Layer.provide(tag.layer));
1636
+ return Object.assign(tag, {
1637
+ [TypeId$1]: TypeId$1,
1638
+ definition,
1639
+ sqlLayer
1640
+ });
1641
+ };
1642
+ //#endregion
1317
1643
  //#region src/DurableObjectAlarm.ts
1318
1644
  var DurableObjectAlarm_exports = /* @__PURE__ */ __exportAll({
1319
1645
  DurableObjectAlarm: () => DurableObjectAlarm,
@@ -1879,7 +2205,7 @@ const makeClient$3 = (definition) => (images) => {
1879
2205
  unsafeRaw: Effect.succeed(images)
1880
2206
  };
1881
2207
  };
1882
- const layer$3 = (tag, definition) => layer$9(tag, definition.binding, isImagesBinding, makeClient$3(definition), { expected: expectedImagesBinding });
2208
+ const layer$3 = (tag, definition) => layer$10(tag, definition.binding, isImagesBinding, makeClient$3(definition), { expected: expectedImagesBinding });
1883
2209
  const make$3 = (id) => Tag$4()(id);
1884
2210
  const Tag$4 = () => (id) => {
1885
2211
  const tag = Context.Service()(id);
@@ -1974,7 +2300,7 @@ const makeClient$2 = (definition) => {
1974
2300
  unsafeRaw: Effect.succeed(kv)
1975
2301
  });
1976
2302
  };
1977
- const layer$2 = (tag, definition) => layer$9(tag, definition.binding, isKvNamespace, makeClient$2(definition), { expected: expectedKvNamespace });
2303
+ const layer$2 = (tag, definition) => layer$10(tag, definition.binding, isKvNamespace, makeClient$2(definition), { expected: expectedKvNamespace });
1978
2304
  const makeDefinition$1 = (id, definition) => {
1979
2305
  const kvDefinition = {
1980
2306
  id,
@@ -2091,7 +2417,7 @@ const makeClient$1 = (definition) => {
2091
2417
  };
2092
2418
  };
2093
2419
  };
2094
- const layer$1 = (tag, definition) => layer$9(tag, definition.binding, isR2Bucket, makeClient$1(definition), { expected: expectedR2Bucket });
2420
+ const layer$1 = (tag, definition) => layer$10(tag, definition.binding, isR2Bucket, makeClient$1(definition), { expected: expectedR2Bucket });
2095
2421
  const make$2 = (id) => Tag$2()(id);
2096
2422
  const Tag$2 = () => (id) => {
2097
2423
  const tag = Context.Service()(id);
@@ -2177,7 +2503,7 @@ const makeClient = (definition) => {
2177
2503
  unsafeRaw: Effect.succeed(workflow)
2178
2504
  });
2179
2505
  };
2180
- const layer = (tag, definition) => layer$9(tag, definition.binding, (value) => isWorkflow(value), makeClient(definition), { expected: expectedWorkflow });
2506
+ const layer = (tag, definition) => layer$10(tag, definition.binding, (value) => isWorkflow(value), makeClient(definition), { expected: expectedWorkflow });
2181
2507
  //#endregion
2182
2508
  //#region src/WorkflowDefinition.ts
2183
2509
  var WorkflowDefinition_exports = /* @__PURE__ */ __exportAll({
@@ -2198,7 +2524,7 @@ const make$1 = (id, definition) => Tag$1()(id, definition);
2198
2524
  const Tag$1 = () => (id, definition) => {
2199
2525
  const workflowDefinition = makeDefinition(id, definition);
2200
2526
  const tag = Context.Service()(id);
2201
- const layer$10 = (binding) => layer(tag, {
2527
+ const layer$11 = (binding) => layer(tag, {
2202
2528
  ...binding,
2203
2529
  payload: definition.payload,
2204
2530
  result: definition.result
@@ -2220,7 +2546,7 @@ const Tag$1 = () => (id, definition) => {
2220
2546
  payload: workflowDefinition.payload,
2221
2547
  result: workflowDefinition.result,
2222
2548
  make: workflowDefinition.make,
2223
- layer: layer$10,
2549
+ layer: layer$11,
2224
2550
  create,
2225
2551
  createBatch,
2226
2552
  get,
@@ -2311,4 +2637,4 @@ const waitForEvent = (name, options) => Effect.flatMap(WorkflowStep$1, (workflow
2311
2637
  const Tag = Tag$1;
2312
2638
  const implement = implement$1;
2313
2639
  //#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 };
2640
+ 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 };