feat(cloudflare): expose bucket client service#344
Open
wking-io wants to merge 3 commits into
Open
Conversation
Add yieldable XClient service tags with a layer factory so downstream Effect services can depend on an already-bound client instead of depending on the binding function directly. The binding still records the deploy-time Worker binding, but the returned client now captures WorkerEnvironment internally and exposes methods without leaking WorkerEnvironment through each method's requirement type. This lets application services remain ordinary Effect services that depend on XClient. Also document the pattern in the examples.
df5c062 to
b3a1c6d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
.layer(boundClient)helpers so application/service layers can receive an already-bound runtime client at the boundary.bind(resource)first, in Worker init, so deploy-time binding discovery cannot be hidden inside an unbuilt service layerContext
I was making an app service (
ImageStorage) that wanted to use R2 without depending onCloudflare.R2Bucket.bind(Bucket)directly. The old pattern made downstream services either bind the resource themselves or accept a binder-shaped dependency, which is awkward for idiomatic Effect services.The first version of this PR let
R2BucketClient.layer(bucket)call.bind(...)internally. That was too easy to misuse: if the layer is only provided around request/RPC handlers, Alchemy may never build that layer during deploy, so the Worker binding would not be discovered. This version makes the dependency explicit: bind in Worker init, then pass the already-bound client into the client layer.This PR applies that client-service pattern across the scoped Cloudflare object bindings and documents both usage styles.
Example service: https://github.com/wking-io/creative-agent/blob/5d0506b861120e4c6d404b9db72d777afee96261/apps/api/src/infra/ImageStorage.ts#L90
Example worker: https://github.com/wking-io/creative-agent/blob/main/apps/api/src/worker.ts
Usage Examples
Direct binding inside a Worker
Use the existing
.bind(...)API when the Worker owns the use site directly. This keeps the shortest path for simple runtime handlers and records the deploy-time Cloudflare binding during Worker init.Providing a bound client to an Effect service
Use the new client service when another service should depend on an already-bound Cloudflare runtime client. The Worker init effect performs the deploy-discoverable bind first; the application service depends on
Cloudflare.R2BucketClientand receives that concrete client from a layer.Same shape for other Cloudflare object clients
The same pattern is available for the other scoped Cloudflare bindings in this PR:
Validation
bun generate:api-referencegit diff --checkbun run build:packagescreative-agentwithbun run infra:typecheckandbun test:e2e:apiagainst the linked local package