Skip to content

Commit 6b962d2

Browse files
authored
Merge branch 'reduxjs:master' into patch-1
2 parents 00dc908 + 261410a commit 6b962d2

File tree

8 files changed

+60
-21
lines changed

8 files changed

+60
-21
lines changed

docs/api/createEntityAdapter.mdx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,11 @@ export interface EntityAdapter<T> extends EntityStateAdapter<T> {
203203

204204
The primary content of an entity adapter is a set of generated reducer functions for adding, updating, and removing entity instances from an entity state object:
205205

206-
- `addOne`: accepts a single entity, and adds it.
207-
- `addMany`: accepts an array of entities or an object in the shape of `Record<EntityId, T>`, and adds them.
208-
- `setAll`: accepts an array of entities or an object in the shape of `Record<EntityId, T>`, and replaces the existing entity contents with the values in the array.
206+
- `addOne`: accepts a single entity, and adds it if it's not already present.
207+
- `addMany`: accepts an array of entities or an object in the shape of `Record<EntityId, T>`, and adds them if not already present.
208+
- `setOne`: accepts a single entity and adds or replaces it
209+
- `setMany`: accepts an array of entities or an an object in the shape of `Record<EntityId, T>`, and adds or replaces them.
210+
- `setAll`: accepts an array of entities or an object in the shape of `Record<EntityId, T>`, and replaces all existing entities with the values in the array.
209211
- `removeOne`: accepts a single entity ID value, and removes the entity with that ID if it exists.
210212
- `removeMany`: accepts an array of entity ID values, and removes each entity with those IDs if they exist.
211213
- `removeAll`: removes all entities from the entity state object.
@@ -214,6 +216,17 @@ The primary content of an entity adapter is a set of generated reducer functions
214216
- `upsertOne`: accepts a single entity. If an entity with that ID exists, it will perform a shallow update and the specified fields will be merged into the existing entity, with any matching fields overwriting the existing values. If the entity does not exist, it will be added.
215217
- `upsertMany`: accepts an array of entities or an object in the shape of `Record<EntityId, T>` that will be shallowly upserted.
216218

219+
:::info Should I add, set or upsert my entity?
220+
221+
All three options will insert _new_ entities into the list. However they differ in how they handle entities that already exist. If an entity **already exists**:
222+
223+
- `addOne` and `addMany` will do nothing with the new entity
224+
- `setOne` and `setMany` will completely replace the old entity with the new one. This will also get rid of any properties on the entity that are not present in the new version of said entity.
225+
- `upsertOne` and `upsertMany` will do a shallow copy to merge the old and new entities overwritng existing values, adding any that were not there and not touching properties not provided in the new entity.
226+
227+
:::
228+
229+
217230
Each method has a signature that looks like:
218231

219232
```ts no-transpile

packages/toolkit/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@
9898
"query"
9999
],
100100
"dependencies": {
101-
"immer": "^9.0.1",
101+
"immer": "^9.0.6",
102102
"redux": "^4.1.0",
103103
"redux-thunk": "^2.3.0",
104104
"reselect": "^4.0.0"

packages/toolkit/scripts/build.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,10 @@ import rollup from 'rollup'
66
import path from 'path'
77
import fs from 'fs-extra'
88
import ts from 'typescript'
9-
import { RawSourceMap, SourceMapConsumer } from 'source-map'
9+
import type { RawSourceMap } from 'source-map'
1010
import merge from 'merge-source-map'
11-
import {
12-
Extractor,
13-
ExtractorConfig,
14-
ExtractorResult,
15-
} from '@microsoft/api-extractor'
11+
import type { ExtractorResult } from '@microsoft/api-extractor'
12+
import { Extractor, ExtractorConfig } from '@microsoft/api-extractor'
1613
import yargs from 'yargs/yargs'
1714

1815
import { extractInlineSourcemap, removeInlineSourceMap } from './sourcemap'
@@ -201,6 +198,7 @@ async function bundle(options: BuildOptions & EntryPointOptions) {
201198
const origin = chunk.text
202199
const sourcemap = extractInlineSourcemap(origin)
203200
const result = ts.transpileModule(removeInlineSourceMap(origin), {
201+
fileName: chunk.path.replace(/.js$/, '.ts'),
204202
compilerOptions: {
205203
sourceMap: true,
206204
module:
@@ -217,7 +215,11 @@ async function bundle(options: BuildOptions & EntryPointOptions) {
217215
const transformResult = await terser.minify(
218216
appendInlineSourceMap(code, mapping),
219217
{
220-
sourceMap: { content: 'inline', asObject: true } as any,
218+
sourceMap: {
219+
content: 'inline',
220+
asObject: true,
221+
url: path.basename(chunk.path) + '.map',
222+
} as any,
221223
output: {
222224
comments: false,
223225
},

packages/toolkit/src/createAsyncThunk.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ type GetSerializedErrorType<ThunkApiConfig> = ThunkApiConfig extends {
177177
? GetSerializedErrorType
178178
: SerializedError
179179

180-
type MaybePromise<T> = T | Promise<T>
180+
type MaybePromise<T> = T | Promise<T> | (T extends any ? Promise<T> : never)
181181

182182
/**
183183
* A type describing the return value of the `payloadCreator` argument to `createAsyncThunk`.

packages/toolkit/src/query/fetchBaseQuery.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,15 +236,29 @@ export function fetchBaseQuery({
236236

237237
meta.response = responseClone
238238

239-
let resultData
239+
let resultData: any
240+
let responseText: string = ''
240241
try {
241-
resultData = await handleResponse(response, responseHandler)
242+
let handleResponseError
243+
await Promise.all([
244+
handleResponse(response, responseHandler).then(
245+
(r) => (resultData = r),
246+
(e) => (handleResponseError = e)
247+
),
248+
// see https://github.com/node-fetch/node-fetch/issues/665#issuecomment-538995182
249+
// we *have* to "use up" both streams at the same time or they will stop running in node-fetch scenarios
250+
responseClone.text().then(
251+
(r) => (responseText = r),
252+
() => {}
253+
),
254+
])
255+
if (handleResponseError) throw handleResponseError
242256
} catch (e) {
243257
return {
244258
error: {
245259
status: 'PARSING_ERROR',
246260
originalStatus: response.status,
247-
data: await responseClone.clone().text(),
261+
data: responseText,
248262
error: String(e),
249263
},
250264
meta,

packages/toolkit/src/tests/createAsyncThunk.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ test('`condition` will see state changes from a synchonously invoked asyncThunk'
818818
expect(onStart).toHaveBeenCalledTimes(2)
819819
})
820820

821-
describe.only('meta', () => {
821+
describe('meta', () => {
822822
const getNewStore = () =>
823823
configureStore({
824824
reducer(actions = [], action) {

packages/toolkit/src/tests/createAsyncThunk.typetest.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,16 @@ const anyAction = { type: 'foo' } as AnyAction
137137
expectType<RejectValue>(unwrapResult(returned))
138138
})()
139139

140+
/**
141+
* regression #1156: union return values fall back to allowing only single member
142+
*/
143+
;(async () => {
144+
const fn = createAsyncThunk('session/isAdmin', async () => {
145+
const response: boolean = false
146+
return response
147+
})
148+
})()
149+
140150
{
141151
interface Item {
142152
name: string

yarn.lock

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5034,7 +5034,7 @@ __metadata:
50345034
eslint-plugin-react: ^7.23.2
50355035
eslint-plugin-react-hooks: ^4.2.0
50365036
fs-extra: ^9.1.0
5037-
immer: ^9.0.1
5037+
immer: ^9.0.6
50385038
invariant: ^2.2.4
50395039
jest: ^26.6.3
50405040
json-stringify-safe: ^5.0.1
@@ -13776,10 +13776,10 @@ fsevents@^1.2.7:
1377613776
languageName: node
1377713777
linkType: hard
1377813778

13779-
"immer@npm:^9.0.1":
13780-
version: 9.0.2
13781-
resolution: "immer@npm:9.0.2"
13782-
checksum: 71487285a890e6fb92ed8950ce3b5b0e2546321bb4dfe82a7395fbc3f24308b0481387b5939fd35681bac8e36161d903f2bcd99ac045acd25ed3a7f21c629bfd
13779+
"immer@npm:^9.0.6":
13780+
version: 9.0.6
13781+
resolution: "immer@npm:9.0.6"
13782+
checksum: 48c9b673ee0f3a05f0651f26c8ccdcbc034a47502dd26e716bd7bb301bcede194d1c5e895d4d6ec8d1e7bfb6444dd1056095b3f10e6c5e08cc3e798497a96531
1378313783
languageName: node
1378413784
linkType: hard
1378513785

0 commit comments

Comments
 (0)