feat(celld): Durable Objects on AWS via denoland/celld - #1127
Open
sam-goodwin wants to merge 4 commits into
Open
feat(celld): Durable Objects on AWS via denoland/celld#1127sam-goodwin wants to merge 4 commits into
sam-goodwin wants to merge 4 commits into
Conversation
Top-level, host-agnostic Celld provider mirroring the Cloudflare DurableObject DX. The DO class is a pure tag; the layer binds the implementation to a fleet (Counter.make(Cells, impl)) and dual-dispatches at build time: hosting inside its fleet, remote RPC stub on any other host. Fleets deploy the same Worker bundle Cloudflare does, plus an authenticated RPC gateway; celld deploy is a pure bucket write via a pinned CLI. Hosting is pluggable behind the Celld.FleetHost keyed-tag seam (the Kubernetes.ClusterAdapter pattern); AWS.providers() contributes the aws-ecs host: S3 bucket, no-NAT VPC with S3 gateway endpoint, Cloud Map discovery, Fargate nodes with an entrypoint that supervises celld and exports ECS task-role credentials (celld v0.1.0's write replication only resolves creds via EC2 IMDS). Live-verified end to end: VPC-attached effectful Lambda driving cells over the fleet gateway — write persistence, per-cell isolation, NDJSON streaming, and typed error decoding. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The inline form couples the implementation to the class — hosted by whichever fleet yields it, with callers selecting the fleet via Counter.client(fleet). The tagged form's layer (Counter.make(fleet, impl)) remains the scalable path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Celld's own model: a fleet is the nodes + bucket and runs exactly one Worker deployment, which contains the Durable Objects. The resources now mirror that: Celld.Fleet composes the infrastructure through the FleetHost seam; Celld.Worker (deploys onto a fleet via `fleet:`) owns the bundle + celld deploy + node rolls and hosts the DO classes — Counter.make(CellsWorker, impl) binds implementations to the Worker. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
celld deploy hard-requires an esbuild binary (its own bundling step — alchemy's artifacts are rolldown-built; the captured invocation is a non-minifying single-file flatten of our chunk graph with node:*/ cloudflare:* external). Only Celld deploys need it, so it moves to an optional peerDependency pinned through the workspace catalog, with a devDependency for the repo's own tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Self-hosted Durable Objects on AWS, built on celld. A top-level
Celldnamespace mirroring celld's own model: a Fleet is the infrastructure (nodes + an S3 bucket), it runs one Worker deployment, and the Worker contains the cells (Durable Objects). Hosting is a pluggable layer —AWS.providers()contributes theaws-ecsfleet host.Start with a single file — a Fleet, a Worker deployed onto it, and an inline cell; the Worker's
fetchruns on the fleet's nodes with native access to the cells:As the app grows, split the cell from the Worker — the class becomes a pure tag and the layer binds the implementation to the Worker that hosts it:
Running the same class on a different Worker is just a different layer, and any other binding host connects the same way — a Lambda Function provides
Counter.client(CellsWorker)(network attachment + connection secrets bind automatically) and calls cells over the fleet gateway:RPC methods behave like local Effects —
Stream-returning methods arrive asStreams, andEffect.faildecodes as the typed failure on the caller.🤖 Generated with Claude Code