Skip to content

Refactor web stores into atomic slices ready to split ChatView#1708

Open
justsomelegs wants to merge 19 commits intopingdotgg:mainfrom
justsomelegs:web/atomic-store-refactor
Open

Refactor web stores into atomic slices ready to split ChatView#1708
justsomelegs wants to merge 19 commits intopingdotgg:mainfrom
justsomelegs:web/atomic-store-refactor

Conversation

@justsomelegs
Copy link
Copy Markdown
Contributor

@justsomelegs justsomelegs commented Apr 3, 2026

What Changed

Refactored the web orchestration store from broad array-based state into a more atomic normalized shape.

Main changes:

  • replaces projects[] / threads[] as the primary store shape with keyed records and id lists
  • splits thread state into narrower slices instead of storing one large thread object as the main reactive unit
  • updates web consumers to read direct keyed state instead of subscribing to large collections and scanning them
  • updates the web test suite and fixtures to use the new normalized store model

Old Pattern

const threads = useStore((s) => s.threads);
const activeThread = threads.find((thread) => thread.id === threadId);
const messages = activeThread?.messages ?? [];

const project = useStore((s) =>
  s.projects.find((project) => project.id === projectId)
);

New Pattern

const shell = useStore((s) => s.threadShellById[threadId]);
const session = useStore((s) => s.threadSessionById[threadId] ?? null);
const messageIds = useStore((s) => s.messageIdsByThreadId[threadId] ?? EMPTY_IDS);

const project = useStore((s) => s.projectById[projectId]);

Why

The old store shape forced many consumers to read broad collections and then search inside them. That made fine-grained subscriptions hard and set us up for unnecessary rerenders once we start breaking large components into smaller ones.

This change establishes the state model we actually want to build on:

  • direct keyed access for exact reads
  • smaller reactive boundaries inside thread state
  • a cleaner base for future work on Sidebar, ChatView, and other hot UI paths

Keeping this as a store-shape-first PR also keeps the follow-up performance work simpler. Future PRs can focus on splitting components and wiring each subcomponent to only the exact slice it needs.

Checklist

  • This PR is small and focused
  • I explained what changed and why

Note

Refactor web store state from arrays to normalized entity maps for projects and threads

  • Replaces projects: Project[] and threads: Thread[] in AppState with normalized maps (projectById, threadShellById, threadSessionById, threadTurnStateById) and id arrays, splitting thread data into immutable shell and volatile turn state slices.
  • Adds selectProjects, selectThreads, createThreadSelector, createProjectSelector, and createSidebarThreadSummarySelector to derive denormalized objects from the new normalized state; createThreadSelector memoizes by reference equality to avoid unnecessary re-renders.
  • Updates all components (ChatView, BranchToolbar, DiffPanel, Sidebar, GitActionsControl, etc.) and hooks to use selectors or direct map lookups instead of array scans.
  • Rewrites syncServerReadModel and applyOrchestrationEvent in store.ts to write into normalized slices via new writeThreadState/removeThreadState/buildThreadState helpers.
  • Risk: any code directly reading the removed state.projects, state.threads, or state.sidebarThreadsById fields will break; all in-tree callers have been migrated to selectors.

Macroscope summarized 025d832.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 3, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 7e735b3d-07ba-4591-89f8-7538e505ff9e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Apr 3, 2026
@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp bot commented Apr 3, 2026

Approvability

Verdict: Needs human review

Major refactor of web store architecture from array-based to normalized/atomic slices, restructuring core state management infrastructure across multiple files. The scope and criticality of these internal data structure changes warrant human review to ensure the migration is complete and correct.

You can customize Macroscope's approvability policy. Learn more.

@justsomelegs justsomelegs changed the title Refactor web stores into atomic slices Refactor web stores into atomic slices ready to split ChatView Apr 3, 2026
@justsomelegs
Copy link
Copy Markdown
Contributor Author

fixed CI issues, should now pass :)

Copy link
Copy Markdown
Member

@juliusmarminge juliusmarminge left a comment

Choose a reason for hiding this comment

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

Got #1765 stacked on top of this so will merge it as a stack when that one's ready!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants