authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-03-02 10:33:38-08:00
committergravatar for jmarminge@gmail.comJulius Marminge <jmarminge@gmail.com> 2026-03-02 13:13:19-08:00
log410444aead745b3a27e5c645643c74a3cb3479c3
treef3264c855f282764b23d571506d8a7676e4e22c4
parent7522d3bde34e7178fb1618ee6ca14ea7c1dc6d0d

Remove useStore selector compatibility shim

Drop the temporary selector overload from useStore and migrate the remaining selector call sites to the unified { state, dispatch } API so the store surface stays single-path. Made-with: Cursor

3 files changed, 16 insertions(+), 11 deletions(-)

apps/web/src/components/DiffPanel.tsx+7-6
......@@ -166,14 +166,15 @@ export default function DiffPanel({ mode = "inline" }: DiffPanelProps) {
166166 select: (params) => (params.threadId ? ThreadId.makeUnsafe(params.threadId) : null),
167167 });
168168 const diffSearch = useSearch({ strict: false, select: (search) => parseDiffRouteSearch(search) });
169 const { state } = useStore();
169170 const activeThreadId = routeThreadId;
170 const activeThread = useStore((state) =>
171 activeThreadId ? state.threads.find((thread) => thread.id === activeThreadId) : undefined,
172 );
171 const activeThread = activeThreadId
172 ? state.threads.find((thread) => thread.id === activeThreadId)
173 : undefined;
173174 const activeProjectId = activeThread?.projectId ?? null;
174 const activeProject = useStore((state) =>
175 activeProjectId ? state.projects.find((project) => project.id === activeProjectId) : undefined,
176 );
175 const activeProject = activeProjectId
176 ? state.projects.find((project) => project.id === activeProjectId)
177 : undefined;
177178 const activeCwd = activeThread?.worktreePath ?? activeProject?.cwd;
178179 const { turnDiffSummaries, inferredCheckpointTurnCountByTurnId } =
179180 useTurnDiffSummaries(activeThread);
apps/web/src/routes/_chat.$threadId.tsx+3-4
......@@ -133,15 +133,14 @@ const DiffPanelInlineSidebar = (props: {
133133};
134134
135135function ChatThreadRouteView() {
136 const threadsHydrated = useStore((state) => state.threadsHydrated);
136 const { state } = useStore();
137 const threadsHydrated = state.threadsHydrated;
137138 const navigate = useNavigate();
138139 const threadId = Route.useParams({
139140 select: (params) => ThreadId.makeUnsafe(params.threadId),
140141 });
141142 const search = Route.useSearch();
142 const threadExists = useStore((state) =>
143 state.threads.some((thread) => thread.id === threadId),
144 );
143 const threadExists = state.threads.some((thread) => thread.id === threadId);
145144 const draftThreadExists = useComposerDraftStore(
146145 (store) => Object.hasOwn(store.draftThreadsByThreadId, threadId),
147146 );
apps/web/src/store.ts+6-1
......@@ -432,7 +432,12 @@ export function StoreProvider({ children }: { children: ReactNode }) {
432432 return createElement(Fragment, null, children);
433433}
434434
435export function useStore() {
435type UseStoreCombinedResult = {
436 state: Pick<AppStore, "projects" | "threads" | "threadsHydrated" | "runtimeMode">;
437 dispatch: AppStore;
438};
439
440export function useStore(): UseStoreCombinedResult {
436441 const state = useAppStore((s) => ({
437442 projects: s.projects,
438443 threads: s.threads,