[spike] tsunami full-context build — review only, do not merge - #583
Draft
MiloszFilimowski wants to merge 26 commits into
Draft
[spike] tsunami full-context build — review only, do not merge#583MiloszFilimowski wants to merge 26 commits into
MiloszFilimowski wants to merge 26 commits into
Conversation
…creenShare/useCustomSource tsunami: ScreenShareController (getDisplayMedia via IDeviceManager, dual- track publish, ended-listener auto-stop, disconnect teardown, persisted TracksMiddleware re-applied on restart - fixes FCE-3574); CustomSource- Controller (queued setSource, pending-publish on join, orphan cleanup, re-publish after reconnect); ClientState grows screenShare + customSources slices; client API startScreenShare/stopScreenShare/ setScreenShareTracksMiddleware/setCustomSource. react-client: ScreenshareContext + CustomSourceContext become store-backed memo adapters in the provider; useScreenshareManager + useCustomSourceManager deleted; manager types moved to types/internal. ONE deliberate test-file change: the FCE-3574 quirk assertion in screenShare.spec.ts flips per its own documented intent (bug now fixed). All other specs unaltered; 69/69 green.
utils/track.ts + utils/bandwidth.ts have no non-test importers; provider logger unused after manager adapters. No ClientState slices added for dataChannel/bandwidth/VAD - the remaining hooks pass on events+delegation with no store consumer (FCE-3579 finding: no current consumer, defer).
Extracted from the RFC spike, adapted to the real ClientState (no speculative slices), plus a remote-video grid driven by getRemoteTracks() on store notifications. Runs against tsunami sources via vite alias (no build step); examples/tsunami/* workspace glob added.
Client now reaches all four controllers uniformly (screen-share wrappers dropped); unused constraint consts, dead trackUtils export, and react-client legacy device-error machinery deleted. TrackPublisher and snapshot memoization deliberately kept (verdicts in SPIKE_NOTES).
Found live on the iOS simulator: RN's polyfilled navigator.mediaDevices has no addEventListener; onDeviceChange now feature-detects and no-ops. Finding recorded: mobile should eventually inject ReactNativeDeviceManager via a provider seam instead of inheriting WebDeviceManager.
examples/tsunami/angular: Angular 20 zoneless standalone app on tsunami sources; store-to-signal bridge is 3 lines; 34-scenario behavioral suite (7 files) mirroring FCE-3030 with its own signallingClient/mediaDevices fakes - the cross-framework proof. Findings applied to tsunami: CustomSourceController no longer emits a redundant notification on disconnect when nothing was published; sources now compile clean under noImplicitOverride/noImplicitReturns so consumers can alias tsunami sources with strict Angular tsconfigs. Recorded for later: platform-type casts repeat at every web render boundary (consider a web-narrowed surface); getRemoteTracks() is the one non-store seam (remote-track ClientState slice when a consumer demands it); events CJS dep triggers Angular bailout warning.
Connection panel now takes Fishjam ID, Sandbox API URL, room and peer name - the app mints the peer token and builds the ws url itself (fishjam-chat model). Values persist in localStorage.
The workspace tsc script emitted js next to sources (tsconfig lacked noEmit) and a bulk add swept them in; check-only now.
…ulk adds swept them in; noEmit guard now prevents this)
state/peerViews.ts: single bucketing core (deduplicates the byte-identical local/remote pair) behind explicit localPeerWithTracks / remotePeerWithTracks; remote views take a narrow RemoteTrackQualitySetter. usePeers is now pure shape conversion (branded ids + DOM casts). peers.spec unaltered.
ClientState gains dataChannel {status: idle|creating|ready, error};
events map one-update-per-event (disconnected resets status, preserves
error); createDataChannels gains an idle-dedup guard and rejects
DataChannelsNotConnectedError ('Peer is not connected') with the same
object mirrored per FCE-3580; publishData mirrors sync throws and
rethrows. useDataChannel is now a store adapter - the never-removed
dataChannelsError listener leak is gone by construction.
dataChannel.spec unaltered.
VoiceActivityMonitor lives outside the state store (remote activity mirrors signalling events, local activity polls mic audio level while subscribed). useVAD becomes a useSyncExternalStore wrapper; useLocalVAD is absorbed. Angular example switches to the tsunami sandbox/url helpers.
…injection points An injected manager owns persistence (persistLastDevice is skipped entirely), which is what lets mobile drop its localStorage polyfill later. clientType flows through the tsunami config into ts-client, so mobile can stop constructing a signalling client of its own.
…undary IDeviceManager grows createMediaStream; the controller exposes a render-ready stream scoped to the active track (the shared initializeDevices stream never leaks the other kind's track into a preview), and useCamera/useMicrophone/ useLivestreamStreamer stop calling the MediaStream global. The global now survives only for the legacy ts-client/webrtc-client core.
Fixes the real classification bug: react-native-webrtc rejects with a MediaStreamError that is not an Error and names permission denial SecurityError, which used to surface as UNHANDLED_ERROR. Permission warnings move from the navigator.mediaDevices monkey-patch onto the actual acquisition path. getDisplayMedia gains native screen-capture options; onDeviceChange becomes an honest no-op (the fork never emits devicechange), deleting the FCE-3689 cast workaround here.
FishjamProvider moves to its own module and declares what mobile is (clientType 'mobile', ReactNativeDeviceManager) instead of constructing a signalling client per render. Device acquisition no longer flows through the fake navigator.mediaDevices.
… else dies registerGlobals() is gone; globals.ts installs RTCPeerConnection (the getConfiguration-caching subclass), RTCIceCandidate, and MediaStream from direct fork imports — the exact set the legacy connection core resolves from globals. The navigator.mediaDevices fake, the in-memory localStorage, the EventTarget global, and the getUserMedia permission monkey-patch are deleted. Breaking for apps that used the removed globals directly (README note).
…ript tsunami sat at 0.0.0 while every other package tracks 0.29.0, and the release script's package list omitted it entirely — so each release would have left it further behind. It stays private:true; that flag is the remaining switch to flip when it actually goes out.
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.
Reference implementation from the Phase A full-context build. Not for merging — extraction happens PR-by-PR per EXTRACTION_MAP.md.