Skip to content

Commit 2d7def1

Browse files
committed
Merge branch 'master' into create-slice-creators
2 parents ef2d024 + e848a55 commit 2d7def1

File tree

83 files changed

+2718
-572
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+2718
-572
lines changed

.github/workflows/tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ jobs:
4848

4949
# Read existing version, reuse that, add a Git short hash
5050
- name: Set build version to Git commit
51-
run: node scripts/writeGitVersion.mjs $(git rev-parse --short HEAD)
51+
run: yarn tsx scripts/writeGitVersion.mts $(git rev-parse --short HEAD)
5252

5353
- name: Check updated version
5454
run: jq .version package.json
@@ -111,7 +111,7 @@ jobs:
111111
fail-fast: false
112112
matrix:
113113
node: ['20.x']
114-
ts: ['4.7', '4.8', '4.9', '5.0', '5.1', '5.2', '5.3', '5.4', '5.5']
114+
ts: ['5.0', '5.1', '5.2', '5.3', '5.4', '5.5']
115115
steps:
116116
- name: Checkout repo
117117
uses: actions/checkout@v4

docs/rtk-query/api/createApi.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ description: 'RTK Query > API: createApi reference'
1616

1717
Typically, you should only have one API slice per base URL that your application needs to communicate with. For example, if your site fetches data from both `/api/posts` and `/api/users`, you would have a single API slice with `/api/` as the base URL, and separate endpoint definitions for `posts` and `users`. This allows you to effectively take advantage of [automated re-fetching](../usage/automated-refetching.mdx) by defining [tag](../usage/automated-refetching.mdx#tags) relationships across endpoints.
1818

19+
This is because:
20+
21+
- Automatic tag invalidation only works within a single API slice. If you have multiple API slices, the automatic invalidation won't work across them.
22+
- Every `createApi` call generates its own middleware, and each middleware added to the store will run checks against every dispatched action. That has a perf cost that adds up. So, if you called `createApi` 10 times and added 10 separate API middleware to the store, that will be noticeably slower perf-wise.
23+
1924
For maintainability purposes, you may wish to split up endpoint definitions across multiple files, while still maintaining a single API slice which includes all of these endpoints. See [code splitting](../usage/code-splitting.mdx) for how you can use the `injectEndpoints` property to inject API endpoints from other files into a single API slice definition.
2025

2126
:::
@@ -91,6 +96,7 @@ export const { useGetPokemonByNameQuery } = pokemonApi
9196
- `endpoint` - The name of the endpoint.
9297
- `type` - Type of request (`query` or `mutation`).
9398
- `forced` - Indicates if a query has been forced.
99+
- `queryCacheKey`- The computed query cache key.
94100
- `extraOptions` - The value of the optional `extraOptions` property provided for a given endpoint
95101

96102
#### baseQuery function signature

docs/rtk-query/api/created-api/api-slice-utils.mdx

Lines changed: 143 additions & 56 deletions
Large diffs are not rendered by default.

docs/rtk-query/api/created-api/hooks.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ type UseMutationResult<T> = {
335335
data?: T // Returned result if present
336336
error?: unknown // Error result if present
337337
endpointName?: string // The name of the given endpoint for the mutation
338-
fulfilledTimestamp?: number // Timestamp for when the mutation was completed
338+
fulfilledTimeStamp?: number // Timestamp for when the mutation was completed
339339

340340
// Derived request status booleans
341341
isUninitialized: boolean // Mutation has not been fired yet

docs/rtk-query/api/created-api/overview.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ This section documents the contents of that API structure, with the different fi
1919

2020
Typically, you should only have one API slice per base URL that your application needs to communicate with. For example, if your site fetches data from both `/api/posts` and `/api/users`, you would have a single API slice with `/api/` as the base URL, and separate endpoint definitions for `posts` and `users`. This allows you to effectively take advantage of [automated re-fetching](../../usage/automated-refetching.mdx) by defining [tag](../../usage/automated-refetching.mdx#tags) relationships across endpoints.
2121

22+
This is because:
23+
24+
- Automatic tag invalidation only works within a single API slice. If you have multiple API slices, the automatic invalidation won't work across them.
25+
- Every `createApi` call generates its own middleware, and each middleware added to the store will run checks against every dispatched action. That has a perf cost that adds up. So, if you called `createApi` 10 times and added 10 separate API middleware to the store, that will be noticeably slower perf-wise.
26+
2227
For maintainability purposes, you may wish to split up endpoint definitions across multiple files, while still maintaining a single API slice which includes all of these endpoints. See [code splitting](../../usage/code-splitting.mdx) for how you can use the `injectEndpoints` property to inject API endpoints from other files into a single API slice definition.
2328

2429
:::

docs/rtk-query/api/fetchBaseQuery.mdx

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ type FetchBaseQueryArgs = {
6464
api: Pick<
6565
BaseQueryApi,
6666
'getState' | 'extra' | 'endpoint' | 'type' | 'forced'
67-
>,
67+
> & { arg: string | FetchArgs },
6868
) => MaybePromise<Headers | void>
6969
fetchFn?: (
7070
input: RequestInfo,
@@ -83,14 +83,60 @@ type FetchBaseQueryResult = Promise<
8383
meta?: { request: Request; response: Response }
8484
}
8585
| {
86-
error: {
87-
status: number
88-
data: any
89-
}
86+
error: FetchBaseQueryError
9087
data?: undefined
9188
meta?: { request: Request; response: Response }
9289
}
9390
>
91+
92+
type FetchBaseQueryError =
93+
| {
94+
/**
95+
* * `number`:
96+
* HTTP status code
97+
*/
98+
status: number
99+
data: unknown
100+
}
101+
| {
102+
/**
103+
* * `"FETCH_ERROR"`:
104+
* An error that occurred during execution of `fetch` or the `fetchFn` callback option
105+
**/
106+
status: 'FETCH_ERROR'
107+
data?: undefined
108+
error: string
109+
}
110+
| {
111+
/**
112+
* * `"PARSING_ERROR"`:
113+
* An error happened during parsing.
114+
* Most likely a non-JSON-response was returned with the default `responseHandler` "JSON",
115+
* or an error occurred while executing a custom `responseHandler`.
116+
**/
117+
status: 'PARSING_ERROR'
118+
originalStatus: number
119+
data: string
120+
error: string
121+
}
122+
| {
123+
/**
124+
* * `"TIMEOUT_ERROR"`:
125+
* Request timed out
126+
**/
127+
status: 'TIMEOUT_ERROR'
128+
data?: undefined
129+
error: string
130+
}
131+
| {
132+
/**
133+
* * `"CUSTOM_ERROR"`:
134+
* A custom error type that you can return from your `queryFn` where another error might not make sense.
135+
**/
136+
status: 'CUSTOM_ERROR'
137+
data?: unknown
138+
error: string
139+
}
94140
```
95141
96142
## Parameters
@@ -105,7 +151,7 @@ Typically a string like `https://api.your-really-great-app.com/v1/`. If you don'
105151

106152
_(optional)_
107153

108-
Allows you to inject headers on every request. You can specify headers at the endpoint level, but you'll typically want to set common headers like `authorization` here. As a convenience mechanism, the second argument allows you to use `getState` to access your redux store in the event you store information you'll need there such as an auth token. Additionally, it provides access to `extra`, `endpoint`, `type`, and `forced` to unlock more granular conditional behaviors.
154+
Allows you to inject headers on every request. You can specify headers at the endpoint level, but you'll typically want to set common headers like `authorization` here. As a convenience mechanism, the second argument allows you to use `getState` to access your redux store in the event you store information you'll need there such as an auth token. Additionally, it provides access to `arg`, `extra`, `endpoint`, `type`, and `forced` to unlock more granular conditional behaviors.
109155

110156
You can mutate the `headers` argument directly, and returning it is optional.
111157

@@ -114,6 +160,7 @@ type prepareHeaders = (
114160
headers: Headers,
115161
api: {
116162
getState: () => unknown
163+
arg: string | FetchArgs
117164
extra: unknown
118165
endpoint: string
119166
type: 'query' | 'mutation'
@@ -297,6 +344,17 @@ export const customApi = createApi({
297344
If you make a `json` request to an API that only returns a `200` with an undefined body, `fetchBaseQuery` will pass that through as `undefined` and will not try to parse it as `json`. This can be common with some APIs, especially on `delete` requests.
298345
:::
299346

347+
#### Default response handler
348+
349+
The default response handler is `"json"`, which is equivalent to the following function:
350+
351+
```ts title="Default responseHandler"
352+
const defaultResponseHandler = async (res: Response) => {
353+
const text = await res.text()
354+
return text.length ? JSON.parse(text) : null
355+
}
356+
```
357+
300358
### Handling non-standard Response status codes
301359

302360
By default, `fetchBaseQuery` will `reject` any `Response` that does not have a status code of `2xx` and set it to `error`. This is the same behavior you've most likely experienced with `axios` and other popular libraries. In the event that you have a non-standard API you're dealing with, you can use the `validateStatus` option to customize this behavior.

docs/rtk-query/internal/overview.mdx

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ RTK-Query uses a very familiar redux-centric architecture. Where the `api` is a
3838
The slices built inside this "build" are:
3939
_Some of which have their own actions_
4040

41-
- querySlice
42-
- mutationSlice
43-
- invalidationSlice
44-
- subscriptionSlice (used as a dummy slice to generate actions internally)
45-
- internalSubscriptionsSlice
46-
- configSlice (internal tracking of focus state, online state, hydration etc)
41+
- `querySlice`
42+
- `mutationSlice`
43+
- `invalidationSlice`
44+
- `subscriptionSlice` (used as a dummy slice to generate actions internally)
45+
- `internalSubscriptionsSlice`
46+
- `configSlice` (internal tracking of focus state, online state, hydration etc)
4747

4848
buildSlice also exposes the core action `resetApiState` which is subsequently added to the `api.util`
4949

@@ -53,21 +53,21 @@ RTK-Query has a series of custom middlewares established within its store to han
5353

5454
Each middleware built during this step is referred to internally as a "Handler" and are as follows:
5555

56-
- `buildDevCheckHandler
57-
- `buildCacheCollectionHandler
58-
- `buildInvalidationByTagsHandler
59-
- `buildPollingHandler
60-
- `buildCacheLifecycleHandler
61-
- `buildQueryLifecycleHandler
56+
- `buildDevCheckHandler`
57+
- `buildCacheCollectionHandler`
58+
- `buildInvalidationByTagsHandler`
59+
- `buildPollingHandler`
60+
- `buildCacheLifecycleHandler`
61+
- `buildQueryLifecycleHandler`
6262

6363
### buildSelectors
6464

6565
build selectors is a crucial step that exposes to the `api` and utils:
6666

67-
- `buildQuerySelector
68-
- `buildMutationSelector
69-
- `selectInvalidatedBy
70-
- `selectCachedArgsForQuery
67+
- `buildQuerySelector`
68+
- `buildMutationSelector`
69+
- `selectInvalidatedBy`
70+
- `selectCachedArgsForQuery`
7171

7272
### return
7373

docs/rtk-query/usage/customizing-queries.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ const staggeredBaseQueryWithBailOut = retry(
636636
// bail out of re-tries immediately if unauthorized,
637637
// because we know successive re-retries would be redundant
638638
if (result.error?.status === 401) {
639-
retry.fail(result.error)
639+
retry.fail(result.error, result.meta)
640640
}
641641

642642
return result

docs/usage/immer-reducers.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ Writing immutable update logic by hand _is_ hard, and **accidentally mutating st
150150
Immer provides a function called `produce`, which accepts two arguments: your original `state`, and a callback function. The callback function is given a "draft" version of that state, and inside the callback, it is safe to write code that mutates the draft value. Immer tracks all attempts to mutate the draft value and then replays those mutations using their immutable equivalents to create a safe, immutably updated result:
151151

152152
```js
153-
import produce from 'immer'
153+
import { produce } from 'immer'
154154

155155
const baseState = [
156156
{

examples/publish-ci/react-native/yarn.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9632,11 +9632,11 @@ __metadata:
96329632

96339633
"typescript@patch:typescript@npm%3A^5.5.4#optional!builtin<compat/typescript>":
96349634
version: 5.5.4
9635-
resolution: "typescript@patch:typescript@npm%3A5.5.4#optional!builtin<compat/typescript>::version=5.5.4&hash=d69c25"
9635+
resolution: "typescript@patch:typescript@npm%3A5.5.4#optional!builtin<compat/typescript>::version=5.5.4&hash=379a07"
96369636
bin:
96379637
tsc: bin/tsc
96389638
tsserver: bin/tsserver
9639-
checksum: 10/2c065f0ef81855eac25c9b658a3c9da65ffc005260c12854c2286f40f3667e1b1ecf8bdbdd37b59aa0397920378ce7900bff8cb32e0f1c7af6fd86efc676718c
9639+
checksum: 10/746fdd0865c5ce4f15e494c57ede03a9e12ede59cfdb40da3a281807853fe63b00ef1c912d7222143499aa82f18b8b472baa1830df8804746d09b55f6cf5b1cc
96409640
languageName: node
96419641
linkType: hard
96429642

0 commit comments

Comments
 (0)