[wrangler] Add experimental support for declarative Durable Object exports#14210
Draft
petebacondarwin wants to merge 2 commits into
Draft
[wrangler] Add experimental support for declarative Durable Object exports#14210petebacondarwin wants to merge 2 commits into
petebacondarwin wants to merge 2 commits into
Conversation
🦋 Changeset detectedLatest commit: 555ddf1 The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
create-cloudflare
@cloudflare/deploy-helpers
@cloudflare/kv-asset-handler
miniflare
@cloudflare/pages-shared
@cloudflare/unenv-preset
@cloudflare/vite-plugin
@cloudflare/vitest-pool-workers
@cloudflare/workers-auth
@cloudflare/workers-editor-shared
@cloudflare/workers-utils
wrangler
@cloudflare/wrangler-bundler
commit: |
bbc1df8 to
2755b93
Compare
petebacondarwin
commented
Jun 16, 2026
| * Workflows are not yet supported on the export path; entries with | ||
| * non-Durable-Object types will be added here as those land. | ||
| */ | ||
| function convertExports( |
Contributor
Author
There was a problem hiding this comment.
This function will be refactored when we add support for other "types" of exports that are not Durable Objects.
…ebab-case Update the new declarative Durable Object `exports` config (still gated behind `X_DO_EXPORTS`) to match the renamed EWC API surface: - Property `transfer_to_script` -> `transfer_to` on the `transferred` tombstone variant. - Enum values for `type`, `state`, and `storage` are now kebab-case on the wire: `durable_object` -> `durable-object`, `expecting_transfer` -> `expecting-transfer`, `legacy_kv` -> `legacy-kv`. - Reconciliation response envelope fields renamed for symmetry: `to_script` -> `transfer_to`, `from_script` -> `transfer_from`. Touches the config types in `@cloudflare/workers-utils`, the validator, the `@cloudflare/config` converter (the kebab->snake `snakeStorage` helper is now redundant and removed), the deploy-helpers reconciliation renderer, the wrangler runtime consumers, the fixture, the E2E test, and the changeset.
2755b93 to
555ddf1
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.
Fixes DEVX-2572.
Adds client-side wiring for the EWC declarative Durable Object exports flow.
What this adds
A new declarative
exportsmap inwrangler.json/wrangler.tomlas an alternative to the legacymigrationsarray, gated behind theX_DO_EXPORTSenvironment variable:{ "exports": { "MyDO": { "type": "durable_object", "storage": "sqlite" }, "OldGone": { "type": "durable_object", "state": "deleted" }, "OldName": { "type": "durable_object", "state": "renamed", "renamed_to": "NewName" }, "Movee": { "type": "durable_object", "state": "transferred", "transfer_to_script": "target-worker" }, "Incoming": { "type": "durable_object", "state": "expecting_transfer", "storage": "sqlite", "transfer_from": "source-worker" } } }typecarries the export kind (currently always"durable_object"); the newstatefield carries the lifecycle and defaults to"created"(live) when omitted. Tombstone states (deleted,renamed,transferred) retire / rename / transfer a provisioned namespace;expecting_transferis a live state that names the receiving side of a two-phase cross-script transfer.Both
wrangler deployandwrangler versions uploadsend the new payload whenX_DO_EXPORTS=trueis set:The upload response's
exports_reconciliationenvelope is rendered with the spec's visibility hierarchy:✘per-class detail (rendered from the v4 envelope'smeta.details[]), thrown as aUserErrorso every blocking scenario surfaces in one round tripblocked_bylists for stale tombstonesexports" hintLocal-dev support
Local development (
wrangler devandunstable_startWorker) now reads Durable Object SQLite storage settings from the newexportsfield, so applications using the declarative flow get correct local-dev storage without needing to also declare amigrationsblock. Live entries (state: "created"andstate: "expecting_transfer") contribute the class to the local-dev DO map; tombstones do not.The validator's "no lifecycle declared" warning is now
exports-aware:exportsentries (live or tombstone), the warning suggests extending theexportsmap.X_DO_EXPORTS=trueis set, the warning also suggestsexports.migrationswarning fires.The helper that drives this also got a more accurate rename:
warnIfDurableObjectsHaveNoMigrations→warnIfDurableObjectsHaveNoLifecycleConfig.@cloudflare/configintegrationThe new
@cloudflare/configpackage'sexports.durableObject()is extended with tombstone factories and anexpectingTransfer()factory. The TS-facing API mirrors the wrangler/EWC structural shape with two stylistic transforms:renamedTo,transferToScript,transferFrom)type: "durable-object",state: "expecting-transfer",storage: "legacy-kv")convertExportsperforms the snake_case / underscore conversion at the wrangler boundary.InferDurableNamespaces<T>now correctly filters tombstones from binding-target inference, so adurableObject()typed binding can only reference a live class.Fixture
fixtures/durable-objects-exports-app/— a two-DO fixture that exercises the new shape end-to-end:CounterA,CounterB)deletedtombstone (OldCounter)renamedtombstone (LegacyName→CounterB)ctx.storage.sql.exec("SELECT 1")to prove SQLite storage is honored in local dev via the newexportsmapTested with
unstable_startWorker.Server dependencies
Requires the
exports_reconciliationaccount entitlement on Cloudflare's side. Hidden behind theX_DO_EXPORTSenv var until that gate ships broadly.Server-side phases: DEVX-2563 (1a), DEVX-2598 (1b), DEVX-2564 (2), DEVX-2600 (1d). DEVX-2599 (1c) adds full
transferredsupport — until that lands, thetransferredtombstone returns a "not yet implemented" error from EWC, which is rendered correctly via the samemeta.detailspath.Spec
https://wiki.cfdata.org/spaces/WX/pages/1396640001
A picture of a cute animal (not mandatory, but encouraged)