Skip to content

Add preact query devtools#10119

Open
JoviDeCroock wants to merge 4 commits intoTanStack:mainfrom
JoviDeCroock:add-preact-devtools-package
Open

Add preact query devtools#10119
JoviDeCroock wants to merge 4 commits intoTanStack:mainfrom
JoviDeCroock:add-preact-devtools-package

Conversation

@JoviDeCroock
Copy link

@JoviDeCroock JoviDeCroock commented Feb 12, 2026

🎯 Changes

This adds the preact-query devtools package similar to the existing vue/solid/svelte/react ones

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr.

🚀 Release Impact

This is the initial release of the package.

Summary by CodeRabbit

  • New Features

    • Added a Preact Query Devtools package with configurable Devtools and Panel components; enabled in development, no-ops in production.
    • Supports floating mode, configurable button/position, initial open state, hide-disabled-queries, error handling and theme options.
  • Documentation

    • Added comprehensive docs for installation, import, usage, floating mode, and configuration options.
  • Tests

    • Added test setup to improve devtools test reliability.

@changeset-bot
Copy link

changeset-bot bot commented Feb 12, 2026

⚠️ No Changeset found

Latest commit: 66a90f4

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions github-actions bot added the documentation Improvements or additions to documentation label Feb 12, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a new @tanstack/preact-query-devtools package: Preact-specific devtools components and panel, docs entry, build/test/lint/ts configs, test setup, and development-only export guards with production no-op stubs.

Changes

Cohort / File(s) Summary
Documentation
docs/config.json, docs/framework/preact/devtools.md
Added Getting Started entry for Preact Devtools and a new guide with install, usage, options, and floating-mode examples.
Package manifest
packages/preact-query-devtools/package.json, packages/preact-query-devtools/.attw.json
New package metadata, scripts, exports map for modern/legacy builds, workspace deps, and attw ignore rule.
Source: components & exports
packages/preact-query-devtools/src/PreactQueryDevtools.tsx, packages/preact-query-devtools/src/PreactQueryDevtoolsPanel.tsx, packages/preact-query-devtools/src/index.ts, packages/preact-query-devtools/src/production.ts, packages/preact-query-devtools/src/*.ts
New Preact wrapper components and panel, public option interfaces, prop-to-devtools syncing via effects, mount/unmount lifecycle, and dev/prod guarded exports (production stubs).
Build & bundler configs
packages/preact-query-devtools/root.tsup.config.js, packages/preact-query-devtools/tsup.config.ts, packages/preact-query-devtools/vite.config.ts
Added tsup modern/legacy builders and a Vite config with Preact preset, resolve conditions, and Vitest coverage/test settings.
TypeScript configs
packages/preact-query-devtools/tsconfig.json, packages/preact-query-devtools/tsconfig.legacy.json, packages/preact-query-devtools/tsconfig.prod.json
New TS project configs (Preact JSX runtime, outputs, and project references for prod/legacy builds).
Linting
packages/preact-query-devtools/eslint.config.js, packages/preact-query-devtools/root.eslint.config.js
Package and root ESLint configs: extend shared rules, TS-aware overrides, cspell custom dictionary, and Vitest test rules.
Testing setup
packages/preact-query-devtools/test-setup.ts
Vitest / testing-library setup: DOM cleanup and wrapping notifyManager.notify with act.

Sequence Diagram(s)

sequenceDiagram
    participant App as App
    participant PDev as PreactQueryDevtools
    participant QC as QueryClient
    participant TD as TanStackDevtools
    participant DOM as DOM

    App->>PDev: mount(props)
    PDev->>QC: resolve client (useQueryClient)
    QC-->>PDev: client
    PDev->>TD: create Devtools instance (client, config)
    TD-->>PDev: instance ready
    PDev->>DOM: create container div
    TD->>DOM: mount UI into container

    App->>PDev: update props (theme, position, etc.)
    PDev->>TD: sync prop changes
    TD->>DOM: reflect updates

    App->>PDev: unmount
    PDev->>TD: unmount & cleanup
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

package: query-devtools

Suggested reviewers

  • TkDodo

Poem

🐇 I hopped in with a curious twitch,
Preact devtools found their niche,
Docs, builds, and mounts all in tune,
I nibble code beneath the moon,
Cheers from a rabbit—hip hip hooray! 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add preact query devtools' clearly and concisely describes the main change: introducing a new preact-query devtools package.
Description check ✅ Passed The PR description includes the required 'Changes' section explaining the addition of preact-query devtools, a completed checklist confirming contribution guide compliance and local testing, and release impact statement marking this as the initial package release.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@JoviDeCroock JoviDeCroock force-pushed the add-preact-devtools-package branch from 359aade to 1e3d386 Compare February 12, 2026 06:06
Copy link
Contributor

@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.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@packages/preact-query-devtools/src/PreactQueryDevtools.tsx`:
- Line 1: The import members are not alphabetically ordered; update the named
import from 'preact/hooks' so the specifiers are sorted alphabetically (e.g.,
ensure useEffect comes before useRef and useState) in the statement that
currently imports useRef, useState, useEffect to satisfy ESLint for the
PreactQueryDevtools component.
- Around line 33-38: The JSDoc for the prop errorTypes is wrong (copied from
styleNonce); update the comment above the errorTypes property (type
Array<DevtoolsErrorType>) to describe what errorTypes does — e.g., that it
accepts an array of DevtoolsErrorType values to filter or categorize which error
kinds the devtools should display or highlight (mention valid enum/members if
applicable), and clarify default behavior when the array is empty or omitted;
edit the JSDoc near the errorTypes declaration to reflect this intent.

In `@packages/preact-query-devtools/vite.config.ts`:
- Around line 1-4: The import order violates ESLint: move the packageJson import
before the type import from 'vite' so that "import packageJson from
'./package.json'" appears above "import type { UserConfig as ViteUserConfig }
from 'vite'"; update the top of the file to list imports as preact, packageJson,
then the vite type import (keeping existing symbols preact, defineConfig,
ViteUserConfig, and packageJson intact).
🧹 Nitpick comments (1)
packages/preact-query-devtools/root.eslint.config.js (1)

20-40: Cspell word list contains terms irrelevant to the Preact package.

Words like solidjs, vue-demi, ɵkind, and ɵproviders appear to be copy-pasted from another package's config. They're harmless but add noise — consider trimming to only Preact-relevant terms.

@@ -0,0 +1,131 @@
import { useRef, useState, useEffect } from 'preact/hooks'
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Sort import members alphabetically to satisfy ESLint.

ESLint reports that useEffect should come before useRef in the import declaration.

Proposed fix
-import { useRef, useState, useEffect } from 'preact/hooks'
+import { useEffect, useRef, useState } from 'preact/hooks'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { useRef, useState, useEffect } from 'preact/hooks'
import { useEffect, useRef, useState } from 'preact/hooks'
🧰 Tools
🪛 ESLint

[error] 1-1: Member 'useEffect' of the import declaration should be sorted alphabetically.

(sort-imports)

🤖 Prompt for AI Agents
In `@packages/preact-query-devtools/src/PreactQueryDevtools.tsx` at line 1, The
import members are not alphabetically ordered; update the named import from
'preact/hooks' so the specifiers are sorted alphabetically (e.g., ensure
useEffect comes before useRef and useState) in the statement that currently
imports useRef, useState, useEffect to satisfy ESLint for the
PreactQueryDevtools component.

Comment on lines 33 to 38
/**
* Use this to pass a nonce to the style tag that is added to the document
* head. This is useful if you are using a Content Security Policy (CSP)
* nonce to allow inline styles.
*/
errorTypes?: Array<DevtoolsErrorType>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Copy-paste error in JSDoc for errorTypes.

The docstring for errorTypes is identical to the one for styleNonce ("Use this to pass a nonce to the style tag…"). It should describe the error types functionality instead.

Proposed fix
   /**
-   * Use this to pass a nonce to the style tag that is added to the document
-   * head. This is useful if you are using a Content Security Policy (CSP)
-   * nonce to allow inline styles.
+   * Use this to provide custom error type handlers for the devtools panel.
    */
   errorTypes?: Array<DevtoolsErrorType>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/**
* Use this to pass a nonce to the style tag that is added to the document
* head. This is useful if you are using a Content Security Policy (CSP)
* nonce to allow inline styles.
*/
errorTypes?: Array<DevtoolsErrorType>
/**
* Use this to provide custom error type handlers for the devtools panel.
*/
errorTypes?: Array<DevtoolsErrorType>
🤖 Prompt for AI Agents
In `@packages/preact-query-devtools/src/PreactQueryDevtools.tsx` around lines 33 -
38, The JSDoc for the prop errorTypes is wrong (copied from styleNonce); update
the comment above the errorTypes property (type Array<DevtoolsErrorType>) to
describe what errorTypes does — e.g., that it accepts an array of
DevtoolsErrorType values to filter or categorize which error kinds the devtools
should display or highlight (mention valid enum/members if applicable), and
clarify default behavior when the array is empty or omitted; edit the JSDoc near
the errorTypes declaration to reflect this intent.

Comment on lines +1 to +4
import preact from '@preact/preset-vite'
import { defineConfig } from 'vitest/config'
import type { UserConfig as ViteUserConfig } from 'vite'
import packageJson from './package.json'
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix import order to satisfy ESLint.

ESLint flags that the ./package.json import should occur before the type import of vite. This is reported as an error and may fail CI.

🔧 Proposed fix
 import preact from '@preact/preset-vite'
 import { defineConfig } from 'vitest/config'
-import type { UserConfig as ViteUserConfig } from 'vite'
 import packageJson from './package.json'
+import type { UserConfig as ViteUserConfig } from 'vite'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import preact from '@preact/preset-vite'
import { defineConfig } from 'vitest/config'
import type { UserConfig as ViteUserConfig } from 'vite'
import packageJson from './package.json'
import preact from '@preact/preset-vite'
import { defineConfig } from 'vitest/config'
import packageJson from './package.json'
import type { UserConfig as ViteUserConfig } from 'vite'
🧰 Tools
🪛 ESLint

[error] 4-4: ./package.json import should occur before type import of vite

(import/order)

🤖 Prompt for AI Agents
In `@packages/preact-query-devtools/vite.config.ts` around lines 1 - 4, The import
order violates ESLint: move the packageJson import before the type import from
'vite' so that "import packageJson from './package.json'" appears above "import
type { UserConfig as ViteUserConfig } from 'vite'"; update the top of the file
to list imports as preact, packageJson, then the vite type import (keeping
existing symbols preact, defineConfig, ViteUserConfig, and packageJson intact).

@JoviDeCroock JoviDeCroock force-pushed the add-preact-devtools-package branch 2 times, most recently from d631591 to fd22045 Compare February 12, 2026 06:14
Copy link
Contributor

@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.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@docs/framework/preact/devtools.md`:
- Around line 69-87: The Options docs omit the hideDisabledQueries and theme
props present on the DevtoolsOptions interface in PreactQueryDevtools.tsx;
update this Options section to document both: add a `hideDisabledQueries?:
boolean` entry describing that it hides queries in the UI that are disabled, and
add a `theme?: "light" | "dark" | string` (or whatever variants the
implementation accepts) entry describing theme selection and default. Reference
the DevtoolsOptions interface/props in PreactQueryDevtools.tsx to ensure wording
and default values match the implementation.

In `@packages/preact-query-devtools/src/PreactQueryDevtoolsPanel.tsx`:
- Line 1: The import list in PreactQueryDevtoolsPanel (the import from
'preact/hooks') is not alphabetized; reorder the imported members so they are
alphabetical (useEffect, useRef, useState) in the import declaration to satisfy
ESLint (update the import that currently declares useRef, useState, useEffect).
🧹 Nitpick comments (1)
packages/preact-query-devtools/src/index.ts (1)

18-18: Export DevtoolsOptions type alongside DevtoolsPanelOptions.

DevtoolsPanelOptions is re-exported from the index, but DevtoolsOptions (defined in PreactQueryDevtools.tsx) is not. Consumers typing props for PreactQueryDevtools must import from the component file directly instead of the main entry point, creating an asymmetric and less discoverable API.

Suggested fix
 export type DevtoolsPanelOptions = DevtoolsPanel.DevtoolsPanelOptions
+export type DevtoolsOptions = Devtools.DevtoolsOptions

Comment on lines +69 to +87
### Options

- `initialIsOpen: boolean`
- Set this `true` if you want the dev tools to default to being open
- `buttonPosition?: "top-left" | "top-right" | "bottom-left" | "bottom-right"`
- Defaults to `bottom-right`
- The position of the Preact Query logo to open and close the devtools panel
- `position?: "top" | "bottom" | "left" | "right"`
- Defaults to `bottom`
- The position of the Preact Query devtools panel
- `client?: QueryClient`,
- Use this to use a custom QueryClient. Otherwise, the one from the nearest context will be used.
- `errorTypes?: { name: string; initializer: (query: Query) => TError}`
- Use this to predefine some errors that can be triggered on your queries. Initializer will be called (with the specific query) when that error is toggled on from the UI. It must return an Error.
- `styleNonce?: string`
- Use this to pass a nonce to the style tag that is added to the document head. This is useful if you are using a Content Security Policy (CSP) nonce to allow inline styles.
- `shadowDOMTarget?: ShadowRoot`
- Default behavior will apply the devtool's styles to the head tag within the DOM.
- Use this to pass a shadow DOM target to the devtools so that the styles will be applied within the shadow DOM instead of within the head tag in the light DOM.
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Documentation is missing hideDisabledQueries and theme options.

The DevtoolsOptions interface in PreactQueryDevtools.tsx includes hideDisabledQueries and theme props, but this Options section doesn't list them. Consider adding them for completeness.

🤖 Prompt for AI Agents
In `@docs/framework/preact/devtools.md` around lines 69 - 87, The Options docs
omit the hideDisabledQueries and theme props present on the DevtoolsOptions
interface in PreactQueryDevtools.tsx; update this Options section to document
both: add a `hideDisabledQueries?: boolean` entry describing that it hides
queries in the UI that are disabled, and add a `theme?: "light" | "dark" |
string` (or whatever variants the implementation accepts) entry describing theme
selection and default. Reference the DevtoolsOptions interface/props in
PreactQueryDevtools.tsx to ensure wording and default values match the
implementation.

@@ -0,0 +1,110 @@
import { useRef, useState, useEffect } from 'preact/hooks'
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Sort import members alphabetically to satisfy ESLint.

ESLint reports that useEffect should come before useRef in the import declaration.

Proposed fix
-import { useRef, useState, useEffect } from 'preact/hooks'
+import { useEffect, useRef, useState } from 'preact/hooks'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { useRef, useState, useEffect } from 'preact/hooks'
import { useEffect, useRef, useState } from 'preact/hooks'
🧰 Tools
🪛 ESLint

[error] 1-1: Member 'useEffect' of the import declaration should be sorted alphabetically.

(sort-imports)

🤖 Prompt for AI Agents
In `@packages/preact-query-devtools/src/PreactQueryDevtoolsPanel.tsx` at line 1,
The import list in PreactQueryDevtoolsPanel (the import from 'preact/hooks') is
not alphabetized; reorder the imported members so they are alphabetical
(useEffect, useRef, useState) in the import declaration to satisfy ESLint
(update the import that currently declares useRef, useState, useEffect).

@theVedanta
Copy link
Contributor

Can we have some of those simple tests that just test open/close state? Like is done in other devtool packages

Copy link
Contributor

@theVedanta theVedanta left a comment

Choose a reason for hiding this comment

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

running workflows

@theVedanta
Copy link
Contributor

This LGTM! Just addressing those two comments about docs and tests can take us to merging.

@JoviDeCroock
Copy link
Author

@theVedanta Most others just have stub tests https://github.com/TanStack/query/blob/main/packages/react-query-devtools/src/__tests__/devtools.test.tsx#L5 I would prefer not to add those. The devtools packages are largely untested and adding a specfic one for that production stuff feels a bit overdone

@theVedanta
Copy link
Contributor

@theVedanta Most others just have stub tests https://github.com/TanStack/query/blob/main/packages/react-query-devtools/src/__tests__/devtools.test.tsx#L5 I would prefer not to add those. The devtools packages are largely untested and adding a specfic one for that production stuff feels a bit overdone

Understandable!

@nx-cloud
Copy link

nx-cloud bot commented Feb 23, 2026

🤖 Nx Cloud AI Fix Eligible

An automatically generated fix could have helped fix failing tasks for this run, but Self-healing CI is disabled for this workspace. Visit workspace settings to enable it and get automatic fixes in future runs.

To disable these notifications, a workspace admin can disable them in workspace settings.


View your CI Pipeline Execution ↗ for commit 66a90f4

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ❌ Failed 37s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 9s View ↗

☁️ Nx Cloud last updated this comment at 2026-02-26 17:27:44 UTC

@theVedanta
Copy link
Contributor

Can you get those lockfile errors, please? I don't expect PR / Preview to pass since it's a new package, but the rest would be fine

Copy link
Contributor

@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/preact-query-devtools/src/PreactQueryDevtools.tsx (1)

113-115: setTheme is called without a guard while setButtonPosition/setPosition both guard against undefined.

theme is optional, so devtools.setTheme(undefined) will fire on every render where theme is not provided. The adjacent effects for buttonPosition and position skip the setter when the prop is absent. If setTheme doesn't treat undefined as "reset to system default", this could cause an unintended override.

♻️ Proposed fix for consistent guard
   useEffect(() => {
-    devtools.setTheme(theme)
+    if (theme) {
+      devtools.setTheme(theme)
+    }
   }, [theme, devtools])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/preact-query-devtools/src/PreactQueryDevtools.tsx` around lines 113
- 115, The useEffect calls devtools.setTheme(theme) without guarding for
undefined; mirror the existing guards used for setButtonPosition and setPosition
by only invoking devtools.setTheme when the incoming prop is defined (e.g.,
check theme !== undefined) inside the useEffect that currently depends on
[theme, devtools]; update the effect that calls devtools.setTheme to skip
calling setTheme when theme is absent so it won't unintentionally override the
devtools theme.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@packages/preact-query-devtools/src/PreactQueryDevtools.tsx`:
- Line 1: The import members are not alphabetized; reorder the named imports in
the import from 'preact/hooks' so they are sorted alphabetically (useEffect,
useRef, useState) to satisfy ESLint — update the import line that currently
lists useRef, useState, useEffect accordingly.

---

Nitpick comments:
In `@packages/preact-query-devtools/src/PreactQueryDevtools.tsx`:
- Around line 113-115: The useEffect calls devtools.setTheme(theme) without
guarding for undefined; mirror the existing guards used for setButtonPosition
and setPosition by only invoking devtools.setTheme when the incoming prop is
defined (e.g., check theme !== undefined) inside the useEffect that currently
depends on [theme, devtools]; update the effect that calls devtools.setTheme to
skip calling setTheme when theme is absent so it won't unintentionally override
the devtools theme.

Copy link
Contributor

@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.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@packages/preact-query-devtools/src/PreactQueryDevtools.tsx`:
- Line 1: The named imports in PreacQueryDevtools.tsx are not alphabetized which
trips the ESLint sort-imports rule; reorder the specifiers in the import from
'preact/hooks' so they are alphabetically sorted (useEffect, useRef, useState)
to satisfy the linter and keep the import statement consistent.

In `@packages/preact-query-devtools/src/PreactQueryDevtoolsPanel.tsx`:
- Line 1: The import members in the top-level import from 'preact/hooks' are not
alphabetically ordered and violate the sort-imports rule; update the import
statement (the line importing useRef, useState, useEffect) so the imported
identifiers are sorted alphabetically (e.g., useEffect, useRef, useState) to
satisfy ESLint.

@JoviDeCroock JoviDeCroock force-pushed the add-preact-devtools-package branch from 3a58351 to 66a90f4 Compare February 26, 2026 17:12
renovate bot and others added 3 commits February 26, 2026 18:13
Copy link
Contributor

@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.

Actionable comments posted: 2

♻️ Duplicate comments (1)
packages/preact-query-devtools/vite.config.ts (1)

3-4: ⚠️ Potential issue | 🟡 Minor

Import order lint failure is still present.

import/order expects import packageJson from './package.json' before the type import from vite (Line 4 should come before Line 3).

🔧 Suggested fix
 import preact from '@preact/preset-vite'
 import { defineConfig } from 'vitest/config'
-import type { UserConfig as ViteUserConfig } from 'vite'
 import packageJson from './package.json'
+import type { UserConfig as ViteUserConfig } from 'vite'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/preact-query-devtools/vite.config.ts` around lines 3 - 4, Reorder
the top-level imports to satisfy import/order by moving the local packageJson
import before the type import from Vite; specifically, place "import packageJson
from './package.json'" above "import type { UserConfig as ViteUserConfig } from
'vite'". This keeps the import of packageJson before the external/type import
and resolves the lint failure.
🧹 Nitpick comments (1)
packages/preact-query-devtools/root.tsup.config.js (1)

10-39: Consider extracting shared tsup options to reduce duplication.
Both builders repeat the same base fields; a small shared base object would make future updates safer.

♻️ Suggested DRY refactor
 export function modernConfig(opts) {
+  const shared = {
+    format: ['cjs', 'esm'],
+    dts: true,
+    sourcemap: true,
+    clean: true,
+    esbuildPlugins: [esbuildPluginFilePathExtensions({ esmExtension: 'js' })],
+  }
+
   return {
+    ...shared,
     entry: opts.entry,
-    format: ['cjs', 'esm'],
     target: ['chrome91', 'firefox90', 'edge91', 'safari15', 'ios15', 'opera77'],
     outDir: 'build/modern',
-    dts: true,
-    sourcemap: true,
-    clean: true,
-    esbuildPlugins: [esbuildPluginFilePathExtensions({ esmExtension: 'js' })],
   }
 }
 
 export function legacyConfig(opts) {
+  const shared = {
+    format: ['cjs', 'esm'],
+    dts: true,
+    sourcemap: true,
+    clean: true,
+    esbuildPlugins: [esbuildPluginFilePathExtensions({ esmExtension: 'js' })],
+  }
+
   return {
+    ...shared,
     entry: opts.entry,
-    format: ['cjs', 'esm'],
     target: ['es2020', 'node16'],
     outDir: 'build/legacy',
-    dts: true,
-    sourcemap: true,
-    clean: true,
-    esbuildPlugins: [esbuildPluginFilePathExtensions({ esmExtension: 'js' })],
   }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/preact-query-devtools/root.tsup.config.js` around lines 10 - 39,
Extract the duplicated tsup options into a shared base object and have
modernConfig and legacyConfig spread/merge that base, keeping only the differing
fields (target and outDir) in each function; move common keys like entry,
format, dts, sourcemap, clean, and esbuildPlugins
(esbuildPluginFilePathExtensions call) into the base, then in modernConfig and
legacyConfig return {...base, target: [...], outDir:
'build/modern'|'build/legacy'} while preserving the existing JSDoc on
legacyConfig and the function signatures.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/framework/preact/devtools.md`:
- Around line 71-82: Update the documented prop signatures to match the
component API: change `initialIsOpen: boolean` to `initialIsOpen?: boolean` and
change `errorTypes?: { name: string; initializer: (query: Query) => TError}` to
`errorTypes?: Array<DevtoolsErrorType>` (or a short inline shape matching the
exported DevtoolsErrorType) and remove the undeclared `TError`; reference the
exported type name `DevtoolsErrorType` (or show its fields) so consumers see the
correct optional types for `initialIsOpen` and `errorTypes` as used by the
component.

In `@packages/preact-query-devtools/src/production.ts`:
- Around line 1-5: The production entry currently imports and re-exports live
runtime components (Devtools.PreactQueryDevtools and
DevtoolsPanel.PreactQueryDevtoolsPanel); change this to type-only imports and
no-op exports so no devtools runtime ships: import the modules only for types
using `typeof` (referencing PreactQueryDevtools and PreactQueryDevtoolsPanel
types from the original modules) and export lightweight no-op functions/objects
that match the same exported symbols (PreactQueryDevtools,
PreactQueryDevtoolsPanel) so consumers keep correct types but no runtime code is
included.

---

Duplicate comments:
In `@packages/preact-query-devtools/vite.config.ts`:
- Around line 3-4: Reorder the top-level imports to satisfy import/order by
moving the local packageJson import before the type import from Vite;
specifically, place "import packageJson from './package.json'" above "import
type { UserConfig as ViteUserConfig } from 'vite'". This keeps the import of
packageJson before the external/type import and resolves the lint failure.

---

Nitpick comments:
In `@packages/preact-query-devtools/root.tsup.config.js`:
- Around line 10-39: Extract the duplicated tsup options into a shared base
object and have modernConfig and legacyConfig spread/merge that base, keeping
only the differing fields (target and outDir) in each function; move common keys
like entry, format, dts, sourcemap, clean, and esbuildPlugins
(esbuildPluginFilePathExtensions call) into the base, then in modernConfig and
legacyConfig return {...base, target: [...], outDir:
'build/modern'|'build/legacy'} while preserving the existing JSDoc on
legacyConfig and the function signatures.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e303464 and 66a90f4.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (17)
  • docs/config.json
  • docs/framework/preact/devtools.md
  • packages/preact-query-devtools/.attw.json
  • packages/preact-query-devtools/eslint.config.js
  • packages/preact-query-devtools/package.json
  • packages/preact-query-devtools/root.eslint.config.js
  • packages/preact-query-devtools/root.tsup.config.js
  • packages/preact-query-devtools/src/PreactQueryDevtools.tsx
  • packages/preact-query-devtools/src/PreactQueryDevtoolsPanel.tsx
  • packages/preact-query-devtools/src/index.ts
  • packages/preact-query-devtools/src/production.ts
  • packages/preact-query-devtools/test-setup.ts
  • packages/preact-query-devtools/tsconfig.json
  • packages/preact-query-devtools/tsconfig.legacy.json
  • packages/preact-query-devtools/tsconfig.prod.json
  • packages/preact-query-devtools/tsup.config.ts
  • packages/preact-query-devtools/vite.config.ts
🚧 Files skipped from review as they are similar to previous changes (8)
  • packages/preact-query-devtools/eslint.config.js
  • packages/preact-query-devtools/tsconfig.legacy.json
  • packages/preact-query-devtools/test-setup.ts
  • docs/config.json
  • packages/preact-query-devtools/src/index.ts
  • packages/preact-query-devtools/package.json
  • packages/preact-query-devtools/tsconfig.json
  • packages/preact-query-devtools/tsconfig.prod.json

Comment on lines +71 to +82
- `initialIsOpen: boolean`
- Set this `true` if you want the dev tools to default to being open
- `buttonPosition?: "top-left" | "top-right" | "bottom-left" | "bottom-right"`
- Defaults to `bottom-right`
- The position of the Preact Query logo to open and close the devtools panel
- `position?: "top" | "bottom" | "left" | "right"`
- Defaults to `bottom`
- The position of the Preact Query devtools panel
- `client?: QueryClient`,
- Use this to use a custom QueryClient. Otherwise, the one from the nearest context will be used.
- `errorTypes?: { name: string; initializer: (query: Query) => TError}`
- Use this to predefine some errors that can be triggered on your queries. Initializer will be called (with the specific query) when that error is toggled on from the UI. It must return an Error.
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Align the documented option signatures with the actual component API.

initialIsOpen is documented as required, and errorTypes is documented as a single object with an undeclared TError. The exported options in this PR use initialIsOpen?: boolean and errorTypes?: Array<DevtoolsErrorType>, so the docs should match to avoid integration mistakes.

Suggested doc fix
-- `initialIsOpen: boolean`
+- `initialIsOpen?: boolean`
   - Set this `true` if you want the dev tools to default to being open
@@
-- `errorTypes?: { name: string; initializer: (query: Query) => TError}`
+- `errorTypes?: Array<DevtoolsErrorType>`
   - Use this to predefine some errors that can be triggered on your queries. Initializer will be called (with the specific query) when that error is toggled on from the UI. It must return an Error.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/preact/devtools.md` around lines 71 - 82, Update the
documented prop signatures to match the component API: change `initialIsOpen:
boolean` to `initialIsOpen?: boolean` and change `errorTypes?: { name: string;
initializer: (query: Query) => TError}` to `errorTypes?:
Array<DevtoolsErrorType>` (or a short inline shape matching the exported
DevtoolsErrorType) and remove the undeclared `TError`; reference the exported
type name `DevtoolsErrorType` (or show its fields) so consumers see the correct
optional types for `initialIsOpen` and `errorTypes` as used by the component.

Comment on lines +1 to +5
import * as Devtools from './PreactQueryDevtools'
import * as DevtoolsPanel from './PreactQueryDevtoolsPanel'

export const PreactQueryDevtools = Devtools.PreactQueryDevtools
export const PreactQueryDevtoolsPanel = DevtoolsPanel.PreactQueryDevtoolsPanel
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== preact-query-devtools package.json (full) =="
pkg="$(fd -p 'package.json' packages/preact-query-devtools | head -n1)"
cat "$pkg"

echo
echo "== preact-query-devtools production.ts =="
prod_file="$(fd -p 'production\.tsx?$' packages/preact-query-devtools | head -n1)"
cat "$prod_file"

echo
echo "== Comparing production files across query-devtools packages =="
for dir in packages/*/; do
  name=$(basename "$dir")
  if [[ $name == *"query-devtools" ]]; then
    prod="$dir/src/production.ts"
    if [ -f "$prod" ] || [ -f "${prod%.*}.tsx" ]; then
      echo "---- $name (production file) ----"
      cat "${prod%.*}.ts" "${prod%.*}.tsx" 2>/dev/null | head -20
    fi
  fi
done

Repository: TanStack/query

Length of output: 4121


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Production implementations across all query-devtools packages =="
for dir in packages/*/query-devtools/src/production.* packages/preact-query-devtools/src/production.* packages/solid-query-devtools/src/production.* packages/vue-query-devtools/src/production.* packages/svelte-query-devtools/src/production.* packages/angular-query-devtools/src/production.*; do
  if [ -f "$dir" ]; then
    echo "---- $(echo $dir | sed 's|packages/||;s|/src.*||') ----"
    cat "$dir"
    echo
  fi
done

echo "== Check for index.tsx/production.tsx pattern in solid-query-devtools =="
if [ -d packages/solid-query-devtools/src ]; then
  echo "---- solid-query-devtools/src/index.tsx ----"
  head -20 packages/solid-query-devtools/src/index.tsx 2>/dev/null || echo "Not found"
  echo
  echo "---- solid-query-devtools/src/production.tsx ----"
  head -20 packages/solid-query-devtools/src/production.tsx 2>/dev/null || echo "Not found"
fi

Repository: TanStack/query

Length of output: 1265


Production entry should not re-export live devtools components.

The ./production export points to build/modern/production.js and currently re-exports live devtools components, which will ship real devtools runtime code in production builds. Follow the pattern established in solid-query-devtools by using type-only imports with typeof annotations and no-op function exports:

Suggested fix
-import * as Devtools from './PreactQueryDevtools'
-import * as DevtoolsPanel from './PreactQueryDevtoolsPanel'
+import type * as Devtools from './PreactQueryDevtools'
+import type * as DevtoolsPanel from './PreactQueryDevtoolsPanel'

-export const PreactQueryDevtools = Devtools.PreactQueryDevtools
-export const PreactQueryDevtoolsPanel = DevtoolsPanel.PreactQueryDevtoolsPanel
+export const PreactQueryDevtools: (typeof Devtools)['PreactQueryDevtools'] = () =>
+  null
+export const PreactQueryDevtoolsPanel: (typeof DevtoolsPanel)['PreactQueryDevtoolsPanel'] =
+  () => null
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import * as Devtools from './PreactQueryDevtools'
import * as DevtoolsPanel from './PreactQueryDevtoolsPanel'
export const PreactQueryDevtools = Devtools.PreactQueryDevtools
export const PreactQueryDevtoolsPanel = DevtoolsPanel.PreactQueryDevtoolsPanel
import type * as Devtools from './PreactQueryDevtools'
import type * as DevtoolsPanel from './PreactQueryDevtoolsPanel'
export const PreactQueryDevtools: (typeof Devtools)['PreactQueryDevtools'] = () =>
null
export const PreactQueryDevtoolsPanel: (typeof DevtoolsPanel)['PreactQueryDevtoolsPanel'] =
() => null
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/preact-query-devtools/src/production.ts` around lines 1 - 5, The
production entry currently imports and re-exports live runtime components
(Devtools.PreactQueryDevtools and DevtoolsPanel.PreactQueryDevtoolsPanel);
change this to type-only imports and no-op exports so no devtools runtime ships:
import the modules only for types using `typeof` (referencing
PreactQueryDevtools and PreactQueryDevtoolsPanel types from the original
modules) and export lightweight no-op functions/objects that match the same
exported symbols (PreactQueryDevtools, PreactQueryDevtoolsPanel) so consumers
keep correct types but no runtime code is included.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants