Layout reactivity
Reduce per-call reactive overhead in useLayout
Summary
packages/app/src/context/layout.tsx creates reactive effects inside view(sessionKey) and tabs(sessionKey) each time these helpers are called. Multiple consumers for the same key can accumulate duplicate watchers. This spec simplifies the API internals so calls stay lightweight while preserving behavior.
Goals
- Remove avoidable per-call
createEffect allocations in view() and tabs()
- Preserve scroll seeding, pruning, and touch semantics
- Keep external
useLayout API stable
Non-goals
- Persistence schema migration
- Session tab behavior redesign
- New layout features
Parallel execution contract
This spec owns:
packages/app/src/context/layout.tsx
packages/app/src/context/layout-scroll.test.ts (if updates needed)
This spec should not modify:
packages/app/src/pages/session.tsx
packages/app/src/components/session/*
Implementation plan
- Consolidate key-touch logic
- Introduce shared internal helper, e.g.
ensureSessionKey(key) that performs:
touch(key)
scroll.seed(key)
- Remove per-call effects in
view() / tabs()
- Replace internal
createEffect(on(key, ...)) usage with lazy key reads inside accessors/memos.
- Ensure reads still invoke
ensureSessionKey at safe points.
- Keep return API stable
- Preserve current method names and behavior:
view(...).scroll, setScroll, terminal, reviewPanel, review
tabs(...).active, all, open, close, move, etc.
- Verify pruning behavior
- Ensure session-key pruning still runs when key set grows and active key changes.
Acceptance criteria
view() and tabs() no longer instantiate per-call key-change effects.
- Existing callers do not require API changes.
- Scroll restore and tab persistence still work across session navigation.
- No regressions in handoff/pending-message behavior.
Validation plan
- Manual:
- Navigate across multiple sessions; verify tabs + review open state + scroll positions restore.
- Toggle terminal/review panels and confirm persisted state remains consistent.
- Tests:
- Update/add targeted tests for key seeding/pruning if behavior changed.
Risks and mitigations
- Risk: subtle key-touch ordering changes affect prune timing.
- Mitigation: keep
touch and seed coupled through one helper and verify prune boundaries.
- Risk: removing effects misses updates for dynamic accessor keys.
- Mitigation: ensure every public accessor path reads current key and calls helper.