From ef81dab9228ef182ffa424baeec3e1fc2c07caaf Mon Sep 17 00:00:00 2001 From: Jer Miller Date: Wed, 23 Sep 2026 14:18:42 -0600 Subject: [PATCH] fix: use patched Undici WebSocket for Jetstream --- bun.lock | 6 +++++- package-lock.json | 7 +++++-- package.json | 6 +++++- src/cmd/firehose.js | 1 + src/cmd/scan.js | 1 + .../canonical-beacon-remote-suite-260727.test.js | 14 ++++++++++---- 6 files changed, 27 insertions(+), 8 deletions(-) diff --git a/bun.lock b/bun.lock index 9339c78..4f226e4 100644 --- a/bun.lock +++ b/bun.lock @@ -17,12 +17,16 @@ "env-paths": "4.0.0", "isomorphic-git": "1.37.0", "memfs": "4.56.10", + "undici": "^6.28.1", }, "devDependencies": { "marked": "^17.0.4", }, }, }, + "overrides": { + "undici": "^6.28.1", + }, "packages": { "@atproto-labs/did-resolver": ["@atproto-labs/did-resolver@0.2.6", "", { "dependencies": { "@atproto-labs/fetch": "0.2.3", "@atproto-labs/pipe": "0.1.1", "@atproto-labs/simple-store": "0.3.0", "@atproto-labs/simple-store-memory": "0.1.4", "@atproto/did": "0.3.0", "zod": "^3.23.8" } }, "sha512-2K1bC04nI2fmgNcvof+yA28IhGlpWn2JKYlPa7To9JTKI45FINCGkQSGiL2nyXlyzDJJ34fZ1aq6/IRFIOIiqg=="], @@ -258,7 +262,7 @@ "uint8arrays": ["uint8arrays@3.0.0", "", { "dependencies": { "multiformats": "^9.4.2" } }, "sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA=="], - "undici": ["undici@6.23.0", "", {}, "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g=="], + "undici": ["undici@6.28.1", "", {}, "sha512-zWpdTVD54H48CIybL0rWQ3ukpb9d23wM7eH5RtfdmeP70cWHNjtfo7P4vZX+5CoDcO53J4Pu5uXp7lNfjc6DRA=="], "unicode-segmenter": ["unicode-segmenter@0.14.5", "", {}, "sha512-jHGmj2LUuqDcX3hqY12Ql+uhUTn8huuxNZGq7GvtF6bSybzH3aFgedYu/KTzQStEgt1Ra2F3HxadNXsNjb3m3g=="], diff --git a/package-lock.json b/package-lock.json index 11ca914..2f63ea2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,8 @@ "commander": "^13.0.0", "env-paths": "4.0.0", "isomorphic-git": "1.37.0", - "memfs": "4.56.10" + "memfs": "4.56.10", + "undici": "^6.28.1" }, "bin": { "vit": "bin/vit.js" @@ -1503,7 +1504,9 @@ "license": "(Apache-2.0 AND MIT)" }, "node_modules/undici": { - "version": "6.23.0", + "version": "6.28.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.28.1.tgz", + "integrity": "sha512-zWpdTVD54H48CIybL0rWQ3ukpb9d23wM7eH5RtfdmeP70cWHNjtfo7P4vZX+5CoDcO53J4Pu5uXp7lNfjc6DRA==", "license": "MIT", "engines": { "node": ">=18.17" diff --git a/package.json b/package.json index be93aef..b4a3788 100644 --- a/package.json +++ b/package.json @@ -33,9 +33,13 @@ "commander": "^13.0.0", "env-paths": "4.0.0", "isomorphic-git": "1.37.0", - "memfs": "4.56.10" + "memfs": "4.56.10", + "undici": "^6.28.1" }, "devDependencies": { "marked": "^17.0.4" + }, + "overrides": { + "undici": "^6.28.1" } } diff --git a/src/cmd/firehose.js b/src/cmd/firehose.js index 2421e90..1f80160 100644 --- a/src/cmd/firehose.js +++ b/src/cmd/firehose.js @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT // Copyright (c) 2026 sol pbc +import { WebSocket } from 'undici'; import { loadConfig } from '../lib/config.js'; import { CAP_COLLECTION, DEFAULT_JETSTREAM_URL } from '../lib/constants.js'; import { resolveRef } from '../lib/cap-ref.js'; diff --git a/src/cmd/scan.js b/src/cmd/scan.js index 140ae5e..7d123c5 100644 --- a/src/cmd/scan.js +++ b/src/cmd/scan.js @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT // Copyright (c) 2026 sol pbc +import { WebSocket } from 'undici'; import { CAP_COLLECTION, SKILL_COLLECTION, DEFAULT_JETSTREAM_URL } from '../lib/constants.js'; import { resolveRef } from '../lib/cap-ref.js'; import { resolveHandleFromDid } from '../lib/pds.js'; diff --git a/test/.fixtures/canonical-beacon-remote-suite-260727.test.js b/test/.fixtures/canonical-beacon-remote-suite-260727.test.js index 7963b44..c6f4d4c 100644 --- a/test/.fixtures/canonical-beacon-remote-suite-260727.test.js +++ b/test/.fixtures/canonical-beacon-remote-suite-260727.test.js @@ -28,6 +28,7 @@ let publishCalls = []; let putRecordCalls = []; let remoteRecords = []; let remoteRepoConfig = {}; +let fakeWebSocketClass; const fakeAgent = { resolveHandle: async () => ({ data: { did: 'did:plc:test' } }), @@ -88,6 +89,14 @@ mock.module('isomorphic-git', () => ({ }, })); +mock.module('undici', () => ({ + WebSocket: class { + constructor(...args) { + return new fakeWebSocketClass(...args); + } + }, +})); + const [ { shipCap }, { default: registerBeacon }, @@ -142,7 +151,6 @@ describe('canonical remote beacon behavior', () => { let errorSpy; let warnSpy; let savedEnv; - let savedWebSocket; beforeEach(() => { testDir = join(tmpdir(), '.test-canonical-beacon-remote-' + Math.random().toString(36).slice(2)); @@ -157,7 +165,6 @@ describe('canonical remote beacon behavior', () => { CODEX_CI: process.env.CODEX_CI, OPENCODE: process.env.OPENCODE, }; - savedWebSocket = globalThis.WebSocket; process.env.CLAUDECODE = ''; process.env.GEMINI_CLI = ''; process.env.CODEX_CI = ''; @@ -174,7 +181,6 @@ describe('canonical remote beacon behavior', () => { logSpy.mockRestore(); errorSpy.mockRestore(); warnSpy.mockRestore(); - globalThis.WebSocket = savedWebSocket; for (const [key, value] of Object.entries(savedEnv)) { if (value === undefined) delete process.env[key]; else process.env[key] = value; @@ -448,7 +454,7 @@ describe('canonical remote beacon behavior', () => { }, }, ]; - globalThis.WebSocket = class FakeWebSocket { + fakeWebSocketClass = class FakeWebSocket { constructor() { queueMicrotask(() => { for (const message of messages) { -- 2.51.2