| author | |
| committer | |
| log | 410444aead745b3a27e5c645643c74a3cb3479c3 |
| tree | f3264c855f282764b23d571506d8a7676e4e22c4 |
| parent | 7522d3bde34e7178fb1618ee6ca14ea7c1dc6d0d |
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: Cursor3 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) { |
| 166 | 166 | select: (params) => (params.threadId ? ThreadId.makeUnsafe(params.threadId) : null), |
| 167 | 167 | }); |
| 168 | 168 | const diffSearch = useSearch({ strict: false, select: (search) => parseDiffRouteSearch(search) }); |
| 169 | const { state } = useStore(); | |
| 169 | 170 | 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; | |
| 173 | 174 | 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; | |
| 177 | 178 | const activeCwd = activeThread?.worktreePath ?? activeProject?.cwd; |
| 178 | 179 | const { turnDiffSummaries, inferredCheckpointTurnCountByTurnId } = |
| 179 | 180 | useTurnDiffSummaries(activeThread); |
apps/web/src/routes/_chat.$threadId.tsx+3-4| ... | ... | @@ -133,15 +133,14 @@ const DiffPanelInlineSidebar = (props: { |
| 133 | 133 | }; |
| 134 | 134 | |
| 135 | 135 | function ChatThreadRouteView() { |
| 136 | const threadsHydrated = useStore((state) => state.threadsHydrated); | |
| 136 | const { state } = useStore(); | |
| 137 | const threadsHydrated = state.threadsHydrated; | |
| 137 | 138 | const navigate = useNavigate(); |
| 138 | 139 | const threadId = Route.useParams({ |
| 139 | 140 | select: (params) => ThreadId.makeUnsafe(params.threadId), |
| 140 | 141 | }); |
| 141 | 142 | 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); | |
| 145 | 144 | const draftThreadExists = useComposerDraftStore( |
| 146 | 145 | (store) => Object.hasOwn(store.draftThreadsByThreadId, threadId), |
| 147 | 146 | ); |
apps/web/src/store.ts+6-1| ... | ... | @@ -432,7 +432,12 @@ export function StoreProvider({ children }: { children: ReactNode }) { |
| 432 | 432 | return createElement(Fragment, null, children); |
| 433 | 433 | } |
| 434 | 434 | |
| 435 | export function useStore() { | |
| 435 | type UseStoreCombinedResult = { | |
| 436 | state: Pick<AppStore, "projects" | "threads" | "threadsHydrated" | "runtimeMode">; | |
| 437 | dispatch: AppStore; | |
| 438 | }; | |
| 439 | ||
| 440 | export function useStore(): UseStoreCombinedResult { | |
| 436 | 441 | const state = useAppStore((s) => ({ |
| 437 | 442 | projects: s.projects, |
| 438 | 443 | threads: s.threads, |