From 87ea6320ae352980777b5ba4e595247d183d52e9 Mon Sep 17 00:00:00 2001 From: Mikhail Golbakh Date: Sun, 11 Aug 2024 16:13:04 +0300 Subject: [PATCH] feat(react-query): update to major v5 --- .github/workflows/release-alpha.yml | 2 +- package-lock.json | 327 ++++++++---------- package.json | 6 +- src/core/types/DataSource.ts | 8 +- src/core/utils/composeFullKey.ts | 2 +- src/core/utils/composeKey.ts | 4 +- src/react-query/hooks/useQueryData.ts | 19 +- src/react-query/impl/infinite/factory.ts | 8 +- src/react-query/impl/infinite/hooks.ts | 15 +- src/react-query/impl/infinite/types.ts | 58 +++- src/react-query/impl/infinite/utils.ts | 51 +-- src/react-query/impl/plain/factory.ts | 8 +- src/react-query/impl/plain/hooks.ts | 15 +- src/react-query/impl/plain/types.ts | 16 +- src/react-query/impl/plain/utils.ts | 36 +- src/react-query/utils/normalizeStatus.ts | 6 +- src/react-query/utils/notReachable.ts | 3 + .../components/DataInfiniteLoader/types.ts | 2 +- src/react/components/DataLoader/types.ts | 2 +- 19 files changed, 320 insertions(+), 268 deletions(-) create mode 100644 src/react-query/utils/notReachable.ts diff --git a/.github/workflows/release-alpha.yml b/.github/workflows/release-alpha.yml index b9cc9b6..b073d87 100644 --- a/.github/workflows/release-alpha.yml +++ b/.github/workflows/release-alpha.yml @@ -15,7 +15,7 @@ on: version: type: string required: false - description: If your build failed and the version is already exists you can set version of package manually, e.g. `3.0.0-alpha.0``. Use the prefix `alpha` otherwise you will get error. + description: If your build failed and the version is already exists you can set version of package manually, e.g. `3.0.0-alpha.0`. Use the prefix `alpha` otherwise you will get error. jobs: release: diff --git a/package-lock.json b/package-lock.json index fa7f0b7..ac7fe4e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,7 @@ "@gravity-ui/prettier-config": "^1.1.0", "@gravity-ui/tsconfig": "^1.0.0", "@swc/jest": "^0.2.36", - "@tanstack/react-query": "^4.36.1", + "@tanstack/react-query": "^5.51.23", "@types/jest": "^29.5.12", "@types/react": "^18.3.3", "eslint": "^8.57.0", @@ -35,8 +35,8 @@ "yarn": "Please use npm instead of yarn to install dependencies" }, "peerDependencies": { - "@tanstack/react-query": "^4.0.0", - "react": "^16.0.0 || ^17.0.0 || ^18.0.0" + "@tanstack/react-query": "^5.0.0", + "react": "^18.0.0" } }, "node_modules/@ampproject/remapping": { @@ -255,18 +255,18 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.620.0.tgz", - "integrity": "sha512-kf3Lqvuq/ciUn4myQjd1a9nhVg95+FEWkIq7pdkgxFoKow8HKj3nuiwI7zYBRTfk0RKXRkJca3GE+3RXpeZSiA==", + "version": "3.627.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.627.0.tgz", + "integrity": "sha512-XTbtRLPVfq2lHo0SUP6HJb6HgBsKsJR54bhhVTwj5SZ4G26KOmx2iFOz9SgHie5apU7vWIhijb48LIhbLArgGg==", "dev": true, "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.620.0", - "@aws-sdk/client-sts": "3.620.0", - "@aws-sdk/core": "3.620.0", - "@aws-sdk/credential-provider-node": "3.620.0", + "@aws-sdk/client-sso-oidc": "3.624.0", + "@aws-sdk/client-sts": "3.624.0", + "@aws-sdk/core": "3.624.0", + "@aws-sdk/credential-provider-node": "3.624.0", "@aws-sdk/middleware-bucket-endpoint": "3.620.0", "@aws-sdk/middleware-expect-continue": "3.620.0", "@aws-sdk/middleware-flexible-checksums": "3.620.0", @@ -274,23 +274,22 @@ "@aws-sdk/middleware-location-constraint": "3.609.0", "@aws-sdk/middleware-logger": "3.609.0", "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-sdk-s3": "3.620.0", - "@aws-sdk/middleware-signing": "3.620.0", + "@aws-sdk/middleware-sdk-s3": "3.626.0", "@aws-sdk/middleware-ssec": "3.609.0", "@aws-sdk/middleware-user-agent": "3.620.0", "@aws-sdk/region-config-resolver": "3.614.0", - "@aws-sdk/signature-v4-multi-region": "3.620.0", + "@aws-sdk/signature-v4-multi-region": "3.626.0", "@aws-sdk/types": "3.609.0", "@aws-sdk/util-endpoints": "3.614.0", "@aws-sdk/util-user-agent-browser": "3.609.0", "@aws-sdk/util-user-agent-node": "3.614.0", "@aws-sdk/xml-builder": "3.609.0", "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.3.0", + "@smithy/core": "^2.3.2", "@smithy/eventstream-serde-browser": "^3.0.5", "@smithy/eventstream-serde-config-resolver": "^3.0.3", "@smithy/eventstream-serde-node": "^3.0.4", - "@smithy/fetch-http-handler": "^3.2.3", + "@smithy/fetch-http-handler": "^3.2.4", "@smithy/hash-blob-browser": "^3.1.2", "@smithy/hash-node": "^3.0.3", "@smithy/hash-stream-node": "^3.1.2", @@ -298,23 +297,24 @@ "@smithy/md5-js": "^3.0.3", "@smithy/middleware-content-length": "^3.0.5", "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.12", + "@smithy/middleware-retry": "^3.0.14", "@smithy/middleware-serde": "^3.0.3", "@smithy/middleware-stack": "^3.0.3", "@smithy/node-config-provider": "^3.1.4", "@smithy/node-http-handler": "^3.1.4", "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.10", + "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.12", - "@smithy/util-defaults-mode-node": "^3.0.12", + "@smithy/util-defaults-mode-browser": "^3.0.14", + "@smithy/util-defaults-mode-node": "^3.0.14", "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-middleware": "^3.0.3", "@smithy/util-retry": "^3.0.3", - "@smithy/util-stream": "^3.1.2", + "@smithy/util-stream": "^3.1.3", "@smithy/util-utf8": "^3.0.0", "@smithy/util-waiter": "^3.1.2", "tslib": "^2.6.2" @@ -324,14 +324,14 @@ } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.620.0.tgz", - "integrity": "sha512-J1CvF7u39XwtCK9rPlkW2AA631EPqkb4PjOOj9aZ9LjQmkJ0DkL+9tEqU2XIWcjDd2Z3hS3LBuS8uN7upIkEnQ==", + "version": "3.624.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.624.0.tgz", + "integrity": "sha512-EX6EF+rJzMPC5dcdsu40xSi2To7GSvdGQNIpe97pD9WvZwM9tRNQnNM4T6HA4gjV1L6Jwk8rBlG/CnveXtLEMw==", "dev": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.620.0", + "@aws-sdk/core": "3.624.0", "@aws-sdk/middleware-host-header": "3.620.0", "@aws-sdk/middleware-logger": "3.609.0", "@aws-sdk/middleware-recursion-detection": "3.620.0", @@ -342,26 +342,26 @@ "@aws-sdk/util-user-agent-browser": "3.609.0", "@aws-sdk/util-user-agent-node": "3.614.0", "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.3.0", - "@smithy/fetch-http-handler": "^3.2.3", + "@smithy/core": "^2.3.2", + "@smithy/fetch-http-handler": "^3.2.4", "@smithy/hash-node": "^3.0.3", "@smithy/invalid-dependency": "^3.0.3", "@smithy/middleware-content-length": "^3.0.5", "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.12", + "@smithy/middleware-retry": "^3.0.14", "@smithy/middleware-serde": "^3.0.3", "@smithy/middleware-stack": "^3.0.3", "@smithy/node-config-provider": "^3.1.4", "@smithy/node-http-handler": "^3.1.4", "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.10", + "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.12", - "@smithy/util-defaults-mode-node": "^3.0.12", + "@smithy/util-defaults-mode-browser": "^3.0.14", + "@smithy/util-defaults-mode-node": "^3.0.14", "@smithy/util-endpoints": "^2.0.5", "@smithy/util-middleware": "^3.0.3", "@smithy/util-retry": "^3.0.3", @@ -373,15 +373,15 @@ } }, "node_modules/@aws-sdk/client-sso-oidc": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.620.0.tgz", - "integrity": "sha512-CWL8aJa6rrNaQXNsLhblGZzbFBrRz4BXAsFBbyqAZEmryr9q/IC7z/ww3nq8CD2UsW+bn89U/XcoP5r1KWUHuQ==", + "version": "3.624.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.624.0.tgz", + "integrity": "sha512-Ki2uKYJKKtfHxxZsiMTOvJoVRP6b2pZ1u3rcUb2m/nVgBPUfLdl8ZkGpqE29I+t5/QaS/sEdbn6cgMUZwl+3Dg==", "dev": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.620.0", - "@aws-sdk/credential-provider-node": "3.620.0", + "@aws-sdk/core": "3.624.0", + "@aws-sdk/credential-provider-node": "3.624.0", "@aws-sdk/middleware-host-header": "3.620.0", "@aws-sdk/middleware-logger": "3.609.0", "@aws-sdk/middleware-recursion-detection": "3.620.0", @@ -392,26 +392,26 @@ "@aws-sdk/util-user-agent-browser": "3.609.0", "@aws-sdk/util-user-agent-node": "3.614.0", "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.3.0", - "@smithy/fetch-http-handler": "^3.2.3", + "@smithy/core": "^2.3.2", + "@smithy/fetch-http-handler": "^3.2.4", "@smithy/hash-node": "^3.0.3", "@smithy/invalid-dependency": "^3.0.3", "@smithy/middleware-content-length": "^3.0.5", "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.12", + "@smithy/middleware-retry": "^3.0.14", "@smithy/middleware-serde": "^3.0.3", "@smithy/middleware-stack": "^3.0.3", "@smithy/node-config-provider": "^3.1.4", "@smithy/node-http-handler": "^3.1.4", "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.10", + "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.12", - "@smithy/util-defaults-mode-node": "^3.0.12", + "@smithy/util-defaults-mode-browser": "^3.0.14", + "@smithy/util-defaults-mode-node": "^3.0.14", "@smithy/util-endpoints": "^2.0.5", "@smithy/util-middleware": "^3.0.3", "@smithy/util-retry": "^3.0.3", @@ -422,20 +422,20 @@ "node": ">=16.0.0" }, "peerDependencies": { - "@aws-sdk/client-sts": "^3.620.0" + "@aws-sdk/client-sts": "^3.624.0" } }, "node_modules/@aws-sdk/client-sts": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.620.0.tgz", - "integrity": "sha512-pG4SqDHZV/ZbpoVoVtpxo6ZZoqVDbVItC3QUO73UJ3Gemxznd/Ck7kAsyb6/dJkV/Aqm3gt2O5UL7vzQLNHSjw==", + "version": "3.624.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.624.0.tgz", + "integrity": "sha512-k36fLZCb2nfoV/DKK3jbRgO/Yf7/R80pgYfMiotkGjnZwDmRvNN08z4l06L9C+CieazzkgRxNUzyppsYcYsQaw==", "dev": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.620.0", - "@aws-sdk/core": "3.620.0", - "@aws-sdk/credential-provider-node": "3.620.0", + "@aws-sdk/client-sso-oidc": "3.624.0", + "@aws-sdk/core": "3.624.0", + "@aws-sdk/credential-provider-node": "3.624.0", "@aws-sdk/middleware-host-header": "3.620.0", "@aws-sdk/middleware-logger": "3.609.0", "@aws-sdk/middleware-recursion-detection": "3.620.0", @@ -446,26 +446,26 @@ "@aws-sdk/util-user-agent-browser": "3.609.0", "@aws-sdk/util-user-agent-node": "3.614.0", "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.3.0", - "@smithy/fetch-http-handler": "^3.2.3", + "@smithy/core": "^2.3.2", + "@smithy/fetch-http-handler": "^3.2.4", "@smithy/hash-node": "^3.0.3", "@smithy/invalid-dependency": "^3.0.3", "@smithy/middleware-content-length": "^3.0.5", "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.12", + "@smithy/middleware-retry": "^3.0.14", "@smithy/middleware-serde": "^3.0.3", "@smithy/middleware-stack": "^3.0.3", "@smithy/node-config-provider": "^3.1.4", "@smithy/node-http-handler": "^3.1.4", "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.10", + "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.12", - "@smithy/util-defaults-mode-node": "^3.0.12", + "@smithy/util-defaults-mode-browser": "^3.0.14", + "@smithy/util-defaults-mode-node": "^3.0.14", "@smithy/util-endpoints": "^2.0.5", "@smithy/util-middleware": "^3.0.3", "@smithy/util-retry": "^3.0.3", @@ -477,17 +477,19 @@ } }, "node_modules/@aws-sdk/core": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.620.0.tgz", - "integrity": "sha512-5D9tMahxIDDFLULS9/ULa0HuIu7CZSshfj6wmDSmigXzkWyUvHoVIrme2z6eM3Icat/MO3d4WEy3445Vk385gQ==", + "version": "3.624.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.624.0.tgz", + "integrity": "sha512-WyFmPbhRIvtWi7hBp8uSFy+iPpj8ccNV/eX86hwF4irMjfc/FtsGVIAeBXxXM/vGCjkdfEzOnl+tJ2XACD4OXg==", "dev": true, "dependencies": { - "@smithy/core": "^2.3.0", + "@smithy/core": "^2.3.2", + "@smithy/node-config-provider": "^3.1.4", "@smithy/protocol-http": "^4.1.0", "@smithy/signature-v4": "^4.1.0", - "@smithy/smithy-client": "^3.1.10", + "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", - "fast-xml-parser": "4.2.5", + "@smithy/util-middleware": "^3.0.3", + "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" }, "engines": { @@ -495,9 +497,9 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.609.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.609.0.tgz", - "integrity": "sha512-v69ZCWcec2iuV9vLVJMa6fAb5xwkzN4jYIT8yjo2c4Ia/j976Q+TPf35Pnz5My48Xr94EFcaBazrWedF+kwfuQ==", + "version": "3.620.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.620.1.tgz", + "integrity": "sha512-ExuILJ2qLW5ZO+rgkNRj0xiAipKT16Rk77buvPP8csR7kkCflT/gXTyzRe/uzIiETTxM7tr8xuO9MP/DQXqkfg==", "dev": true, "dependencies": { "@aws-sdk/types": "3.609.0", @@ -510,19 +512,19 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.620.0.tgz", - "integrity": "sha512-BI2BdrSKDmB/2ouB/NJR0PT0x/+5fmoF6XOE78hFBb4F5w/yynGgcJY936dF+oREfpME6ehjB2b0okGg78Scpw==", + "version": "3.622.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.622.0.tgz", + "integrity": "sha512-VUHbr24Oll1RK3WR8XLUugLpgK9ZuxEm/NVeVqyFts1Ck9gsKpRg1x4eH7L7tW3SJ4TDEQNMbD7/7J+eoL2svg==", "dev": true, "dependencies": { "@aws-sdk/types": "3.609.0", - "@smithy/fetch-http-handler": "^3.2.3", + "@smithy/fetch-http-handler": "^3.2.4", "@smithy/node-http-handler": "^3.1.4", "@smithy/property-provider": "^3.1.3", "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.10", + "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", - "@smithy/util-stream": "^3.1.2", + "@smithy/util-stream": "^3.1.3", "tslib": "^2.6.2" }, "engines": { @@ -530,16 +532,16 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.620.0.tgz", - "integrity": "sha512-P9fYi6dzZIl8ITC7qAPf5DX9omI3LfA91g3KH+0OUmS3ctP7tN+gNo3HmqlzoqnwPe0pXn1FumYAe1qFl6Yjjg==", + "version": "3.624.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.624.0.tgz", + "integrity": "sha512-mMoNIy7MO2WTBbdqMyLpbt6SZpthE6e0GkRYpsd0yozPt0RZopcBhEh+HG1U9Y1PVODo+jcMk353vAi61CfnhQ==", "dev": true, "dependencies": { - "@aws-sdk/credential-provider-env": "3.609.0", - "@aws-sdk/credential-provider-http": "3.620.0", - "@aws-sdk/credential-provider-process": "3.614.0", - "@aws-sdk/credential-provider-sso": "3.620.0", - "@aws-sdk/credential-provider-web-identity": "3.609.0", + "@aws-sdk/credential-provider-env": "3.620.1", + "@aws-sdk/credential-provider-http": "3.622.0", + "@aws-sdk/credential-provider-process": "3.620.1", + "@aws-sdk/credential-provider-sso": "3.624.0", + "@aws-sdk/credential-provider-web-identity": "3.621.0", "@aws-sdk/types": "3.609.0", "@smithy/credential-provider-imds": "^3.2.0", "@smithy/property-provider": "^3.1.3", @@ -551,21 +553,21 @@ "node": ">=16.0.0" }, "peerDependencies": { - "@aws-sdk/client-sts": "^3.620.0" + "@aws-sdk/client-sts": "^3.624.0" } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.620.0.tgz", - "integrity": "sha512-or8ahy4ysURcWgKX00367DMDTTyMynDEl+FQh4wce66fMyePhFVuoPcRgXzWsi8KYmL95sPCfJFNqBMyFNcgvQ==", + "version": "3.624.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.624.0.tgz", + "integrity": "sha512-vYyGK7oNpd81BdbH5IlmQ6zfaQqU+rPwsKTDDBeLRjshtrGXOEpfoahVpG9PX0ibu32IOWp4ZyXBNyVrnvcMOw==", "dev": true, "dependencies": { - "@aws-sdk/credential-provider-env": "3.609.0", - "@aws-sdk/credential-provider-http": "3.620.0", - "@aws-sdk/credential-provider-ini": "3.620.0", - "@aws-sdk/credential-provider-process": "3.614.0", - "@aws-sdk/credential-provider-sso": "3.620.0", - "@aws-sdk/credential-provider-web-identity": "3.609.0", + "@aws-sdk/credential-provider-env": "3.620.1", + "@aws-sdk/credential-provider-http": "3.622.0", + "@aws-sdk/credential-provider-ini": "3.624.0", + "@aws-sdk/credential-provider-process": "3.620.1", + "@aws-sdk/credential-provider-sso": "3.624.0", + "@aws-sdk/credential-provider-web-identity": "3.621.0", "@aws-sdk/types": "3.609.0", "@smithy/credential-provider-imds": "^3.2.0", "@smithy/property-provider": "^3.1.3", @@ -578,9 +580,9 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.614.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.614.0.tgz", - "integrity": "sha512-Q0SI0sTRwi8iNODLs5+bbv8vgz8Qy2QdxbCHnPk/6Cx6LMf7i3dqmWquFbspqFRd8QiqxStrblwxrUYZi09tkA==", + "version": "3.620.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.620.1.tgz", + "integrity": "sha512-hWqFMidqLAkaV9G460+1at6qa9vySbjQKKc04p59OT7lZ5cO5VH5S4aI05e+m4j364MBROjjk2ugNvfNf/8ILg==", "dev": true, "dependencies": { "@aws-sdk/types": "3.609.0", @@ -594,12 +596,12 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.620.0.tgz", - "integrity": "sha512-xtIj2hmq3jcKwvGmqhoYapbWeQfFyoQgKBtwD6nx0M6oS5lbFH4rzHhj0gBwatZDjMa35cWtcYVUJCv2/9mWvA==", + "version": "3.624.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.624.0.tgz", + "integrity": "sha512-A02bayIjU9APEPKr3HudrFHEx0WfghoSPsPopckDkW7VBqO4wizzcxr75Q9A3vNX+cwg0wCN6UitTNe6pVlRaQ==", "dev": true, "dependencies": { - "@aws-sdk/client-sso": "3.620.0", + "@aws-sdk/client-sso": "3.624.0", "@aws-sdk/token-providers": "3.614.0", "@aws-sdk/types": "3.609.0", "@smithy/property-provider": "^3.1.3", @@ -612,9 +614,9 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.609.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.609.0.tgz", - "integrity": "sha512-U+PG8NhlYYF45zbr1km3ROtBMYqyyj/oK8NRp++UHHeuavgrP+4wJ4wQnlEaKvJBjevfo3+dlIBcaeQ7NYejWg==", + "version": "3.621.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.621.0.tgz", + "integrity": "sha512-w7ASSyfNvcx7+bYGep3VBgC3K6vEdLmlpjT7nSIHxxQf+WSdvy+HynwJosrpZax0sK5q0D1Jpn/5q+r5lwwW6w==", "dev": true, "dependencies": { "@aws-sdk/types": "3.609.0", @@ -626,7 +628,7 @@ "node": ">=16.0.0" }, "peerDependencies": { - "@aws-sdk/client-sts": "^3.609.0" + "@aws-sdk/client-sts": "^3.621.0" } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { @@ -740,39 +742,24 @@ } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.620.0.tgz", - "integrity": "sha512-AAZ6NLVOx/bP97PYj/afCMeySzxOHocgJG3ZXh6f8MnJcGpZgx8NyRm0vtiYUTFrS2JtU4xV05Dl3j4afV3s4A==", + "version": "3.626.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.626.0.tgz", + "integrity": "sha512-frFh6GQ1OEGueB0fL6Ft5rdHF+eu8JZUREjeBNEcg1qRqtMpPOlYkKzJ434d4zo+JHSK5xKFeb/Gu/kvB4LxEA==", "dev": true, "dependencies": { + "@aws-sdk/core": "3.624.0", "@aws-sdk/types": "3.609.0", "@aws-sdk/util-arn-parser": "3.568.0", + "@smithy/core": "^2.3.2", "@smithy/node-config-provider": "^3.1.4", "@smithy/protocol-http": "^4.1.0", "@smithy/signature-v4": "^4.1.0", - "@smithy/smithy-client": "^3.1.10", + "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-stream": "^3.1.2", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-signing": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.620.0.tgz", - "integrity": "sha512-gxI7rubiaanUXaLfJ4NybERa9MGPNg2Ycl/OqANsozrBnR3Pw8vqy3EuVImQOyn2pJ2IFvl8ZPoSMHf4pX56FQ==", - "dev": true, - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/signature-v4": "^4.1.0", - "@smithy/types": "^3.3.0", "@smithy/util-middleware": "^3.0.3", + "@smithy/util-stream": "^3.1.3", + "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, "engines": { @@ -827,12 +814,12 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.620.0.tgz", - "integrity": "sha512-yu1pTCqIbkSdaOvmyfW9vV9jWe3pDApkQPZLg4VEN5dXDWRtgQ/amv88myyCEoG14irUN1tsbvytcKzGyEXnhA==", + "version": "3.626.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.626.0.tgz", + "integrity": "sha512-n3yN668b2XLY6155y2KRCCDfA67Acxf/wUS60wGPNrJKk9O5AZzGQzZF8tLfMSng5YBS/CCHN40ooMhRwSLWUg==", "dev": true, "dependencies": { - "@aws-sdk/middleware-sdk-s3": "3.620.0", + "@aws-sdk/middleware-sdk-s3": "3.626.0", "@aws-sdk/types": "3.609.0", "@smithy/protocol-http": "^4.1.0", "@smithy/signature-v4": "^4.1.0", @@ -5744,16 +5731,16 @@ } }, "node_modules/@smithy/core": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.3.1.tgz", - "integrity": "sha512-BC7VMXx/1BCmRPCVzzn4HGWAtsrb7/0758EtwOGFJQrlSwJBEjCcDLNZLFoL/68JexYa2s+KmgL/UfmXdG6v1w==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.3.2.tgz", + "integrity": "sha512-in5wwt6chDBcUv1Lw1+QzZxN9fBffi+qOixfb65yK4sDuKG7zAUO9HAFqmVzsZM3N+3tTyvZjtnDXePpvp007Q==", "dev": true, "dependencies": { "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.13", + "@smithy/middleware-retry": "^3.0.14", "@smithy/middleware-serde": "^3.0.3", "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.11", + "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", "@smithy/util-middleware": "^3.0.3", "tslib": "^2.6.2" @@ -5965,15 +5952,15 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.13.tgz", - "integrity": "sha512-zvCLfaRYCaUmjbF2yxShGZdolSHft7NNCTA28HVN9hKcEbOH+g5irr1X9s+in8EpambclGnevZY4A3lYpvDCFw==", + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.14.tgz", + "integrity": "sha512-7ZaWZJOjUxa5hgmuMspyt8v/zVsh0GXYuF7OvCmdcbVa/xbnKQoYC+uYKunAqRGTkxjOyuOCw9rmFUFOqqC0eQ==", "dev": true, "dependencies": { "@smithy/node-config-provider": "^3.1.4", "@smithy/protocol-http": "^4.1.0", "@smithy/service-error-classification": "^3.0.3", - "@smithy/smithy-client": "^3.1.11", + "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", "@smithy/util-middleware": "^3.0.3", "@smithy/util-retry": "^3.0.3", @@ -6139,9 +6126,9 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.11.tgz", - "integrity": "sha512-l0BpyYkciNyMaS+PnFFz4aO5sBcXvGLoJd7mX9xrMBIm2nIQBVvYgp2ZpPDMzwjKCavsXu06iuCm0F6ZJZc6yQ==", + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", + "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", "dev": true, "dependencies": { "@smithy/middleware-endpoint": "^3.1.0", @@ -6239,13 +6226,13 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.13.tgz", - "integrity": "sha512-ZIRSUsnnMRStOP6OKtW+gCSiVFkwnfQF2xtf32QKAbHR6ACjhbAybDvry+3L5qQYdh3H6+7yD/AiUE45n8mTTw==", + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.14.tgz", + "integrity": "sha512-0iwTgKKmAIf+vFLV8fji21Jb2px11ktKVxbX6LIDPAUJyWQqGqBVfwba7xwa1f2FZUoolYQgLvxQEpJycXuQ5w==", "dev": true, "dependencies": { "@smithy/property-provider": "^3.1.3", - "@smithy/smithy-client": "^3.1.11", + "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", "bowser": "^2.11.0", "tslib": "^2.6.2" @@ -6255,16 +6242,16 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.13.tgz", - "integrity": "sha512-voUa8TFJGfD+U12tlNNLCDlXibt9vRdNzRX45Onk/WxZe7TS+hTOZouEZRa7oARGicdgeXvt1A0W45qLGYdy+g==", + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.14.tgz", + "integrity": "sha512-e9uQarJKfXApkTMMruIdxHprhcXivH1flYCe8JRDTzkkLx8dA3V5J8GZlST9yfDiRWkJpZJlUXGN9Rc9Ade3OQ==", "dev": true, "dependencies": { "@smithy/config-resolver": "^3.0.5", "@smithy/credential-provider-imds": "^3.2.0", "@smithy/node-config-provider": "^3.1.4", "@smithy/property-provider": "^3.1.3", - "@smithy/smithy-client": "^3.1.11", + "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, @@ -7141,9 +7128,9 @@ } }, "node_modules/@tanstack/query-core": { - "version": "4.36.1", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.36.1.tgz", - "integrity": "sha512-DJSilV5+ytBP1FbFcEJovv4rnnm/CokuVvrBEtW/Va9DvuJ3HksbXUJEpI0aV1KtuL4ZoO9AVE6PyNLzF7tLeA==", + "version": "5.51.21", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.51.21.tgz", + "integrity": "sha512-POQxm42IUp6n89kKWF4IZi18v3fxQWFRolvBA6phNVmA8psdfB1MvDnGacCJdS+EOX12w/CyHM62z//rHmYmvw==", "dev": true, "funding": { "type": "github", @@ -7151,30 +7138,19 @@ } }, "node_modules/@tanstack/react-query": { - "version": "4.36.1", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.36.1.tgz", - "integrity": "sha512-y7ySVHFyyQblPl3J3eQBWpXZkliroki3ARnBKsdJchlgt7yJLRDUcf4B8soufgiYt3pEQIkBWBx1N9/ZPIeUWw==", + "version": "5.51.23", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.51.23.tgz", + "integrity": "sha512-CfJCfX45nnVIZjQBRYYtvVMIsGgWLKLYC4xcUiYEey671n1alvTZoCBaU9B85O8mF/tx9LPyrI04A6Bs2THv4A==", "dev": true, "dependencies": { - "@tanstack/query-core": "4.36.1", - "use-sync-external-store": "^1.2.0" + "@tanstack/query-core": "5.51.21" }, "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-native": "*" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - }, - "react-native": { - "optional": true - } + "react": "^18.0.0" } }, "node_modules/@tokenizer/token": { @@ -11962,18 +11938,18 @@ "dev": true }, "node_modules/fast-xml-parser": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz", - "integrity": "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", + "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", "dev": true, "funding": [ - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" - }, { "type": "github", "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" } ], "dependencies": { @@ -20589,15 +20565,6 @@ "punycode": "^2.1.0" } }, - "node_modules/use-sync-external-store": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", - "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", - "dev": true, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index 715b01d..70470b8 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "@gravity-ui/prettier-config": "^1.1.0", "@gravity-ui/tsconfig": "^1.0.0", "@swc/jest": "^0.2.36", - "@tanstack/react-query": "^4.36.1", + "@tanstack/react-query": "^5.51.23", "@types/jest": "^29.5.12", "@types/react": "^18.3.3", "eslint": "^8.57.0", @@ -63,7 +63,7 @@ "react": "^18.3.1" }, "peerDependencies": { - "@tanstack/react-query": "^4.0.0", - "react": "^16.0.0 || ^17.0.0 || ^18.0.0" + "@tanstack/react-query": "^5.0.0", + "react": "^18.0.0" } } diff --git a/src/core/types/DataSource.ts b/src/core/types/DataSource.ts index f08ae43..fcd0212 100644 --- a/src/core/types/DataSource.ts +++ b/src/core/types/DataSource.ts @@ -1,6 +1,6 @@ import type {idle} from '../constants'; -export type DataSourceKey = readonly unknown[]; +export type DataSourceKey = ReadonlyArray; export type DataSourceTag = string; declare const errorHintSymbol: unique symbol; @@ -9,11 +9,11 @@ declare const stateHintSymbol: unique symbol; export interface DataSource< TContext, TParams, - TRequest, + TRequest extends object, TResponse, TData, TError, - TOptions, + TOptions extends object, TState, TFetchContext, > { @@ -31,7 +31,7 @@ export interface DataSource< [errorHintSymbol]?: TError; - options?: TOptions; + options?: Partial; [stateHintSymbol]?: TState; } diff --git a/src/core/utils/composeFullKey.ts b/src/core/utils/composeFullKey.ts index 7c01194..ae014e2 100644 --- a/src/core/utils/composeFullKey.ts +++ b/src/core/utils/composeFullKey.ts @@ -5,7 +5,7 @@ import {composeKey} from './composeKey'; export const composeFullKey = ( dataSource: TDataSource, params: DataSourceParams, -): readonly string[] => { +): ReadonlyArray => { const tags = dataSource.tags?.(params) ?? []; return [dataSource.name, ...tags, composeKey(dataSource, params)]; diff --git a/src/core/utils/composeKey.ts b/src/core/utils/composeKey.ts index 8ee0eab..ec605e7 100644 --- a/src/core/utils/composeKey.ts +++ b/src/core/utils/composeKey.ts @@ -1,5 +1,5 @@ // TODO(DakEnviy): Do not use react-query in core -import {hashQueryKey} from '@tanstack/react-query'; +import {hashKey} from '@tanstack/react-query'; import {idle} from '../constants'; import type {AnyDataSource, DataSourceParams} from '../types/DataSource'; @@ -8,4 +8,4 @@ export const composeKey = ( dataSource: TDataSource, params: DataSourceParams, ): string => - params === idle ? `${dataSource.name}:idle` : `${dataSource.name}(${hashQueryKey(params)})`; + params === idle ? `${dataSource.name}:idle` : `${dataSource.name}(${hashKey(params)})`; diff --git a/src/react-query/hooks/useQueryData.ts b/src/react-query/hooks/useQueryData.ts index f6dd069..c5cb44c 100644 --- a/src/react-query/hooks/useQueryData.ts +++ b/src/react-query/hooks/useQueryData.ts @@ -1,28 +1,37 @@ import type {DataSourceOptions, DataSourceParams, DataSourceState} from '../../core'; import {useInfiniteQueryData} from '../impl/infinite/hooks'; +import type {AnyInfiniteQueryDataSource} from '../impl/infinite/types'; import {usePlainQueryData} from '../impl/plain/hooks'; import type {AnyQueryDataSource} from '../types'; +import {notReachable} from '../utils/notReachable'; import {useQueryContext} from './useQueryContext'; export const useQueryData = ( dataSource: TDataSource, params: DataSourceParams, - options?: DataSourceOptions, + options?: Partial>, ): DataSourceState => { const context = useQueryContext(); + const type = dataSource.type; let state: DataSourceState | undefined; // Do not change data source type in the same hook call - if (dataSource.type === 'plain') { + if (type === 'plain') { // eslint-disable-next-line react-hooks/rules-of-hooks state = usePlainQueryData(context, dataSource, params, options); - } else if (dataSource.type === 'infinite') { + } else if (type === 'infinite') { // eslint-disable-next-line react-hooks/rules-of-hooks - state = useInfiniteQueryData(context, dataSource, params, options); + state = useInfiniteQueryData( + context, + dataSource, + params, + // TS can't calculate types in this place + options as Partial> | undefined, + ); } else { - throw new Error('Data Source type must be plain or infinite'); + return notReachable(type, `Data Source type must be plain or infinite, got: ${type}`); } return state as DataSourceState; diff --git a/src/react-query/impl/infinite/factory.ts b/src/react-query/impl/infinite/factory.ts index 7a2cec9..7be688c 100644 --- a/src/react-query/impl/infinite/factory.ts +++ b/src/react-query/impl/infinite/factory.ts @@ -1,6 +1,12 @@ import type {InfiniteQueryDataSource} from './types'; -export const makeInfiniteQueryDataSource = ( +export const makeInfiniteQueryDataSource = < + TParams, + TRequest extends object, + TResponse, + TData, + TError, +>( config: Omit, 'type'>, ): InfiniteQueryDataSource => ({ ...config, diff --git a/src/react-query/impl/infinite/hooks.ts b/src/react-query/impl/infinite/hooks.ts index 3792a7c..eb1ab1d 100644 --- a/src/react-query/impl/infinite/hooks.ts +++ b/src/react-query/impl/infinite/hooks.ts @@ -1,8 +1,11 @@ -import {useMemo} from 'react'; - import {useInfiniteQuery} from '@tanstack/react-query'; -import type {DataSourceContext, DataSourceOptions, DataSourceParams} from '../../../core'; +import type { + DataSourceContext, + DataSourceOptions, + DataSourceParams, + DataSourceState, +} from '../../../core'; import type {AnyInfiniteQueryDataSource} from './types'; import {composeOptions, transformResult} from './utils'; @@ -11,10 +14,10 @@ export const useInfiniteQueryData = , dataSource: TDataSource, params: DataSourceParams, - options?: DataSourceOptions, -) => { + options?: Partial>, +): DataSourceState => { const composedOptions = composeOptions(context, dataSource, params, options); const result = useInfiniteQuery(composedOptions); - return useMemo(() => transformResult(result), [result]); + return transformResult(result); }; diff --git a/src/react-query/impl/infinite/types.ts b/src/react-query/impl/infinite/types.ts index bd8f7ec..7dc1d25 100644 --- a/src/react-query/impl/infinite/types.ts +++ b/src/react-query/impl/infinite/types.ts @@ -1,4 +1,5 @@ import type { + InfiniteData, InfiniteQueryObserverOptions, InfiniteQueryObserverResult, QueryFunctionContext, @@ -8,29 +9,64 @@ import type {Overwrite} from 'utility-types'; import type {ActualData, DataLoaderStatus, DataSource, DataSourceKey} from '../../../core'; import type {QueryDataSourceContext} from '../../types'; -export type InfiniteQueryDataSource = DataSource< +export type InfiniteQueryDataSource< + TParams, + TRequest extends object, + TResponse, + TData, + TError, +> = DataSource< QueryDataSourceContext, TParams, TRequest, TResponse, TData, TError, - InfiniteQueryObserverOptions, TResponse>, - ResultWrapper, TError>>, - QueryFunctionContext | undefined> + InfiniteQueryObserverOptions< + TResponse, + TError, + InfiniteData, Partial>, + TResponse, + DataSourceKey, + Partial + >, + ResultWrapper< + InfiniteQueryObserverResult< + InfiniteData, Partial>, + TError + >, + TRequest, + TResponse, + TData, + TError + >, + QueryFunctionContext> > & { type: 'infinite'; - next: (lastPage: TResponse, allPages: TResponse[]) => Partial | undefined; - prev?: (firstPage: TResponse, allPages: TResponse[]) => Partial | undefined; + next: (lastPage: TResponse, allPages: TResponse[]) => Partial | null | undefined; + prev?: (firstPage: TResponse, allPages: TResponse[]) => Partial | null | undefined; }; // eslint-disable-next-line @typescript-eslint/no-explicit-any export type AnyInfiniteQueryDataSource = InfiniteQueryDataSource; -type ResultWrapper = - T extends InfiniteQueryObserverResult - ? Overwrite & { - originalStatus: T['status']; - originalData: T['data']; +// It is used instead of `Partial>` because TS can't calculate type +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type AnyPageParam = Partial; + +type ResultWrapper = + TResult extends InfiniteQueryObserverResult< + InfiniteData, Partial>, + TError + > + ? Overwrite< + TResult, + {status: DataLoaderStatus; data: DataWrapper>} + > & { + originalStatus: TResult['status']; + originalData: TResult['data']; } : never; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type DataWrapper = TActualData extends any[] ? TActualData : TActualData[]; diff --git a/src/react-query/impl/infinite/utils.ts b/src/react-query/impl/infinite/utils.ts index c7b8e91..76ca8cb 100644 --- a/src/react-query/impl/infinite/utils.ts +++ b/src/react-query/impl/infinite/utils.ts @@ -1,4 +1,6 @@ +import {skipToken} from '@tanstack/react-query'; import type { + InfiniteData, InfiniteQueryObserverOptions, InfiniteQueryObserverResult, QueryFunctionContext, @@ -12,63 +14,64 @@ import type { DataSourceKey, DataSourceOptions, DataSourceParams, - DataSourceRequest, DataSourceResponse, DataSourceState, } from '../../../core'; import {normalizeStatus} from '../../utils/normalizeStatus'; -import type {AnyInfiniteQueryDataSource} from './types'; +import type {AnyInfiniteQueryDataSource, AnyPageParam} from './types'; const EMPTY_ARRAY: unknown[] = []; +const EMPTY_OBJECT = {}; export const composeOptions = ( context: DataSourceContext, dataSource: TDataSource, params: DataSourceParams, - options?: DataSourceOptions, + options?: Partial>, ): InfiniteQueryObserverOptions< DataSourceResponse, DataSourceError, - DataSourceData, - DataSourceResponse + InfiniteData, AnyPageParam>, + DataSourceResponse, + DataSourceKey, + AnyPageParam > => { const {transformParams, transformResponse, next, prev} = dataSource; + const queryFn = ( + fetchContext: QueryFunctionContext, + ): DataSourceResponse | Promise> => { + const request = transformParams ? transformParams(params) : params; + const paginatedRequest = {...request, ...fetchContext.pageParam}; + + return dataSource.fetch(context, fetchContext, paginatedRequest); + }; + return { - ...dataSource.options, - enabled: params !== idle, queryKey: composeFullKey(dataSource, params), - queryFn: ( - fetchContext: QueryFunctionContext< - DataSourceKey, - Partial> | undefined - >, - ) => { - const actualParams = transformParams ? transformParams(params) : params; - const request = - typeof actualParams === 'object' - ? {...actualParams, ...fetchContext.pageParam} - : actualParams; - - return dataSource.fetch(context, fetchContext, request); - }, + queryFn: params === idle ? skipToken : queryFn, select: transformResponse ? (data) => ({...data, pages: data.pages.map(transformResponse)}) : undefined, + initialPageParam: EMPTY_OBJECT, getNextPageParam: next, getPreviousPageParam: prev, + ...dataSource.options, ...options, }; }; export const transformResult = ( - result: InfiniteQueryObserverResult, DataSourceError>, -) => { + result: InfiniteQueryObserverResult< + InfiniteData, AnyPageParam>, + DataSourceError + >, +): DataSourceState => { return { ...result, status: normalizeStatus(result.status, result.fetchStatus), - data: result.data?.pages.flat() ?? EMPTY_ARRAY, + data: result.data?.pages.flat(1) ?? EMPTY_ARRAY, originalStatus: result.status, originalData: result.data, } as DataSourceState; diff --git a/src/react-query/impl/plain/factory.ts b/src/react-query/impl/plain/factory.ts index 44254a6..8423b6a 100644 --- a/src/react-query/impl/plain/factory.ts +++ b/src/react-query/impl/plain/factory.ts @@ -1,6 +1,12 @@ import type {PlainQueryDataSource} from './types'; -export const makePlainQueryDataSource = ( +export const makePlainQueryDataSource = < + TParams, + TRequest extends object, + TResponse, + TData, + TError, +>( config: Omit, 'type'>, ): PlainQueryDataSource => ({ ...config, diff --git a/src/react-query/impl/plain/hooks.ts b/src/react-query/impl/plain/hooks.ts index 991377b..80d0928 100644 --- a/src/react-query/impl/plain/hooks.ts +++ b/src/react-query/impl/plain/hooks.ts @@ -1,8 +1,11 @@ -import {useMemo} from 'react'; - import {useQuery} from '@tanstack/react-query'; -import type {DataSourceContext, DataSourceOptions, DataSourceParams} from '../../../core'; +import type { + DataSourceContext, + DataSourceOptions, + DataSourceParams, + DataSourceState, +} from '../../../core'; import type {AnyPlainQueryDataSource} from './types'; import {composeOptions, transformResult} from './utils'; @@ -11,10 +14,10 @@ export const usePlainQueryData = ( context: DataSourceContext, dataSource: TDataSource, params: DataSourceParams, - options?: DataSourceOptions, -) => { + options?: Partial>, +): DataSourceState => { const composedOptions = composeOptions(context, dataSource, params, options); const result = useQuery(composedOptions); - return useMemo(() => transformResult(result), [result]); + return transformResult(result); }; diff --git a/src/react-query/impl/plain/types.ts b/src/react-query/impl/plain/types.ts index 41990e6..4570351 100644 --- a/src/react-query/impl/plain/types.ts +++ b/src/react-query/impl/plain/types.ts @@ -8,16 +8,22 @@ import type {Overwrite} from 'utility-types'; import type {ActualData, DataLoaderStatus, DataSource, DataSourceKey} from '../../../core'; import type {QueryDataSourceContext} from '../../types'; -export type PlainQueryDataSource = DataSource< +export type PlainQueryDataSource< + TParams, + TRequest extends object, + TResponse, + TData, + TError, +> = DataSource< QueryDataSourceContext, TParams, TRequest, TResponse, TData, TError, - QueryObserverOptions, TResponse>, + QueryObserverOptions, TResponse, DataSourceKey>, ResultWrapper, TError>>, - QueryFunctionContext + QueryFunctionContext > & { type: 'plain'; }; @@ -25,6 +31,6 @@ export type PlainQueryDataSource = // eslint-disable-next-line @typescript-eslint/no-explicit-any export type AnyPlainQueryDataSource = PlainQueryDataSource; -type ResultWrapper = T extends QueryObserverResult - ? Overwrite & {originalStatus: T['status']} +type ResultWrapper = TResult extends QueryObserverResult + ? Overwrite & {originalStatus: TResult['status']} : never; diff --git a/src/react-query/impl/plain/utils.ts b/src/react-query/impl/plain/utils.ts index 4cde40c..b5b0103 100644 --- a/src/react-query/impl/plain/utils.ts +++ b/src/react-query/impl/plain/utils.ts @@ -1,7 +1,8 @@ -import type { - QueryFunctionContext, - QueryObserverOptions, - QueryObserverResult, +import { + type QueryFunctionContext, + type QueryObserverOptions, + type QueryObserverResult, + skipToken, } from '@tanstack/react-query'; import {composeFullKey, idle} from '../../../core'; @@ -23,33 +24,38 @@ export const composeOptions = ( context: DataSourceContext, dataSource: TDataSource, params: DataSourceParams, - options?: DataSourceOptions, + options?: Partial>, ): QueryObserverOptions< DataSourceResponse, DataSourceError, DataSourceData, - DataSourceResponse + DataSourceResponse, + DataSourceKey > => { const {transformParams} = dataSource; + const queryFn = ( + fetchContext: QueryFunctionContext, + ): DataSourceResponse | Promise> => { + return dataSource.fetch( + context, + fetchContext, + transformParams ? transformParams(params) : params, + ); + }; + return { - ...dataSource.options, - enabled: params !== idle, queryKey: composeFullKey(dataSource, params), - queryFn: (fetchContext: QueryFunctionContext) => - dataSource.fetch( - context, - fetchContext, - transformParams ? transformParams(params) : params, - ), + queryFn: params === idle ? skipToken : queryFn, select: dataSource.transformResponse, + ...dataSource.options, ...options, }; }; export const transformResult = ( result: QueryObserverResult, DataSourceError>, -) => { +): DataSourceState => { return { ...result, status: normalizeStatus(result.status, result.fetchStatus), diff --git a/src/react-query/utils/normalizeStatus.ts b/src/react-query/utils/normalizeStatus.ts index 7e2fa9e..18593d7 100644 --- a/src/react-query/utils/normalizeStatus.ts +++ b/src/react-query/utils/normalizeStatus.ts @@ -6,7 +6,11 @@ export const normalizeStatus = ( status: QueryStatus, fetchStatus: FetchStatus, ): DataLoaderStatus => { - if (status === 'loading' && fetchStatus === 'idle') { + if (status === 'pending') { + if (fetchStatus === 'fetching') { + return 'loading'; + } + return 'success'; } diff --git a/src/react-query/utils/notReachable.ts b/src/react-query/utils/notReachable.ts new file mode 100644 index 0000000..ab80a4a --- /dev/null +++ b/src/react-query/utils/notReachable.ts @@ -0,0 +1,3 @@ +export const notReachable = (value: never, message?: string): never => { + throw new Error(message || `Not reachable state: ${value}`); +}; diff --git a/src/react/components/DataInfiniteLoader/types.ts b/src/react/components/DataInfiniteLoader/types.ts index f358af9..526af99 100644 --- a/src/react/components/DataInfiniteLoader/types.ts +++ b/src/react/components/DataInfiniteLoader/types.ts @@ -10,7 +10,7 @@ export interface MoreViewProps { export interface DataInfiniteLoaderProps< TError, - TLoadingViewProps extends {} = {}, + TLoadingViewProps extends object = {}, TErrorViewProps extends ErrorViewProps = ErrorViewProps, TMoreViewProps extends MoreViewProps = MoreViewProps, > { diff --git a/src/react/components/DataLoader/types.ts b/src/react/components/DataLoader/types.ts index 949927b..785e387 100644 --- a/src/react/components/DataLoader/types.ts +++ b/src/react/components/DataLoader/types.ts @@ -5,7 +5,7 @@ import type {ErrorAction, ErrorViewProps} from '../types'; export interface DataLoaderProps< TError, - TLoadingViewProps extends {} = {}, + TLoadingViewProps extends object = {}, TErrorViewProps extends ErrorViewProps = ErrorViewProps, > { status: DataLoaderStatus;