mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 13:05:32 +09:00
chore(deps): upgrade all dependencies, toolchains and images (#2825)
This commit is contained in:
1 parent
56e04e7b53
commit
3b552e00ef
510 files changed
+23614
-37473
No files matched your search
@@ -1,37 +1,44 @@
|
||||
# Vendored: livekit-client
|
||||
# Vendored livekit-client
|
||||
|
||||
- **Upstream:** https://github.com/livekit/client-sdk-js
|
||||
- **Version:** v2.17.2 (git tag `v2.17.2`)
|
||||
- **License:** Apache-2.0
|
||||
- **Date vendored:** 2026-05-25
|
||||
Vendored from https://github.com/livekit/client-sdk-js at tag `v2.22.3` (commit `53dd840`) under the Apache-2.0 licence. Re-vendored from `v2.17.2` on 2026-09-17.
|
||||
|
||||
## Source transforms
|
||||
|
||||
Every file went through the same mechanical steps, so a fresh upstream tree can be brought into this shape before merging.
|
||||
|
||||
1. Test files, `src/test` and snapshots are dropped. Files that are not reachable from `src/index.ts` or `src/e2ee/worker/e2ee.worker.ts` are dropped too.
|
||||
2. Comments are stripped. `/// <reference>` lines, `@ts-expect-error` directives that are still needed and `biome-ignore` lines stay.
|
||||
3. Relative imports get explicit `.ts` extensions, and directory imports point at `index.ts`.
|
||||
4. Each file starts with the LiveKit SPDX header.
|
||||
5. `biome check --write --unsafe` runs with the repo config. The unsafe fixes are reviewed by hand, because `useOptionalChain` turned `callback && callback(x)` into a call on `false` in `room/debounce.ts`, and `noUnusedPrivateClassMembers` deleted a field that was still written in `utils/dataPacketBuffer.ts`.
|
||||
6. The tree is made to pass `tsgo --noEmit` under `fluxer_app/tsconfig.json`. That means `override` modifiers, explicit `return undefined`, typed `let` declarations, no async promise executors, literal enum members and no unused `@ts-expect-error` directives.
|
||||
7. `@livekit/throws-transformer/throws` imports point at `src/utils/throws.ts`, which copies its type definitions, so the dev-only package is not a dependency.
|
||||
|
||||
## Fluxer modifications
|
||||
|
||||
Changes applied on top of the upstream v2.17.2 source. These were previously a pnpm patch at `patches/[email protected]` and are now plain source edits in this package.
|
||||
1. **AV1 end-to-end encryption** (`src/e2ee/worker/av1Utils.ts`, `FrameCryptor.ts`, `src/room/track/utils.ts`)
|
||||
|
||||
1. **AV1 E2EE support** (`src/e2ee/worker/av1Crypto.ts`, `FrameCryptor.ts`, `e2ee.worker.ts`)
|
||||
OBU-level AV1 encryption and decryption with an E2EE metadata OBU. `video/AV1X` maps to `av1`.
|
||||
|
||||
OBU-level AV1 encryption and decryption for end-to-end encrypted voice and video.
|
||||
2. **Cryptor context for reused senders** (`src/e2ee/E2eeManager.ts`, `src/e2ee/worker/FrameCryptor.ts`)
|
||||
|
||||
2. **UpdateTrackContext message** (`src/e2ee/types.ts`, worker dispatch)
|
||||
Upstream 2.22 tracks the id of a reused receiver in `E2EE_TRACK_ID` and sends `updateCodec` with `previousTrackId`. Fluxer applies the same to senders, passes the codec and track id from `LocalSenderCreated`, and resets codec detection whenever a cryptor moves to another track id or codec. This replaces the old `updateTrackContext` message and `get/setE2EETransformState`.
|
||||
|
||||
`updateCodec` replaced with `updateTrackContext`, which carries participant identity and track id so a reused track cannot pick up the wrong codec.
|
||||
3. **E2EE frame guards** (`src/e2ee/worker/FrameCryptor.ts`, `naluUtils.ts`)
|
||||
|
||||
3. **E2EEManager state tracking** (`src/e2ee/E2eeManager.ts`)
|
||||
Trailer, IV, tag and clear-prefix bounds are checked before any view is built, and malformed frames are dropped without ending the transform. NALU clear bytes are clamped to the frame length. H.265 slices keep 3 clear bytes where upstream keeps 2. The SIF trailer check is bounds safe.
|
||||
|
||||
`getE2EETransformState()` and `setE2EETransformState()` for transform lifecycle management.
|
||||
4. **No plaintext before the encryption state is known** (`src/e2ee/worker/FrameCryptor.ts`)
|
||||
|
||||
4. **Screen share scalability mode** (`src/room/participant/LocalParticipant.ts`)
|
||||
The encoder drops frames while the participant's encryption state is unknown. Upstream passes them through. Upstream 2.22 already drops them on decode.
|
||||
|
||||
A caller-supplied `scalabilityMode` is preserved for screen shares instead of being forced to `L3T3_KEY`, so VP9 and AV1 screen shares use the browser default unless Fluxer asks for a specific SVC layout.
|
||||
5. **Screen share scalability mode** (`src/room/participant/LocalParticipant.ts`)
|
||||
|
||||
5. **E2EE frame layout guards** (`src/e2ee/worker/FrameCryptor.ts`)
|
||||
|
||||
Encrypted frame trailer, IV, tag and clear-prefix bounds are validated before any typed-array view is constructed, and malformed frames are dropped without tearing down the transform stream.
|
||||
A caller-supplied `scalabilityMode` is kept for screen shares. Upstream forces `L1T3` and `contentHint = 'motion'`. `L3T3_KEY` is only defaulted for cameras, and SVC layers are only sent to the server when an encoding has a scalability mode.
|
||||
|
||||
6. **Encrypted backup codec publishing** (`src/room/participant/LocalParticipant.ts`, `src/e2ee/E2eeManager.ts`)
|
||||
|
||||
Backup codec tracks can be advertised and published while E2EE is on, with sender transforms attached using the cloned media track id and codec.
|
||||
Backup codecs are advertised and published while E2EE is on. The simulcast sender emits `LocalSenderCreated` with its codec and track id so it gets its own transform. A failed backup codec publish stops the cloned track and is logged instead of thrown.
|
||||
|
||||
7. **Publisher codec preferences** (`src/room/RTCEngine.ts`)
|
||||
|
||||
@@ -43,34 +50,57 @@ Changes applied on top of the upstream v2.17.2 source. These were previously a p
|
||||
|
||||
8. **Media publishing defaults** (`src/room/defaults.ts`, `src/room/utils.ts`, `src/room/track/options.ts`)
|
||||
|
||||
Codec fallback follows actual sender capabilities in the order H.264, VP9, VP8, AV1, HEVC. Advanced codecs are paired with an H.264 backup simulcast, and screen shares default to maintain-resolution with a 4K60-ready bitrate cap. AV1 and HEVC come last because both are opt-in in Fluxer, so a fallback inside `publishTrack` must not land on a codec the user did not enable. Fluxer picks the codec itself before publishing, so this order only applies when the client overrides the request, such as the reconnect republish that runs outside Fluxer's own flows.
|
||||
Codec fallback follows actual sender capabilities in the order H.264, VP9, VP8, AV1, HEVC through `supportsVideoCodec()` and `selectPreferredVideoCodec()`. HEVC is never reported on Firefox. Advanced codecs get an H.264 backup simulcast, dynacast is on, DTX is off, degradation preference is `maintain-resolution`, and screen shares default to the `original` preset at 20 Mbps and 60 fps. `musicHighQualityStereo` is 510 kbps. AV1 and HEVC come last because both are opt-in in Fluxer, so a fallback inside `publishTrack` must not land on a codec the user did not enable.
|
||||
|
||||
9. **High-fidelity Opus SDP munging** (`src/room/PCTransport.ts`)
|
||||
9. **High-fidelity Opus SDP munging** (`src/room/PCTransport.ts`, `src/room/participant/LocalParticipant.ts`)
|
||||
|
||||
Local offers and remote answers are munged to force Opus RED and FEC, 10 ms packet time, no DTX, and a 510 kbps maximum average bitrate. Stereo signalling stays opt-in. `stereo=1` and `sprop-stereo=1` are added only for publications whose `TrackBitrateInfo.stereo` is set (studio mode above the stereo bitrate threshold, and screen-share audio) and for the subscriber mids the server advertised as stereo, so a mono microphone is not encoded and decoded as a two-channel stream.
|
||||
Local offers and remote answers force Opus RED and FEC, 10 ms packet time, no DTX and a 510 kbps maximum average bitrate. `stereo=1` and `sprop-stereo=1` are only added for publications whose `TrackBitrateInfo.stereo` is set and for the subscriber mids the server advertised as stereo. Audio bitrates are registered on every browser, not only Firefox. The initial offer sent with the join request is not munged, as upstream does not munge it either.
|
||||
|
||||
10. **Remote audio volume restore at exactly zero** (`src/room/track/RemoteAudioTrack.ts`)
|
||||
10. **Remote audio volume held at zero** (`src/room/track/RemoteAudioTrack.ts`)
|
||||
|
||||
`attach()`, `connectWebAudio()` and `getVolume()` guarded the remembered `elementVolume` with a truthiness check, so a track deliberately held at `0` came back at full volume whenever it was re-attached or its Web Audio graph was rebuilt. All three now test `!== undefined`. Remote gains above `1.0` are only legal because `setVolume()` takes the Web Audio `gainNode` branch, as the `el.volume` branch would throw `IndexSizeError`, so `webAudioMix` must stay unconditional.
|
||||
`attach()`, `connectWebAudio()` and `getVolume()` test `elementVolume !== undefined`, so a track held at `0` stays silent after re-attach. Remote gains above `1.0` rely on the Web Audio `gainNode` branch, so `webAudioMix` must stay on.
|
||||
|
||||
11. **Processor teardown before source stop** (`src/room/track/LocalTrack.ts`)
|
||||
|
||||
`stop()` called `super.stop()` first, killing the source `MediaStreamTrack` and closing the readable that feeds a track processor before `processor.destroy()` ran. A camera-effect worker therefore saw input EOF before its owner's stop command and reported an operational failure during an ordinary camera-off. The processor is now captured, detached and torn down before `super.stop()`.
|
||||
`stop()` detaches and destroys the processor before `super.stop()` ends the source track.
|
||||
|
||||
12. **Transactional source and processor swaps** (`src/room/track/LocalTrack.ts`, `LocalVideoTrack.ts`, `LocalAudioTrack.ts`)
|
||||
|
||||
`setMediaStreamTrack()` applied the new source, restarted the processor and re-armed the sender with no unwind path, so a failure part-way through left a half-applied track with listeners moved, elements detached and the sender pointing at a dead track. It now takes `SetMediaStreamTrackOptions` (`force`, `deferEndedListener`, `preservePreviousTrack`) and, on failure, restores the previous source, constraints, `enabled` state, listeners, processor and sender. It throws `TrackInvalidError` when the previous source is no longer `live`, because an ended track cannot be restored, and surfaces both failures as an `AggregateError` when the unwind itself fails.
|
||||
`setMediaStreamTrack()` takes `SetMediaStreamTrackOptions` (`force`, `deferEndedListener`, `preservePreviousTrack`, `isUnmuting`) and restores the previous source, constraints, `enabled` state, listeners, processor and sender when a swap fails. `stageTrackReplacement()` and `commitStagedTrackReplacement()` give a two-phase swap. `runWithTrackChangeLock()` and `stopProcessorIfCurrent()` are public for the app. Secondary simulcast senders get the processed track, and processor install and teardown roll back every sender. Upstream's `onSenderTrackSwapped()` hook runs after a successful `replaceTrack`, `stageTrackReplacement`, `setProcessor`, `stopProcessor` and `stopProcessorIfCurrent`.
|
||||
|
||||
`stageTrackReplacement()` and `commitStagedTrackReplacement()` add a two-phase swap. The candidate becomes the active source with its `ended` listener deferred and the previous source preserved, and only the commit adopts the `ended` listener and clears the staged identity, so a caller can validate its publication before the swap is observable. `replaceTrack()` and `restart()` guard the `providedByUser` flip behind a `replacementCommitted` flag. `restart()` still detaches and stops the previous source before calling `getUserMedia()`, as upstream does, because Safari ends a freshly acquired track with a capture failure while the old track for the same device is still live. `setSimulcastTrackSender()` routes an installed processor's `processedTrack` to a newly registered secondary sender so a backup codec never publishes raw frames while the primary is processed. Processor install and teardown in all three classes roll the processed and raw sender track back, including `LocalVideoTrack`'s secondary simulcast senders, and aggregate every cleanup failure instead of discarding it.
|
||||
13. **Track bitrate entries are replaced** (`src/room/PCTransport.ts`)
|
||||
|
||||
13. **Start bitrate for every video codec** (`src/room/PCTransport.ts`, `src/room/participant/LocalParticipant.ts`, `src/room/participant/publishUtils.ts`)
|
||||
`setTrackCodecBitrate()` replaces the entry for the same cid or transceiver instead of appending, because `trackBitrates` is never cleared. Start bitrates for every video codec are upstream since 2.22 through `applyVideoStartBitrate()`.
|
||||
|
||||
`x-google-start-bitrate` was reachable only by AV1 and VP9 because it was gated twice. The publish path registered a track bitrate only for SVC codecs, and the offer munging returned early for everything else. H.264, H.265 and VP8 therefore opened at the Chromium default and had to ramp, which showed up as a 3000 kbps screen share encoding at 346 kbps twenty seconds in. The bitrate is now registered for every video codec from the highest encoding (`maxEncodingBitrate()`, so a simulcast ladder contributes its top layer), and the offer munging applies it whenever a max bitrate is known. The dependency descriptor extension stays SVC-only. `appendStartBitrateToFmtp()` holds the fmtp edit so it can be tested, and `setTrackCodecBitrate()` replaces an entry for the same cid or transceiver instead of appending, since `trackBitrates` is never cleared.
|
||||
14. **Subscriber video decoder exclusions** (`src/options.ts`, `src/room/RTCEngine.ts`, `src/room/PCTransportManager.ts`, `src/room/PCTransport.ts`)
|
||||
|
||||
`RoomOptions.subscriberVideoCodecExclusions` removes codecs from receive transceivers with `setCodecPreferences()` before every offer and answer, including the initial offer sent with the join request. Firefox and Safari are skipped.
|
||||
|
||||
15. **ICE diagnostics** (`src/room/PCTransportManager.ts`)
|
||||
|
||||
ICE candidate errors are logged once per transport, code, URL and address until the next ICE restart. The transport connect timeout names each transport's connection, ICE and signalling state.
|
||||
|
||||
16. **Screen share capture options** (`src/room/track/options.ts`, `src/room/track/utils.ts`)
|
||||
|
||||
`ScreenShareCaptureOptions` has `windowAudio`, `monitorTypeSurfaces` and `restrictOwnAudio`. `restrictOwnAudio` and `suppressLocalAudioPlayback` are passed as audio constraints.
|
||||
|
||||
17. **Stats and monitors** (`src/room/stats.ts`, `src/room/track/Track.ts`, `LocalVideoTrack.ts`, `RemoteVideoTrack.ts`, `RemoteTrack.ts`, `LocalAudioTrack.ts`)
|
||||
|
||||
Sender stats have `encoderImplementation` and `powerEfficientEncoder`, receiver stats have `powerEfficientDecoder`. `runMonitor()` skips a stats poll while the previous one is still running. Adaptive stream tracks that are not visible skip receiver stats. `setPublishingLayersForSender` writes `maxFramerate` where upstream writes a misspelt `maxFrameRate`, and `videoLayersFromEncodings` handles an SVC codec without a scalability mode.
|
||||
|
||||
18. **Smaller fixes** (`src/api/SignalClient.ts`, `src/api/utils.ts`, `src/room/Room.ts`, `src/room/timers.ts`, `src/room/utils.ts`, `src/e2ee/worker/e2ee.worker.ts`)
|
||||
|
||||
The abort path passes its reason to `SignalClient.close()` as the reason instead of `updateState`. `handleOnClose` is public so `simulateScenario` needs no suppression. Queue bypass checks no longer log every request. Abort reasons that are numbers, booleans, bigints or symbols become strings. `Room` connect rejections are always `Error` instances. `CriticalTimers` binds the native timers when the module loads. `Future` rejects when its executor throws. The e2ee worker listens with `addEventListener`, and the outgoing data stream sink no longer logs aborts to `console`.
|
||||
|
||||
## Removed upstream code
|
||||
|
||||
`connectionHelper`, `createLocalScreenTracks`, `getStereoAudioStreamTrack`, `isLocalPub`, the frame metadata worker, `room/token-source/test-tokens.ts`, `utils/subscribeToEvents.ts`, and the `DataTrackPacket`, data track packet extension and `LocalTrackRecorder` exports. `createV0RtcUrl`, `truncateBytes`, `videoQualityForRid` and `STOP_REFETCH_DELAY_MS` are no longer exported.
|
||||
|
||||
## Updating from upstream
|
||||
|
||||
1. Check the upstream changelog for the target version.
|
||||
2. `git diff v2.17.2..v<new> -- src/` to see what changed.
|
||||
3. Apply relevant upstream changes to this package's `src/`.
|
||||
4. Update the version field in `package.json` to match the new upstream version.
|
||||
5. Update this file with the new version and date.
|
||||
1. Read the upstream changelog for the target version.
|
||||
2. Run the source transforms on the old tag and on the new tag. Keep the old result as the merge base and the new result as the other side.
|
||||
3. Strip blank lines from the base, this tree and the new tree, run `git merge-file --diff3 --diff-algorithm=histogram` per file, and put blank lines back from the new tree. Blank-line drift between the trees otherwise turns into conflicts.
|
||||
4. Resolve conflicts with the modification list above. Where upstream rewrote a function that carries a Fluxer change, start from the upstream function and reapply the change.
|
||||
5. Diff the result against the transformed new tag after compiling both to JavaScript without types. Every hunk should belong to a modification listed here.
|
||||
6. Run `tsgo --noEmit` under the app tsconfig, `biome check`, `knip` and `pnpm --filter livekit-client test`, then update the version in `package.json` and this file.
|
||||
Reference in new issue
Block a user