effect-cf 0.27.0 → 0.28.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.
Files changed (67) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +6 -0
  3. package/dist/{Artifacts-DcoXcRP5.d.mts → Artifacts-DnHQA-Ax.d.mts} +42 -25
  4. package/dist/{Artifacts-BhWrdyqX.mjs → Artifacts-rq3hUKQE.mjs} +46 -30
  5. package/dist/{Binding-COCtoJXa.d.mts → Binding-xJJJPmiD.d.mts} +6 -5
  6. package/dist/ComputerArtifacts.d.mts +1 -1
  7. package/dist/ComputerArtifacts.mjs +9 -9
  8. package/dist/ComputerWorkspace.d.mts +5 -5
  9. package/dist/ComputerWorkspace.mjs +107 -75
  10. package/dist/ComputerWorkspaceHost.d.mts +1 -1
  11. package/dist/ComputerWorkspaceHost.mjs +18 -16
  12. package/dist/{DurableObjectState-Dux8KfjG.mjs → DurableObjectState-BjkK2kwH.mjs} +3 -3
  13. package/dist/{DurableObjectState-biHrHwrh.d.mts → DurableObjectState-OupNMMUl.d.mts} +89 -64
  14. package/dist/{ErrorMessage-_lg53p3W.mjs → ErrorMessage-BM0K-Nik.mjs} +1 -4
  15. package/dist/{Hyperdrive-6p59yyVk.d.mts → Hyperdrive-z-9fFz15.d.mts} +2 -2
  16. package/dist/HyperdrivePg.d.mts +2 -2
  17. package/dist/Vitest.d.mts +6 -5
  18. package/dist/Vitest.mjs +2 -2
  19. package/dist/{WorkflowBinding-zlRPCXVf.d.mts → WorkflowBinding-DUZtKCVM.d.mts} +5 -10
  20. package/dist/index.d.mts +88 -62
  21. package/dist/index.mjs +291 -181
  22. package/package.json +1 -1
  23. package/src/AiGateway.ts +62 -7
  24. package/src/AnalyticsEngine.ts +17 -13
  25. package/src/Artifacts.ts +111 -47
  26. package/src/Binding.ts +34 -23
  27. package/src/BrowserRendering.ts +72 -33
  28. package/src/CloudflareOtlp.ts +21 -11
  29. package/src/ComputerArtifacts.ts +17 -9
  30. package/src/ComputerWorkspace.ts +202 -98
  31. package/src/ComputerWorkspaceHost.ts +55 -27
  32. package/src/ContainerNamespace.ts +8 -9
  33. package/src/D1.ts +8 -14
  34. package/src/DurableObject.ts +33 -13
  35. package/src/DurableObjectAlarm.ts +17 -5
  36. package/src/DurableObjectDefinition.ts +89 -72
  37. package/src/DurableObjectNamespace.ts +26 -12
  38. package/src/DurableObjectRpcWebSocket.ts +9 -10
  39. package/src/DurableObjectState.ts +1 -0
  40. package/src/DurableObjectStorage.ts +5 -2
  41. package/src/DurableObjectWebSocket.ts +4 -1
  42. package/src/Email.ts +26 -25
  43. package/src/Hyperdrive.ts +4 -10
  44. package/src/Images.ts +12 -14
  45. package/src/Kv.ts +15 -17
  46. package/src/Queue.ts +2 -1
  47. package/src/QueueBinding.ts +7 -12
  48. package/src/QueueDefinition.ts +7 -2
  49. package/src/R2.ts +33 -24
  50. package/src/Rpc.ts +15 -21
  51. package/src/RpcDefinition.ts +33 -38
  52. package/src/ServiceBinding.ts +26 -8
  53. package/src/Vectorize.ts +45 -18
  54. package/src/Vitest.ts +9 -3
  55. package/src/WebTransport.ts +11 -5
  56. package/src/Worker.ts +97 -24
  57. package/src/WorkerDefinition.ts +143 -63
  58. package/src/WorkersAi.ts +50 -28
  59. package/src/Workflow.ts +66 -13
  60. package/src/WorkflowBinding.ts +18 -25
  61. package/src/WorkflowDefinition.ts +4 -2
  62. package/src/internal/Entrypoint.ts +29 -13
  63. package/src/internal/ErrorMessage.ts +7 -6
  64. package/src/internal/RpcInvocation.ts +34 -11
  65. package/src/internal/Runtime.ts +33 -22
  66. package/src/internal/Telemetry.ts +17 -10
  67. package/src/internal/WorkerContext.ts +3 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # effect-cf
2
2
 
3
+ ## 0.28.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#105](https://github.com/danieljvdm/effect-cf/pull/105) [`f5dfd5e`](https://github.com/danieljvdm/effect-cf/commit/f5dfd5e2c79b257cc760dc0b2cdf5a2901b0b295) Thanks [@danieljvdm](https://github.com/danieljvdm)! - Bound internally scheduled telemetry flushes so exporter retries cannot extend Worker or Durable Object event lifetimes indefinitely.
8
+
9
+ - [#106](https://github.com/danieljvdm/effect-cf/pull/106) [`c0fbb85`](https://github.com/danieljvdm/effect-cf/commit/c0fbb8535479262741e6844935e9ff9d508f6b56) Thanks [@danieljvdm](https://github.com/danieljvdm)! - Silently absorb failures raised while scheduling automatic OTLP telemetry flushes so platform boundary defects cannot feed back into the configured exporter. Document the two-second best-effort boundary and keep explicit queue flush policy application-owned.
10
+
11
+ ## 0.28.0
12
+
13
+ ### Minor Changes
14
+
15
+ - [#104](https://github.com/danieljvdm/effect-cf/pull/104) [`4aadbd0`](https://github.com/danieljvdm/effect-cf/commit/4aadbd0b6e76449bac190dbc5abb4c20486c8761) Thanks [@danieljvdm](https://github.com/danieljvdm)! - Allow workflow step Effects to fail terminally with `WorkflowStepNonRetryableError`, which is rethrown to Cloudflare as its native `NonRetryableError`.
16
+
17
+ - [#104](https://github.com/danieljvdm/effect-cf/pull/104) [`4aadbd0`](https://github.com/danieljvdm/effect-cf/commit/4aadbd0b6e76449bac190dbc5abb4c20486c8761) Thanks [@danieljvdm](https://github.com/danieljvdm)! - Support method-only remote Artifacts repository bindings with a typed `info()` client operation and live commit history shapes.
18
+
19
+ - [#102](https://github.com/danieljvdm/effect-cf/pull/102) [`1b32c54`](https://github.com/danieljvdm/effect-cf/commit/1b32c54757bf404c2454389b0386e0996974cdc6) Thanks [@danieljvdm](https://github.com/danieljvdm)! - Harden Cloudflare and WebTransport runtime boundaries with receiver-safe invocation, truthful return types, validated external data, and stricter event-layer requirements.
20
+
3
21
  ## 0.27.0
4
22
 
5
23
  ### Minor Changes
package/README.md CHANGED
@@ -357,6 +357,12 @@ Producers should usually use `const queue = yield* AvatarQueue` and then call `q
357
357
 
358
358
  Queue handlers run inline failures through Cloudflare's normal retry path. If background work scheduled with `WorkerContext.waitUntil(...)` should also make the batch retry, use `WorkerContext.waitUntilPropagating(...)` or `waitUntil(..., { mode: "propagate" })`; the default `waitUntil` mode observes and logs failures without rejecting the native `waitUntil` promise.
359
359
 
360
+ effect-cf automatically schedules best-effort OTLP flushes only for Worker
361
+ fetch/RPC and Durable Object alarm/RPC handlers. Those internal flushes are
362
+ capped at two seconds. Queue handlers do not flush telemetry automatically;
363
+ applications that explicitly flush in a queue handler own that flush's timeout
364
+ and failure policy.
365
+
360
366
  ## Cache Example
361
367
 
362
368
  `Cache.layer` exposes Cloudflare's global Cache API as an Effect service. Cache misses are represented by `Option.none()`, and named caches are available through `open(...)`.
@@ -1,10 +1,10 @@
1
- import { c as WorkerEnvironment, r as BindingValidationError, t as BindingNotFoundError } from "./Binding-COCtoJXa.mjs";
1
+ import { c as WorkerEnvironment, r as BindingValidationError, t as BindingNotFoundError } from "./Binding-xJJJPmiD.mjs";
2
2
  import { Context, Effect, Layer } from "effect";
3
3
  declare namespace Artifacts_d_exports {
4
- export { ArtifactsBinding, ArtifactsClient, ArtifactsCommit, ArtifactsCreateOptions, ArtifactsCreateRepoResult, ArtifactsCreateTokenResult, ArtifactsDefinition, ArtifactsErrorCode, ArtifactsForkOptions, ArtifactsImportParams, ArtifactsImportSource, ArtifactsImportTarget, ArtifactsImportTargetOptions, ArtifactsListOptions, ArtifactsLogOptions, ArtifactsLogResult, ArtifactsOperation, ArtifactsOperationError, ArtifactsRepoBinding, ArtifactsRepoClient, ArtifactsRepoInfo, ArtifactsRepoListEntry, ArtifactsRepoListResult, ArtifactsRepoStatus, ArtifactsService, ArtifactsTokenInfo, ArtifactsTokenListResult, ArtifactsTokenScope, ArtifactsTokenState, ArtifactsTree, Cursor, LayerOptions, RepoName, Tag, TagClass, artifactsErrorCodes, artifactsErrorNumericCodes, isArtifactsBinding, isArtifactsRepoBinding, layer, make, makeClient };
4
+ export { ArtifactsBinding, ArtifactsClient, ArtifactsCommit, ArtifactsCommitIdentity, ArtifactsCreateOptions, ArtifactsCreateRepoResult, ArtifactsCreateTokenResult, ArtifactsDefinition, ArtifactsErrorCode, ArtifactsForkOptions, ArtifactsImportParams, ArtifactsImportSource, ArtifactsImportTarget, ArtifactsImportTargetOptions, ArtifactsListOptions, ArtifactsLogOptions, ArtifactsLogResult, ArtifactsOperation, ArtifactsOperationError, ArtifactsRepoBinding, ArtifactsRepoClient, ArtifactsRepoInfo, ArtifactsRepoListEntry, ArtifactsRepoListResult, ArtifactsRepoStatus, ArtifactsService, ArtifactsTokenInfo, ArtifactsTokenListResult, ArtifactsTokenScope, ArtifactsTokenState, ArtifactsTree, Cursor, LayerOptions, RepoName, Tag, TagClass, artifactsErrorCodes, artifactsErrorNumericCodes, isArtifactsBinding, isArtifactsRepoBinding, layer, make, makeClient };
5
5
  }
6
6
  /** Artifacts operation represented by {@link ArtifactsOperationError}. */
7
- type ArtifactsOperation = "createClient" | "create" | "get" | "import" | "list" | "delete" | "createToken" | "listTokens" | "getToken" | "revokeToken" | "fork" | "log" | "readCommit" | "readTree" | "cli";
7
+ type ArtifactsOperation = "createClient" | "create" | "get" | "import" | "list" | "delete" | "createToken" | "listTokens" | "getToken" | "revokeToken" | "fork" | "info" | "log" | "readCommit" | "readTree" | "cli";
8
8
  /** Documented string error codes returned by Cloudflare Artifacts. */
9
9
  declare const artifactsErrorCodes: readonly ["ALREADY_EXISTS", "NOT_FOUND", "IMPORT_IN_PROGRESS", "FORK_IN_PROGRESS", "INVALID_INPUT", "INVALID_REPO_NAME", "INVALID_TTL", "INVALID_URL", "REMOTE_AUTH_REQUIRED", "UPSTREAM_UNAVAILABLE", "MEMORY_LIMIT", "INTERNAL_ERROR"];
10
10
  /** Documented numeric error codes returned by Cloudflare Artifacts. */
@@ -74,32 +74,34 @@ type ArtifactsCreateTokenResult = CloudflareArtifactsCreateTokenResult;
74
74
  type ArtifactsTokenInfo = CloudflareArtifactsTokenInfo;
75
75
  /** Repository token list result. */
76
76
  type ArtifactsTokenListResult = CloudflareArtifactsTokenListResult;
77
- /**
78
- * Commit history returned by `log()`.
79
- *
80
- * Cloudflare currently documents this generated type by name but does not
81
- * publish its fields in the binding reference or Workers type declarations.
82
- */
83
- interface ArtifactsLogResult {
84
- readonly [field: string]: unknown;
77
+ /** Identity recorded for a Git commit author or committer. */
78
+ interface ArtifactsCommitIdentity {
79
+ readonly name: string;
80
+ readonly email: string;
85
81
  }
86
- /**
87
- * Parsed Git commit returned by `readCommit()`.
88
- *
89
- * Cloudflare currently documents this generated type by name but does not
90
- * publish its fields in the binding reference or Workers type declarations.
91
- */
82
+ /** Parsed Git commit returned by `readCommit()` and `log()`. */
92
83
  interface ArtifactsCommit {
93
- readonly [field: string]: unknown;
94
- }
84
+ readonly hash: string;
85
+ readonly treeHash: string;
86
+ readonly message: string;
87
+ readonly author: ArtifactsCommitIdentity;
88
+ readonly committer: ArtifactsCommitIdentity;
89
+ readonly parents: ReadonlyArray<string>;
90
+ /** Unix timestamp in seconds. */
91
+ readonly authoredAt: number;
92
+ /** Unix timestamp in seconds. */
93
+ readonly committedAt: number;
94
+ }
95
+ /** Bare commit array returned by `log()`. */
96
+ type ArtifactsLogResult = ReadonlyArray<ArtifactsCommit>;
95
97
  /**
96
98
  * Parsed Git tree returned by `readTree()`.
97
99
  *
98
100
  * Cloudflare currently documents this generated type by name but does not
99
101
  * publish its fields in the binding reference or Workers type declarations.
100
102
  */
101
- interface ArtifactsTree {
102
- readonly [field: string]: unknown;
103
+ interface ArtifactsTree<Field = unknown> {
104
+ readonly [field: string]: Field;
103
105
  }
104
106
  /** Options for `Artifacts.create()`. */
105
107
  interface ArtifactsCreateOptions {
@@ -155,7 +157,15 @@ interface ArtifactsLogOptions {
155
157
  readonly offset?: number;
156
158
  }
157
159
  /** Runtime repository handle, including methods absent from current shipped Workers types. */
158
- interface ArtifactsRepoBinding extends ArtifactsRepoInfo {
160
+ interface ArtifactsRepoBinding extends Partial<ArtifactsRepoInfo> {
161
+ /**
162
+ * Read repository metadata.
163
+ *
164
+ * Remote bindings expose method-only RPC handles and provide metadata only
165
+ * through this method. It is optional solely for compatibility with older
166
+ * local handles that expose metadata as data properties.
167
+ */
168
+ readonly info?: () => Promise<ArtifactsRepoInfo>;
159
169
  /**
160
170
  * Create a Git token for the repository.
161
171
  *
@@ -178,8 +188,15 @@ interface ArtifactsBinding {
178
188
  readonly list: (options?: ArtifactsListOptions) => Promise<ArtifactsRepoListResult>;
179
189
  readonly delete: (name: RepoName) => Promise<boolean>;
180
190
  }
181
- /** Effect wrapper around a repository handle returned by `Artifacts.get()`. */
191
+ /**
192
+ * Effect wrapper around a repository handle returned by `Artifacts.get()`.
193
+ *
194
+ * The inherited metadata is the snapshot read while resolving the client.
195
+ * Use `info()` to refresh it from the repository handle.
196
+ */
182
197
  interface ArtifactsRepoClient extends ArtifactsRepoInfo {
198
+ /** Read and validate the repository's current metadata. */
199
+ readonly info: () => Effect.Effect<ArtifactsRepoInfo, ArtifactsOperationError>;
183
200
  /**
184
201
  * Create a Git token for the repository.
185
202
  *
@@ -220,9 +237,9 @@ interface TagClass<Self, Id extends string> extends Context.ServiceClass<Self, I
220
237
  readonly layer: (options: LayerOptions) => Layer.Layer<Self, BindingNotFoundError | BindingValidationError, WorkerEnvironment>;
221
238
  }
222
239
  /** Tests whether a value exposes the complete documented Artifacts repo handle API. */
223
- declare const isArtifactsRepoBinding: (value: unknown) => value is ArtifactsRepoBinding;
240
+ declare const isArtifactsRepoBinding: <Candidate>(value: Candidate) => value is Candidate & ArtifactsRepoBinding;
224
241
  /** Tests whether a value exposes the complete documented Artifacts namespace API. */
225
- declare const isArtifactsBinding: (value: unknown) => value is ArtifactsBinding;
242
+ declare const isArtifactsBinding: <Candidate>(value: Candidate) => value is Candidate & ArtifactsBinding;
226
243
  declare const makeClient: (definition: ArtifactsDefinition) => (artifacts: ArtifactsBinding) => ArtifactsClient;
227
244
  declare const layer: <Self>(tag: Context.Service<Self, ArtifactsClient>, definition: ArtifactsDefinition) => Layer.Layer<Self, BindingNotFoundError | BindingValidationError, WorkerEnvironment>;
228
245
  declare const make: <Id extends string>(id: Id) => TagClass<ArtifactsService<Id>, Id>;
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
- import { a as WorkerEnvironment, t as causeMessage } from "./ErrorMessage-_lg53p3W.mjs";
3
- import { Context, Data, Effect, Layer } from "effect";
2
+ import { a as WorkerEnvironment, t as causeMessage } from "./ErrorMessage-BM0K-Nik.mjs";
3
+ import { Context, Data, Effect, Layer, Predicate, Schema } from "effect";
4
4
  //#region src/Binding.ts
5
5
  var Binding_exports = /* @__PURE__ */ __exportAll({
6
6
  BindingNotFoundError: () => BindingNotFoundError,
@@ -16,18 +16,18 @@ var BindingNotFoundError = class extends Data.TaggedError("BindingNotFoundError"
16
16
  /** Error raised when a binding exists but does not match the expected shape. */
17
17
  var BindingValidationError = class extends Data.TaggedError("BindingValidationError") {};
18
18
  const defaultExpected = "Cloudflare binding resource";
19
- const isPropertyTarget = (value) => (typeof value === "object" || typeof value === "function") && value !== null;
19
+ const isPropertyTarget = (value) => Predicate.isObjectOrArray(value) || Predicate.isFunction(value);
20
20
  const getObjectName = (value) => {
21
21
  const tag = (() => {
22
22
  try {
23
23
  return Object.prototype.toString.call(value).slice(8, -1);
24
24
  } catch {
25
- return typeof value;
25
+ return Predicate.isFunction(value) ? "function" : "object";
26
26
  }
27
27
  })();
28
28
  const constructorName = (() => {
29
29
  try {
30
- return "constructor" in value && typeof value.constructor === "function" && typeof value.constructor.name === "string" ? value.constructor.name : void 0;
30
+ return "constructor" in value && Predicate.isFunction(value.constructor) && Predicate.isString(value.constructor.name) ? value.constructor.name : void 0;
31
31
  } catch {
32
32
  return;
33
33
  }
@@ -50,14 +50,21 @@ const propertyNames = (value) => {
50
50
  };
51
51
  const isMethod = (value, name) => {
52
52
  try {
53
- return typeof Reflect.get(value, name) === "function";
53
+ return Predicate.hasProperty(value, name) && Predicate.isFunction(value[name]);
54
54
  } catch {
55
55
  return false;
56
56
  }
57
57
  };
58
58
  const describeActual = (value) => {
59
59
  if (value === null) return "null";
60
- if (typeof value !== "object" && typeof value !== "function") return typeof value;
60
+ if (!isPropertyTarget(value)) {
61
+ if (Predicate.isString(value)) return "string";
62
+ if (Predicate.isNumber(value)) return "number";
63
+ if (Predicate.isBoolean(value)) return "boolean";
64
+ if (Predicate.isBigInt(value)) return "bigint";
65
+ if (Predicate.isSymbol(value)) return "symbol";
66
+ return "undefined";
67
+ }
61
68
  const names = propertyNames(value);
62
69
  const methods = names.filter((name) => isMethod(value, name));
63
70
  const properties = names.filter((name) => !methods.includes(name));
@@ -75,7 +82,7 @@ const getBinding = (env, binding, isResource, options) => Effect.gen(function* (
75
82
  message: `Cloudflare binding "${binding}" failed validation. Expected WorkerEnvironment object; got ${actual}`
76
83
  }));
77
84
  }
78
- const resource = Reflect.get(env, binding);
85
+ const resource = Predicate.hasProperty(env, binding) ? env[binding] : void 0;
79
86
  if (resource === void 0) return yield* Effect.fail(new BindingNotFoundError({
80
87
  binding,
81
88
  message: `Cloudflare binding "${binding}" was not found in WorkerEnvironment`
@@ -171,13 +178,13 @@ var ArtifactsOperationError = class extends Data.TaggedError("ArtifactsOperation
171
178
  }
172
179
  };
173
180
  const artifactsErrorDetails = (cause) => {
174
- if (typeof cause !== "object" || cause === null) return {};
175
- const code = Reflect.get(cause, "code");
176
- const numericCode = Reflect.get(cause, "numericCode");
177
- return {
178
- ...typeof code === "string" ? { code } : {},
179
- ...typeof numericCode === "number" ? { numericCode } : {}
180
- };
181
+ if (!Predicate.isObject(cause)) return {};
182
+ const code = Predicate.hasProperty(cause, "code") ? cause.code : void 0;
183
+ const numericCode = Predicate.hasProperty(cause, "numericCode") ? cause.numericCode : void 0;
184
+ const details = {};
185
+ if (Predicate.isString(code)) details.code = code;
186
+ if (Predicate.isNumber(numericCode)) details.numericCode = numericCode;
187
+ return details;
181
188
  };
182
189
  const artifactsError = (binding, operation, cause) => new ArtifactsOperationError({
183
190
  binding,
@@ -193,22 +200,31 @@ const spanOptions = (binding, operation) => ({ attributes: {
193
200
  binding,
194
201
  operation
195
202
  } });
196
- const hasFunction = (value, key) => typeof Reflect.get(value, key) === "function";
203
+ const hasFunction = (value, key) => Predicate.hasProperty(value, key) && Predicate.isFunction(value[key]);
204
+ const ArtifactsRepoInfoSchema = Schema.Struct({
205
+ id: Schema.String,
206
+ name: Schema.String,
207
+ description: Schema.NullOr(Schema.String),
208
+ defaultBranch: Schema.String,
209
+ createdAt: Schema.String,
210
+ updatedAt: Schema.String,
211
+ lastPushAt: Schema.NullOr(Schema.String),
212
+ source: Schema.NullOr(Schema.String),
213
+ readOnly: Schema.Boolean,
214
+ remote: Schema.String
215
+ });
216
+ const decodeRepoInfo = (binding, value) => Schema.decodeUnknownEffect(ArtifactsRepoInfoSchema)(value).pipe(Effect.mapError((cause) => artifactsError(binding, "info", cause)));
217
+ const readRepoInfo = (binding, repo) => {
218
+ if (hasFunction(repo, "info")) return tryArtifactsPromise(binding, "info", () => repo.info()).pipe(Effect.flatMap((info) => decodeRepoInfo(binding, info)), Effect.withSpan("Artifacts.info", spanOptions(binding, "info")));
219
+ return decodeRepoInfo(binding, repo).pipe(Effect.withSpan("Artifacts.info", spanOptions(binding, "info")));
220
+ };
197
221
  /** Tests whether a value exposes the complete documented Artifacts repo handle API. */
198
- const isArtifactsRepoBinding = (value) => typeof value === "object" && value !== null && hasFunction(value, "createToken") && hasFunction(value, "listTokens") && hasFunction(value, "revokeToken") && hasFunction(value, "fork") && hasFunction(value, "log") && hasFunction(value, "readCommit") && hasFunction(value, "readTree");
222
+ const isArtifactsRepoBinding = (value) => hasFunction(value, "createToken") && hasFunction(value, "listTokens") && hasFunction(value, "revokeToken") && hasFunction(value, "fork") && hasFunction(value, "log") && hasFunction(value, "readCommit") && hasFunction(value, "readTree");
199
223
  /** Tests whether a value exposes the complete documented Artifacts namespace API. */
200
- const isArtifactsBinding = (value) => typeof value === "object" && value !== null && hasFunction(value, "create") && hasFunction(value, "get") && hasFunction(value, "import") && hasFunction(value, "list") && hasFunction(value, "delete");
201
- const wrapRepo = (binding, repo) => ({
202
- id: repo.id,
203
- name: repo.name,
204
- description: repo.description,
205
- defaultBranch: repo.defaultBranch,
206
- createdAt: repo.createdAt,
207
- updatedAt: repo.updatedAt,
208
- lastPushAt: repo.lastPushAt,
209
- source: repo.source,
210
- readOnly: repo.readOnly,
211
- remote: repo.remote,
224
+ const isArtifactsBinding = (value) => hasFunction(value, "create") && hasFunction(value, "get") && hasFunction(value, "import") && hasFunction(value, "list") && hasFunction(value, "delete");
225
+ const wrapRepo = (binding, repo, info) => ({
226
+ ...info,
227
+ info: () => readRepoInfo(binding, repo),
212
228
  createToken: Effect.fn("Artifacts.createToken", spanOptions(binding, "createToken"))((scope, ttl) => tryArtifactsPromise(binding, "createToken", () => repo.createToken(scope, ttl))),
213
229
  listTokens: tryArtifactsPromise(binding, "listTokens", () => repo.listTokens()).pipe(Effect.withSpan("Artifacts.listTokens", spanOptions(binding, "listTokens"))),
214
230
  revokeToken: Effect.fn("Artifacts.revokeToken", spanOptions(binding, "revokeToken"))((tokenOrId) => tryArtifactsPromise(binding, "revokeToken", () => repo.revokeToken(tokenOrId))),
@@ -221,7 +237,7 @@ const wrapRepo = (binding, repo) => ({
221
237
  const makeClient = (definition) => (artifacts) => ({
222
238
  definition,
223
239
  create: Effect.fn("Artifacts.create", spanOptions(definition.binding, "create"))((name, options) => tryArtifactsPromise(definition.binding, "create", () => artifacts.create(name, options))),
224
- get: Effect.fn("Artifacts.get", spanOptions(definition.binding, "get"))((name) => tryArtifactsPromise(definition.binding, "get", () => artifacts.get(name)).pipe(Effect.flatMap((repo) => isArtifactsRepoBinding(repo) ? Effect.succeed(wrapRepo(definition.binding, repo)) : Effect.fail(artifactsError(definition.binding, "get", /* @__PURE__ */ new TypeError(`Expected ${expectedArtifactsRepo}`)))))),
240
+ get: Effect.fn("Artifacts.get", spanOptions(definition.binding, "get"))((name) => tryArtifactsPromise(definition.binding, "get", () => artifacts.get(name)).pipe(Effect.flatMap((repo) => isArtifactsRepoBinding(repo) ? readRepoInfo(definition.binding, repo).pipe(Effect.map((info) => wrapRepo(definition.binding, repo, info))) : Effect.fail(artifactsError(definition.binding, "get", /* @__PURE__ */ new TypeError(`Expected ${expectedArtifactsRepo}`)))))),
225
241
  import: Effect.fn("Artifacts.import", spanOptions(definition.binding, "import"))((params) => tryArtifactsPromise(definition.binding, "import", () => artifacts.import(params))),
226
242
  list: Effect.fn("Artifacts.list", spanOptions(definition.binding, "list"))((options) => tryArtifactsPromise(definition.binding, "list", () => artifacts.list(options))),
227
243
  delete: Effect.fn("Artifacts.delete", spanOptions(definition.binding, "delete"))((name) => tryArtifactsPromise(definition.binding, "delete", () => artifacts.delete(name))),
@@ -1,4 +1,4 @@
1
- import { Config, ConfigProvider, Context, Effect, Layer } from "effect";
1
+ import { Config, ConfigProvider, Context, Effect, Layer, Predicate } from "effect";
2
2
  declare namespace Environment_d_exports {
3
3
  export { WorkerConfig, WorkerEnv, WorkerEnvironment };
4
4
  }
@@ -116,6 +116,7 @@ declare class BindingValidationError extends BindingValidationError_base<{
116
116
  interface ValidationOptions {
117
117
  readonly expected?: string;
118
118
  }
119
+ type BindingCandidate = Parameters<typeof Predicate.isUnknown>[0];
119
120
  /**
120
121
  * Creates a Context tag + layer for reading and validating a Cloudflare binding.
121
122
  *
@@ -128,11 +129,11 @@ interface BindingService<Self, Id extends string, Service> extends Context.Servi
128
129
  readonly binding: string;
129
130
  readonly layer: Layer.Layer<Self, BindingNotFoundError | BindingValidationError, WorkerEnvironment>;
130
131
  }
131
- declare function layer<Self, Resource>(tag: Context.Service<Self, Resource>, binding: string, isResource: (value: unknown) => value is Resource, wrap?: undefined, options?: ValidationOptions): Layer.Layer<Self, BindingNotFoundError | BindingValidationError, WorkerEnvironment>;
132
- declare function layer<Self, Resource, Service>(tag: Context.Service<Self, Service>, binding: string, isResource: (value: unknown) => value is Resource, wrap: (resource: Resource) => Service, options?: ValidationOptions): Layer.Layer<Self, BindingNotFoundError | BindingValidationError, WorkerEnvironment>;
132
+ declare function layer<Self, Resource>(tag: Context.Service<Self, Resource>, binding: string, isResource: (value: BindingCandidate) => value is Resource, wrap?: undefined, options?: ValidationOptions): Layer.Layer<Self, BindingNotFoundError | BindingValidationError, WorkerEnvironment>;
133
+ declare function layer<Self, Resource, Service>(tag: Context.Service<Self, Service>, binding: string, isResource: (value: BindingCandidate) => value is Resource, wrap: (resource: Resource) => Service, options?: ValidationOptions): Layer.Layer<Self, BindingNotFoundError | BindingValidationError, WorkerEnvironment>;
133
134
  declare const Service: <Self>() => {
134
- <Id extends string, Resource>(id: Id, binding: string, isResource: (value: unknown) => value is Resource, wrap?: undefined, options?: ValidationOptions): BindingService<Self, Id, Resource>;
135
- <Id extends string, Resource, Service>(id: Id, binding: string, isResource: (value: unknown) => value is Resource, wrap: (resource: Resource) => Service, options?: ValidationOptions): BindingService<Self, Id, Service>;
135
+ <Id extends string, Resource>(id: Id, binding: string, isResource: (value: BindingCandidate) => value is Resource, wrap?: undefined, options?: ValidationOptions): BindingService<Self, Id, Resource>;
136
+ <Id extends string, Resource, Service>(id: Id, binding: string, isResource: (value: BindingCandidate) => value is Resource, wrap: (resource: Resource) => Service, options?: ValidationOptions): BindingService<Self, Id, Service>;
136
137
  };
137
138
  //#endregion
138
139
  export { Environment_d_exports as a, WorkerEnvironment as c, Binding_d_exports as i, BindingService as n, WorkerConfig as o, BindingValidationError as r, WorkerEnv as s, BindingNotFoundError as t };
@@ -1,4 +1,4 @@
1
- import { a as ArtifactsOperationError, c as ArtifactsTokenListResult, i as ArtifactsCreateTokenResult, n as ArtifactsCreateOptions, o as ArtifactsRepoInfo, r as ArtifactsCreateRepoResult, s as ArtifactsTokenInfo, t as ArtifactsBinding, u as RepoName } from "./Artifacts-DcoXcRP5.mjs";
1
+ import { a as ArtifactsOperationError, c as ArtifactsTokenListResult, i as ArtifactsCreateTokenResult, n as ArtifactsCreateOptions, o as ArtifactsRepoInfo, r as ArtifactsCreateRepoResult, s as ArtifactsTokenInfo, t as ArtifactsBinding, u as RepoName } from "./Artifacts-DnHQA-Ax.mjs";
2
2
  import { Effect } from "effect";
3
3
  import { ArtifactClient, ArtifactImportOptions, ArtifactImportSource, ArtifactRepoSummary, ArtifactScope, ArtifactsCLIInput, ArtifactsCLIResult, RemoteAddFn } from "@cloudflare/computer/artifacts";
4
4
  //#region src/ComputerArtifacts.d.ts
@@ -1,14 +1,14 @@
1
- import { t as ArtifactsOperationError } from "./Artifacts-BhWrdyqX.mjs";
2
- import { Effect } from "effect";
1
+ import { t as ArtifactsOperationError } from "./Artifacts-rq3hUKQE.mjs";
2
+ import { Effect, Predicate } from "effect";
3
3
  //#region src/ComputerArtifacts.ts
4
4
  const artifactsErrorDetails = (cause) => {
5
- if (typeof cause !== "object" || cause === null) return {};
6
- const code = Reflect.get(cause, "code");
7
- const numericCode = Reflect.get(cause, "numericCode");
8
- return {
9
- ...typeof code === "string" ? { code } : {},
10
- ...typeof numericCode === "number" ? { numericCode } : {}
11
- };
5
+ if (!Predicate.isObject(cause)) return {};
6
+ const code = Predicate.hasProperty(cause, "code") ? cause.code : void 0;
7
+ const numericCode = Predicate.hasProperty(cause, "numericCode") ? cause.numericCode : void 0;
8
+ const details = {};
9
+ if (Predicate.isString(code)) details.code = code;
10
+ if (Predicate.isNumber(numericCode)) details.numericCode = numericCode;
11
+ return details;
12
12
  };
13
13
  const operationError = (binding, operation, cause) => new ArtifactsOperationError({
14
14
  binding,
@@ -1,5 +1,5 @@
1
1
  import { ComputerArtifactsClient } from "./ComputerArtifacts.mjs";
2
- import { t as DurableObjectState } from "./DurableObjectState-biHrHwrh.mjs";
2
+ import { t as DurableObjectState } from "./DurableObjectState-OupNMMUl.mjs";
3
3
  import { Context, Effect, Layer, Schema, Scope, Stream } from "effect";
4
4
  import { CommitView, GitClient, GitCloneOptions, GitCommitOptions, GitDiffOptions, GitFetchOptions, GitLogOptions, GitUpdateRefOptions } from "@cloudflare/computer/git";
5
5
  import { ExecSyncResult, RuntimeExecOptions, RuntimeGetOptions, RuntimeKillOptions, ShellValue, SkippedEntry, ThinkWorkspaceCompatibility, WorkspaceClient, WorkspaceRuntimeResult, WorkspaceRuntimeValue as WorkspaceRuntimeValue$1 } from "@cloudflare/computer";
@@ -229,7 +229,7 @@ type EffectThinkMethod<Method> = Method extends ((...args: infer Args) => Promis
229
229
  /** Effect wrapper of the optional Think compatibility surface. */
230
230
  type ComputerWorkspaceThink = { readonly [Name in keyof ThinkWorkspaceCompatibility]: EffectThinkMethod<ThinkWorkspaceCompatibility[Name]>; };
231
231
  /** Effect service over every client surface exposed by Cloudflare Computer. */
232
- interface ComputerWorkspaceShape {
232
+ interface ComputerWorkspaceService {
233
233
  readonly fs: ComputerWorkspaceFilesystem;
234
234
  readonly git: ComputerWorkspaceGit;
235
235
  readonly runtime: ComputerWorkspaceRuntime;
@@ -265,8 +265,8 @@ interface ComputerWorkspaceShape {
265
265
  * {@link ComputerWorkspace.layer} in Durable Objects so the parent client and
266
266
  * every runtime handle are disposed by Effect `Scope`.
267
267
  */
268
- declare const fromWorkspaceClient: (client: WorkspaceClient) => ComputerWorkspaceShape;
269
- declare const ComputerWorkspace_base: Context.ServiceClass<ComputerWorkspace, "effect-cf/ComputerWorkspace", ComputerWorkspaceShape>;
268
+ declare const fromWorkspaceClient: (client: WorkspaceClient) => ComputerWorkspaceService;
269
+ declare const ComputerWorkspace_base: Context.ServiceClass<ComputerWorkspace, "effect-cf/ComputerWorkspace", ComputerWorkspaceService>;
270
270
  /** Effect service for the workspace owned by the enclosing Durable Object. */
271
271
  declare class ComputerWorkspace extends ComputerWorkspace_base {
272
272
  /**
@@ -276,4 +276,4 @@ declare class ComputerWorkspace extends ComputerWorkspace_base {
276
276
  static readonly layer: Layer.Layer<ComputerWorkspace, never, DurableObjectState>;
277
277
  }
278
278
  //#endregion
279
- export { ComputerWorkspace, ComputerWorkspaceAssets, ComputerWorkspaceFilesystem, ComputerWorkspaceGit, ComputerWorkspaceRuntime, ComputerWorkspaceShape, ComputerWorkspaceThink, ListDirectoryOptions, ReadTextFileOptions, RemovePathOptions, WorkspaceAssetsError, WorkspaceDirectoryEntry, WorkspaceEntryStat, WorkspaceExec, WorkspaceExecChunk, WorkspaceExecCollect, WorkspaceExecEncoding, WorkspaceExecError, WorkspaceExecEvent, WorkspaceExecOptions, WorkspaceExecResult, WorkspaceExecRun, WorkspaceExecSignal, WorkspaceExecSkippedEntry, WorkspaceExecSyncResult, WorkspaceFindOptions, WorkspaceFoundEntry, WorkspaceFsError, WorkspaceGetExec, WorkspaceGetExecOptions, WorkspaceGitCheckoutOptions, WorkspaceGitCloneOptions, WorkspaceGitCommit, WorkspaceGitCommitOptions, WorkspaceGitDiffOptions, WorkspaceGitError, WorkspaceGitFetchOptions, WorkspaceGitFetchResult, WorkspaceGitLogOptions, WorkspaceGitPerson, WorkspaceGitUpdateRefOptions, WorkspaceGrepMatch, WorkspaceGrepOptions, WorkspaceMkdirOptions, WorkspaceReadEncoding, WorkspaceReadFile, WorkspaceReadFileOptions, WorkspaceRuntimeValue, WorkspaceWriteFileContent, WorkspaceWriteFileOptions, fromWorkspaceClient };
279
+ export { ComputerWorkspace, ComputerWorkspaceAssets, ComputerWorkspaceFilesystem, ComputerWorkspaceGit, ComputerWorkspaceRuntime, ComputerWorkspaceService, type ComputerWorkspaceService as ComputerWorkspaceShape, ComputerWorkspaceThink, ListDirectoryOptions, ReadTextFileOptions, RemovePathOptions, WorkspaceAssetsError, WorkspaceDirectoryEntry, WorkspaceEntryStat, WorkspaceExec, WorkspaceExecChunk, WorkspaceExecCollect, WorkspaceExecEncoding, WorkspaceExecError, WorkspaceExecEvent, WorkspaceExecOptions, WorkspaceExecResult, WorkspaceExecRun, WorkspaceExecSignal, WorkspaceExecSkippedEntry, WorkspaceExecSyncResult, WorkspaceFindOptions, WorkspaceFoundEntry, WorkspaceFsError, WorkspaceGetExec, WorkspaceGetExecOptions, WorkspaceGitCheckoutOptions, WorkspaceGitCloneOptions, WorkspaceGitCommit, WorkspaceGitCommitOptions, WorkspaceGitDiffOptions, WorkspaceGitError, WorkspaceGitFetchOptions, WorkspaceGitFetchResult, WorkspaceGitLogOptions, WorkspaceGitPerson, WorkspaceGitUpdateRefOptions, WorkspaceGrepMatch, WorkspaceGrepOptions, WorkspaceMkdirOptions, WorkspaceReadEncoding, WorkspaceReadFile, WorkspaceReadFileOptions, WorkspaceRuntimeValue, WorkspaceWriteFileContent, WorkspaceWriteFileOptions, fromWorkspaceClient };