From 0b15552007ec5b3efc94754ab62e921575a15a4b Mon Sep 17 00:00:00 2001 From: Sunil Pai Date: Sat, 7 Feb 2026 00:48:43 +0000 Subject: [PATCH 1/2] Support basePath for PartySocket reconnect Add support for using basePath instead of room when reconnecting PartySocket. Introduce a basePath property propagated through the constructor, getWSOptions, and setWSProperties. Relax reconnect validation to require host and either room or basePath, and update error messages accordingly. Update tests to reflect the new validation messages and add a test ensuring reconnect succeeds when basePath is provided. Include a changeset documenting the patch. --- .changeset/fix-basepath-reconnect.md | 5 +++++ packages/partysocket/src/index.ts | 17 +++++++++++++---- .../src/tests/error-handling.test.ts | 16 ++++++++++++++-- .../src/tests/partysocket-url.test.ts | 2 +- 4 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 .changeset/fix-basepath-reconnect.md diff --git a/.changeset/fix-basepath-reconnect.md b/.changeset/fix-basepath-reconnect.md new file mode 100644 index 0000000..d66cf00 --- /dev/null +++ b/.changeset/fix-basepath-reconnect.md @@ -0,0 +1,5 @@ +--- +"partysocket": patch +--- + +Fix `PartySocket.reconnect()` crashing when using `basePath` without `room`. The reconnect guard now accepts either `room` or `basePath` as sufficient context to construct a connection URL. diff --git a/packages/partysocket/src/index.ts b/packages/partysocket/src/index.ts index db01f3e..66310e2 100644 --- a/packages/partysocket/src/index.ts +++ b/packages/partysocket/src/index.ts @@ -141,6 +141,7 @@ export default class PartySocket extends ReconnectingWebSocket { room?: string; host!: string; path!: string; + basePath?: string; constructor(readonly partySocketOptions: PartySocketOptions) { const wsOptions = getWSOptions(partySocketOptions); @@ -169,7 +170,8 @@ export default class PartySocket extends ReconnectingWebSocket { ...partySocketOptions, host: partySocketOptions.host ?? this.host, room: partySocketOptions.room ?? this.room, - path: partySocketOptions.path ?? this.path + path: partySocketOptions.path ?? this.path, + basePath: partySocketOptions.basePath ?? this.basePath }); this._url = wsOptions.urlProvider; @@ -180,7 +182,7 @@ export default class PartySocket extends ReconnectingWebSocket { } private setWSProperties(wsOptions: ReturnType) { - const { _pk, _pkurl, name, room, host, path } = wsOptions; + const { _pk, _pkurl, name, room, host, path, basePath } = wsOptions; this._pk = _pk; this._pkurl = _pkurl; @@ -188,15 +190,21 @@ export default class PartySocket extends ReconnectingWebSocket { this.room = room; this.host = host; this.path = path; + this.basePath = basePath; } public reconnect( code?: number | undefined, reason?: string | undefined ): void { - if (!this.room || !this.host) { + if (!this.host) { throw new Error( - "The room and host must be set before connecting, use `updateProperties` method to set them or pass them to the constructor." + "The host must be set before connecting, use `updateProperties` method to set it or pass it to the constructor." + ); + } + if (!this.room && !this.basePath) { + throw new Error( + "The room (or basePath) must be set before connecting, use `updateProperties` method to set it or pass it to the constructor." ); } super.reconnect(code, reason); @@ -256,6 +264,7 @@ function getWSOptions(partySocketOptions: PartySocketOptions) { room: party.room, host: party.host, path: party.path, + basePath: partySocketOptions.basePath, protocols: protocols, socketOptions: socketOptions, urlProvider: party.urlProvider diff --git a/packages/partysocket/src/tests/error-handling.test.ts b/packages/partysocket/src/tests/error-handling.test.ts index a73668c..985a185 100644 --- a/packages/partysocket/src/tests/error-handling.test.ts +++ b/packages/partysocket/src/tests/error-handling.test.ts @@ -126,7 +126,7 @@ describe.skip("Error Handling - PartySocket Validation", () => { expect(() => { ps.reconnect(); - }).toThrow("The room and host must be set"); + }).toThrow("The host must be set"); }); test("throws when reconnecting without room", () => { @@ -140,7 +140,19 @@ describe.skip("Error Handling - PartySocket Validation", () => { expect(() => { ps.reconnect(); - }).toThrow("The room and host must be set"); + }).toThrow("The room (or basePath) must be set"); + }); + + test("does not throw when reconnecting with basePath and no room", () => { + const ps = new PartySocket({ + host: "example.com", + basePath: "custom/path", + startClosed: true + }); + + expect(() => { + ps.reconnect(); + }).not.toThrow(); }); test("handles missing WebSocket constructor gracefully", async () => { diff --git a/packages/partysocket/src/tests/partysocket-url.test.ts b/packages/partysocket/src/tests/partysocket-url.test.ts index 3bec785..8a979d0 100644 --- a/packages/partysocket/src/tests/partysocket-url.test.ts +++ b/packages/partysocket/src/tests/partysocket-url.test.ts @@ -432,7 +432,7 @@ describe.skip("PartySocket.updateProperties", () => { ps.updateProperties({ host: "", room: "" }); expect(() => { ps.reconnect(); - }).toThrow("The room and host must be set"); + }).toThrow("The host must be set"); }); }); From 3772c94d64feeb325b1325e25eb8aa246abb5d52 Mon Sep 17 00:00:00 2001 From: Sunil Pai Date: Sat, 7 Feb 2026 00:53:31 +0000 Subject: [PATCH 2/2] Bump partyserver to ^0.1.2 Update partyserver version from ^0.1.1 to ^0.1.2 across packages: hono-party, partysub, partysync, partywhen, and y-partyserver. This aligns package.json devDependencies/dependencies with the updated package-lock. --- package-lock.json | 10 +++++----- packages/hono-party/package.json | 2 +- packages/partysub/package.json | 2 +- packages/partysync/package.json | 2 +- packages/partywhen/package.json | 2 +- packages/y-partyserver/package.json | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2683112..1a820b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12235,7 +12235,7 @@ "devDependencies": { "@cloudflare/workers-types": "^4.20251218.0", "hono": "^4.11.1", - "partyserver": "^0.1.1" + "partyserver": "^0.1.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20240729.0", @@ -12327,7 +12327,7 @@ "license": "ISC", "devDependencies": { "@cloudflare/workers-types": "^4.20251218.0", - "partyserver": "^0.1.1", + "partyserver": "^0.1.2", "partysocket": "^1.1.11" }, "peerDependencies": { @@ -12345,7 +12345,7 @@ }, "devDependencies": { "@cloudflare/workers-types": "^4.20251218.0", - "partyserver": "^0.1.1" + "partyserver": "^0.1.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20240729.0", @@ -12367,7 +12367,7 @@ "license": "ISC", "dependencies": { "cron-parser": "^5.4.0", - "partyserver": "^0.1.1" + "partyserver": "^0.1.2" } }, "packages/y-partyserver": { @@ -12382,7 +12382,7 @@ "devDependencies": { "@cloudflare/workers-types": "^4.20251218.0", "@types/lodash.debounce": "^4.0.9", - "partyserver": "^0.1.1", + "partyserver": "^0.1.2", "ws": "^8.18.3", "yjs": "^13.6.28" }, diff --git a/packages/hono-party/package.json b/packages/hono-party/package.json index 470ca5f..9364a9a 100644 --- a/packages/hono-party/package.json +++ b/packages/hono-party/package.json @@ -37,6 +37,6 @@ "devDependencies": { "@cloudflare/workers-types": "^4.20251218.0", "hono": "^4.11.1", - "partyserver": "^0.1.1" + "partyserver": "^0.1.2" } } diff --git a/packages/partysub/package.json b/packages/partysub/package.json index c375d14..df17dcf 100644 --- a/packages/partysub/package.json +++ b/packages/partysub/package.json @@ -46,7 +46,7 @@ }, "devDependencies": { "@cloudflare/workers-types": "^4.20251218.0", - "partyserver": "^0.1.1", + "partyserver": "^0.1.2", "partysocket": "^1.1.11" } } diff --git a/packages/partysync/package.json b/packages/partysync/package.json index 7064aa2..116aa90 100644 --- a/packages/partysync/package.json +++ b/packages/partysync/package.json @@ -54,6 +54,6 @@ }, "devDependencies": { "@cloudflare/workers-types": "^4.20251218.0", - "partyserver": "^0.1.1" + "partyserver": "^0.1.2" } } diff --git a/packages/partywhen/package.json b/packages/partywhen/package.json index 9b3f297..d50c21e 100644 --- a/packages/partywhen/package.json +++ b/packages/partywhen/package.json @@ -29,6 +29,6 @@ "description": "A library for scheduling and running tasks in Cloudflare Workers", "dependencies": { "cron-parser": "^5.4.0", - "partyserver": "^0.1.1" + "partyserver": "^0.1.2" } } diff --git a/packages/y-partyserver/package.json b/packages/y-partyserver/package.json index c331f91..2c50e6a 100644 --- a/packages/y-partyserver/package.json +++ b/packages/y-partyserver/package.json @@ -53,7 +53,7 @@ "devDependencies": { "@cloudflare/workers-types": "^4.20251218.0", "@types/lodash.debounce": "^4.0.9", - "partyserver": "^0.1.1", + "partyserver": "^0.1.2", "ws": "^8.18.3", "yjs": "^13.6.28" }