refactor: share useSessionStream core and mention range math across web and mobile#615
Merged
Merged
Conversation
…eb and mobile The two useSessionStream hooks were 93% identical (same scheduler, state shape, and two-effect machine lifecycle); the delta was transport and auth. A shared useSessionStreamCore(sessionId, active, transport) now lives in @atrium/surface-client, taking the SessionStreamTransport interface centaur-client already defines. Web passes a module-constant transport over sessionsApi.openStream (machine effect still keyed on sessionId only); mobile memoizes a fetch-SSE transport on serverUrl|token so auth changes reopen the stream exactly as before. Wrapper exports unchanged; no call-site edits. Adds the cycle-free shared -> centaur-client workspace dep. The mention range-maintenance math (web maintainRanges / mobile updateMentionRangesForEdit) was algebraically equivalent with one redundant disjunct; the canonical updateMentionRangesForEdit now lives in shared/src/mentions.ts with five edit-scenario tests, and both platforms import it. Consolidations verified in the 2026-07-19 dead-code audit; see docs/archive/notes/2026-07-19-dead-code-audit.md. Validation: pnpm check green (server 909, web 872, mobile 227, shared 458, centaur-client 315), both typechecks + centaur-client build green; local e2e green through 61 specs twice (runs capped by harness timeout) — gating on CI e2e.
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.
Consolidations from the 2026-07-19 dead-code audit (
docs/archive/notes/2026-07-19-dead-code-audit.md; verified feasible by adversarial review before implementation).useSessionStream — web and mobile carried 93%-identical hooks (byte-identical scheduler, state shape, two-effect machine lifecycle). The shared
useSessionStreamCore(sessionId, active, transport)in@atrium/surface-clientnow owns the lifecycle; the seam is theSessionStreamTransportinterface centaur-client already defines:sessionsApi.openStream→ machine effect keyed onsessionIdonly, as before (test mocks still intercept via property access)useMemofetch-SSE transport onserverUrl|token→ auth changes reopen the stream, as beforesetActivewrite and cleanup order preserved exactlyshared → centaur-clientworkspace dep (precedent:useWsis already a shared React hook)Mention range math —
maintainRanges(web) andupdateMentionRangesForEdit(mobile) were hand-proven algebraically equivalent (web's extrastart<oldEnddisjunct is redundant). One canonicalupdateMentionRangesForEditinshared/src/mentions.ts, five new edit-scenario tests; mobile re-exports it so its tests/callers are unchanged.Net: 10 files, +193/−217; the drift-prone duplicates are gone.
Validation:
pnpm checkfully green (2,781 tests across packages), web+mobile typecheck, centaur-client build. Local e2e ran green through 61 specs twice before hitting a harness time cap — gating on this PR's CI e2e (the protocol that landed #610/#611/#613).