Skip to content

Explicit Durable Object deletion, renamedFrom and conditional bindings - #7

Open
jonasnobile wants to merge 1 commit into
mainfrom
feat/durable-object-lifecycle
Open

jonasnobile wants to merge 1 commit into
mainfrom
feat/durable-object-lifecycle

Conversation

@jonasnobile

Copy link
Copy Markdown
Member

Ideas taken from Cloudflare's new cloudflare.config.ts (its exports map with deleted / renamed states), adapted to the wrangler migrations oblaka already generates.

Durable Objects are never deleted by accident

Removing a binding used to append a deleted_classes migration by default, so deleting one line deleted the stored data, and a class rename looked like delete + create.

Now a class that was bound in the previous generated config and is no longer bound fails the run. The check runs for the whole worker tree before any resource is applied or any config is written. The definition has to say what should happen:

new Worker({
	bindings: {
		ChatRoom: new DurableObject({ name: 'chat-room', className: 'ChatRoom', renamedFrom: 'Room' }),
	},
	deletedDurableObjects: ['OldCounter'],
})
  • renamedFrom generates renamed_classes, so the data moves to the new class.
  • deletedDurableObjects deletes the listed classes.
  • deleteDurableObjectsOnRemoval: true keeps the old implicit deletion, false keeps removed classes without a binding.
  • The run fails when renamedFrom names a class that is still bound, when two classes rename from the same one, or when a class is both bound and listed for deletion.

Live classes are computed by replaying the migration history (src/utils/migrations.ts), shared by DurableObject and Container. A deleted class can be created again, and renamedFrom / deletedDurableObjects can stay in the definition after deploy. The existing history stripping on deletion is kept only for a class created once and never renamed, transferred or deleted. Longer histories stay intact so they remain consistent.

Breaking: an unset deleteDurableObjectsOnRemoval now fails the run instead of deleting the removed class.

Conditional bindings

A binding set to false, null or undefined is skipped (env === 'production' && new KVNamespace(...)). The README warns against making DurableObject / Container bindings conditional, because all environments share one migration history in the generated file.

README

  • The resource table lists all 20 resources (7 were missing) and marks which ones oblaka provisions through the API.
  • New sections: conditional bindings, the Durable Object lifecycle, and Env types via wrangler types on the generated config. Checked: that already types DO namespaces by class. A TS-level InferEnv would make worker typechecks pull in oblaka's Node sources, so it was dropped.

Not verified

Whether Cloudflare accepts deleted_classes for a class whose creation was stripped from the history, when deploying to a fresh environment. That behaviour predates this PR.

Checks

bun test (136 pass), typecheck, lint, format:check.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Wy7TXnDtEsRyAsc254tCs3

…indings

Removing a Durable Object binding no longer deletes the class and its data
implicitly. A class that was bound in the previous generated config and is
no longer bound now fails the run, before any resource is applied or any
config is written, until the definition says what to do:

- deletedDurableObjects: ['Old'] on the worker deletes the class
- renamedFrom on DurableObject generates a renamed_classes migration
- deleteDurableObjectsOnRemoval: true keeps the old implicit deletion,
  false keeps the class without a binding

Live classes are computed by replaying the migration history, so a deleted
class can be created again. The history is stripped on deletion only when
the class was created once and never renamed, transferred or deleted.

Bindings set to false, null or undefined are skipped.

README: list all resources and which of them oblaka provisions, document
conditional bindings, the Durable Object lifecycle and wrangler types.

BREAKING CHANGE: deleteDurableObjectsOnRemoval now defaults to failing the
run instead of deleting the removed class.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wy7TXnDtEsRyAsc254tCs3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant