Skip to content

refactor(app): extract session prefetch controller from layout.tsx - #1058

Merged
Astro-Han merged 1 commit into
devfrom
claude/layout-prefetch
Jun 2, 2026
Merged

refactor(app): extract session prefetch controller from layout.tsx#1058
Astro-Han merged 1 commit into
devfrom
claude/layout-prefetch

Conversation

@Astro-Han

@Astro-Han Astro-Han commented Jun 2, 2026

Copy link
Copy Markdown
Owner

Summary

Extract the session message prefetch controller out of pages/layout.tsx into a focused module. Slice 1 of the layout governance split tracked in #1056 (carries on the #875 follow-up sequence).

  • New packages/app/src/pages/layout/pawwork-session-prefetch.ts exports createPawworkSessionPrefetch, owning the prefetch queue: per-directory queues, bounded concurrency, pending limit, LRU eviction, priority warm of neighboring sessions, and the route/visibility-driven effects.
  • pages/layout.tsx now calls the controller with a named dependency object and consumes the returned { prefetchSession, warm }.

Mechanical extraction: the moved code is verbatim, with external references rewired to injected reactive accessors (params, route, currentDir, visibleSessionDirs, navigation sessions, globalSDK, globalSync). Effects still register under the Layout owner. No change to user-visible behavior, DOM, copy, aria labels, command IDs, storage keys, or styling.

layout.tsx: 2204 -> 1960 lines.

Touched files

  • packages/app/src/pages/layout.tsx — remove inlined prefetch block + now-unused imports; wire controller
  • packages/app/src/pages/layout/pawwork-session-prefetch.ts — new controller

Review focus

  • Reactive boundary: deps passed as accessors/objects, not frozen values; effects under Layout owner.
  • Prefetch queue semantics unchanged (concurrency 2, pending limit 10, span 4, max 10 sessions/dir).
  • Import cleanup correct (Message type, retry, session-prefetch fns, pickSessionCacheEvictions removed from layout.tsx; dropSessionCaches kept).

Verification

  • bun turbo typecheck — green (8/8)
  • eslint on both changed files — clean
  • bun test layout suite (src/pages/layout/*.test.ts(x)) — 158 pass / 0 fail

Tests

No new test added: this is a verbatim extraction, and the core decision logic it orchestrates (shouldSkipSessionPrefetch, runSessionPrefetch, pickSessionCacheEvictions) already lives in and is tested under @/context/global-sync/session-prefetch and session-cache. Directly unit-testing the controller's stateful queue would require mocking several modules (cf. known mock.module leakage in #957), not worth it for a no-behavior-change move. The existing 158 layout tests guard regressions.

Risk

Low. Mechanical move behind a stable interface. Main risk is a reactivity regression (a dep captured as a value), mitigated by passing accessors and verified via typecheck + existing tests.

Refs #1056

Summary by CodeRabbit

  • Refactor
    • Refactored session message prefetching with improved concurrency control and queue management to ensure more efficient background loading of messages across sessions and directories.

Move the session message prefetch queue (LRU eviction, bounded concurrency,
priority warm) out of pages/layout.tsx into
pages/layout/pawwork-session-prefetch.ts as createPawworkSessionPrefetch.

Mechanical extraction: reactive dependencies (params, route, currentDir,
visibleSessionDirs, navigation sessions, global SDK/sync) are passed as a
named dependency object; effects run under the Layout owner unchanged. No
user-visible behavior change.

Refs #1056
@Astro-Han Astro-Han added P2 Medium priority app Application behavior and product flows task Narrow execution, audit, spike, migration, tracking, or upstream follow-up work tech-debt Supplemental cleanup, maintainability, architecture, test, or quality debt context labels Jun 2, 2026
@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Session prefetch logic is extracted from layout.tsx into a new dedicated module with queued concurrent fetching, LRU-based cache eviction, and Solid store reconciliation. Layout refactored to delegate prefetch orchestration to the new factory.

Changes

Session Prefetch Module Extraction

Layer / File(s) Summary
Prefetch types and utilities
packages/app/src/pages/layout/pawwork-session-prefetch.ts
SessionPrefetchInput contract, per-directory queue and pending data types, concurrency/limit constants, and mergeByID utility for stable merge-by-id operations.
Factory initialization and state management
packages/app/src/pages/layout/pawwork-session-prefetch.ts
Cancellation token, per-directory queues, and LRU tracking initialization. Effects prune non-visible directories and reset pending/inflight state on route or SDK changes.
Core async prefetch pipeline
packages/app/src/pages/layout/pawwork-session-prefetch.ts
Per-directory queue and prefetchMessages task: SDK fetch with retry, token/revision staleness checks, message/part merge-by-id, stale cache clearing, and Solid store reconciliation for messages and parts.
Queue pump, public API, and navigation integration
packages/app/src/pages/layout/pawwork-session-prefetch.ts
pumpPrefetch drives bounded-concurrency processing with inflight tracking. prefetchSession and warm helpers enqueue with cache-skip, dedupe, LRU/limit, and priority reordering. Navigation effect auto-prefetches current session and warms neighbors.
Layout integration and prefetch cleanup
packages/app/src/pages/layout.tsx
Remove Message type and session-prefetch imports. Import createPawworkSessionPrefetch and replace inline prefetch logic with factory call, wiring prefetchSession and warm into sidebar context.

Sequence Diagram

sequenceDiagram
  participant Navigation as Navigation / Route Change
  participant prefetchSession
  participant PrefetchQueue as Prefetch Queue
  participant PumpPrefetch as pumpPrefetch
  participant prefetchMessages as prefetchMessages
  participant SDK as SDK Client
  participant SolidStore as Solid Store
  
  Navigation->>prefetchSession: prefetch current session (high priority)
  prefetchSession->>PrefetchQueue: enqueue session, apply LRU/dedupe
  prefetchSession->>prefetchSession: reorder pending by priority
  
  PumpPrefetch->>PumpPrefetch: check concurrency limit
  PumpPrefetch->>prefetchMessages: start async fetch task
  
  prefetchMessages->>SDK: fetchSessionMessages with retry
  SDK-->>prefetchMessages: messages + parts
  
  prefetchMessages->>prefetchMessages: merge by id, compute cursor
  prefetchMessages->>SolidStore: reconcile message list
  prefetchMessages->>SolidStore: reconcile per-message parts
  prefetchMessages->>prefetchMessages: setSessionPrefetch metadata
  
  prefetchMessages-->>PumpPrefetch: on complete
  PumpPrefetch->>PumpPrefetch: decrement counters, continue pump
  
  Navigation->>prefetchSession: warm neighboring sessions
  prefetchSession->>PrefetchQueue: enqueue nearby in span window
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

  • #1056: Directly implements the session prefetch extraction and controller wiring described in the related task—creates createPawworkSessionPrefetch, exports public API (prefetchSession, warm), and refactors layout.tsx to delegate prefetch orchestration to the new module.

Poem

🐰 A queue hops in, then bounces out,
With LRU's clever, speedy clout.
Sessions warm before you roam,
Solid stores now have a home.
Pawwork prefetch, clean and light! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: extracting the session prefetch controller from layout.tsx into a new module.
Description check ✅ Passed The description is comprehensive and mostly complete, addressing all major sections except Human Review Status which needs to be set explicitly.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/layout-prefetch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added the ui Design system and user interface label Jun 2, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested priority: P2 (includes user-path files (packages/app/src/pages/layout.tsx, packages/app/src/pages/layout/pawwork-session-prefetch.ts)).

P1/P0 are reserved for maintainer confirmation. Please relabel manually if this is a release blocker, security issue, data-loss risk, or updater/runtime failure.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the session prefetching logic in the layout component by extracting it from packages/app/src/pages/layout.tsx into a new dedicated helper file packages/app/src/pages/layout/pawwork-session-prefetch.ts. This improves code modularity and readability by removing over 200 lines of inline prefetching logic and cleaning up unused imports. I have no feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/src/pages/layout/pawwork-session-prefetch.ts`:
- Around line 62-67: The per-directory maps are using raw directory strings
causing duplicate keys for equivalent workspaces; normalize keys by calling
workspaceKey(directory) before accessing or setting entries in prefetchedByDir
and prefetchQueues (e.g., in the lruFor helper and the other map access sites
around the prefetch queue logic). Update lruFor to compute const key =
workspaceKey(directory) and use prefetchedByDir.get(key)/set(key, created), and
make the same change where prefetchQueues is read/modified (the blocks
referenced around lines 83-89 and 100-121) so all lookups/sets use
workspaceKey(...) instead of the raw directory string.
- Around line 91-98: The effect that runs in createEffect currently increments
prefetchToken and clears inflight state and prefetchQueues but fails to reset
the per-directory LRU snapshot, so old entries in prefetchedByDir continue to
count against PREFETCH_MAX_SESSIONS_PER_DIR; update the effect (the createEffect
block that touches input.route(), input.globalSDK.url, prefetchToken.value,
clearSessionPrefetchInflight(), prefetchQueues.clear()) to also reset/clear
prefetchedByDir (or reinitialize its LRU data structure) so prefetchSession()
sees an empty per-directory budget after a route/SDK reset.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ebdd0000-44bd-4608-8d8c-861baf6ffeec

📥 Commits

Reviewing files that changed from the base of the PR and between 5aeb1ec and 60224c3.

📒 Files selected for processing (2)
  • packages/app/src/pages/layout.tsx
  • packages/app/src/pages/layout/pawwork-session-prefetch.ts

Comment thread packages/app/src/pages/layout/pawwork-session-prefetch.ts
Comment thread packages/app/src/pages/layout/pawwork-session-prefetch.ts
@Astro-Han

Copy link
Copy Markdown
Owner Author

Re CodeRabbit's two findings (raw-directory map keys; prefetchedByDir not cleared on route/SDK reset): both describe pre-existing prefetch behavior, not regressions from this PR. This is a verbatim extraction — the deleted block in the diff uses the same raw-directory keys and the same reset effect that intentionally leaves prefetchedByDir alone.

  • Map keys: the original keyed prefetchedByDir / prefetchQueues by raw directory; markPrefetched normalizes via workspaceKey() only where it compares against the current dir. Changing the map keys is a behavior change, out of scope for a pure-extraction slice.
  • LRU on reset: prefetchedByDir is pruned by the visibility-driven effect (the first createEffect in the controller, dropping any dir not in visibleSessionDirs()), so it is not orphaned across route changes. The route/url reset effect leaving it intact matches the original exactly.

Keeping this slice behavior-identical per #1056. If either is worth changing, it should be a separate prefetch bug PR with its own review, not bundled into the governance extraction.

@Astro-Han
Astro-Han merged commit 6f12d52 into dev Jun 2, 2026
37 of 39 checks passed
@Astro-Han
Astro-Han deleted the claude/layout-prefetch branch June 2, 2026 12:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app Application behavior and product flows P2 Medium priority task Narrow execution, audit, spike, migration, tracking, or upstream follow-up work tech-debt Supplemental cleanup, maintainability, architecture, test, or quality debt context ui Design system and user interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant