From e8cf099fa5b42f67f4f2efcb8ab626e0308e4807 Mon Sep 17 00:00:00 2001 From: Ryan Gaus Date: Thu, 18 Jun 2026 11:29:52 -0400 Subject: [PATCH 1/2] fix: ensure that sortPresets does NOT mutate values passed in via options into Room What could happen previously is if the user passed in the layers into LiveKitRoom in components-js in the wrong order, then the JSON.stringify comparisons which were being done at that layer could be attempting to compare the sorted (via side effect) version with the new value the user passed in (which has a different ref and would not be sorted), always recreating the room. --- src/room/participant/publishUtils.test.ts | 6 ++++++ src/room/participant/publishUtils.ts | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/room/participant/publishUtils.test.ts b/src/room/participant/publishUtils.test.ts index 1580084e4e..e04c3f9f89 100644 --- a/src/room/participant/publishUtils.test.ts +++ b/src/room/participant/publishUtils.test.ts @@ -174,6 +174,12 @@ describe('customSimulcastLayers', () => { expect(sortedPresets[1].encoding.maxFramerate).toBe(15); expect(sortedPresets[2].encoding.maxFramerate).toBe(20); }); + it('does not mutate the passed-in array', () => { + const presets = [VideoPresets.h1440, VideoPresets.h360, VideoPresets.h1080, VideoPresets.h90]; + const original = [...presets]; + sortPresets(presets); + expect(presets).toEqual(original); + }); }); describe('screenShareSimulcastDefaults', () => { diff --git a/src/room/participant/publishUtils.ts b/src/room/participant/publishUtils.ts index 3d5d64862b..4e6c92ae9c 100644 --- a/src/room/participant/publishUtils.ts +++ b/src/room/participant/publishUtils.ts @@ -419,7 +419,10 @@ function encodingsFromPresets( /** @internal */ export function sortPresets(presets: Array | undefined) { if (!presets) return; - return presets.sort((a, b) => { + // Sort a copy so we don't mutate the caller's array in place. Mutating the + // passed-in simulcast layers can cause consumers that compare options by value + // (e.g. components-react's useLiveKitRoom) to detect a spurious change. + return presets.slice().sort((a, b) => { const { encoding: aEnc } = a; const { encoding: bEnc } = b; From 53e5575f3d2183e4a4bffab97f2ea16359a70be8 Mon Sep 17 00:00:00 2001 From: Ryan Gaus Date: Thu, 18 Jun 2026 11:35:41 -0400 Subject: [PATCH 2/2] fix: add missing changeset --- .changeset/tired-views-turn.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/tired-views-turn.md diff --git a/.changeset/tired-views-turn.md b/.changeset/tired-views-turn.md new file mode 100644 index 0000000000..bbc7aab977 --- /dev/null +++ b/.changeset/tired-views-turn.md @@ -0,0 +1,5 @@ +--- +'livekit-client': patch +--- + +Ensure that sortPresets does NOT mutate values passed in via options into Room