Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .changeset/fresh-alarms-remember-names.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/short-lions-greet-warmly.md

This file was deleted.

2 changes: 1 addition & 1 deletion fixtures/chat/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
},
"dependencies": {
"nanoid": "^5.1.9",
"partyserver": "^0.5.3",
"partyserver": "^0.5.4",
"partysocket": "^1.1.18",
"react": "^19.2.5",
"react-dom": "^19.2.5"
Expand Down
2 changes: 1 addition & 1 deletion fixtures/globe/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
},
"dependencies": {
"cobe": "^2.0.1",
"partyserver": "^0.5.3",
"partyserver": "^0.5.4",
"partysocket": "^1.1.18",
"react": "^19.2.5",
"react-dom": "^19.2.5"
Expand Down
2 changes: 1 addition & 1 deletion fixtures/hono/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"dependencies": {
"hono": "^4.12.15",
"hono-party": "^2.1.0",
"partyserver": "^0.5.3",
"partyserver": "^0.5.4",
"partysocket": "^1.1.18",
"react": "^19.2.5",
"react-dom": "^19.2.5"
Expand Down
2 changes: 1 addition & 1 deletion fixtures/tiptap-yjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"@tiptap/extension-collaboration": "^3.22.4",
"@tiptap/react": "^3.22.4",
"@tiptap/starter-kit": "^3.22.4",
"partyserver": "^0.5.3",
"partyserver": "^0.5.4",
"react": "^19.2.5",
"react-dom": "^19.2.5",
"tailwindcss": "^4.2.4",
Expand Down
2 changes: 1 addition & 1 deletion fixtures/tldraw/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"start": "vite dev"
},
"dependencies": {
"partyserver": "^0.5.3",
"partyserver": "^0.5.4",
"partysocket": "^1.1.18",
"react": "^19.2.5",
"react-dom": "^19.2.5",
Expand Down
2 changes: 1 addition & 1 deletion fixtures/todo-sync/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"dependencies": {
"nanoid": "^5.1.9",
"partyfn": "^0.1.0",
"partyserver": "^0.5.3",
"partyserver": "^0.5.4",
"partysocket": "^1.1.18",
"partysync": "^2.1.0",
"react": "^19.2.5",
Expand Down
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions packages/partyserver/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# partyflare

## 0.5.4

### Patch Changes

- [#391](https://github.com/cloudflare/partykit/pull/391) [`6273c96`](https://github.com/cloudflare/partykit/commit/6273c96ca1886d4ce2f5c710fdf2c407a827bb03) Thanks [@threepointone](https://github.com/threepointone)! - Persist a `__ps_name` fallback for name-based Durable Objects during initialization. This lets alarm handlers recover `this.name` even when firing on a stale on-disk alarm record that was scheduled by an older workerd version that didn't yet persist `name` into the alarm record. See cloudflare/partykit#390.

- [#393](https://github.com/cloudflare/partykit/pull/393) [`5335251`](https://github.com/cloudflare/partykit/commit/533525117ab7acbaebfa9b5c62e3821ce03be189) Thanks [@threepointone](https://github.com/threepointone)! - Complete the WebSocket close handshake when a client initiates the close. Previously, both the hibernating `webSocketClose` handler and the non-hibernating close-event listener forwarded to user `onClose` but never sent a reciprocal Close frame, leaving clients stuck in `CLOSING` until they timed out and reported `1006` (abnormal closure). The framework now reciprocates the peer's Close frame in a `finally` block on both paths — required by the Hibernation API on every compat date, and required by the standard `accept()` API on compat dates before `2026-04-07` (where the runtime's `web_socket_auto_reply_to_close` flag isn't yet active). Calling `close()` on an already-closed socket is a silent no-op, so user code that already calls `connection.close(...)` from `onClose` is unaffected. Reserved close codes (`1005`, `1006`, `1015`) are normalized to `1000` before reciprocation so they don't throw `InvalidAccessError`. See cloudflare/partykit#389.

## 0.5.3

### Patch Changes
Expand All @@ -11,6 +19,7 @@
The fix is at the call site, not in PartyServer: pass `id: someBoundDONamespace.idFromName(facetName)` to `ctx.facets.get(...)`. The facet then gets its own native `ctx.id.name === facetName` and PartyServer's `name` getter does the right thing automatically. No `setName()` is required, no `__ps_name` storage record is written, and cold-wake recovery happens for free because the factory re-runs and `idFromName` is deterministic.

This release adds:

- **A "Using PartyServer with Durable Object Facets" section in the README** that walks through the recommended pattern with a code example, calls out the implicit-id footgun explicitly, and documents that plain-string `id` values are not a substitute for `idFromName(facetName)` (workerd treats string ids as `idFromString`-like, so the resulting facet has no `ctx.id.name`).
- **`setName()` docstring updated** to clarify that facets are NOT a `setName()` use case — point to the explicit-`id` pattern instead. The original `setName()` `ctx.id.name` mismatch throw is preserved as a typo guard for the `idFromName` happy path.
- **End-to-end facet test coverage** against the real workerd `ctx.facets.get(...)` API. A `FacetParent` / `FacetChild` fixture exercises both the implicit-id path (pinning the runtime contract that `this.name` returns the parent's name in that flow — i.e., behavior-as-documentation so framework authors are unsurprised) and the explicit-id path (recommended; verifies that all reasonable id-construction strategies work and that cold wake recovers without any storage record). Plain-string `id` is also tested; the test asserts it does NOT carry a name, pinning the contract so callers don't get tempted by the type signature.
Expand Down Expand Up @@ -39,6 +48,7 @@
```

Backward compatible:

- For DOs addressed via `idFromName()` / `getByName()` (the happy path), `setName()` continues to NOT write storage — `ctx.id.name` is the source of truth and `setName()` is just a no-op-plus-onStart.
- The pre-existing direct-storage-write pattern keeps working — the storage write becomes idempotent with what `setName()` would do.

Expand All @@ -53,6 +63,7 @@
0.5.0 moved the legacy storage hydrate into `alarm()` only, breaking Cloudflare Agents facets and any other framework that writes `__ps_name` directly before calling `__unsafe_ensureInitialized()`. Facet DOs are spawned via `ctx.facets.get(...)` rather than `idFromName()` and therefore have `ctx.id.name === undefined`; they relied on PartyServer reading the storage record back to populate `this.name` before `onStart()`.

Changes:

- Move the legacy `__ps_name` hydrate from `alarm()` into `#ensureInitialized()`, still gated on `!ctx.id.name && !#_name` so it costs nothing on the happy path (normal `idFromName()`/`getByName()` DOs skip the storage read entirely).
- `Server.fetch()` now delegates to `#ensureInitialized()` for the hydrate instead of doing its own. The `x-partykit-room` header fallback remains as a last resort when neither `ctx.id.name` nor a legacy storage record is available.
- `Server.alarm()` is simplified — it no longer needs its own hydrate call since `#ensureInitialized()` handles it.
Expand All @@ -67,6 +78,7 @@
Durable Objects now expose `ctx.id.name` on every entry point (constructor, fetch, alarm, hibernating websocket handlers) when the DO is addressed via `idFromName()`/`getByName()`. PartyServer now uses this as the primary source of `this.name`, which simplifies routing, eliminates storage writes, and makes `this.name` available inside the constructor.

Changes in `partyserver`:

- `this.name` resolves from `this.ctx.id.name`. The apologetic `workerd#2240` error message is gone.
- `this.name` is now available **inside the constructor** and from class field initializers, not just after `setName()`/`fetch()` has run.
- `routePartykitRequest` no longer issues a `setName()`/`_initAndFetch()` RPC before `fetch()`. The WebSocket path goes from 2 RPCs to 1; the HTTP path remains 1 RPC. Props, when supplied, are delivered to the DO via the `x-partykit-props` request header, set after `onBeforeConnect`/`onBeforeRequest` hooks run.
Expand All @@ -78,6 +90,7 @@
- When reading `this.name` throws, it is because `ctx.id.name` is undefined and no legacy fallback has populated the name: the DO was addressed via `idFromString()` or `newUniqueId()` (both unsupported), the runtime is too old to expose `ctx.id.name`, or a pre-2026-03-15 alarm fired before the legacy storage fallback ran.

Changes in all affected packages (`partyserver`, `partysub`, `partysync`, `y-partyserver`, `hono-party`):

- `@cloudflare/workers-types` peer dependency bumped from `^4.20240729.0` to `^4.20260424.1`. The old range predates `ctx.id.name` in the type surface.

Not supported: addressing PartyServer DOs via `idFromString()` or `newUniqueId()`. These paths return `ctx.id.name === undefined` inside the DO and will surface as a clear error from `this.name`. PartyServer has always assumed name-based addressing via `getServerByName` / `routePartykitRequest`; this release makes that assumption explicit.
Expand Down Expand Up @@ -398,12 +411,14 @@
### Patch Changes

- [`528adea`](https://github.com/threepointone/partyserver/commit/528adeaced6dce6e888d2f54cc75c3569bf2c277) Thanks [@threepointone](https://github.com/threepointone)! - some fixes and tweaks

- getServerByName was throwing on all requests
- `Env` is now an optional arg when defining `Server`
- `y-partyserver/provider` can now take an optional `prefix` arg to use a custom url to connect
- `routePartyKitRequest`/`getServerByName` now accepts `jurisdiction`

bonus:

- added a bunch of fixtures
- added stubs for docs

Expand Down
2 changes: 1 addition & 1 deletion packages/partyserver/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "partyserver",
"version": "0.5.3",
"version": "0.5.4",
"repository": {
"type": "git",
"url": "git://github.com/cloudflare/partykit.git"
Expand Down
Loading