diff --git a/.browserslistrc b/.browserslistrc deleted file mode 100644 index 01b924286a..0000000000 --- a/.browserslistrc +++ /dev/null @@ -1,7 +0,0 @@ -# Browsers we support -Chrome >= 73 -Firefox >= 78 -Edge >= 79 -Safari >= 12.0 -iOS >= 12.0 -opera >= 53 diff --git a/.codesandbox/ci.json b/.codesandbox/ci.json index 1579e59404..350d4ac77a 100644 --- a/.codesandbox/ci.json +++ b/.codesandbox/ci.json @@ -1,5 +1,6 @@ { "installCommand": "install:csb", + "buildCommand": "build:all", "sandboxes": [ "/examples/react/basic-typescript", "/examples/solid/basic-typescript", diff --git a/.eslintrc.cjs b/.eslintrc.cjs index b2653165af..59ac301dd3 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,3 +1,6 @@ +// @ts-check + +/** @type {import('eslint').Linter.Config} */ const config = { root: true, parser: '@typescript-eslint/parser', @@ -15,7 +18,7 @@ const config = { }, parserOptions: { tsconfigRootDir: __dirname, - project: './tsconfig.base.json', + project: './tsconfig.json', sourceType: 'module', ecmaVersion: 2020, }, @@ -42,6 +45,7 @@ const config = { '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-non-null-assertion': 'off', '@typescript-eslint/no-unnecessary-condition': 'error', + '@typescript-eslint/no-unnecessary-type-assertion': 'error', '@typescript-eslint/no-unused-vars': 'off', '@typescript-eslint/no-inferrable-types': [ 'error', diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e21849e3d7..6b2760e1b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: version: 8 - uses: actions/setup-node@v3 with: - node-version: 16.14.2 + node-version: 18.16.0 registry-url: https://registry.npmjs.org/ cache: 'pnpm' - name: Install dependencies @@ -42,7 +42,7 @@ jobs: - name: Run Tests uses: nick-fields/retry@v2.8.3 with: - command: pnpm run test:ci --base=${{ github.event.before }} + command: pnpm run test:ci timeout_minutes: 10 max_attempts: 3 - name: Publish diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index d84c5ad437..e69ac10d27 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -27,14 +27,14 @@ jobs: - name: Setup Node uses: actions/setup-node@v3 with: - node-version: 16.14.2 + node-version: 18.16.0 cache: 'pnpm' - name: Install dependencies run: pnpm --filter "./packages/**" --filter query --prefer-offline install - name: Get appropriate base and head commits for `nx affected` commands uses: nrwl/nx-set-shas@v3 with: - main-branch-name: 'main' + main-branch-name: 'alpha' - run: | echo "BASE: ${{ env.NX_BASE }}" echo "HEAD: ${{ env.NX_HEAD }}" @@ -45,7 +45,7 @@ jobs: with: timeout_minutes: 5 max_attempts: 3 - command: npx nx affected --targets=test:eslint,test:lib,test:types,test:build + command: npx nx affected --targets=test:eslint,test:lib,test:types,test:build,test:bundle - name: Stop Agents run: npx nx-cloud stop-all-agents - name: Upload coverage to Codecov @@ -68,7 +68,7 @@ jobs: - name: Setup Node uses: actions/setup-node@v3 with: - node-version: 16.14.2 + node-version: 18.16.0 cache: 'pnpm' - name: Install dependencies run: pnpm --filter "./packages/**" --filter query --prefer-offline install @@ -88,38 +88,9 @@ jobs: - name: Setup Node uses: actions/setup-node@v3 with: - node-version: 16.14.2 + node-version: 18.16.0 cache: 'pnpm' - name: Install dependencies run: pnpm --filter "./packages/**" --filter query --prefer-offline install - name: Run prettier run: pnpm run test:format - test-react-17: - name: 'Test React 17' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - ref: ${{ github.head_ref }} - repository: ${{github.event.pull_request.head.repo.full_name}} - - uses: pnpm/action-setup@v2.2.4 - with: - version: 8 - - uses: actions/setup-node@v3 - with: - node-version: 16.14.2 - cache: 'pnpm' - - name: Install dependencies - run: pnpm --filter "./packages/**" --filter query --prefer-offline install - - name: Derive appropriate SHAs for base and head for `nx affected` commands - uses: nrwl/nx-set-shas@v2 - - name: Run Tests - uses: nick-fields/retry@v2.8.3 - with: - timeout_minutes: 5 - max_attempts: 3 - command: npx nx affected --targets=test:lib --base=${{ github.event.pull_request.base.sha }} - env: - NX_CLOUD_DISTRIBUTED_EXECUTION: false - REACTJS_VERSION: 17 diff --git a/.nvmrc b/.nvmrc index fb457f39d5..8ddbc0c64a 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v16.19.0 +v18.16.0 diff --git a/README.md b/README.md index 6298e5f1e6..067af84a60 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ Hooks for fetching, caching and updating asynchronous data in React, Solid, Svel - - + + semantic-release diff --git a/babel.config.js b/babel.config.js deleted file mode 100644 index fed83c015a..0000000000 --- a/babel.config.js +++ /dev/null @@ -1,48 +0,0 @@ -const { NODE_ENV, BABEL_ENV } = process.env -const cjs = NODE_ENV === 'test' || BABEL_ENV === 'commonjs' -const es = BABEL_ENV === 'es' -const loose = true - -module.exports = { - presets: [ - [ - '@babel/preset-env', - { - loose, - modules: false, - exclude: [ - '@babel/plugin-transform-regenerator', - '@babel/plugin-transform-parameters', - ], - }, - ], - '@babel/preset-typescript', - ], - plugins: [ - cjs && ['@babel/transform-modules-commonjs', { loose }], - es && ['babel-plugin-add-import-extension', { extension: 'mjs' }], - // no runtime for umd builds - BABEL_ENV && [ - '@babel/transform-runtime', - { - version: require('./package.json').dependencies[ - '@babel/runtime' - ].replace(/^[^0-9]*/, ''), - }, - ], - ].filter(Boolean), - overrides: [ - { - include: [ - './packages/react-query/**', - './packages/react-query-devtools/**', - './packages/react-query-persist-client/**', - ], - presets: ['@babel/react'], - }, - { - include: ['./packages/solid-query/**'], - presets: ['babel-preset-solid'], - }, - ], -} diff --git a/docs/config.json b/docs/config.json index c958bbd08f..dbe2a967af 100644 --- a/docs/config.json +++ b/docs/config.json @@ -164,10 +164,6 @@ "label": "Suspense", "to": "react/guides/suspense" }, - { - "label": "Custom Logger", - "to": "react/guides/custom-logger" - }, { "label": "Testing", "to": "react/guides/testing" @@ -177,12 +173,16 @@ "to": "react/guides/does-this-replace-client-state" }, { - "label": "Migrating to React Query 3", + "label": "Migrating to v3", "to": "react/guides/migrating-to-react-query-3" }, { - "label": "Migrating to React Query 4", + "label": "Migrating to v4", "to": "react/guides/migrating-to-react-query-4" + }, + { + "label": "Migrating to v5", + "to": "react/guides/migrating-to-v5" } ] }, @@ -246,6 +246,10 @@ "label": "Load-More & Infinite Scroll", "to": "react/examples/react/load-more-infinite-scroll" }, + { + "label": "Infinite query with Max pages", + "to": "react/examples/react/infinite-query-with-max-pages" + }, { "label": "Suspense", "to": "react/examples/react/suspense" @@ -274,6 +278,10 @@ "label": "Next.js", "to": "react/examples/react/nextjs" }, + { + "label": "Next.js app with streaming", + "to": "react/examples/react/nextjs-suspense-streaming" + }, { "label": "React Native", "to": "react/examples/react/react-native" @@ -302,10 +310,6 @@ { "label": "Exhaustive Deps", "to": "react/eslint/exhaustive-deps" - }, - { - "label": "Prefer object syntax", - "to": "react/eslint/prefer-query-object-syntax" } ] }, @@ -357,6 +361,10 @@ "label": "useIsMutating", "to": "react/reference/useIsMutating" }, + { + "label": "useMutationState", + "to": "react/reference/useMutationState" + }, { "label": "QueryClient", "to": "react/reference/QueryClient" @@ -574,10 +582,6 @@ "label": "Suspense", "to": "vue/guides/suspense" }, - { - "label": "Custom Logger", - "to": "vue/guides/custom-logger" - }, { "label": "Testing", "to": "vue/guides/testing" @@ -585,6 +589,10 @@ { "label": "Does this replace [Vuex, Pinia]?", "to": "vue/guides/does-this-replace-client-state" + }, + { + "label": "Migrating to v5", + "to": "react/guides/migrating-to-v5" } ] }, diff --git a/docs/react/adapters/react-query.md b/docs/react/adapters/react-query.md index 226effa957..31a67e9c5f 100644 --- a/docs/react/adapters/react-query.md +++ b/docs/react/adapters/react-query.md @@ -16,7 +16,7 @@ function Example() { return (
- {query.isLoading + {query.isPending ? 'Loading...' : query.isError ? 'Error!' diff --git a/docs/react/adapters/solid-query.md b/docs/react/adapters/solid-query.md index bf49538831..b42bd624f4 100644 --- a/docs/react/adapters/solid-query.md +++ b/docs/react/adapters/solid-query.md @@ -13,12 +13,15 @@ import { Switch, Match, For } from 'solid-js' const queryClient = new QueryClient() function Example() { - const query = createQuery(() => ['todos'], fetchTodos) + const query = createQuery({ + queryKey: () => ['todos'], + queryFn: fetchTodos + }) return (
- +

Loading...

@@ -69,10 +72,16 @@ Solid Query offers an API similar to React Query, but there are some key differ ```tsx // ❌ react version -useQuery(["todos", todo], fetchTodos) +useQuery({ + queryKey: ["todos", todo], + queryFn: fetchTodos +}) // ✅ solid version -createQuery(() => ["todos", todo()], fetchTodos) +createQuery({ + queryKey: () => ["todos", todo()], + queryFn: fetchTodos +}) ``` - Suspense works for queries out of the box if you access the query data inside a `` boundary. @@ -81,7 +90,11 @@ createQuery(() => ["todos", todo()], fetchTodos) import { For, Suspense } from 'solid-js' function Example() { - const query = createQuery(() => ['todos'], fetchTodos) + const query = createQuery({ + queryKey: () => ['todos'], + queryFn: fetchTodos + }) + return (
{/* ✅ Will trigger loading fallback, data accessed in a suspense context. */} @@ -113,25 +126,26 @@ export default function App() { function Example() { // ❌ react version -- supports destructing outside reactive context - // const { isLoading, error, data } = useQuery(['repoData'], () => - // fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res => + // const { isPending, error, data } = useQuery({ + // queryKey: ['repoData'], () => + // queryFn: fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res => // res.json() // ) - // ) + // }) // ✅ solid version -- does not support destructuring outside reactive context - const query = createQuery( - () => ['repoData'], - () => + const query = createQuery({ + queryKey: () => ['repoData'], + queryFn: () => fetch('https://api.github.com/repos/tannerlinsley/react-query').then( (res) => res.json(), ), - ) + }) // ✅ access query properties in JSX reactive context return ( - Loading... + Loading... Error: {query.error.message}
@@ -161,7 +175,9 @@ const queryClient = new QueryClient() function Example() { const [enabled, setEnabled] = createSignal(false) - const query = createQuery(() => ['todos'], fetchTodos, { + const query = createQuery({ + queryKey: () => ['todos'], + queryFn: fetchTodos, // ❌ passing a signal directly is not reactive // enabled: enabled(), @@ -174,7 +190,7 @@ function Example() { return (
- +

Loading...

diff --git a/docs/react/adapters/vue-query.md b/docs/react/adapters/vue-query.md index 09a822b48d..9c5d7e64d1 100644 --- a/docs/react/adapters/vue-query.md +++ b/docs/react/adapters/vue-query.md @@ -20,7 +20,7 @@ import { useQueryClient, useQuery, useMutation } from "@tanstack/vue-query"; const queryClient = useQueryClient(); // Query -const { isLoading, isError, data, error } = useQuery({ queryKey: ['todos'], queryFn: getTodos }); +const { isPending, isError, data, error } = useQuery({ queryKey: ['todos'], queryFn: getTodos }); // Mutation const mutation = useMutation({ @@ -40,7 +40,7 @@ function onButtonClick() {