Skip to content

refactor: migrate search to react-query#92

Merged
rsbh merged 5 commits into
mainfrom
refactor/search-react-query
May 20, 2026
Merged

refactor: migrate search to react-query#92
rsbh merged 5 commits into
mainfrom
refactor/search-react-query

Conversation

@rsbh
Copy link
Copy Markdown
Member

@rsbh rsbh commented May 20, 2026

Summary

  • Replace manual fetch/abort/debounce in search with useQuery + keepPreviousData
  • Lodash debounce drives debouncedSearch state for query key (150ms)
  • Prefetch search suggestions on hydration for instant display on dialog open

Test plan

  • Open search dialog (Cmd/Ctrl+K) — suggestions load instantly
  • Type search query — results appear after debounce
  • Fast typing — no excessive API calls
  • Close and reopen dialog — cached suggestions shown

🤖 Generated with Claude Code

rsbh and others added 2 commits May 20, 2026 11:08
Replace manual fetch/abort/debounce with useQuery and keepPreviousData.
Lodash debounce drives debouncedSearch state for the query key.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Suggestions cached before dialog opens for instant display.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Search suggestions are now preloaded during application startup for faster results.
  • Refactor

    • Improved search component performance with enhanced state management and input debouncing for a more responsive user experience.

Walkthrough

This PR refactors the Search component to use @tanstack/react-query for data fetching instead of manual state and AbortController management, adds a new prefetchSearchSuggestions() utility, and integrates it into app hydration to prefetch search suggestions on client startup.

Changes

Search Component React Query Migration and Prefetch

Layer / File(s) Summary
Search component React Query refactor
packages/chronicle/src/components/ui/search.tsx
Search component now imports useQuery/keepPreviousData from React Query, replaces manual fetch/AbortController state with a debounced debouncedSearch driving a keyed query (enabled only when dialog open), and deduplicates results directly from the query data. Input onChange is wired to the debounced updater.
Search suggestions prefetch and hydration integration
packages/chronicle/src/lib/preload.ts, packages/chronicle/src/server/entry-client.tsx
Adds prefetchSearchSuggestions() that calls queryClient.prefetchQuery(['search', '', undefined]) to fetch /api/search, and invokes this helper during client hydration in entry-client.tsx.

Sequence Diagram

sequenceDiagram
  participant User
  participant SearchComponent
  participant ReactQuery
  participant SearchAPI

  User->>SearchComponent: types query
  SearchComponent->>SearchComponent: debounce(input) -> debouncedSearch
  SearchComponent->>ReactQuery: useQuery(['search', debouncedSearch, tag], enabled=open)
  ReactQuery->>SearchAPI: GET /api/search?q=debouncedSearch
  SearchAPI-->>ReactQuery: results
  ReactQuery-->>SearchComponent: data (keepPreviousData)
  SearchComponent->>SearchComponent: deduplicate data
  SearchComponent-->>User: render suggestions/results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • raystack/chronicle#8: Touches the search UI and /api/search wiring that this refactor builds on.
  • raystack/chronicle#45: Modifies packages/chronicle/src/components/ui/search.tsx—overlaps on Search component changes.
  • raystack/chronicle#83: Adds QueryClientProvider and page-data prefetching; related to prefetch integration in entry-client.tsx.

Suggested reviewers

  • rohilsurana
  • paanSinghCoder
  • rohanchkrabrty
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'refactor: migrate search to react-query' directly and clearly summarizes the main change: migrating the search component from manual fetch/AbortController logic to react-query's useQuery.
Description check ✅ Passed The description is directly related to the changeset, detailing the migration to react-query, debounce implementation, prefetching strategy, and providing a concrete test plan aligned with the code changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 refactor/search-react-query

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 20, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
chronicle Ready Ready Preview, Comment May 20, 2026 5:43am

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/chronicle/src/lib/preload.ts (1)

44-53: 💤 Low value

Prefetch only covers unversioned documentation.

The hardcoded query key ['search', '', undefined] won't match versioned searches where tag equals version.dir (e.g., ['search', '', 'v1']). Users on versioned URLs won't benefit from this prefetch.

Consider accepting an optional tag parameter to support versioned prefetch:

-export function prefetchSearchSuggestions() {
+export function prefetchSearchSuggestions(tag?: string) {
   queryClient.prefetchQuery({
-    queryKey: ['search', '', undefined],
+    queryKey: ['search', '', tag],
     queryFn: async () => {
-      const res = await fetch('/api/search');
+      const params = tag ? `?tag=${encodeURIComponent(tag)}` : '';
+      const res = await fetch(`/api/search${params}`);
       if (!res.ok) throw new Error(String(res.status));
       return res.json();
     },
   });
 }

Then in entry-client.tsx, resolve the version first and pass routeVersion.dir.

🤖 Prompt for 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.

In `@packages/chronicle/src/lib/preload.ts` around lines 44 - 53, The
prefetchSearchSuggestions function currently only prefetches the unversioned key
['search', '', undefined], so versioned searches (tag = version.dir) miss the
prefetch; change prefetchSearchSuggestions to accept an optional tag parameter
(e.g., prefetchSearchSuggestions(tag?: string)), include that tag in the
queryKey (['search','', tag]) and use it when calling queryClient.prefetchQuery,
and update the call site in entry-client.tsx to resolve the route version and
pass routeVersion.dir (or undefined) into prefetchSearchSuggestions so versioned
pages receive the correct prefetched data.
🤖 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.

Nitpick comments:
In `@packages/chronicle/src/lib/preload.ts`:
- Around line 44-53: The prefetchSearchSuggestions function currently only
prefetches the unversioned key ['search', '', undefined], so versioned searches
(tag = version.dir) miss the prefetch; change prefetchSearchSuggestions to
accept an optional tag parameter (e.g., prefetchSearchSuggestions(tag?:
string)), include that tag in the queryKey (['search','', tag]) and use it when
calling queryClient.prefetchQuery, and update the call site in entry-client.tsx
to resolve the route version and pass routeVersion.dir (or undefined) into
prefetchSearchSuggestions so versioned pages receive the correct prefetched
data.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 37eb0353-98a5-4922-95d8-86c1f534576f

📥 Commits

Reviewing files that changed from the base of the PR and between 0679bdf and 478974e.

📒 Files selected for processing (3)
  • packages/chronicle/src/components/ui/search.tsx
  • packages/chronicle/src/lib/preload.ts
  • packages/chronicle/src/server/entry-client.tsx

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
useMemo is semantically correct for memoizing a computed value.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread packages/chronicle/src/components/ui/search.tsx Outdated
Comment thread packages/chronicle/src/server/entry-client.tsx
Move debouncedSearch update to onChange handler directly,
removing unnecessary useEffect sync.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@rsbh rsbh requested a review from rohanchkrabrty May 20, 2026 08:11
@rsbh rsbh merged commit 8af88b9 into main May 20, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants