effect-cf 0.13.0 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # effect-cf
2
2
 
3
+ ## 0.13.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#41](https://github.com/danieljvdm/effect-cf/pull/41) [`6e1ddc9`](https://github.com/danieljvdm/effect-cf/commit/6e1ddc9e246ee966dee7a66eae38739241d23816) Thanks [@danieljvdm](https://github.com/danieljvdm)! - Provide an epoch-based Effect clock in Worker and Durable Object runtimes so OTLP
8
+ span and log timestamps are valid under Cloudflare workerd.
9
+
3
10
  ## 0.13.0
4
11
 
5
12
  ### Minor Changes
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./chunk-CfYAbeIz.mjs";
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";
2
+ import { a as WorkerConfig, i as layer$11, n as Binding_exports, o as WorkerEnvironment, r as Service$2, t as Hyperdrive_exports } from "./Hyperdrive-89hg_Fck.mjs";
3
3
  import { Cause, Clock, Config, ConfigProvider, Context, Data, DateTime, Duration, Effect, Exit, Layer, ManagedRuntime, Option, Queue, Schema } from "effect";
4
4
  import { FetchHttpClient, HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
5
5
  import { Otlp, OtlpLogger, OtlpMetrics, OtlpSerialization, OtlpTracer } from "effect/unstable/observability";
@@ -302,7 +302,7 @@ const runPromiseExitPreservingTypedFailures = async (effect) => {
302
302
  var CloudflareOtlp_exports = /* @__PURE__ */ __exportAll({
303
303
  CloudflareOtlpSettings: () => CloudflareOtlpSettings,
304
304
  durableObjectLayer: () => durableObjectLayer,
305
- layer: () => layer$9,
305
+ layer: () => layer$10,
306
306
  layerJson: () => layerJson,
307
307
  layerProtobuf: () => layerProtobuf,
308
308
  settingsConfig: () => settingsConfig,
@@ -537,14 +537,14 @@ const makeLayer = (options = {}, runtimeAttributes = {}) => makeLayerFromSetting
537
537
  * specific endpoints are used as-is, matching the OpenTelemetry OTLP exporter
538
538
  * convention.
539
539
  */
540
- const layer$9 = (options = {}) => makeLayer(options);
540
+ const layer$10 = (options = {}) => makeLayer(options);
541
541
  /** Base OTLP telemetry layer forced to JSON serialization. */
542
- const layerJson = (options = {}) => layer$9({
542
+ const layerJson = (options = {}) => layer$10({
543
543
  ...options,
544
544
  serialization: "json"
545
545
  });
546
546
  /** Base OTLP telemetry layer forced to protobuf serialization. */
547
- const layerProtobuf = (options = {}) => layer$9({
547
+ const layerProtobuf = (options = {}) => layer$10({
548
548
  ...options,
549
549
  serialization: "protobuf"
550
550
  });
@@ -622,7 +622,7 @@ const Service$1 = () => (id, definition) => {
622
622
  var QueueBinding_exports = /* @__PURE__ */ __exportAll({
623
623
  QueueOperationError: () => QueueOperationError,
624
624
  isQueue: () => isQueue,
625
- layer: () => layer$8,
625
+ layer: () => layer$9,
626
626
  makeClient: () => makeClient$6
627
627
  });
628
628
  const expectedQueueProducer = "Queue producer binding with send(); optional sendBatch()/metrics()";
@@ -678,7 +678,7 @@ const makeClient$6 = (definition) => {
678
678
  unsafeRaw: Effect.succeed(queue)
679
679
  });
680
680
  };
681
- const layer$8 = (tag, definition) => layer$10(tag, definition.binding, (value) => isQueue(value), makeClient$6(definition), { expected: expectedQueueProducer });
681
+ const layer$9 = (tag, definition) => layer$11(tag, definition.binding, (value) => isQueue(value), makeClient$6(definition), { expected: expectedQueueProducer });
682
682
  //#endregion
683
683
  //#region src/QueueDefinition.ts
684
684
  var QueueDefinition_exports = /* @__PURE__ */ __exportAll({
@@ -701,7 +701,7 @@ const make$9 = (id, definition) => Tag$10()(id, definition);
701
701
  const Tag$10 = () => (id, definition) => {
702
702
  const queueDefinition = makeDefinition$4(id, definition);
703
703
  const tag = Context.Service()(id);
704
- const layer = (binding) => layer$8(tag, {
704
+ const layer = (binding) => layer$9(tag, {
705
705
  ...binding,
706
706
  message: definition.message
707
707
  });
@@ -957,7 +957,7 @@ var ServiceBinding_exports = /* @__PURE__ */ __exportAll({
957
957
  ServiceBindingFetchError: () => ServiceBindingFetchError,
958
958
  ServiceBindingRpcError: () => ServiceBindingRpcError,
959
959
  isServiceBindingClient: () => isServiceBindingClient,
960
- layer: () => layer$7,
960
+ layer: () => layer$8,
961
961
  makeClient: () => makeClient$5,
962
962
  makeDirectMethods: () => makeDirectMethods$1
963
963
  });
@@ -1021,7 +1021,7 @@ const makeClient$5 = (definition) => {
1021
1021
  });
1022
1022
  };
1023
1023
  };
1024
- const layer$7 = (tag, definition) => layer$10(tag, definition.binding, (value) => isServiceBindingClient(value), makeClient$5(definition), { expected: expectedServiceBinding });
1024
+ const layer$8 = (tag, definition) => layer$11(tag, definition.binding, (value) => isServiceBindingClient(value), makeClient$5(definition), { expected: expectedServiceBinding });
1025
1025
  /**
1026
1026
  * Creates a typed Effect service for a Worker service binding.
1027
1027
  *
@@ -1138,7 +1138,7 @@ const Tag$8 = () => (id, methods) => {
1138
1138
  ...binding,
1139
1139
  definition
1140
1140
  });
1141
- const layer = (binding) => layer$7(tag, bindingDefinition(binding));
1141
+ const layer = (binding) => layer$8(tag, bindingDefinition(binding));
1142
1142
  const fetch = (input, init) => Effect.gen(function* () {
1143
1143
  return yield* (yield* tag).fetch(input, init);
1144
1144
  });
@@ -1179,6 +1179,26 @@ const wrapHandlers$1 = (definition, handlers) => {
1179
1179
  */
1180
1180
  const implement$5 = (_definition, handlers) => handlers;
1181
1181
  //#endregion
1182
+ //#region src/internal/Clock.ts
1183
+ const maxTimerMillis = 2 ** 31 - 1;
1184
+ const nanosPerMilli = BigInt(1e6);
1185
+ const clock = {
1186
+ currentTimeMillisUnsafe: () => Date.now(),
1187
+ currentTimeMillis: Effect.sync(() => clock.currentTimeMillisUnsafe()),
1188
+ currentTimeNanosUnsafe: () => BigInt(Date.now()) * nanosPerMilli,
1189
+ currentTimeNanos: Effect.sync(() => clock.currentTimeNanosUnsafe()),
1190
+ sleep: (duration) => {
1191
+ const millis = Duration.toMillis(duration);
1192
+ if (millis <= 0) return Effect.yieldNow;
1193
+ return Effect.callback((resume) => {
1194
+ if (millis > maxTimerMillis) return;
1195
+ const handle = setTimeout(() => resume(Effect.void), millis);
1196
+ return Effect.sync(() => clearTimeout(handle));
1197
+ });
1198
+ }
1199
+ };
1200
+ const layer$7 = Layer.effect(Clock.Clock, Effect.succeed(clock));
1201
+ //#endregion
1182
1202
  //#region src/internal/Entrypoint.ts
1183
1203
  const provideEntrypointServices = (layer, services) => layer.pipe(Layer.provideMerge(services));
1184
1204
  const defineEntrypointRpcMethods = (target, prototype, rpc, reservedMethodNames, run) => {
@@ -1259,7 +1279,7 @@ function make$6(layer, optionsOrFetch) {
1259
1279
  constructor(ctx, env) {
1260
1280
  super(ctx, env);
1261
1281
  let runWaitUntilEffect = () => Promise.reject(/* @__PURE__ */ new Error("WorkerContext runtime is not initialized"));
1262
- const runtimeLayer = provideEntrypointServices(layer, Layer.mergeAll(Layer.succeed(ExecutionContext, ctx), ConfigProvider.layer(Effect.succeed(WorkerConfig.providerFromEnv(env))), Layer.succeed(WorkerContext, fromExecutionContext(ctx, (effect) => runWaitUntilEffect(effect))), Layer.succeed(WorkerEnvironment, env)));
1282
+ const runtimeLayer = provideEntrypointServices(layer, Layer.mergeAll(layer$7, Layer.succeed(ExecutionContext, ctx), ConfigProvider.layer(Effect.succeed(WorkerConfig.providerFromEnv(env))), Layer.succeed(WorkerContext, fromExecutionContext(ctx, (effect) => runWaitUntilEffect(effect))), Layer.succeed(WorkerEnvironment, env)));
1263
1283
  this.runtime = ManagedRuntime.make(runtimeLayer);
1264
1284
  runWaitUntilEffect = (effect) => this.runtime.runPromiseExit(effect);
1265
1285
  }
@@ -1378,7 +1398,7 @@ const makeClient$4 = (definition) => {
1378
1398
  });
1379
1399
  };
1380
1400
  };
1381
- const layer$6 = (tag, definition) => layer$10(tag, definition.binding, (value) => isDurableObjectNamespaceClient(value), makeClient$4(definition), { expected: expectedDurableObjectNamespace });
1401
+ const layer$6 = (tag, definition) => layer$11(tag, definition.binding, (value) => isDurableObjectNamespaceClient(value), makeClient$4(definition), { expected: expectedDurableObjectNamespace });
1382
1402
  const makeDirectMethods = (rpcDefinition, helpers) => {
1383
1403
  const methods = {};
1384
1404
  if (rpcDefinition !== void 0) {
@@ -1549,7 +1569,7 @@ const make$4 = (layer, options = {}) => {
1549
1569
  runtime;
1550
1570
  constructor(state, env) {
1551
1571
  super(state, env);
1552
- const runtimeLayer = provideEntrypointServices(layer, Layer.mergeAll(Layer.succeed(DurableObjectState, fromDurableObjectState(state)), Layer.succeed(WorkerEnvironment, env)));
1572
+ const runtimeLayer = provideEntrypointServices(layer, Layer.mergeAll(layer$7, Layer.succeed(DurableObjectState, fromDurableObjectState(state)), Layer.succeed(WorkerEnvironment, env)));
1553
1573
  this.runtime = ManagedRuntime.make(runtimeLayer);
1554
1574
  const initialize = options.initialize;
1555
1575
  if (initialize !== void 0) state.waitUntil(this[RunSymbol](initialize, { eventLayer: false }));
@@ -2155,7 +2175,7 @@ const makeClient$3 = (definition) => (images) => {
2155
2175
  unsafeRaw: Effect.succeed(images)
2156
2176
  };
2157
2177
  };
2158
- const layer$3 = (tag, definition) => layer$10(tag, definition.binding, isImagesBinding, makeClient$3(definition), { expected: expectedImagesBinding });
2178
+ const layer$3 = (tag, definition) => layer$11(tag, definition.binding, isImagesBinding, makeClient$3(definition), { expected: expectedImagesBinding });
2159
2179
  const make$3 = (id) => Tag$4()(id);
2160
2180
  const Tag$4 = () => (id) => {
2161
2181
  const tag = Context.Service()(id);
@@ -2250,7 +2270,7 @@ const makeClient$2 = (definition) => {
2250
2270
  unsafeRaw: Effect.succeed(kv)
2251
2271
  });
2252
2272
  };
2253
- const layer$2 = (tag, definition) => layer$10(tag, definition.binding, isKvNamespace, makeClient$2(definition), { expected: expectedKvNamespace });
2273
+ const layer$2 = (tag, definition) => layer$11(tag, definition.binding, isKvNamespace, makeClient$2(definition), { expected: expectedKvNamespace });
2254
2274
  const makeDefinition$1 = (id, definition) => {
2255
2275
  const kvDefinition = {
2256
2276
  id,
@@ -2367,7 +2387,7 @@ const makeClient$1 = (definition) => {
2367
2387
  };
2368
2388
  };
2369
2389
  };
2370
- const layer$1 = (tag, definition) => layer$10(tag, definition.binding, isR2Bucket, makeClient$1(definition), { expected: expectedR2Bucket });
2390
+ const layer$1 = (tag, definition) => layer$11(tag, definition.binding, isR2Bucket, makeClient$1(definition), { expected: expectedR2Bucket });
2371
2391
  const make$2 = (id) => Tag$2()(id);
2372
2392
  const Tag$2 = () => (id) => {
2373
2393
  const tag = Context.Service()(id);
@@ -2453,7 +2473,7 @@ const makeClient = (definition) => {
2453
2473
  unsafeRaw: Effect.succeed(workflow)
2454
2474
  });
2455
2475
  };
2456
- const layer = (tag, definition) => layer$10(tag, definition.binding, (value) => isWorkflow(value), makeClient(definition), { expected: expectedWorkflow });
2476
+ const layer = (tag, definition) => layer$11(tag, definition.binding, (value) => isWorkflow(value), makeClient(definition), { expected: expectedWorkflow });
2457
2477
  //#endregion
2458
2478
  //#region src/WorkflowDefinition.ts
2459
2479
  var WorkflowDefinition_exports = /* @__PURE__ */ __exportAll({
@@ -2474,7 +2494,7 @@ const make$1 = (id, definition) => Tag$1()(id, definition);
2474
2494
  const Tag$1 = () => (id, definition) => {
2475
2495
  const workflowDefinition = makeDefinition(id, definition);
2476
2496
  const tag = Context.Service()(id);
2477
- const layer$11 = (binding) => layer(tag, {
2497
+ const layer$12 = (binding) => layer(tag, {
2478
2498
  ...binding,
2479
2499
  payload: definition.payload,
2480
2500
  result: definition.result
@@ -2496,7 +2516,7 @@ const Tag$1 = () => (id, definition) => {
2496
2516
  payload: workflowDefinition.payload,
2497
2517
  result: workflowDefinition.result,
2498
2518
  make: workflowDefinition.make,
2499
- layer: layer$11,
2519
+ layer: layer$12,
2500
2520
  create,
2501
2521
  createBatch,
2502
2522
  get,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "effect-cf",
3
- "version": "0.13.0",
3
+ "version": "0.13.1",
4
4
  "description": "Effect-native primitives for Cloudflare Workers and bindings.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -10,6 +10,7 @@ import type * as Binding from "./Binding";
10
10
  import * as DurableObjectDefinition from "./DurableObjectDefinition";
11
11
  import type * as DurableObjectNamespace from "./DurableObjectNamespace";
12
12
  import type * as Rpc from "./Rpc";
13
+ import * as CloudflareClock from "./internal/Clock";
13
14
  import * as Entrypoint from "./internal/Entrypoint";
14
15
 
15
16
  const reservedMethodNames = new Set<string>([
@@ -161,6 +162,7 @@ export const make = <
161
162
  super(state, env);
162
163
 
163
164
  const services = Layer.mergeAll(
165
+ CloudflareClock.layer,
164
166
  Layer.succeed(DurableObjectState, fromDurableObjectState(state)),
165
167
  Layer.succeed(WorkerEnvironment, env),
166
168
  );
package/src/Worker.ts CHANGED
@@ -10,6 +10,7 @@ import type * as Rpc from "./Rpc";
10
10
  import type * as RpcDefinition from "./RpcDefinition";
11
11
  import type * as ServiceBinding from "./ServiceBinding";
12
12
  import * as WorkerDefinition from "./WorkerDefinition";
13
+ import * as CloudflareClock from "./internal/Clock";
13
14
  import * as Entrypoint from "./internal/Entrypoint";
14
15
  import { fromExecutionContext, type RunWaitUntilEffect } from "./internal/WorkerContext";
15
16
 
@@ -241,6 +242,7 @@ export function make<
241
242
  Promise.reject(new Error("WorkerContext runtime is not initialized"));
242
243
 
243
244
  const services = Layer.mergeAll(
245
+ CloudflareClock.layer,
244
246
  Layer.succeed(ExecutionContext, ctx),
245
247
  ConfigProvider.layer(Effect.succeed(WorkerConfig.providerFromEnv(env))),
246
248
  Layer.succeed(
@@ -0,0 +1,28 @@
1
+ import { Clock, Duration, Effect, Layer } from "effect";
2
+
3
+ const maxTimerMillis = 2 ** 31 - 1;
4
+ const nanosPerMilli = BigInt(1_000_000);
5
+
6
+ export const clock: Clock.Clock = {
7
+ currentTimeMillisUnsafe: () => Date.now(),
8
+ currentTimeMillis: Effect.sync(() => clock.currentTimeMillisUnsafe()),
9
+ currentTimeNanosUnsafe: () => BigInt(Date.now()) * nanosPerMilli,
10
+ currentTimeNanos: Effect.sync(() => clock.currentTimeNanosUnsafe()),
11
+ sleep: (duration) => {
12
+ const millis = Duration.toMillis(duration);
13
+ if (millis <= 0) {
14
+ return Effect.yieldNow;
15
+ }
16
+
17
+ return Effect.callback<void>((resume) => {
18
+ if (millis > maxTimerMillis) {
19
+ return;
20
+ }
21
+
22
+ const handle = setTimeout(() => resume(Effect.void), millis);
23
+ return Effect.sync(() => clearTimeout(handle));
24
+ });
25
+ },
26
+ };
27
+
28
+ export const layer = Layer.effect(Clock.Clock, Effect.succeed(clock));