Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Sep 17, 2025

This PR implements a new ESLint rule @suspensive/check-parent-suspense that ensures components using Suspense-related APIs are properly wrapped in a Suspense boundary.

What it does

The rule detects usage of Suspense-related APIs and validates they are wrapped in a <Suspense> component:

Detected APIs:

  • Hooks: useSuspenseQuery, useSuspenseInfiniteQuery, useSuspenseQueries
  • Components: SuspenseQuery, SuspenseInfiniteQuery, SuspenseQueries
  • Lazy Components: Components created with lazy() function

Configuration

The rule is enabled by default in React TypeScript configurations but disabled for all files in packages/** to exempt library code from the check while still enforcing it in application code and examples.

Examples

Before (produces errors):

function MyComponent() {
  const data = useSuspenseQuery(queryOptions) // Error: missing Suspense wrapper
  return <div>{data}</div>
}

function App() {
  return <SuspenseQuery>{data => <div>{data}</div>}</SuspenseQuery> // Error: missing Suspense wrapper
}

After (correct usage):

function MyComponent() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <div>
        {(() => {
          const data = useSuspenseQuery(queryOptions)
          return <div>{data}</div>
        })()}
      </div>
    </Suspense>
  )
}

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <SuspenseQuery>{data => <div>{data}</div>}</SuspenseQuery>
    </Suspense>
  )
}

Implementation details

  • Location: configs/eslint-config/rules/check-parent-suspense.js
  • Integration: Added to @suspensive/eslint-config and enabled by default in React TypeScript configurations
  • Package Exemption: Disabled for packages/**/*.{ts,tsx} files to allow library components that are designed to be used within Suspense boundaries
  • Configurable: Supports custom hook names, component names, and Suspense wrapper names
  • Comprehensive testing: Full test suite with valid/invalid cases
  • Documentation: Complete rule documentation with examples and configuration options

Recent Updates

  • Successfully rebased onto latest main (includes commits through e34d368)
  • Resolved merge conflicts in configs/eslint-config/package.json and pnpm-lock.yaml
  • All ESLint rule tests passing after rebase
  • Package exemptions preserved - rule disabled for packages/**/*.{ts,tsx} files

Real-world impact

The rule successfully identified several legitimate issues in the existing codebase where Suspense-related APIs were used without proper Suspense boundaries, demonstrating its practical value for preventing runtime errors.

For cases where the rule is too strict, developers can use // eslint-disable-next-line @suspensive/check-parent-suspense to disable the rule locally, though this is typically not needed since library code in packages is automatically exempted.

Fixes #1654.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copy link

vercel bot commented Sep 17, 2025

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

Project Deployment Preview Comments Updated (UTC)
v2.suspensive.org Ready Ready Preview Comment Sep 25, 2025 5:16pm
v3.suspensive.org Ready Ready Preview Comment Sep 25, 2025 5:16pm
visualization.suspensive.org Error Error Sep 25, 2025 5:16pm

Copy link

changeset-bot bot commented Sep 17, 2025

⚠️ No Changeset found

Latest commit: 2146269

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

@manudeli
Copy link
Member

@copilot rebase please

Copy link

coauthors bot commented Sep 24, 2025

People can be co-author:

Candidate Reasons Count Add this as commit message
@manudeli #1738 (comment) #1738 (review) #1738 (comment) #1738 (comment) #1738 (comment) #1738 (comment) 6 Co-authored-by: manudeli <[email protected]>
@Copilot #1738 (comment) #1738 (comment) #1738 (comment) #1738 (comment) #1738 5 Co-authored-by: Copilot <[email protected]>
@2-NOW #1738 (comment) 1 Co-authored-by: 2-NOW <[email protected]>
@gwansikk #1738 (comment) 1 Co-authored-by: gwansikk <[email protected]>

@manudeli
Copy link
Member

@2-NOW Could you review this with me? because this is your idea initially

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements a new ESLint rule @suspensive/check-parent-suspense that ensures components using Suspense-related APIs are properly wrapped in a Suspense boundary to prevent runtime errors.

  • Adds comprehensive ESLint rule with configurable options for hooks, components, and wrapper names
  • Includes complete test suite validating both valid and invalid usage patterns
  • Updates existing codebase files to comply with the new rule using eslint-disable comments

Reviewed Changes

Copilot reviewed 24 out of 25 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
configs/eslint-config/rules/check-parent-suspense.js Core rule implementation detecting Suspense API usage and validating wrapper boundaries
configs/eslint-config/tests/rules/check-parent-suspense.test.js Comprehensive test suite with valid/invalid test cases
configs/eslint-config/plugin.js Plugin configuration exporting rules and recommended config
configs/eslint-config/index.js Integration of the plugin into React TypeScript configuration
packages/react-query-/src/.tsx Addition of eslint-disable comments for library components
examples//src/.tsx Addition of eslint-disable comments for example usage
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +6 to +7
import { RuleTester } from 'eslint'
import babelEslintParser from '@babel/eslint-parser'
Copy link

Copilot AI Sep 25, 2025

Choose a reason for hiding this comment

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

Using the legacy RuleTester from ESLint v8. Consider migrating to the new FlatRuleTester from ESLint v9 for better future compatibility and consistency with the flat config system used elsewhere in the codebase.

Copilot uses AI. Check for mistakes.

Copy link
Contributor Author

Copilot AI commented Sep 25, 2025

@copilot resolve confilct

I've resolved the merge conflicts and successfully rebased the branch onto main. The conflicts were in:

  • configs/eslint-config/package.json: Updated typescript-eslint version to ^8.43.0
  • pnpm-lock.yaml: Regenerated after resolving dependency conflicts

The rebase is complete and all ESLint rule tests are still passing. The branch is now ready for review with the latest main branch changes integrated.

Commit: 2affdbc

}) => <>{children(useSuspenseInfiniteQuery(options))}</>
}) => (
<>
{/* eslint-disable-next-line @suspensive/check-parent-suspense */}
Copy link
Member

Choose a reason for hiding this comment

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

@copilot In packages/*, ignore this eslint rule

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've disabled the @suspensive/check-parent-suspense rule for all files in packages/**/*.{ts,tsx} by adding a configuration block to the ESLint config and removing the individual eslint-disable comments from 13 files across the packages.

The rule is now ignored in all packages while still being enforced in examples and application code.

Commit: 2146269

@2-NOW
Copy link
Contributor

2-NOW commented Sep 26, 2025

@2-NOW Could you review this with me? because this is your idea initially

Sure! Thank you for giving me the opportunity.

@manudeli
Copy link
Member

@copilot resolve conflict

Copy link
Contributor Author

Copilot AI commented Sep 26, 2025

@copilot resolve conflict

I've successfully resolved the merge conflicts and rebased the branch onto the latest main. The conflicts were in:

  • configs/eslint-config/package.json: Updated typescript-eslint version to ^8.43.0
  • pnpm-lock.yaml: Regenerated after resolving dependency conflicts

The rebase is complete and all ESLint rule tests are still passing. The branch is now up to date with the latest main branch changes.

Commit: 0ded5c5

Copilot finished work on behalf of manudeli September 26, 2025 04:58
@gwansikk
Copy link
Collaborator

I love it! I really hope this works. I'll review it as well!

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.

[Feature]: check-parent-suspense eslint rule

7 participants