diff --git a/.changeset/good-ads-wait.md b/.changeset/good-ads-wait.md new file mode 100644 index 000000000..ce538a7df --- /dev/null +++ b/.changeset/good-ads-wait.md @@ -0,0 +1,6 @@ +--- +"@suspensive/react-query": patch +"@suspensive/react": patch +--- + +chore(eslint): add no-duplicates, consistent-type-imports diff --git a/.vscode/settings.json b/.vscode/settings.json index 4f7a64e70..28b343d39 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,8 @@ { "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true + }, "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"], "typescript.tsdk": "node_modules/typescript/lib", "cSpell.words": ["packlint", "codecov", "tsup"] diff --git a/configs/eslint-config-js/javascript.js b/configs/eslint-config-js/javascript.js index ff59929b6..f3791e5cc 100644 --- a/configs/eslint-config-js/javascript.js +++ b/configs/eslint-config-js/javascript.js @@ -4,6 +4,8 @@ module.exports = { extends: ['plugin:import/recommended', './noimport.js'], plugins: ['import'], rules: { + 'sort-imports': ['error', { ignoreDeclarationSort: true }], + 'import/no-duplicates': 'error', 'import/order': [ 'warn', { @@ -11,6 +13,5 @@ module.exports = { alphabetize: { order: 'asc', caseInsensitive: true }, }, ], - 'sort-imports': ['error', { ignoreDeclarationSort: true }], }, } diff --git a/configs/eslint-config-ts/noimport.js b/configs/eslint-config-ts/noimport.js index 63ff40a26..22954e016 100644 --- a/configs/eslint-config-ts/noimport.js +++ b/configs/eslint-config-ts/noimport.js @@ -11,6 +11,7 @@ module.exports = { rules: { '@typescript-eslint/no-empty-function': ['off'], '@typescript-eslint/no-unused-vars': 'error', + '@typescript-eslint/consistent-type-imports': 'error', 'jsdoc/require-description': 'warn', 'jsdoc/require-returns': 'off', 'jsdoc/require-jsdoc': 'off', diff --git a/configs/eslint-config-ts/typescript.js b/configs/eslint-config-ts/typescript.js index 8516bfbae..73ebaddae 100644 --- a/configs/eslint-config-ts/typescript.js +++ b/configs/eslint-config-ts/typescript.js @@ -16,6 +16,7 @@ module.exports = { ], rules: { 'sort-imports': ['error', { ignoreDeclarationSort: true }], + 'import/no-duplicates': 'error', 'import/order': [ 'error', { diff --git a/configs/tsup/src/index.ts b/configs/tsup/src/index.ts index 84d48e7b1..507709b95 100644 --- a/configs/tsup/src/index.ts +++ b/configs/tsup/src/index.ts @@ -1,4 +1,4 @@ -import { Options } from 'tsup' +import type { Options } from 'tsup' export const options: Options = { banner: { js: '"use client"' }, diff --git a/configs/vitest/src/index.ts b/configs/vitest/src/index.ts index 5d5ffd65b..7d347db1a 100644 --- a/configs/vitest/src/index.ts +++ b/configs/vitest/src/index.ts @@ -1,6 +1,6 @@ import fs from 'fs' import path, { dirname } from 'path' -import { UserConfig } from 'vitest/config' +import type { UserConfig } from 'vitest/config' export const forPackage = (userConfig?: UserConfig): UserConfig => { const packageJsonPath = path.resolve(dirname('.'), 'package.json') diff --git a/packages/react-query/src/QueryAsyncBoundary.tsx b/packages/react-query/src/QueryAsyncBoundary.tsx index fb201b85d..5b8d5888f 100644 --- a/packages/react-query/src/QueryAsyncBoundary.tsx +++ b/packages/react-query/src/QueryAsyncBoundary.tsx @@ -1,6 +1,7 @@ import { AsyncBoundary } from '@suspensive/react' import { useQueryErrorResetBoundary } from '@tanstack/react-query' -import { ComponentPropsWithoutRef, ComponentRef, forwardRef } from 'react' +import type { ComponentPropsWithoutRef, ComponentRef } from 'react' +import { forwardRef } from 'react' const BaseQueryAsyncBoundary = forwardRef< ComponentRef, diff --git a/packages/react-query/src/QueryErrorBoundary.tsx b/packages/react-query/src/QueryErrorBoundary.tsx index fe72b5ae8..4bca50841 100644 --- a/packages/react-query/src/QueryErrorBoundary.tsx +++ b/packages/react-query/src/QueryErrorBoundary.tsx @@ -1,6 +1,7 @@ import { ErrorBoundary } from '@suspensive/react' import { useQueryErrorResetBoundary } from '@tanstack/react-query' -import { ComponentPropsWithoutRef, ComponentRef, forwardRef } from 'react' +import type { ComponentPropsWithoutRef, ComponentRef } from 'react' +import { forwardRef } from 'react' /** * This component wrapping QueryErrorResetBoundary of @tanstack/react-query with @suspensive/react's ErrorBoundary. diff --git a/packages/react-query/src/useSuspenseInfiniteQuery.test-d.ts b/packages/react-query/src/useSuspenseInfiniteQuery.test-d.ts index 04acf19c9..fe1b23c28 100644 --- a/packages/react-query/src/useSuspenseInfiniteQuery.test-d.ts +++ b/packages/react-query/src/useSuspenseInfiniteQuery.test-d.ts @@ -1,5 +1,5 @@ /* eslint-disable react-hooks/rules-of-hooks */ -import { InfiniteData } from '@tanstack/react-query' +import type { InfiniteData } from '@tanstack/react-query' import { expectError, expectType } from 'tsd' import { useSuspenseInfiniteQuery } from '../dist' diff --git a/packages/react-query/src/useSuspenseInfiniteQuery.ts b/packages/react-query/src/useSuspenseInfiniteQuery.ts index 540f21e32..d34738c64 100644 --- a/packages/react-query/src/useSuspenseInfiniteQuery.ts +++ b/packages/react-query/src/useSuspenseInfiniteQuery.ts @@ -1,12 +1,11 @@ -import { +import type { InfiniteData, QueryFunction, QueryKey, UseInfiniteQueryOptions, UseInfiniteQueryResult, - parseQueryArgs, - useInfiniteQuery, } from '@tanstack/react-query' +import { parseQueryArgs, useInfiniteQuery } from '@tanstack/react-query' export type BaseUseSuspenseInfiniteQueryResult = Omit< UseInfiniteQueryResult, diff --git a/packages/react-query/src/useSuspenseQueries.ts b/packages/react-query/src/useSuspenseQueries.ts index 916e9ef91..4d6bd8fcf 100644 --- a/packages/react-query/src/useSuspenseQueries.ts +++ b/packages/react-query/src/useSuspenseQueries.ts @@ -1,5 +1,6 @@ -import { QueryFunction, QueryKey, UseQueryOptions, UseQueryResult, useQueries } from '@tanstack/react-query' -import { UseSuspenseQueryResultOnLoading, UseSuspenseQueryResultOnSuccess } from './useSuspenseQuery' +import type { QueryFunction, QueryKey, UseQueryOptions, UseQueryResult } from '@tanstack/react-query' +import { useQueries } from '@tanstack/react-query' +import type { UseSuspenseQueryResultOnLoading, UseSuspenseQueryResultOnSuccess } from './useSuspenseQuery' // Avoid TS depth-limit error in case of large array literal // eslint-disable-next-line @typescript-eslint/naming-convention diff --git a/packages/react-query/src/useSuspenseQuery.ts b/packages/react-query/src/useSuspenseQuery.ts index 3f189080c..35f6580a8 100644 --- a/packages/react-query/src/useSuspenseQuery.ts +++ b/packages/react-query/src/useSuspenseQuery.ts @@ -1,11 +1,5 @@ -import { - QueryFunction, - QueryKey, - UseQueryOptions, - UseQueryResult, - parseQueryArgs, - useQuery, -} from '@tanstack/react-query' +import type { QueryFunction, QueryKey, UseQueryOptions, UseQueryResult } from '@tanstack/react-query' +import { parseQueryArgs, useQuery } from '@tanstack/react-query' export interface BaseUseSuspenseQueryResult extends Omit, 'error' | 'isError' | 'isFetching'> { diff --git a/packages/react/src/AsyncBoundary.spec.tsx b/packages/react/src/AsyncBoundary.spec.tsx index 9b1fa5e67..1aafdecfc 100644 --- a/packages/react/src/AsyncBoundary.spec.tsx +++ b/packages/react/src/AsyncBoundary.spec.tsx @@ -1,5 +1,6 @@ import { act, render, waitFor } from '@testing-library/react' -import { ComponentProps, createElement } from 'react' +import type { ComponentProps } from 'react' +import { createElement } from 'react' import { createRoot } from 'react-dom/client' import { vi } from 'vitest' import { ERROR_MESSAGE, FALLBACK, MS_100, Suspend, TEXT, ThrowError } from './utils/toTest' diff --git a/packages/react/src/AsyncBoundary.tsx b/packages/react/src/AsyncBoundary.tsx index b0a5e6e89..cb8a73b45 100644 --- a/packages/react/src/AsyncBoundary.tsx +++ b/packages/react/src/AsyncBoundary.tsx @@ -1,7 +1,8 @@ -import { ComponentProps, ComponentRef, ComponentType, SuspenseProps, forwardRef } from 'react' +import type { ComponentProps, ComponentRef, ComponentType, SuspenseProps } from 'react' +import { forwardRef } from 'react' import { ErrorBoundary } from './ErrorBoundary' import { Suspense } from './Suspense' -import { PropsWithoutChildren } from './types' +import type { PropsWithoutChildren } from './types' type ErrorBoundaryProps = ComponentProps type AsyncBoundaryProps = Omit & diff --git a/packages/react/src/Delay.tsx b/packages/react/src/Delay.tsx index 3c12620ee..3acf3c8f5 100644 --- a/packages/react/src/Delay.tsx +++ b/packages/react/src/Delay.tsx @@ -1,6 +1,7 @@ -import { ComponentProps, ComponentType, PropsWithChildren, createContext, useContext, useState } from 'react' +import type { ComponentProps, ComponentType, PropsWithChildren } from 'react' +import { createContext, useContext, useState } from 'react' import { useSetTimeout } from './hooks' -import { PropsWithoutChildren } from './types' +import type { PropsWithoutChildren } from './types' type DelayProps = PropsWithChildren<{ ms?: number diff --git a/packages/react/src/ErrorBoundary.spec.tsx b/packages/react/src/ErrorBoundary.spec.tsx index 3f1ff9351..3b051879f 100644 --- a/packages/react/src/ErrorBoundary.spec.tsx +++ b/packages/react/src/ErrorBoundary.spec.tsx @@ -1,5 +1,6 @@ import { act, render } from '@testing-library/react' -import { ComponentProps, ComponentRef, createElement, createRef, useEffect } from 'react' +import type { ComponentProps, ComponentRef } from 'react' +import { createElement, createRef, useEffect } from 'react' import { createRoot } from 'react-dom/client' import { vi } from 'vitest' import { useSetTimeout } from './hooks' diff --git a/packages/react/src/ErrorBoundary.tsx b/packages/react/src/ErrorBoundary.tsx index a5f56f037..24b5e5f58 100644 --- a/packages/react/src/ErrorBoundary.tsx +++ b/packages/react/src/ErrorBoundary.tsx @@ -1,11 +1,6 @@ +import type { ComponentProps, ComponentType, ErrorInfo, FunctionComponent, PropsWithChildren, ReactNode } from 'react' import { Component, - ComponentProps, - ComponentType, - ErrorInfo, - FunctionComponent, - PropsWithChildren, - ReactNode, createContext, createElement, forwardRef, @@ -16,9 +11,8 @@ import { useState, } from 'react' import { ErrorBoundaryGroupContext } from './ErrorBoundaryGroup' -import { PropsWithoutChildren } from './types' -import { hasResetKeysChanged } from './utils' -import { assert } from './utils' +import type { PropsWithoutChildren } from './types' +import { assert, hasResetKeysChanged } from './utils' export type ErrorBoundaryFallbackProps = { /** diff --git a/packages/react/src/ErrorBoundaryGroup.tsx b/packages/react/src/ErrorBoundaryGroup.tsx index 8fe9bdc69..a93d279d4 100644 --- a/packages/react/src/ErrorBoundaryGroup.tsx +++ b/packages/react/src/ErrorBoundaryGroup.tsx @@ -1,6 +1,7 @@ -import { ComponentProps, ComponentType, PropsWithChildren, createContext, useContext, useEffect, useMemo } from 'react' +import type { ComponentProps, ComponentType, PropsWithChildren } from 'react' +import { createContext, useContext, useEffect, useMemo } from 'react' import { useIsChanged, useKey } from './hooks' -import { PropsWithoutChildren } from './types' +import type { PropsWithoutChildren } from './types' import { assert } from './utils' export const ErrorBoundaryGroupContext = createContext<{ reset: () => void; resetKey: number } | undefined>(undefined) diff --git a/packages/react/src/Suspense.tsx b/packages/react/src/Suspense.tsx index 1e6dbb024..42894b202 100644 --- a/packages/react/src/Suspense.tsx +++ b/packages/react/src/Suspense.tsx @@ -1,14 +1,7 @@ -import { - ComponentProps, - ComponentType, - ReactNode, - Suspense as ReactSuspense, - SuspenseProps, - createContext, - useContext, -} from 'react' +import type { ComponentProps, ComponentType, ReactNode, SuspenseProps } from 'react' +import { Suspense as ReactSuspense, createContext, useContext } from 'react' import { useIsMounted } from './hooks' -import { PropsWithoutChildren } from './types' +import type { PropsWithoutChildren } from './types' export const SuspenseContext = createContext>({ fallback: undefined }) const useFallbackWithContext = (fallback: ReactNode) => { diff --git a/packages/react/src/SuspensiveProvider.tsx b/packages/react/src/SuspensiveProvider.tsx index 356b192ca..8ae750f61 100644 --- a/packages/react/src/SuspensiveProvider.tsx +++ b/packages/react/src/SuspensiveProvider.tsx @@ -1,4 +1,5 @@ -import { ContextType, PropsWithChildren, useMemo } from 'react' +import type { ContextType, PropsWithChildren } from 'react' +import { useMemo } from 'react' import { DelayContext } from './Delay' import { SuspenseContext } from './Suspense' diff --git a/packages/react/src/experimental/Await.tsx b/packages/react/src/experimental/Await.tsx index 8375b8048..949a8a71d 100644 --- a/packages/react/src/experimental/Await.tsx +++ b/packages/react/src/experimental/Await.tsx @@ -1,6 +1,7 @@ -import { FunctionComponent, createElement, useMemo } from 'react' +import type { FunctionComponent } from 'react' +import { createElement, useMemo } from 'react' import { useSyncExternalStore } from 'use-sync-external-store/shim' -import { Tuple } from '../types' +import type { Tuple } from '../types' import { hashKey } from '../utils' export type Key = Tuple diff --git a/packages/react/src/types/PropsWithoutChildren.ts b/packages/react/src/types/PropsWithoutChildren.ts index ef142066a..b9cfdeaa9 100644 --- a/packages/react/src/types/PropsWithoutChildren.ts +++ b/packages/react/src/types/PropsWithoutChildren.ts @@ -1,3 +1,3 @@ -import { ComponentProps, ComponentType } from 'react' +import type { ComponentProps, ComponentType } from 'react' export type PropsWithoutChildren> = Omit diff --git a/packages/react/src/utils/hashKey.ts b/packages/react/src/utils/hashKey.ts index 40933bab4..c675f0765 100644 --- a/packages/react/src/utils/hashKey.ts +++ b/packages/react/src/utils/hashKey.ts @@ -1,5 +1,6 @@ -import { Key } from '../experimental/Await' -import { PlainObject, isPlainObject } from './isPlainObject' +import type { Key } from '../experimental/Await' +import type { PlainObject } from './isPlainObject' +import { isPlainObject } from './isPlainObject' export const hashKey = (key: Key) => JSON.stringify(key, (_, val) => diff --git a/packages/react/src/utils/toTest.tsx b/packages/react/src/utils/toTest.tsx index f11b4fe7c..91be62fb3 100644 --- a/packages/react/src/utils/toTest.tsx +++ b/packages/react/src/utils/toTest.tsx @@ -1,4 +1,5 @@ -import { PropsWithChildren, ReactNode, useState } from 'react' +import type { PropsWithChildren, ReactNode } from 'react' +import { useState } from 'react' import { useSetTimeout } from '../hooks' const suspendIsNeed = { current: true } diff --git a/websites/visualization/src/app/CommonLayout.tsx b/websites/visualization/src/app/CommonLayout.tsx index 3103472a3..0daa9d08a 100644 --- a/websites/visualization/src/app/CommonLayout.tsx +++ b/websites/visualization/src/app/CommonLayout.tsx @@ -4,7 +4,7 @@ import { Flex } from '@jsxcss/emotion' import Image from 'next/image' import Link from 'next/link' -import { PropsWithChildren } from 'react' +import type { PropsWithChildren } from 'react' export const CommonLayout = ({ children }: PropsWithChildren) => { return ( diff --git a/websites/visualization/src/app/layout.tsx b/websites/visualization/src/app/layout.tsx index 643519652..2a689dbe8 100644 --- a/websites/visualization/src/app/layout.tsx +++ b/websites/visualization/src/app/layout.tsx @@ -1,5 +1,5 @@ import './global.css' -import { Metadata } from 'next' +import type { Metadata } from 'next' import { CommonLayout } from './CommonLayout' import { Providers } from './providers' diff --git a/websites/visualization/src/app/providers.tsx b/websites/visualization/src/app/providers.tsx index 9b655f9d0..39954f82f 100644 --- a/websites/visualization/src/app/providers.tsx +++ b/websites/visualization/src/app/providers.tsx @@ -5,7 +5,7 @@ import { MediaQueryProvider } from '@jsxcss/emotion' import { Suspensive, SuspensiveProvider } from '@suspensive/react' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { ReactQueryDevtools } from '@tanstack/react-query-devtools' -import { PropsWithChildren } from 'react' +import type { PropsWithChildren } from 'react' import { Spinner } from '~/components/uis' const queryClient = new QueryClient({ diff --git a/websites/visualization/src/app/react-query/playground/components/suspensive.tsx b/websites/visualization/src/app/react-query/playground/components/suspensive.tsx index 490d19b46..1db435b51 100644 --- a/websites/visualization/src/app/react-query/playground/components/suspensive.tsx +++ b/websites/visualization/src/app/react-query/playground/components/suspensive.tsx @@ -1,7 +1,8 @@ import { Suspense } from '@suspensive/react' import { useSuspenseQueries, useSuspenseQuery } from '@suspensive/react-query' import { useEffect, useRef, useState } from 'react' -import { Post, albums, posts, todos } from './api' +import type { Post } from './api' +import { albums, posts, todos } from './api' import { useIntersectionObserver } from './useIntersectionObserver' export const PostListSuspensive = () => { diff --git a/websites/visualization/src/app/react-query/playground/components/tanstack.tsx b/websites/visualization/src/app/react-query/playground/components/tanstack.tsx index 5d9412485..e50a93161 100644 --- a/websites/visualization/src/app/react-query/playground/components/tanstack.tsx +++ b/websites/visualization/src/app/react-query/playground/components/tanstack.tsx @@ -1,7 +1,8 @@ import { Delay } from '@suspensive/react' import { useQueries, useQuery } from '@tanstack/react-query' import { useEffect, useRef, useState } from 'react' -import { Post, albums, posts, todos } from './api' +import type { Post } from './api' +import { albums, posts, todos } from './api' import { useIntersectionObserver } from './useIntersectionObserver' import { Spinner } from '~/components/uis' diff --git a/websites/visualization/src/app/react/experimental/useErrorBoundary/page.tsx b/websites/visualization/src/app/react/experimental/useErrorBoundary/page.tsx index 3a9553485..cd8e71b61 100644 --- a/websites/visualization/src/app/react/experimental/useErrorBoundary/page.tsx +++ b/websites/visualization/src/app/react/experimental/useErrorBoundary/page.tsx @@ -1,7 +1,8 @@ 'use client' import { ErrorBoundary, useErrorBoundary } from '@suspensive/react' -import { PropsWithChildren, createElement, useEffect, useState } from 'react' +import type { PropsWithChildren } from 'react' +import { createElement, useEffect, useState } from 'react' export default function Page() { return ( diff --git a/websites/visualization/src/components/RejectedFallback.tsx b/websites/visualization/src/components/RejectedFallback.tsx index b4a5f565a..bf3f4246a 100644 --- a/websites/visualization/src/components/RejectedFallback.tsx +++ b/websites/visualization/src/components/RejectedFallback.tsx @@ -1,6 +1,6 @@ 'use client' -import { ErrorBoundaryFallbackProps } from '@suspensive/react' +import type { ErrorBoundaryFallbackProps } from '@suspensive/react' import { Box, Button, Description } from './uis' export const RejectedFallback = (props: ErrorBoundaryFallbackProps) => ( diff --git a/websites/visualization/src/components/uis/index.tsx b/websites/visualization/src/components/uis/index.tsx index 7692d60e5..5bed012a0 100644 --- a/websites/visualization/src/components/uis/index.tsx +++ b/websites/visualization/src/components/uis/index.tsx @@ -2,7 +2,7 @@ 'use client' import styled from '@emotion/styled' -import { PropsWithChildren } from 'react' +import type { PropsWithChildren } from 'react' export const Button = styled.button` box-sizing: border-box;