Use ctx.id.name for PartyServer name#378
Merged
Merged
Conversation
PartyServer now uses native ctx.id.name as the primary source for this.name (minor release). This makes this.name available in the constructor and onStart for cold wakes, removes the prior storage write of __ps_name, and eliminates several setName/_initAndFetch RPCs (WS path reduced from 2 RPCs to 1; HTTP path unchanged). setName() and _initAndFetch() are deprecated (setName will throw if the provided name differs from ctx.id.name). Props are delivered via x-partykit-props; x-partykit-room remains a fallback when ctx.id.name is unavailable. Alarms still fall back to stored __ps_name for pre-2026-03-15 scheduled alarms. Tests and worker helpers were updated accordingly. Also includes dependency bumps across fixtures and updated package-lock entries.
🦋 Changeset detectedLatest commit: 9beaec8 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 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 |
hono-party
partyfn
partyserver
partysocket
partysub
partysync
partytracks
partywhen
y-partyserver
commit: |
Regression fix: with no props, `getServerByName` was returning a stub with 0 RPCs, meaning `onStart()` had not run by the time user-defined RPC methods on the stub were invoked (user RPCs don't pass through `Server.fetch()` and therefore don't trigger `#ensureInitialized()`). Restore the unconditional `setName()` call so `onStart()` is guaranteed to have completed before `getServerByName()` resolves. The call is now cheap internally (no storage write; name is read from `ctx.id.name`), so this only costs the RPC round-trip. Also: - Simplify `_initAndFetch` (now a thin shim: setName + fetch). - Add regression test covering `getServerByName` + user RPC method. - Update README `.name` docs to reflect constructor availability. - Update changeset to drop the "0 RPC" claim for getServerByName. Made-with: Cursor
- Bump @cloudflare/workers-types peer dep to ^4.20260424.1 across partyserver, partysub, partysync, y-partyserver, hono-party. The old ^4.20240729.0 range predates `ctx.id.name` in the type surface. - Improve the "cannot determine name" error in Server.fetch() to list the three real causes (idFromString/newUniqueId, old workerd runtime, direct stub.fetch without a helper) so users on old runtimes get an actionable hint instead of a misleading "missing header" message. - Add NameInConstructorServer + test guarding the headline Phase 1 capability: `this.name` must be readable from class field initializers and the constructor body. Made-with: Cursor
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
Durable Objects now expose
ctx.id.nameon every entry point (constructor, fetch, alarm, hibernating websocket handlers) when the DO is addressed viaidFromName()/getByName(). This PR makes that the primary source ofthis.namein PartyServer and retires the scaffolding we built to paper over its absence.this.nameresolves fromthis.ctx.id.name. It is now available inside the constructor, which was never possible before. The apologeticworkerd#2240error message is gone.routePartykitRequestno longer issues asetName()/_initAndFetch()RPC beforefetch(). The WebSocket path goes from 2 RPCs to 1; HTTP stays at 1. Props (when supplied) are delivered via thex-partykit-propsrequest header, set afteronBeforeConnect/onBeforeRequesthooks run so they aren't visible to user hook code.getServerByNamecontinues to perform a single RPC that awaitsonStart()before returning, so user-defined RPC methods on the stub can rely on initialization being done (native DO RPCs don't pass throughServer.fetch()and thus don't trigger#ensureInitialized()themselves). That RPC is now cheaper internally — no storage write.Serverno longer writes the__ps_namerecord to storage. Existing records remain on disk and are only read insidealarm()as a fallback for alarms scheduled before 2026-03-15 (wherectx.id.nameis not carried into the alarm handler — see the Durable Objects ID docs).setName()and_initAndFetch()are marked@deprecated. They continue to work for backward compatibility.setName(name)now throws ifnamedoes not matchctx.id.name._initAndFetch()is simplified tosetName()+fetch().x-partykit-roomheader is still accepted as a fallback whenctx.id.nameis unavailable.Call-count delta
getServerByName(ns, name)getServerByName(ns, name, { props })routePartykitRequestHTTProutePartykitRequestWS__ps_namestorage writes__ps_namestorage readsNot supported
Addressing PartyServer DOs via
idFromString()ornewUniqueId(). These paths havectx.id.name === undefinedinside the DO and will surface as a clear error fromthis.name. PartyServer has always assumed name-based addressing viagetServerByName/routePartykitRequest; this release makes that assumption explicit.Test plan
npm run check:test)npm run check:type)npm run check:lint,npm run check:format)this.nameresolves fromctx.id.nameon first fetch without any header or setName RPCsetName()throws when called with a name different fromctx.id.namegetServerByNameawaitsonStartbefore returning so user-defined RPC methods see initialized state__ps_namestorage fallback exercised vianewUniqueId()to simulate pre-2026-03-15 alarms wherectx.id.nameis actually undefinedx-partykit-roomheader fallback still works for directstub.fetch()callers__unsafe_ensureInitialized()still works as expected in their native-RPC path