effect-cf 0.15.0 → 0.17.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,7 +1,7 @@
1
1
  import { t as __exportAll } from "./chunk-CfYAbeIz.mjs";
2
- import { a as WorkerConfig, i as layer$16, 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 { FetchHttpClient, HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
2
+ import { a as WorkerConfig, i as layer$18, 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, Result, Schema } from "effect";
4
+ import { FetchHttpClient, HttpClient, HttpClientRequest, HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
5
5
  import { OtlpLogger, OtlpMetrics, OtlpSerialization, OtlpTracer } from "effect/unstable/observability";
6
6
  import { D1Client } from "@effect/sql-d1";
7
7
  import { DurableObject, RpcStub, RpcTarget, WorkerEntrypoint, WorkflowEntrypoint } from "cloudflare:workers";
@@ -11,13 +11,13 @@ import * as RpcServer from "effect/unstable/rpc/RpcServer";
11
11
  import { SqliteClient } from "@effect/sql-sqlite-do";
12
12
  //#region src/WorkersAi.ts
13
13
  var WorkersAi_exports = /* @__PURE__ */ __exportAll({
14
- Tag: () => Tag$15,
14
+ Tag: () => Tag$17,
15
15
  WorkersAiOperationError: () => WorkersAiOperationError,
16
16
  embeddingResponse: () => embeddingResponse,
17
17
  isWorkersAiBinding: () => isWorkersAiBinding,
18
- layer: () => layer$15,
19
- make: () => make$15,
20
- makeClient: () => makeClient$11
18
+ layer: () => layer$17,
19
+ make: () => make$17,
20
+ makeClient: () => makeClient$13
21
21
  });
22
22
  const expectedWorkersAiBinding = "Workers AI binding with run(), gateway(), and models()";
23
23
  /** Error raised when a Workers AI operation fails. */
@@ -41,7 +41,7 @@ const embeddingResponse = (value) => ({
41
41
  data: value.data ?? [],
42
42
  shape: value.shape ?? []
43
43
  });
44
- const makeClient$11 = (definition) => (ai) => {
44
+ const makeClient$13 = (definition) => (ai) => {
45
45
  const run = ((model, input, options) => tryWorkersAiPromise(definition.binding, "run", () => ai.run(model, input, options)));
46
46
  return {
47
47
  definition,
@@ -53,11 +53,11 @@ const makeClient$11 = (definition) => (ai) => {
53
53
  unsafeRaw: Effect.succeed(ai)
54
54
  };
55
55
  };
56
- const layer$15 = (tag, definition) => layer$16(tag, definition.binding, (value) => isWorkersAiBinding(value), makeClient$11(definition), { expected: expectedWorkersAiBinding });
57
- const make$15 = (id) => Tag$15()(id);
58
- const Tag$15 = () => (id) => {
56
+ const layer$17 = (tag, definition) => layer$18(tag, definition.binding, (value) => isWorkersAiBinding(value), makeClient$13(definition), { expected: expectedWorkersAiBinding });
57
+ const make$17 = (id) => Tag$17()(id);
58
+ const Tag$17 = () => (id) => {
59
59
  const tag = Context.Service()(id);
60
- const makeLayer = (definition) => layer$15(tag, definition);
60
+ const makeLayer = (definition) => layer$17(tag, definition);
61
61
  return Object.assign(tag, {
62
62
  id,
63
63
  layer: makeLayer
@@ -67,11 +67,11 @@ const Tag$15 = () => (id) => {
67
67
  //#region src/AiGateway.ts
68
68
  var AiGateway_exports = /* @__PURE__ */ __exportAll({
69
69
  AiGatewayOperationError: () => AiGatewayOperationError,
70
- Tag: () => Tag$14,
70
+ Tag: () => Tag$16,
71
71
  isAiGatewayBinding: () => isAiGatewayBinding,
72
- layer: () => layer$14,
73
- make: () => make$14,
74
- makeClient: () => makeClient$10,
72
+ layer: () => layer$16,
73
+ make: () => make$16,
74
+ makeClient: () => makeClient$12,
75
75
  makeClientFromAi: () => makeClientFromAi,
76
76
  makeHttpClient: () => makeHttpClient
77
77
  });
@@ -98,7 +98,7 @@ const providerUrl = (baseUrl, path = "") => {
98
98
  };
99
99
  const gatewayUrl = (definition) => `https://gateway.ai.cloudflare.com/v1/${definition.accountId}/${definition.gatewayId}/`;
100
100
  const isAiGatewayBinding = (value) => isWorkersAiBinding(value);
101
- const makeClient$10 = (definition, gateway) => ({
101
+ const makeClient$12 = (definition, gateway) => ({
102
102
  definition,
103
103
  run: (data, options) => tryAiGatewayPromise(definition.binding, "run", () => gateway.run(Array.isArray(data) ? [...data] : data, options)),
104
104
  getUrl: (provider) => tryAiGatewayPromise(definition.binding, "getUrl", () => gateway.getUrl(provider)),
@@ -115,11 +115,11 @@ const makeClientFromAi = (definition, ai) => {
115
115
  const withGateway = (operation) => gateway.pipe(Effect.flatMap(operation));
116
116
  return {
117
117
  definition,
118
- run: (data, options) => withGateway((raw) => makeClient$10(definition, raw).run(data, options)),
119
- getUrl: (provider) => withGateway((raw) => makeClient$10(definition, raw).getUrl(provider)),
120
- fetch: (options) => withGateway((raw) => makeClient$10(definition, raw).fetch(options)),
121
- patchLog: (logId, data) => withGateway((raw) => makeClient$10(definition, raw).patchLog(logId, data)),
122
- getLog: (logId) => withGateway((raw) => makeClient$10(definition, raw).getLog(logId)),
118
+ run: (data, options) => withGateway((raw) => makeClient$12(definition, raw).run(data, options)),
119
+ getUrl: (provider) => withGateway((raw) => makeClient$12(definition, raw).getUrl(provider)),
120
+ fetch: (options) => withGateway((raw) => makeClient$12(definition, raw).fetch(options)),
121
+ patchLog: (logId, data) => withGateway((raw) => makeClient$12(definition, raw).patchLog(logId, data)),
122
+ getLog: (logId) => withGateway((raw) => makeClient$12(definition, raw).getLog(logId)),
123
123
  unsafeRaw: gateway
124
124
  };
125
125
  };
@@ -159,25 +159,291 @@ const makeHttpClient = (definition, request = fetch) => {
159
159
  unsafeRaw: Effect.fail(aiGatewayError(binding, "unsafeRaw", /* @__PURE__ */ new TypeError("HTTP AI Gateway clients have no raw binding")))
160
160
  };
161
161
  };
162
- const layer$14 = (tag, definition) => layer$16(tag, definition.binding, isAiGatewayBinding, (ai) => makeClientFromAi(definition, ai), { expected: expectedAiGatewayBinding });
163
- const make$14 = (id) => Tag$14()(id);
164
- const Tag$14 = () => (id) => {
162
+ const layer$16 = (tag, definition) => layer$18(tag, definition.binding, isAiGatewayBinding, (ai) => makeClientFromAi(definition, ai), { expected: expectedAiGatewayBinding });
163
+ const make$16 = (id) => Tag$16()(id);
164
+ const Tag$16 = () => (id) => {
165
165
  const tag = Context.Service()(id);
166
- const makeLayer = (definition) => layer$14(tag, definition);
166
+ const makeLayer = (definition) => layer$16(tag, definition);
167
167
  return Object.assign(tag, {
168
168
  id,
169
169
  layer: makeLayer
170
170
  });
171
171
  };
172
172
  //#endregion
173
+ //#region src/AnalyticsEngine.ts
174
+ var AnalyticsEngine_exports = /* @__PURE__ */ __exportAll({
175
+ AnalyticsEngineDataPointSchema: () => AnalyticsEngineDataPointSchema,
176
+ AnalyticsEngineFieldValueSchema: () => AnalyticsEngineFieldValueSchema,
177
+ AnalyticsEngineOperationError: () => AnalyticsEngineOperationError,
178
+ AnalyticsEngineQueryError: () => AnalyticsEngineQueryError,
179
+ AnalyticsEngineWriteValidationError: () => AnalyticsEngineWriteValidationError,
180
+ QueryTag: () => QueryTag,
181
+ Tag: () => Tag$15,
182
+ isAnalyticsEngineDataset: () => isAnalyticsEngineDataset,
183
+ layer: () => layer$15,
184
+ make: () => make$15,
185
+ makeClient: () => makeClient$11,
186
+ makeQuery: () => makeQuery,
187
+ makeQueryClient: () => makeQueryClient,
188
+ queryConfig: () => queryConfig,
189
+ queryFetchLayer: () => queryFetchLayer,
190
+ queryFetchLayerConfig: () => queryFetchLayerConfig,
191
+ queryLayer: () => queryLayer,
192
+ queryLayerConfig: () => queryLayerConfig,
193
+ writeLimits: () => writeLimits
194
+ });
195
+ const expectedAnalyticsEngineDataset = "Analytics Engine dataset binding with writeDataPoint()";
196
+ const defaultQueryApiBaseUrl = "https://api.cloudflare.com/client/v4";
197
+ const textEncoder = new TextEncoder();
198
+ const writeLimits = {
199
+ maxBlobs: 20,
200
+ maxDoubles: 20,
201
+ maxIndexes: 1,
202
+ maxBlobBytes: 16 * 1024,
203
+ maxIndexBytes: 96,
204
+ maxDataPointsPerInvocation: 250
205
+ };
206
+ const queryColumnSchema = Schema.Struct({
207
+ name: Schema.String,
208
+ type: Schema.String
209
+ });
210
+ const queryRowSchema = Schema.Record(Schema.String, Schema.Unknown);
211
+ const queryResponseSchema = Schema.Struct({
212
+ meta: Schema.Array(queryColumnSchema),
213
+ data: Schema.Array(queryRowSchema),
214
+ rows: Schema.Number
215
+ });
216
+ const AnalyticsEngineFieldValueSchema = Schema.NullOr(Schema.Union([Schema.String, Schema.instanceOf(ArrayBuffer)]));
217
+ const AnalyticsEngineDataPointSchema = Schema.Struct({
218
+ indexes: Schema.optional(Schema.Array(AnalyticsEngineFieldValueSchema)),
219
+ doubles: Schema.optional(Schema.Array(Schema.Finite)),
220
+ blobs: Schema.optional(Schema.Array(AnalyticsEngineFieldValueSchema))
221
+ });
222
+ const decodeQueryResponse = Schema.decodeUnknownEffect(queryResponseSchema);
223
+ const decodeDataPoint = Schema.decodeUnknownEffect(AnalyticsEngineDataPointSchema);
224
+ /** Error raised when an Analytics Engine operation fails. */
225
+ var AnalyticsEngineOperationError = class extends Data.TaggedError("AnalyticsEngineOperationError") {};
226
+ /** Error raised when an Analytics Engine write input violates Cloudflare limits. */
227
+ var AnalyticsEngineWriteValidationError = class extends Data.TaggedError("AnalyticsEngineWriteValidationError") {};
228
+ /** Error raised when an Analytics Engine SQL API query fails. */
229
+ var AnalyticsEngineQueryError = class extends Data.TaggedError("AnalyticsEngineQueryError") {};
230
+ const analyticsEngineError = (binding, operation, cause) => new AnalyticsEngineOperationError({
231
+ binding,
232
+ operation,
233
+ cause
234
+ });
235
+ const analyticsEngineWriteValidationError = (binding, operation, violations, cause) => new AnalyticsEngineWriteValidationError({
236
+ binding,
237
+ operation,
238
+ violations,
239
+ cause
240
+ });
241
+ const analyticsEngineQueryError = (definition, operation, message, options) => new AnalyticsEngineQueryError({
242
+ operation,
243
+ accountId: definition.accountId,
244
+ message,
245
+ status: options?.status,
246
+ body: options?.body,
247
+ cause: options?.cause
248
+ });
249
+ const tryAnalyticsEngineSync = (binding, operation, evaluate) => Effect.try({
250
+ try: evaluate,
251
+ catch: (cause) => analyticsEngineError(binding, operation, cause)
252
+ });
253
+ const normalizeBatchSize = (batchSize) => {
254
+ if (batchSize === void 0 || !Number.isFinite(batchSize) || batchSize <= 0) return writeLimits.maxDataPointsPerInvocation;
255
+ return Math.min(Math.floor(batchSize), writeLimits.maxDataPointsPerInvocation);
256
+ };
257
+ const resolveWritePolicy = (defaults, options) => ({
258
+ onInvalid: options?.onInvalid ?? defaults?.onInvalid ?? "error",
259
+ batchSize: normalizeBatchSize(options?.batchSize ?? defaults?.batchSize)
260
+ });
261
+ const fieldPath = (prefix, field) => prefix === "" ? field : `${prefix}.${field}`;
262
+ const indexedPath = (prefix, field, index) => `${fieldPath(prefix, field)}[${index}]`;
263
+ const byteLength = (value) => {
264
+ if (value === null) return 0;
265
+ return typeof value === "string" ? textEncoder.encode(value).byteLength : value.byteLength;
266
+ };
267
+ const lengthViolation = (path, label, actual, limit) => ({
268
+ path,
269
+ message: `${label} exceeds Cloudflare Analytics Engine limit`,
270
+ actual,
271
+ limit
272
+ });
273
+ const validateDataPointLimits = (dataPoint, pathPrefix = "") => {
274
+ const violations = [];
275
+ if (dataPoint.blobs !== void 0 && dataPoint.blobs.length > writeLimits.maxBlobs) violations.push(lengthViolation(fieldPath(pathPrefix, "blobs"), "blobs", dataPoint.blobs.length, writeLimits.maxBlobs));
276
+ if (dataPoint.doubles !== void 0 && dataPoint.doubles.length > writeLimits.maxDoubles) violations.push(lengthViolation(fieldPath(pathPrefix, "doubles"), "doubles", dataPoint.doubles.length, writeLimits.maxDoubles));
277
+ if (dataPoint.indexes !== void 0 && dataPoint.indexes.length > writeLimits.maxIndexes) violations.push(lengthViolation(fieldPath(pathPrefix, "indexes"), "indexes", dataPoint.indexes.length, writeLimits.maxIndexes));
278
+ if (dataPoint.blobs !== void 0) {
279
+ const blobBytes = dataPoint.blobs.reduce((total, value) => total + byteLength(value), 0);
280
+ if (blobBytes > writeLimits.maxBlobBytes) violations.push(lengthViolation(fieldPath(pathPrefix, "blobs"), "blob bytes", blobBytes, writeLimits.maxBlobBytes));
281
+ }
282
+ if (dataPoint.indexes !== void 0) for (let index = 0; index < dataPoint.indexes.length; index++) {
283
+ const indexBytes = byteLength(dataPoint.indexes[index] ?? null);
284
+ if (indexBytes > writeLimits.maxIndexBytes) violations.push(lengthViolation(indexedPath(pathPrefix, "indexes", index), "index bytes", indexBytes, writeLimits.maxIndexBytes));
285
+ }
286
+ return violations;
287
+ };
288
+ const schemaViolation = (pathPrefix, cause) => ({
289
+ path: pathPrefix === "" ? "$" : pathPrefix,
290
+ message: cause.message
291
+ });
292
+ const toAnalyticsEngineDataPoint = (dataPoint) => ({
293
+ ...dataPoint.indexes === void 0 ? {} : { indexes: [...dataPoint.indexes] },
294
+ ...dataPoint.doubles === void 0 ? {} : { doubles: [...dataPoint.doubles] },
295
+ ...dataPoint.blobs === void 0 ? {} : { blobs: [...dataPoint.blobs] }
296
+ });
297
+ 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))));
299
+ const violations = validateDataPointLimits(validated, pathPrefix);
300
+ if (violations.length > 0) return yield* Effect.fail(analyticsEngineWriteValidationError(binding, operation, violations));
301
+ return validated;
302
+ });
303
+ const validateOptionalDataPoint = (binding, operation, dataPoint) => dataPoint === void 0 ? Effect.succeed(void 0) : validateDataPoint(binding, operation, dataPoint);
304
+ const validateDataPoints = (binding, operation, dataPoints, policy) => Effect.gen(function* () {
305
+ const points = dataPoints.length > writeLimits.maxDataPointsPerInvocation && policy.onInvalid === "drop" ? dataPoints.slice(0, writeLimits.maxDataPointsPerInvocation) : dataPoints;
306
+ const violations = [];
307
+ if (dataPoints.length > writeLimits.maxDataPointsPerInvocation && policy.onInvalid === "error") violations.push(lengthViolation("dataPoints", "data points per Worker invocation", dataPoints.length, writeLimits.maxDataPointsPerInvocation));
308
+ const validPoints = [];
309
+ for (let index = 0; index < points.length; index++) {
310
+ const result = yield* Effect.result(validateDataPoint(binding, operation, points[index], `dataPoints[${index}]`));
311
+ if (Result.isSuccess(result)) validPoints.push(result.success);
312
+ else if (policy.onInvalid === "error") violations.push(...result.failure.violations);
313
+ }
314
+ if (violations.length > 0) return yield* Effect.fail(analyticsEngineWriteValidationError(binding, operation, violations));
315
+ return validPoints;
316
+ });
317
+ const writeChunks = (binding, operation, dataset, dataPoints, batchSize) => Effect.gen(function* () {
318
+ const writeDataPoints = Reflect.get(dataset, "writeDataPoints");
319
+ for (let index = 0; index < dataPoints.length; index += batchSize) {
320
+ const chunk = dataPoints.slice(index, index + batchSize);
321
+ if (typeof writeDataPoints === "function") yield* tryAnalyticsEngineSync(binding, operation, () => writeDataPoints.call(dataset, chunk));
322
+ else for (const point of chunk) yield* tryAnalyticsEngineSync(binding, operation, () => dataset.writeDataPoint(point));
323
+ }
324
+ });
325
+ const queryApiUrl = (definition) => {
326
+ const baseUrl = new URL(definition.apiBaseUrl ?? defaultQueryApiBaseUrl);
327
+ baseUrl.pathname = `${baseUrl.pathname.replace(/\/+$/, "")}/accounts/${definition.accountId}/analytics_engine/sql`;
328
+ return baseUrl.href;
329
+ };
330
+ const queryRequest = (definition, sql, options) => {
331
+ let request = HttpClientRequest.post(queryApiUrl(definition)).pipe(HttpClientRequest.bodyText(sql, "text/plain;charset=UTF-8"));
332
+ if (options?.headers !== void 0) request = HttpClientRequest.setHeaders(request, options.headers);
333
+ return HttpClientRequest.bearerToken(request, definition.apiToken);
334
+ };
335
+ const responseText = (definition, response, operation) => response.text.pipe(Effect.catch((cause) => Effect.fail(analyticsEngineQueryError(definition, operation, "Failed to read Analytics Engine SQL API response body", { cause }))));
336
+ const executeQueryRequest = (definition, httpClient, sql, options) => Effect.gen(function* () {
337
+ const response = yield* httpClient.execute(queryRequest(definition, sql, options)).pipe(Effect.mapError((cause) => analyticsEngineQueryError(definition, "query", "Analytics Engine SQL API request failed", { cause })));
338
+ if (response.status < 200 || response.status >= 300) {
339
+ const body = yield* responseText(definition, response, "queryErrorBody");
340
+ return yield* Effect.fail(analyticsEngineQueryError(definition, "query", `Analytics Engine SQL API returned HTTP ${response.status}`, {
341
+ status: response.status,
342
+ body
343
+ }));
344
+ }
345
+ return response;
346
+ });
347
+ const makeQueryClientWith = (definition, httpClient) => {
348
+ const raw = (sql, options) => executeQueryRequest(definition, httpClient, sql, options);
349
+ 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 })))));
351
+ });
352
+ const queryResult = (row, sql, options) => Effect.gen(function* () {
353
+ const result = yield* query(sql, options);
354
+ const decodeRow = Schema.decodeUnknownEffect(row);
355
+ const data = [];
356
+ for (const value of result.data) data.push(yield* decodeRow(value));
357
+ return {
358
+ ...result,
359
+ data,
360
+ rows: result.rows
361
+ };
362
+ });
363
+ return {
364
+ definition,
365
+ raw,
366
+ query,
367
+ queryResult,
368
+ queryRows: (row, sql, options) => queryResult(row, sql, options).pipe(Effect.map((result) => result.data)),
369
+ queryOne: (row, sql, options) => queryResult(row, sql, options).pipe(Effect.map((result) => result.data[0] === void 0 ? Option.none() : Option.some(result.data[0]))),
370
+ queryText: (sql, options) => raw(sql, options).pipe(Effect.flatMap((response) => responseText(definition, response, "text")))
371
+ };
372
+ };
373
+ const makeQueryClient = (definition) => Effect.map(HttpClient.HttpClient, (httpClient) => makeQueryClientWith(definition, httpClient));
374
+ const isAnalyticsEngineDataset = (value) => {
375
+ if (typeof value !== "object" || value === null) return false;
376
+ return typeof Reflect.get(value, "writeDataPoint") === "function";
377
+ };
378
+ const makeClient$11 = (definition, defaults) => (dataset) => {
379
+ const writeDataPoint = (dataPoint, options) => {
380
+ const policy = resolveWritePolicy(defaults, options);
381
+ return validateOptionalDataPoint(definition.binding, "writeDataPoint", dataPoint).pipe(Effect.matchEffect({
382
+ onFailure: (error) => policy.onInvalid === "drop" ? Effect.succeed(void 0) : Effect.fail(error),
383
+ onSuccess: (point) => tryAnalyticsEngineSync(definition.binding, "writeDataPoint", () => dataset.writeDataPoint(point))
384
+ }));
385
+ };
386
+ const writeDataPoints = (dataPoints, options) => {
387
+ const policy = resolveWritePolicy(defaults, options);
388
+ return Effect.gen(function* () {
389
+ const validPoints = yield* validateDataPoints(definition.binding, "writeDataPoints", dataPoints, policy);
390
+ yield* writeChunks(definition.binding, "writeDataPoints", dataset, validPoints, policy.batchSize);
391
+ });
392
+ };
393
+ return {
394
+ definition,
395
+ writeDataPoint,
396
+ write: writeDataPoint,
397
+ writeDataPoints,
398
+ writeBatch: writeDataPoints,
399
+ unsafeRaw: Effect.succeed(dataset)
400
+ };
401
+ };
402
+ const queryConfig = (options) => Config.all({
403
+ accountId: options?.accountId ?? Config.string("CLOUDFLARE_ACCOUNT_ID"),
404
+ apiToken: options?.apiToken ?? Config.redacted("CLOUDFLARE_API_TOKEN"),
405
+ apiBaseUrl: options?.apiBaseUrl ?? Config.string("CLOUDFLARE_API_BASE_URL").pipe(Config.withDefault(defaultQueryApiBaseUrl))
406
+ });
407
+ const queryLayer = (tag, definition) => Layer.effect(tag, makeQueryClient(definition));
408
+ const queryFetchLayer = (tag, definition) => queryLayer(tag, definition).pipe(Layer.provide(FetchHttpClient.layer));
409
+ const queryLayerConfig = (tag, config = queryConfig()) => Layer.effect(tag, Effect.gen(function* () {
410
+ return yield* makeQueryClient(yield* config);
411
+ }));
412
+ const queryFetchLayerConfig = (tag, config = queryConfig()) => queryLayerConfig(tag, config).pipe(Layer.provide(FetchHttpClient.layer));
413
+ const layer$15 = (tag, definition) => layer$18(tag, definition.binding, isAnalyticsEngineDataset, makeClient$11(definition, definition.write), { expected: expectedAnalyticsEngineDataset });
414
+ const make$15 = (id) => Tag$15()(id);
415
+ const makeQuery = (id) => QueryTag()(id);
416
+ const Tag$15 = () => (id) => {
417
+ const tag = Context.Service()(id);
418
+ const makeLayer = (definition) => layer$15(tag, definition);
419
+ return Object.assign(tag, {
420
+ id,
421
+ layer: makeLayer
422
+ });
423
+ };
424
+ const QueryTag = () => (id) => {
425
+ const tag = Context.Service()(id);
426
+ const makeLayer = (definition) => queryLayer(tag, definition);
427
+ const makeFetchLayer = (definition) => queryFetchLayer(tag, definition);
428
+ const makeLayerConfig = (config) => queryLayerConfig(tag, config);
429
+ const makeFetchLayerConfig = (config) => queryFetchLayerConfig(tag, config);
430
+ return Object.assign(tag, {
431
+ id,
432
+ layer: makeLayer,
433
+ fetchLayer: makeFetchLayer,
434
+ layerConfig: makeLayerConfig,
435
+ fetchLayerConfig: makeFetchLayerConfig
436
+ });
437
+ };
438
+ //#endregion
173
439
  //#region src/BrowserRendering.ts
174
440
  var BrowserRendering_exports = /* @__PURE__ */ __exportAll({
175
441
  BrowserRenderingOperationError: () => BrowserRenderingOperationError,
176
- Tag: () => Tag$13,
442
+ Tag: () => Tag$14,
177
443
  isBrowserRenderingBinding: () => isBrowserRenderingBinding,
178
- layer: () => layer$13,
179
- make: () => make$13,
180
- makeClient: () => makeClient$9
444
+ layer: () => layer$14,
445
+ make: () => make$14,
446
+ makeClient: () => makeClient$10
181
447
  });
182
448
  const expectedBrowserRenderingBinding = "Browser Rendering binding resource";
183
449
  /** Error raised when a Browser Rendering operation fails. */
@@ -214,17 +480,17 @@ const wrapBrowser = (binding, browser) => ({
214
480
  disconnect: browser.disconnect === void 0 ? Effect.void : tryBrowserRenderingSync(binding, "disconnect", () => browser.disconnect())
215
481
  });
216
482
  const isBrowserRenderingBinding = (value) => (typeof value === "object" || typeof value === "function") && value !== null;
217
- const makeClient$9 = (definition) => (binding) => ({
483
+ const makeClient$10 = (definition) => (binding) => ({
218
484
  definition,
219
485
  launchWith: (launch, options) => tryBrowserRenderingPromise(definition.binding, "launch", () => launch(binding, options)).pipe(Effect.map((browser) => wrapBrowser(definition.binding, browser))),
220
486
  connectWith: (connect, options) => tryBrowserRenderingPromise(definition.binding, "connect", () => connect(binding, options)).pipe(Effect.map((browser) => wrapBrowser(definition.binding, browser))),
221
487
  unsafeRaw: Effect.succeed(binding)
222
488
  });
223
- const layer$13 = (tag, definition) => layer$16(tag, definition.binding, isBrowserRenderingBinding, makeClient$9(definition), { expected: expectedBrowserRenderingBinding });
224
- const make$13 = (id) => Tag$13()(id);
225
- const Tag$13 = () => (id) => {
489
+ const layer$14 = (tag, definition) => layer$18(tag, definition.binding, isBrowserRenderingBinding, makeClient$10(definition), { expected: expectedBrowserRenderingBinding });
490
+ const make$14 = (id) => Tag$14()(id);
491
+ const Tag$14 = () => (id) => {
226
492
  const tag = Context.Service()(id);
227
- const makeLayer = (definition) => layer$13(tag, definition);
493
+ const makeLayer = (definition) => layer$14(tag, definition);
228
494
  return Object.assign(tag, {
229
495
  id,
230
496
  layer: makeLayer
@@ -523,7 +789,7 @@ const runPromiseExitPreservingTypedFailures = async (effect) => {
523
789
  //#region src/CloudflareOtlp.ts
524
790
  var CloudflareOtlp_exports = /* @__PURE__ */ __exportAll({
525
791
  durableObjectLayer: () => durableObjectLayer,
526
- layer: () => layer$12,
792
+ layer: () => layer$13,
527
793
  layerJson: () => layerJson,
528
794
  layerProtobuf: () => layerProtobuf,
529
795
  workerLayer: () => workerLayer
@@ -585,14 +851,14 @@ const makeLayer = (options = {}, runtimeAttributes = {}) => {
585
851
  * installed as the primary `ConfigProvider`; outside Cloudflare, the ambient
586
852
  * Effect `ConfigProvider` remains the fallback.
587
853
  */
588
- const layer$12 = (options = {}) => makeLayer(options);
854
+ const layer$13 = (options = {}) => makeLayer(options);
589
855
  /** Base OTLP telemetry layer forced to JSON serialization. */
590
- const layerJson = (options = {}) => layer$12({
856
+ const layerJson = (options = {}) => layer$13({
591
857
  ...options,
592
858
  serialization: "json"
593
859
  });
594
860
  /** Base OTLP telemetry layer forced to protobuf serialization. */
595
- const layerProtobuf = (options = {}) => layer$12({
861
+ const layerProtobuf = (options = {}) => layer$13({
596
862
  ...options,
597
863
  serialization: "protobuf"
598
864
  });
@@ -619,6 +885,118 @@ const durableObjectLayer = (options = {}) => Layer.unwrap(Effect.map(DurableObje
619
885
  "cloudflare.durable_object.id": options.includeObjectId ? state.id.toString() : void 0
620
886
  })));
621
887
  //#endregion
888
+ //#region src/ContainerNamespace.ts
889
+ var ContainerNamespace_exports = /* @__PURE__ */ __exportAll({
890
+ ContainerNamespace: () => ContainerNamespace,
891
+ ContainerOperationError: () => ContainerOperationError,
892
+ ContainerState: () => ContainerState,
893
+ Tag: () => Tag$13,
894
+ isContainerNamespaceResource: () => isContainerNamespaceResource,
895
+ layer: () => layer$12,
896
+ make: () => make$13,
897
+ makeClient: () => makeClient$9
898
+ });
899
+ const expectedContainerNamespace = "Container namespace binding with getByName()";
900
+ /** Serializable state reported by a Cloudflare Container instance. */
901
+ const ContainerState = Schema.Union([Schema.Struct({
902
+ lastChange: Schema.Finite,
903
+ status: Schema.Literals([
904
+ "running",
905
+ "stopping",
906
+ "stopped",
907
+ "healthy"
908
+ ])
909
+ }), Schema.Struct({
910
+ lastChange: Schema.Finite,
911
+ status: Schema.Literal("stopped_with_code"),
912
+ exitCode: Schema.optionalKey(Schema.Int)
913
+ })]);
914
+ /** Failure raised when invoking a named Container operation. */
915
+ var ContainerOperationError = class extends Data.TaggedError("ContainerOperationError") {};
916
+ const tryContainerPromise = (definition, instance, operation, evaluate) => Effect.tryPromise({
917
+ try: evaluate,
918
+ catch: (cause) => new ContainerOperationError({
919
+ binding: definition.binding,
920
+ instance,
921
+ operation,
922
+ cause
923
+ })
924
+ });
925
+ const makeInstanceClient = (definition, instance, stub) => ({
926
+ unsafeRaw: Effect.succeed(stub),
927
+ state: tryContainerPromise(definition, instance, "state", () => stub.getState()).pipe(Effect.flatMap(Schema.decodeUnknownEffect(ContainerState)), Effect.mapError((cause) => cause instanceof ContainerOperationError ? cause : new ContainerOperationError({
928
+ binding: definition.binding,
929
+ instance,
930
+ operation: "state",
931
+ cause
932
+ }))),
933
+ fetch: (input, init) => tryContainerPromise(definition, instance, "fetch", () => stub.fetch(input, init)),
934
+ start: (options, waitOptions) => tryContainerPromise(definition, instance, "start", () => stub.start(options, waitOptions)),
935
+ startAndWaitForPorts: (options) => tryContainerPromise(definition, instance, "startAndWaitForPorts", () => stub.startAndWaitForPorts(options)),
936
+ stop: (signal) => tryContainerPromise(definition, instance, "stop", () => stub.stop(signal)),
937
+ destroy: tryContainerPromise(definition, instance, "destroy", () => stub.destroy())
938
+ });
939
+ const isContainerNamespaceResource = (value) => typeof value === "object" && value !== null && typeof Reflect.get(value, "getByName") === "function";
940
+ const makeClient$9 = (definition) => (namespace) => {
941
+ const getByName = (name, options) => Effect.try({
942
+ try: () => makeInstanceClient(definition, name, namespace.getByName(name, options)),
943
+ catch: (cause) => new ContainerOperationError({
944
+ binding: definition.binding,
945
+ instance: name,
946
+ operation: "getByName",
947
+ cause
948
+ })
949
+ });
950
+ const byName = (name, options) => {
951
+ const instance = getByName(name, options);
952
+ return {
953
+ unsafeRaw: Effect.flatMap(instance, (client) => client.unsafeRaw),
954
+ state: Effect.flatMap(instance, (client) => client.state),
955
+ fetch: (input, init) => Effect.flatMap(instance, (client) => client.fetch(input, init)),
956
+ start: (startOptions, waitOptions) => Effect.flatMap(instance, (client) => client.start(startOptions, waitOptions)),
957
+ startAndWaitForPorts: (startOptions) => Effect.flatMap(instance, (client) => client.startAndWaitForPorts(startOptions)),
958
+ stop: (signal) => Effect.flatMap(instance, (client) => client.stop(signal)),
959
+ destroy: Effect.flatMap(instance, (client) => client.destroy)
960
+ };
961
+ };
962
+ return {
963
+ definition,
964
+ getByName,
965
+ byName,
966
+ unsafeRaw: Effect.succeed(namespace)
967
+ };
968
+ };
969
+ const layer$12 = (tag, definition) => layer$18(tag, definition.binding, isContainerNamespaceResource, makeClient$9(definition), { expected: expectedContainerNamespace });
970
+ const make$13 = (id) => Tag$13()(id);
971
+ /** Creates a typed Effect service for a Cloudflare Container namespace. */
972
+ const Tag$13 = () => (id) => {
973
+ const tag = Context.Service()(id);
974
+ const makeLayer = (definition) => layer$12(tag, definition);
975
+ const getByName = (name, options) => Effect.gen(function* () {
976
+ return yield* (yield* tag).getByName(name, options);
977
+ });
978
+ const byName = (name, options) => ({
979
+ state: Effect.flatMap(getByName(name, options), (instance) => instance.state),
980
+ fetch: (input, init) => Effect.flatMap(getByName(name, options), (instance) => instance.fetch(input, init)),
981
+ start: (startOptions, waitOptions) => Effect.flatMap(getByName(name, options), (instance) => instance.start(startOptions, waitOptions)),
982
+ startAndWaitForPorts: (startOptions) => Effect.flatMap(getByName(name, options), (instance) => instance.startAndWaitForPorts(startOptions)),
983
+ stop: (signal) => Effect.flatMap(getByName(name, options), (instance) => instance.stop(signal)),
984
+ destroy: Effect.flatMap(getByName(name, options), (instance) => instance.destroy),
985
+ unsafeRaw: Effect.flatMap(getByName(name, options), (instance) => instance.unsafeRaw)
986
+ });
987
+ const unsafeRaw = Effect.fn(function* () {
988
+ return yield* (yield* tag).unsafeRaw;
989
+ });
990
+ return Object.assign(tag, {
991
+ id,
992
+ layer: makeLayer,
993
+ getByName,
994
+ byName,
995
+ unsafeRaw
996
+ });
997
+ };
998
+ const ContainerNamespace = Tag$13;
999
+ //#endregion
622
1000
  //#region src/D1.ts
623
1001
  var D1_exports = /* @__PURE__ */ __exportAll({
624
1002
  Service: () => Service$1,
@@ -726,7 +1104,7 @@ const makeClient$8 = (definition) => {
726
1104
  unsafeRaw: Effect.succeed(queue)
727
1105
  });
728
1106
  };
729
- const layer$11 = (tag, definition) => layer$16(tag, definition.binding, (value) => isQueue(value), makeClient$8(definition), { expected: expectedQueueProducer });
1107
+ const layer$11 = (tag, definition) => layer$18(tag, definition.binding, (value) => isQueue(value), makeClient$8(definition), { expected: expectedQueueProducer });
730
1108
  //#endregion
731
1109
  //#region src/QueueDefinition.ts
732
1110
  var QueueDefinition_exports = /* @__PURE__ */ __exportAll({
@@ -1069,7 +1447,7 @@ const makeClient$7 = (definition) => {
1069
1447
  });
1070
1448
  };
1071
1449
  };
1072
- const layer$10 = (tag, definition) => layer$16(tag, definition.binding, (value) => isServiceBindingClient(value), makeClient$7(definition), { expected: expectedServiceBinding });
1450
+ const layer$10 = (tag, definition) => layer$18(tag, definition.binding, (value) => isServiceBindingClient(value), makeClient$7(definition), { expected: expectedServiceBinding });
1073
1451
  /**
1074
1452
  * Creates a typed Effect service for a Worker service binding.
1075
1453
  *
@@ -1446,7 +1824,7 @@ const makeClient$6 = (definition) => {
1446
1824
  });
1447
1825
  };
1448
1826
  };
1449
- const layer$8 = (tag, definition) => layer$16(tag, definition.binding, (value) => isDurableObjectNamespaceClient(value), makeClient$6(definition), { expected: expectedDurableObjectNamespace });
1827
+ const layer$8 = (tag, definition) => layer$18(tag, definition.binding, (value) => isDurableObjectNamespaceClient(value), makeClient$6(definition), { expected: expectedDurableObjectNamespace });
1450
1828
  const makeDirectMethods = (rpcDefinition, helpers) => {
1451
1829
  const methods = {};
1452
1830
  if (rpcDefinition !== void 0) {
@@ -2161,7 +2539,7 @@ const makeClient$5 = (definition) => (email) => {
2161
2539
  unsafeRaw: Effect.succeed(email)
2162
2540
  };
2163
2541
  };
2164
- const layer$5 = (tag, definition) => layer$16(tag, definition.binding, isEmailBinding, makeClient$5(definition), { expected: expectedSendEmailBinding });
2542
+ const layer$5 = (tag, definition) => layer$18(tag, definition.binding, isEmailBinding, makeClient$5(definition), { expected: expectedSendEmailBinding });
2165
2543
  const make$5 = (id) => Tag$6()(id);
2166
2544
  const Tag$6 = () => (id) => {
2167
2545
  const tag = Context.Service()(id);
@@ -2268,7 +2646,7 @@ const makeClient$4 = (definition) => (images) => {
2268
2646
  unsafeRaw: Effect.succeed(images)
2269
2647
  };
2270
2648
  };
2271
- const layer$4 = (tag, definition) => layer$16(tag, definition.binding, isImagesBinding, makeClient$4(definition), { expected: expectedImagesBinding });
2649
+ const layer$4 = (tag, definition) => layer$18(tag, definition.binding, isImagesBinding, makeClient$4(definition), { expected: expectedImagesBinding });
2272
2650
  const make$4 = (id) => Tag$5()(id);
2273
2651
  const Tag$5 = () => (id) => {
2274
2652
  const tag = Context.Service()(id);
@@ -2363,7 +2741,7 @@ const makeClient$3 = (definition) => {
2363
2741
  unsafeRaw: Effect.succeed(kv)
2364
2742
  });
2365
2743
  };
2366
- const layer$3 = (tag, definition) => layer$16(tag, definition.binding, isKvNamespace, makeClient$3(definition), { expected: expectedKvNamespace });
2744
+ const layer$3 = (tag, definition) => layer$18(tag, definition.binding, isKvNamespace, makeClient$3(definition), { expected: expectedKvNamespace });
2367
2745
  const makeDefinition$1 = (id, definition) => {
2368
2746
  const kvDefinition = {
2369
2747
  id,
@@ -2480,7 +2858,7 @@ const makeClient$2 = (definition) => {
2480
2858
  };
2481
2859
  };
2482
2860
  };
2483
- const layer$2 = (tag, definition) => layer$16(tag, definition.binding, isR2Bucket, makeClient$2(definition), { expected: expectedR2Bucket });
2861
+ const layer$2 = (tag, definition) => layer$18(tag, definition.binding, isR2Bucket, makeClient$2(definition), { expected: expectedR2Bucket });
2484
2862
  const make$3 = (id) => Tag$3()(id);
2485
2863
  const Tag$3 = () => (id) => {
2486
2864
  const tag = Context.Service()(id);
@@ -2566,7 +2944,7 @@ const makeClient$1 = (definition) => {
2566
2944
  unsafeRaw: Effect.succeed(workflow)
2567
2945
  });
2568
2946
  };
2569
- const layer$1 = (tag, definition) => layer$16(tag, definition.binding, (value) => isWorkflow(value), makeClient$1(definition), { expected: expectedWorkflow });
2947
+ const layer$1 = (tag, definition) => layer$18(tag, definition.binding, (value) => isWorkflow(value), makeClient$1(definition), { expected: expectedWorkflow });
2570
2948
  //#endregion
2571
2949
  //#region src/WorkflowDefinition.ts
2572
2950
  var WorkflowDefinition_exports = /* @__PURE__ */ __exportAll({
@@ -2740,7 +3118,7 @@ const makeClient = (definition) => (index) => {
2740
3118
  unsafeRaw: Effect.succeed(index)
2741
3119
  };
2742
3120
  };
2743
- const layer = (tag, definition) => layer$16(tag, definition.binding, isVectorizeBinding, makeClient(definition), { expected: expectedVectorizeBinding });
3121
+ const layer = (tag, definition) => layer$18(tag, definition.binding, isVectorizeBinding, makeClient(definition), { expected: expectedVectorizeBinding });
2744
3122
  const make = (id) => Tag()(id);
2745
3123
  const Tag = () => (id) => {
2746
3124
  const tag = Context.Service()(id);
@@ -2751,4 +3129,4 @@ const Tag = () => (id) => {
2751
3129
  });
2752
3130
  };
2753
3131
  //#endregion
2754
- export { AiGateway_exports as AiGateway, Binding_exports as Binding, BrowserRendering_exports as BrowserRendering, 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, Email_exports as Email, 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, Vectorize_exports as Vectorize, Worker_exports as Worker, WorkerConfig, WorkerDefinition_exports as WorkerDefinition, WorkerEnvironment, WorkersAi_exports as WorkersAi, Workflow_exports as Workflow, WorkflowBinding_exports as WorkflowBinding, WorkflowDefinition_exports as WorkflowDefinition };
3132
+ export { AiGateway_exports as AiGateway, AnalyticsEngine_exports as AnalyticsEngine, Binding_exports as Binding, BrowserRendering_exports as BrowserRendering, CloudflareOtlp_exports as CloudflareOtlp, ContainerNamespace_exports as ContainerNamespace, 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, Email_exports as Email, 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, Vectorize_exports as Vectorize, Worker_exports as Worker, WorkerConfig, WorkerDefinition_exports as WorkerDefinition, WorkerEnvironment, WorkersAi_exports as WorkersAi, Workflow_exports as Workflow, WorkflowBinding_exports as WorkflowBinding, WorkflowDefinition_exports as WorkflowDefinition };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "effect-cf",
3
- "version": "0.15.0",
3
+ "version": "0.17.0",
4
4
  "description": "Effect-native primitives for Cloudflare Workers and bindings.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -39,6 +39,7 @@
39
39
  "prepublishOnly": "vp run build"
40
40
  },
41
41
  "devDependencies": {
42
+ "@cloudflare/containers": "catalog:",
42
43
  "@cloudflare/vitest-pool-workers": "catalog:",
43
44
  "@cloudflare/workers-types": "catalog:",
44
45
  "@effect/platform-node": "4.0.0-beta.77",