@data-client/core 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +133 -409
- package/dist/index.umd.min.js +1 -1
- package/dist/next.js +61 -101
- package/legacy/actionTypes.js +2 -2
- package/legacy/controller/Controller.js +276 -6
- package/legacy/controller/createFetch.js +3 -14
- package/legacy/controller/createInvalidate.js +1 -1
- package/legacy/controller/createInvalidateAll.js +1 -1
- package/legacy/controller/createOptimistic.js +1 -7
- package/legacy/controller/createReset.js +1 -1
- package/legacy/controller/createSet.js +31 -0
- package/legacy/controller/createSubscription.js +3 -7
- package/legacy/index.js +2 -5
- package/legacy/internal.js +2 -2
- package/legacy/manager/DevtoolsManager.js +2 -2
- package/legacy/manager/LogoutManager.js +2 -2
- package/legacy/manager/NetworkManager.js +28 -59
- package/legacy/manager/PollingSubscription.js +18 -27
- package/legacy/manager/SubscriptionManager.js +16 -42
- package/legacy/middlewareTypes.js +1 -1
- package/legacy/newActions.js +1 -1
- package/legacy/next/index.js +3 -3
- package/legacy/state/reducer/createReducer.js +2 -6
- package/legacy/state/reducer/fetchReducer.js +3 -13
- package/legacy/state/reducer/invalidateReducer.js +1 -1
- package/legacy/state/reducer/setReducer.js +9 -16
- package/legacy/types.js +2 -6
- package/lib/actionTypes.d.ts +1 -0
- package/lib/actionTypes.d.ts.map +1 -1
- package/lib/actionTypes.js +2 -2
- package/lib/controller/Controller.d.ts +126 -6
- package/lib/controller/Controller.d.ts.map +1 -1
- package/lib/controller/Controller.js +276 -6
- package/lib/controller/createFetch.d.ts +2 -2
- package/lib/controller/createFetch.d.ts.map +1 -1
- package/lib/controller/createFetch.js +3 -14
- package/lib/controller/createInvalidate.d.ts +1 -1
- package/lib/controller/createInvalidate.d.ts.map +1 -1
- package/lib/controller/createInvalidate.js +1 -1
- package/lib/controller/createInvalidateAll.d.ts +1 -1
- package/lib/controller/createInvalidateAll.d.ts.map +1 -1
- package/lib/controller/createInvalidateAll.js +1 -1
- package/lib/controller/createOptimistic.d.ts +2 -2
- package/lib/controller/createOptimistic.d.ts.map +1 -1
- package/lib/controller/createOptimistic.js +1 -7
- package/lib/controller/createReset.d.ts +1 -1
- package/lib/controller/createReset.d.ts.map +1 -1
- package/lib/controller/createReset.js +1 -1
- package/lib/controller/{createReceive.d.ts → createSet.d.ts} +6 -6
- package/lib/controller/createSet.d.ts.map +1 -0
- package/lib/controller/createSet.js +31 -0
- package/lib/controller/createSubscription.d.ts +3 -3
- package/lib/controller/createSubscription.d.ts.map +1 -1
- package/lib/controller/createSubscription.js +3 -7
- package/lib/index.d.ts +2 -6
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -5
- package/lib/internal.d.ts +1 -1
- package/lib/internal.d.ts.map +1 -1
- package/lib/internal.js +2 -2
- package/lib/manager/DevtoolsManager.d.ts +1 -1
- package/lib/manager/DevtoolsManager.js +2 -2
- package/lib/manager/LogoutManager.d.ts +4 -5
- package/lib/manager/LogoutManager.d.ts.map +1 -1
- package/lib/manager/LogoutManager.js +2 -2
- package/lib/manager/NetworkManager.d.ts +4 -5
- package/lib/manager/NetworkManager.d.ts.map +1 -1
- package/lib/manager/NetworkManager.js +28 -61
- package/lib/manager/PollingSubscription.d.ts +9 -9
- package/lib/manager/PollingSubscription.d.ts.map +1 -1
- package/lib/manager/PollingSubscription.js +18 -27
- package/lib/manager/SubscriptionManager.d.ts +10 -15
- package/lib/manager/SubscriptionManager.d.ts.map +1 -1
- package/lib/manager/SubscriptionManager.js +16 -42
- package/lib/middlewareTypes.d.ts +5 -5
- package/lib/middlewareTypes.d.ts.map +1 -1
- package/lib/middlewareTypes.js +1 -1
- package/lib/newActions.d.ts +26 -18
- package/lib/newActions.d.ts.map +1 -1
- package/lib/newActions.js +1 -1
- package/lib/next/index.d.ts +2 -2
- package/lib/next/index.d.ts.map +1 -1
- package/lib/next/index.js +3 -3
- package/lib/state/reducer/createReducer.d.ts.map +1 -1
- package/lib/state/reducer/createReducer.js +2 -6
- package/lib/state/reducer/fetchReducer.d.ts +1 -2
- package/lib/state/reducer/fetchReducer.d.ts.map +1 -1
- package/lib/state/reducer/fetchReducer.js +3 -14
- package/lib/state/reducer/invalidateReducer.d.ts +3 -4
- package/lib/state/reducer/invalidateReducer.d.ts.map +1 -1
- package/lib/state/reducer/invalidateReducer.js +1 -1
- package/lib/state/reducer/setReducer.d.ts +2 -38
- package/lib/state/reducer/setReducer.d.ts.map +1 -1
- package/lib/state/reducer/setReducer.js +9 -17
- package/lib/types.d.ts +9 -30
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js +2 -6
- package/package.json +3 -3
- package/src/actionTypes.ts +1 -1
- package/src/controller/Controller.ts +491 -10
- package/src/controller/createFetch.ts +4 -19
- package/src/controller/createInvalidate.ts +1 -1
- package/src/controller/createInvalidateAll.ts +1 -1
- package/src/controller/createOptimistic.ts +3 -9
- package/src/controller/createReset.ts +1 -1
- package/src/controller/{createReceive.ts → createSet.ts} +9 -17
- package/src/controller/createSubscription.ts +3 -10
- package/src/index.ts +2 -16
- package/src/internal.ts +1 -1
- package/src/manager/DevtoolsManager.ts +1 -1
- package/src/manager/LogoutManager.ts +4 -5
- package/src/manager/NetworkManager.ts +31 -80
- package/src/manager/PollingSubscription.ts +26 -27
- package/src/manager/SubscriptionManager.ts +22 -54
- package/src/manager/__tests__/__snapshots__/pollingSubscription.ts.snap +10 -8
- package/src/manager/__tests__/logoutManager.ts +5 -5
- package/src/manager/__tests__/manager.ts +2 -4
- package/src/manager/__tests__/networkManager.ts +8 -42
- package/src/manager/__tests__/pollingSubscription.ts +259 -151
- package/src/manager/__tests__/subscriptionManager.ts +7 -13
- package/src/middlewareTypes.ts +5 -10
- package/src/newActions.ts +33 -23
- package/src/next/index.ts +2 -2
- package/src/state/__tests__/reducer.ts +59 -297
- package/src/state/reducer/createReducer.ts +3 -11
- package/src/state/reducer/fetchReducer.ts +5 -18
- package/src/state/reducer/invalidateReducer.ts +2 -2
- package/src/state/reducer/setReducer.ts +10 -22
- package/src/types.ts +9 -78
- package/ts3.4/actionTypes.d.ts +1 -0
- package/ts3.4/controller/Controller.d.ts +168 -6
- package/ts3.4/controller/createFetch.d.ts +2 -2
- package/ts3.4/controller/createInvalidate.d.ts +1 -1
- package/ts3.4/controller/createInvalidateAll.d.ts +1 -1
- package/ts3.4/controller/createOptimistic.d.ts +1 -1
- package/ts3.4/controller/createReset.d.ts +1 -1
- package/ts3.4/controller/{createReceive.d.ts → createSet.d.ts} +6 -6
- package/ts3.4/controller/createSubscription.d.ts +3 -3
- package/ts3.4/index.d.ts +2 -7
- package/ts3.4/internal.d.ts +1 -1
- package/ts3.4/manager/DevtoolsManager.d.ts +1 -1
- package/ts3.4/manager/LogoutManager.d.ts +4 -5
- package/ts3.4/manager/NetworkManager.d.ts +4 -5
- package/ts3.4/manager/PollingSubscription.d.ts +9 -9
- package/ts3.4/manager/SubscriptionManager.d.ts +10 -15
- package/ts3.4/middlewareTypes.d.ts +5 -5
- package/ts3.4/newActions.d.ts +26 -18
- package/ts3.4/next/index.d.ts +2 -2
- package/ts3.4/state/reducer/fetchReducer.d.ts +1 -2
- package/ts3.4/state/reducer/invalidateReducer.d.ts +3 -4
- package/ts3.4/state/reducer/setReducer.d.ts +2 -38
- package/ts3.4/types.d.ts +8 -30
- package/legacy/compatibleActions.js +0 -2
- package/legacy/controller/BaseController.js +0 -289
- package/legacy/controller/createReceive.js +0 -36
- package/legacy/endpoint/index.js +0 -2
- package/legacy/endpoint/shapes.js +0 -2
- package/legacy/endpoint/types.js +0 -2
- package/legacy/legacyActions.js +0 -2
- package/legacy/next/Controller.js +0 -24
- package/legacy/previousActions.js +0 -2
- package/legacy/state/applyUpdatersToResults.js +0 -4
- package/legacy/state/legacy-actions/createFetch.js +0 -62
- package/legacy/state/legacy-actions/createReceive.js +0 -37
- package/legacy/state/legacy-actions/createReceiveError.js +0 -28
- package/legacy/state/legacy-actions/index.js +0 -4
- package/legacy/state/reducerInstance.js +0 -9
- package/lib/compatibleActions.d.ts +0 -47
- package/lib/compatibleActions.d.ts.map +0 -1
- package/lib/compatibleActions.js +0 -2
- package/lib/controller/BaseController.d.ts +0 -128
- package/lib/controller/BaseController.d.ts.map +0 -1
- package/lib/controller/BaseController.js +0 -289
- package/lib/controller/createReceive.d.ts.map +0 -1
- package/lib/controller/createReceive.js +0 -36
- package/lib/endpoint/index.d.ts +0 -3
- package/lib/endpoint/index.d.ts.map +0 -1
- package/lib/endpoint/index.js +0 -2
- package/lib/endpoint/shapes.d.ts +0 -25
- package/lib/endpoint/shapes.d.ts.map +0 -1
- package/lib/endpoint/shapes.js +0 -2
- package/lib/endpoint/types.d.ts +0 -45
- package/lib/endpoint/types.d.ts.map +0 -1
- package/lib/endpoint/types.js +0 -2
- package/lib/legacyActions.d.ts +0 -92
- package/lib/legacyActions.d.ts.map +0 -1
- package/lib/legacyActions.js +0 -2
- package/lib/next/Controller.d.ts +0 -14
- package/lib/next/Controller.d.ts.map +0 -1
- package/lib/next/Controller.js +0 -24
- package/lib/previousActions.d.ts +0 -91
- package/lib/previousActions.d.ts.map +0 -1
- package/lib/previousActions.js +0 -2
- package/lib/state/applyUpdatersToResults.d.ts +0 -13
- package/lib/state/applyUpdatersToResults.d.ts.map +0 -1
- package/lib/state/applyUpdatersToResults.js +0 -7
- package/lib/state/legacy-actions/createFetch.d.ts +0 -19
- package/lib/state/legacy-actions/createFetch.d.ts.map +0 -1
- package/lib/state/legacy-actions/createFetch.js +0 -62
- package/lib/state/legacy-actions/createReceive.d.ts +0 -14
- package/lib/state/legacy-actions/createReceive.d.ts.map +0 -1
- package/lib/state/legacy-actions/createReceive.js +0 -37
- package/lib/state/legacy-actions/createReceiveError.d.ts +0 -9
- package/lib/state/legacy-actions/createReceiveError.d.ts.map +0 -1
- package/lib/state/legacy-actions/createReceiveError.js +0 -28
- package/lib/state/legacy-actions/index.d.ts +0 -4
- package/lib/state/legacy-actions/index.d.ts.map +0 -1
- package/lib/state/legacy-actions/index.js +0 -4
- package/lib/state/reducerInstance.d.ts +0 -7
- package/lib/state/reducerInstance.d.ts.map +0 -1
- package/lib/state/reducerInstance.js +0 -9
- package/src/compatibleActions.ts +0 -96
- package/src/controller/BaseController.ts +0 -508
- package/src/endpoint/index.ts +0 -14
- package/src/endpoint/shapes.ts +0 -53
- package/src/endpoint/types.ts +0 -72
- package/src/legacyActions.ts +0 -163
- package/src/manager/__tests__/__snapshots__/pollingSubscription-endpoint.ts.snap +0 -49
- package/src/manager/__tests__/networkManager-legacy.ts +0 -394
- package/src/manager/__tests__/pollingSubscription-endpoint.ts +0 -423
- package/src/next/Controller.ts +0 -39
- package/src/previousActions.ts +0 -159
- package/src/state/__tests__/applyUpdatersToResults.ts +0 -40
- package/src/state/applyUpdatersToResults.ts +0 -29
- package/src/state/legacy-actions/createFetch.ts +0 -95
- package/src/state/legacy-actions/createReceive.ts +0 -68
- package/src/state/legacy-actions/createReceiveError.ts +0 -43
- package/src/state/legacy-actions/index.ts +0 -3
- package/src/state/reducerInstance.ts +0 -14
- package/ts3.4/compatibleActions.d.ts +0 -47
- package/ts3.4/controller/BaseController.d.ts +0 -170
- package/ts3.4/endpoint/index.d.ts +0 -3
- package/ts3.4/endpoint/shapes.d.ts +0 -25
- package/ts3.4/endpoint/types.d.ts +0 -45
- package/ts3.4/legacyActions.d.ts +0 -95
- package/ts3.4/next/Controller.d.ts +0 -14
- package/ts3.4/previousActions.d.ts +0 -94
- package/ts3.4/state/applyUpdatersToResults.d.ts +0 -13
- package/ts3.4/state/legacy-actions/createFetch.d.ts +0 -19
- package/ts3.4/state/legacy-actions/createReceive.d.ts +0 -14
- package/ts3.4/state/legacy-actions/createReceiveError.d.ts +0 -9
- package/ts3.4/state/legacy-actions/index.d.ts +0 -4
- package/ts3.4/state/reducerInstance.d.ts +0 -7
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { INVALID } from '@data-client/endpoint';
|
|
2
2
|
import {
|
|
3
3
|
ArticleResource,
|
|
4
|
-
ArticleResourceWithOtherListUrl,
|
|
5
4
|
PaginatedArticleResource,
|
|
6
5
|
Article,
|
|
7
6
|
PaginatedArticle,
|
|
8
|
-
UrlArticle,
|
|
9
7
|
} from '__tests__/new';
|
|
10
8
|
|
|
11
9
|
import { Controller } from '../..';
|
|
12
10
|
import {
|
|
13
|
-
|
|
11
|
+
SET_TYPE,
|
|
14
12
|
INVALIDATE_TYPE,
|
|
15
13
|
FETCH_TYPE,
|
|
16
14
|
RESET_TYPE,
|
|
17
15
|
GC_TYPE,
|
|
18
16
|
} from '../../actionTypes';
|
|
19
|
-
import
|
|
20
|
-
import {
|
|
17
|
+
import createSet from '../../controller/createSet';
|
|
18
|
+
import {
|
|
19
|
+
UpdateFunction,
|
|
20
|
+
State,
|
|
21
|
+
ActionTypes,
|
|
22
|
+
FetchAction,
|
|
23
|
+
SetAction,
|
|
24
|
+
ResetAction,
|
|
25
|
+
InvalidateAction,
|
|
26
|
+
GCAction,
|
|
27
|
+
} from '../../types';
|
|
21
28
|
import createReducer, { initialState } from '../reducer/createReducer';
|
|
22
29
|
|
|
23
|
-
type FetchAction = legacyActions.FetchAction;
|
|
24
|
-
type ReceiveAction<T extends string | number | object | null = any> =
|
|
25
|
-
legacyActions.ReceiveAction<T>;
|
|
26
|
-
type ResetAction = legacyActions.ResetAction;
|
|
27
|
-
type InvalidateAction = legacyActions.InvalidateAction;
|
|
28
|
-
type GCAction = legacyActions.GCAction;
|
|
29
|
-
|
|
30
30
|
describe('reducer', () => {
|
|
31
31
|
let reducer: (
|
|
32
32
|
state: State<unknown> | undefined,
|
|
@@ -40,11 +40,12 @@ describe('reducer', () => {
|
|
|
40
40
|
describe('singles', () => {
|
|
41
41
|
const id = 20;
|
|
42
42
|
const payload = { id, title: 'hi', content: 'this is the content' };
|
|
43
|
-
const action:
|
|
44
|
-
type:
|
|
43
|
+
const action: SetAction = {
|
|
44
|
+
type: SET_TYPE,
|
|
45
45
|
payload,
|
|
46
|
+
endpoint: ArticleResource.get,
|
|
46
47
|
meta: {
|
|
47
|
-
|
|
48
|
+
args: [{ id }],
|
|
48
49
|
key: ArticleResource.get.url({ id }),
|
|
49
50
|
date: 5000000000,
|
|
50
51
|
expiresAt: 5000500000,
|
|
@@ -158,9 +159,11 @@ describe('reducer', () => {
|
|
|
158
159
|
const spy = jest.spyOn(ExpiresSoon, 'expiresAt');
|
|
159
160
|
const localAction = {
|
|
160
161
|
...partialResultAction,
|
|
162
|
+
endpoint: (partialResultAction.endpoint as any).extend({
|
|
163
|
+
schema: ExpiresSoon,
|
|
164
|
+
}),
|
|
161
165
|
meta: {
|
|
162
166
|
...partialResultAction.meta,
|
|
163
|
-
schema: ExpiresSoon,
|
|
164
167
|
date: partialResultAction.meta.date * 2,
|
|
165
168
|
expiresAt: partialResultAction.meta.expiresAt * 2,
|
|
166
169
|
fetchedAt: partialResultAction.meta.date * 2,
|
|
@@ -191,31 +194,35 @@ describe('reducer', () => {
|
|
|
191
194
|
it('mutate should never change results', () => {
|
|
192
195
|
const id = 20;
|
|
193
196
|
const payload = { id, title: 'hi', content: 'this is the content' };
|
|
194
|
-
const action:
|
|
195
|
-
type:
|
|
197
|
+
const action: SetAction = {
|
|
198
|
+
type: SET_TYPE,
|
|
196
199
|
payload,
|
|
200
|
+
endpoint: ArticleResource.get,
|
|
197
201
|
meta: {
|
|
198
|
-
|
|
199
|
-
key: ArticleResource.
|
|
202
|
+
args: [{ id }],
|
|
203
|
+
key: ArticleResource.get.key(payload),
|
|
200
204
|
date: 0,
|
|
205
|
+
fetchedAt: 0,
|
|
201
206
|
expiresAt: 1000000000000,
|
|
202
207
|
},
|
|
203
208
|
};
|
|
204
209
|
const iniState = {
|
|
205
210
|
...initialState,
|
|
206
|
-
results: { abc: '5', [ArticleResource.
|
|
211
|
+
results: { abc: '5', [ArticleResource.get.key(payload)]: `${id}` },
|
|
207
212
|
};
|
|
208
213
|
const newState = reducer(iniState, action);
|
|
209
214
|
expect(newState.results).toStrictEqual(iniState.results);
|
|
210
215
|
});
|
|
211
216
|
it('purge should delete entities', () => {
|
|
212
217
|
const id = 20;
|
|
213
|
-
const action:
|
|
214
|
-
type:
|
|
218
|
+
const action: SetAction = {
|
|
219
|
+
type: SET_TYPE,
|
|
215
220
|
payload: { id },
|
|
221
|
+
endpoint: ArticleResource.delete,
|
|
216
222
|
meta: {
|
|
217
|
-
|
|
223
|
+
args: [{ id }],
|
|
218
224
|
key: ArticleResource.delete.key({ id }),
|
|
225
|
+
fetchedAt: 0,
|
|
219
226
|
date: 0,
|
|
220
227
|
expiresAt: 0,
|
|
221
228
|
},
|
|
@@ -238,203 +245,11 @@ describe('reducer', () => {
|
|
|
238
245
|
const newState = reducer(iniState, action);
|
|
239
246
|
expect(newState.results.abc).toBe(iniState.results.abc);
|
|
240
247
|
const expectedEntities = { ...iniState.entities[Article.key] };
|
|
241
|
-
expectedEntities['20'] =
|
|
248
|
+
expectedEntities['20'] = INVALID;
|
|
242
249
|
expect(newState.entities[Article.key]).toEqual(expectedEntities);
|
|
243
250
|
});
|
|
244
251
|
|
|
245
|
-
|
|
246
|
-
describe('Update on get (pagination use case)', () => {
|
|
247
|
-
const shape = PaginatedArticleResource.getList;
|
|
248
|
-
function makeOptimisticAction(
|
|
249
|
-
payload: {
|
|
250
|
-
results: Partial<PaginatedArticle>[];
|
|
251
|
-
},
|
|
252
|
-
updaters: {
|
|
253
|
-
[key: string]: UpdateFunction<
|
|
254
|
-
(typeof shape)['schema'],
|
|
255
|
-
(typeof shape)['schema']
|
|
256
|
-
>;
|
|
257
|
-
},
|
|
258
|
-
) {
|
|
259
|
-
return {
|
|
260
|
-
type: RECEIVE_TYPE,
|
|
261
|
-
payload,
|
|
262
|
-
meta: {
|
|
263
|
-
schema: PaginatedArticleResource.getList.schema,
|
|
264
|
-
key: PaginatedArticleResource.getList.key({
|
|
265
|
-
cursor: 2,
|
|
266
|
-
}),
|
|
267
|
-
updaters,
|
|
268
|
-
date: 5000000000,
|
|
269
|
-
expiresAt: 5000500000,
|
|
270
|
-
},
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
const insertAfterUpdater = <T extends { results?: string[] } | undefined>(
|
|
275
|
-
newPage: { results: string[] },
|
|
276
|
-
oldResults: T,
|
|
277
|
-
) => ({
|
|
278
|
-
...oldResults,
|
|
279
|
-
results: [...(oldResults?.results || []), ...newPage.results],
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
const insertBeforeUpdater = <
|
|
283
|
-
T extends { results?: string[] } | undefined,
|
|
284
|
-
>(
|
|
285
|
-
newPage: { results: string[] },
|
|
286
|
-
oldResults: T,
|
|
287
|
-
) => ({
|
|
288
|
-
...oldResults,
|
|
289
|
-
results: [...newPage.results, ...(oldResults?.results || [])],
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
const iniState: any = {
|
|
293
|
-
...initialState,
|
|
294
|
-
entities: {
|
|
295
|
-
[PaginatedArticle.key]: {
|
|
296
|
-
'10': PaginatedArticle.fromJS({ id: 10 }),
|
|
297
|
-
},
|
|
298
|
-
},
|
|
299
|
-
results: {
|
|
300
|
-
[PaginatedArticleResource.getList.key()]: { results: ['10'] },
|
|
301
|
-
},
|
|
302
|
-
};
|
|
303
|
-
|
|
304
|
-
it('should insert a new page of resources into a list request', () => {
|
|
305
|
-
const newState = reducer(
|
|
306
|
-
iniState,
|
|
307
|
-
makeOptimisticAction(
|
|
308
|
-
{ results: [{ id: 11 }, { id: 12 }] },
|
|
309
|
-
{
|
|
310
|
-
[PaginatedArticleResource.getList.key()]: insertAfterUpdater,
|
|
311
|
-
},
|
|
312
|
-
),
|
|
313
|
-
);
|
|
314
|
-
expect(
|
|
315
|
-
newState.results[PaginatedArticleResource.getList.key()],
|
|
316
|
-
).toStrictEqual({ results: ['10', '11', '12'] });
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
it('should insert correctly into the beginning of the list request', () => {
|
|
320
|
-
const newState = reducer(
|
|
321
|
-
iniState,
|
|
322
|
-
makeOptimisticAction(
|
|
323
|
-
{ results: [{ id: 11 }, { id: 12 }] },
|
|
324
|
-
{
|
|
325
|
-
[PaginatedArticleResource.getList.key()]: insertBeforeUpdater,
|
|
326
|
-
},
|
|
327
|
-
),
|
|
328
|
-
);
|
|
329
|
-
expect(
|
|
330
|
-
newState.results[PaginatedArticleResource.getList.key()],
|
|
331
|
-
).toStrictEqual({ results: ['11', '12', '10'] });
|
|
332
|
-
});
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
describe('rpc update on create', () => {
|
|
336
|
-
const createEndpoint = ArticleResource.create;
|
|
337
|
-
function makeOptimisticAction(
|
|
338
|
-
payload: Partial<Article>,
|
|
339
|
-
updaters: {
|
|
340
|
-
[key: string]: UpdateFunction<
|
|
341
|
-
(typeof createEndpoint)['schema'],
|
|
342
|
-
(typeof Article)[]
|
|
343
|
-
>;
|
|
344
|
-
},
|
|
345
|
-
) {
|
|
346
|
-
return {
|
|
347
|
-
type: RECEIVE_TYPE,
|
|
348
|
-
payload,
|
|
349
|
-
meta: {
|
|
350
|
-
schema: Article,
|
|
351
|
-
key: ArticleResource.create.key({}),
|
|
352
|
-
updaters,
|
|
353
|
-
date: 0,
|
|
354
|
-
expiresAt: 100000000000,
|
|
355
|
-
},
|
|
356
|
-
};
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
const insertAfterUpdater = (
|
|
360
|
-
result: string,
|
|
361
|
-
oldResults: string[] | undefined,
|
|
362
|
-
) => [...(oldResults || []), result];
|
|
363
|
-
|
|
364
|
-
const insertBeforeUpdater = (
|
|
365
|
-
result: string,
|
|
366
|
-
oldResults: string[] | undefined,
|
|
367
|
-
) => [result, ...(oldResults || [])];
|
|
368
|
-
|
|
369
|
-
const iniState: any = {
|
|
370
|
-
...initialState,
|
|
371
|
-
entities: {
|
|
372
|
-
[UrlArticle.key]: {
|
|
373
|
-
'10': UrlArticle.fromJS({ id: 10 }),
|
|
374
|
-
'21': UrlArticle.fromJS({ id: 21 }),
|
|
375
|
-
},
|
|
376
|
-
},
|
|
377
|
-
results: {
|
|
378
|
-
[ArticleResourceWithOtherListUrl.getList.key()]: ['10'],
|
|
379
|
-
[ArticleResourceWithOtherListUrl.otherList.key()]: ['21'],
|
|
380
|
-
},
|
|
381
|
-
};
|
|
382
|
-
|
|
383
|
-
it('it should run inserts for a simple resource after the existing list entities', () => {
|
|
384
|
-
const newState = reducer(
|
|
385
|
-
iniState,
|
|
386
|
-
makeOptimisticAction(
|
|
387
|
-
{ id: 11 },
|
|
388
|
-
{
|
|
389
|
-
[ArticleResource.getList.key()]: insertAfterUpdater,
|
|
390
|
-
},
|
|
391
|
-
),
|
|
392
|
-
);
|
|
393
|
-
expect(newState.results[ArticleResource.getList.key()]).toStrictEqual([
|
|
394
|
-
'10',
|
|
395
|
-
'11',
|
|
396
|
-
]);
|
|
397
|
-
});
|
|
398
|
-
|
|
399
|
-
it('it should run inserts for a simple resource before the existing list entities', () => {
|
|
400
|
-
const newState = reducer(
|
|
401
|
-
iniState,
|
|
402
|
-
makeOptimisticAction(
|
|
403
|
-
{ id: 11 },
|
|
404
|
-
{
|
|
405
|
-
[ArticleResource.getList.key()]: insertBeforeUpdater,
|
|
406
|
-
},
|
|
407
|
-
),
|
|
408
|
-
);
|
|
409
|
-
expect(newState.results[ArticleResource.getList.key()]).toStrictEqual([
|
|
410
|
-
'11',
|
|
411
|
-
'10',
|
|
412
|
-
]);
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
it('it runs inserts for multiple updaters', () => {
|
|
416
|
-
const newState = reducer(
|
|
417
|
-
iniState,
|
|
418
|
-
makeOptimisticAction(
|
|
419
|
-
{ id: 11 },
|
|
420
|
-
{
|
|
421
|
-
[ArticleResourceWithOtherListUrl.getList.key()]:
|
|
422
|
-
insertAfterUpdater,
|
|
423
|
-
[ArticleResourceWithOtherListUrl.otherList.key()]:
|
|
424
|
-
insertAfterUpdater,
|
|
425
|
-
},
|
|
426
|
-
),
|
|
427
|
-
);
|
|
428
|
-
expect(
|
|
429
|
-
newState.results[ArticleResourceWithOtherListUrl.getList.key()],
|
|
430
|
-
).toStrictEqual(['10', '11']);
|
|
431
|
-
expect(
|
|
432
|
-
newState.results[ArticleResourceWithOtherListUrl.otherList.key()],
|
|
433
|
-
).toStrictEqual(['21', '11']);
|
|
434
|
-
});
|
|
435
|
-
});
|
|
436
|
-
});
|
|
437
|
-
|
|
252
|
+
/* this is probably not needed and will eventually be deprecated
|
|
438
253
|
describe('endpoint.update', () => {
|
|
439
254
|
describe('Update on get (pagination use case)', () => {
|
|
440
255
|
const endpoint = PaginatedArticleResource.getList;
|
|
@@ -452,7 +267,7 @@ describe('reducer', () => {
|
|
|
452
267
|
};
|
|
453
268
|
|
|
454
269
|
it('should insert a new page of resources into a list request', () => {
|
|
455
|
-
const action =
|
|
270
|
+
const action = createSet(
|
|
456
271
|
{ results: [{ id: 11 }, { id: 12 }] },
|
|
457
272
|
{
|
|
458
273
|
...endpoint,
|
|
@@ -479,7 +294,7 @@ describe('reducer', () => {
|
|
|
479
294
|
it('should insert correctly into the beginning of the list request', () => {
|
|
480
295
|
const newState = reducer(
|
|
481
296
|
iniState,
|
|
482
|
-
|
|
297
|
+
createSet(
|
|
483
298
|
{ results: [{ id: 11 }, { id: 12 }] },
|
|
484
299
|
{
|
|
485
300
|
...endpoint,
|
|
@@ -519,7 +334,7 @@ describe('reducer', () => {
|
|
|
519
334
|
};
|
|
520
335
|
const newState = reducer(
|
|
521
336
|
iniState,
|
|
522
|
-
|
|
337
|
+
createSet(
|
|
523
338
|
{ results: [{ id: 11 }, { id: 12 }] },
|
|
524
339
|
{
|
|
525
340
|
...endpoint,
|
|
@@ -546,7 +361,7 @@ describe('reducer', () => {
|
|
|
546
361
|
});
|
|
547
362
|
});
|
|
548
363
|
});
|
|
549
|
-
})
|
|
364
|
+
});*/
|
|
550
365
|
|
|
551
366
|
it('invalidates resources correctly', () => {
|
|
552
367
|
const id = 20;
|
|
@@ -589,12 +404,14 @@ describe('reducer', () => {
|
|
|
589
404
|
it('should set error in meta for "receive"', () => {
|
|
590
405
|
const id = 20;
|
|
591
406
|
const error = new Error('hi');
|
|
592
|
-
const action:
|
|
593
|
-
type:
|
|
407
|
+
const action: SetAction = {
|
|
408
|
+
type: SET_TYPE,
|
|
594
409
|
payload: error,
|
|
410
|
+
endpoint: ArticleResource.get,
|
|
595
411
|
meta: {
|
|
596
|
-
|
|
412
|
+
args: [{ id }],
|
|
597
413
|
key: ArticleResource.get.key({ id }),
|
|
414
|
+
fetchedAt: 5000000000,
|
|
598
415
|
date: 5000000000,
|
|
599
416
|
expiresAt: 5000500000,
|
|
600
417
|
},
|
|
@@ -607,12 +424,14 @@ describe('reducer', () => {
|
|
|
607
424
|
it('should not modify state on error for "rpc"', () => {
|
|
608
425
|
const id = 20;
|
|
609
426
|
const error = new Error('hi');
|
|
610
|
-
const action:
|
|
611
|
-
type:
|
|
427
|
+
const action: SetAction = {
|
|
428
|
+
type: SET_TYPE,
|
|
612
429
|
payload: error,
|
|
430
|
+
endpoint: ArticleResource.get,
|
|
613
431
|
meta: {
|
|
614
|
-
|
|
432
|
+
args: [{ id }],
|
|
615
433
|
key: ArticleResource.get.key({ id }),
|
|
434
|
+
fetchedAt: 0,
|
|
616
435
|
date: 0,
|
|
617
436
|
expiresAt: 10000000000000000000,
|
|
618
437
|
},
|
|
@@ -626,12 +445,14 @@ describe('reducer', () => {
|
|
|
626
445
|
it('should not delete on error for "purge"', () => {
|
|
627
446
|
const id = 20;
|
|
628
447
|
const error = new Error('hi');
|
|
629
|
-
const action:
|
|
630
|
-
type:
|
|
448
|
+
const action: SetAction = {
|
|
449
|
+
type: SET_TYPE,
|
|
631
450
|
payload: error,
|
|
451
|
+
endpoint: ArticleResource.delete,
|
|
632
452
|
meta: {
|
|
633
|
-
|
|
453
|
+
args: [{ id }],
|
|
634
454
|
key: ArticleResource.delete.key({ id }),
|
|
455
|
+
fetchedAt: 0,
|
|
635
456
|
date: 0,
|
|
636
457
|
expiresAt: 0,
|
|
637
458
|
},
|
|
@@ -652,15 +473,17 @@ describe('reducer', () => {
|
|
|
652
473
|
expect(newState.entities).toBe(iniState.entities);
|
|
653
474
|
});
|
|
654
475
|
it('rest-hooks/fetch should console.warn()', () => {
|
|
655
|
-
const warnspy = jest
|
|
476
|
+
const warnspy = jest
|
|
477
|
+
.spyOn(global.console, 'warn')
|
|
478
|
+
.mockImplementation(() => {});
|
|
656
479
|
try {
|
|
657
480
|
const action: FetchAction = {
|
|
658
481
|
type: FETCH_TYPE,
|
|
659
482
|
payload: () => new Promise<any>(() => null),
|
|
483
|
+
endpoint: ArticleResource.get,
|
|
660
484
|
meta: {
|
|
661
|
-
|
|
485
|
+
args: [{ id: 5 }],
|
|
662
486
|
key: ArticleResource.get.url({ id: 5 }),
|
|
663
|
-
type: 'read' as const,
|
|
664
487
|
throttle: true,
|
|
665
488
|
reject: (v: any) => null,
|
|
666
489
|
resolve: (v: any) => null,
|
|
@@ -693,7 +516,7 @@ describe('reducer', () => {
|
|
|
693
516
|
describe('RESET', () => {
|
|
694
517
|
let warnspy: jest.SpyInstance;
|
|
695
518
|
beforeEach(() => {
|
|
696
|
-
warnspy = jest.spyOn(global.console, 'warn');
|
|
519
|
+
warnspy = jest.spyOn(global.console, 'warn').mockImplementation(() => {});
|
|
697
520
|
});
|
|
698
521
|
afterEach(() => {
|
|
699
522
|
warnspy.mockRestore();
|
|
@@ -724,67 +547,6 @@ describe('reducer', () => {
|
|
|
724
547
|
expect(newState.meta).toEqual({});
|
|
725
548
|
expect(newState.entities).toEqual({});
|
|
726
549
|
});
|
|
727
|
-
|
|
728
|
-
// TODO(breaking): Remove once Date support is removed from action
|
|
729
|
-
it('reset should delete all entries (legacy format)', () => {
|
|
730
|
-
const action: ResetAction = {
|
|
731
|
-
type: RESET_TYPE,
|
|
732
|
-
date: new Date(),
|
|
733
|
-
};
|
|
734
|
-
const iniState: any = {
|
|
735
|
-
...initialState,
|
|
736
|
-
entities: {
|
|
737
|
-
[Article.key]: {
|
|
738
|
-
'10': Article.fromJS({ id: 10 }),
|
|
739
|
-
'20': Article.fromJS({ id: 20 }),
|
|
740
|
-
'25': Article.fromJS({ id: 25 }),
|
|
741
|
-
},
|
|
742
|
-
[PaginatedArticle.key]: {
|
|
743
|
-
hi: PaginatedArticle.fromJS({ id: 5 }),
|
|
744
|
-
},
|
|
745
|
-
'5': undefined,
|
|
746
|
-
},
|
|
747
|
-
results: { abc: '20' },
|
|
748
|
-
};
|
|
749
|
-
const newState = reducer(iniState, action);
|
|
750
|
-
expect(newState.results).toEqual({});
|
|
751
|
-
expect(newState.meta).toEqual({});
|
|
752
|
-
expect(newState.entities).toEqual({});
|
|
753
|
-
});
|
|
754
|
-
|
|
755
|
-
it('reset without date should warn about deprecation', () => {
|
|
756
|
-
const action: any = {
|
|
757
|
-
type: RESET_TYPE,
|
|
758
|
-
};
|
|
759
|
-
const iniState: any = {
|
|
760
|
-
...initialState,
|
|
761
|
-
entities: {
|
|
762
|
-
[Article.key]: {
|
|
763
|
-
'10': Article.fromJS({ id: 10 }),
|
|
764
|
-
'20': Article.fromJS({ id: 20 }),
|
|
765
|
-
'25': Article.fromJS({ id: 25 }),
|
|
766
|
-
},
|
|
767
|
-
[PaginatedArticle.key]: {
|
|
768
|
-
hi: PaginatedArticle.fromJS({ id: 5 }),
|
|
769
|
-
},
|
|
770
|
-
'5': undefined,
|
|
771
|
-
},
|
|
772
|
-
results: { abc: '20' },
|
|
773
|
-
};
|
|
774
|
-
const newState = reducer(iniState, action);
|
|
775
|
-
expect(newState.results).toEqual({});
|
|
776
|
-
expect(newState.meta).toEqual({});
|
|
777
|
-
expect(newState.entities).toEqual({});
|
|
778
|
-
expect(newState.lastReset).toBeDefined();
|
|
779
|
-
expect(newState.lastReset).toBeGreaterThan(0);
|
|
780
|
-
expect(warnspy.mock.calls).toMatchInlineSnapshot(`
|
|
781
|
-
[
|
|
782
|
-
[
|
|
783
|
-
"rest-hooks/reset sent without 'date' member. This is deprecated. Please use createReset() action creator to ensure correct action shape.",
|
|
784
|
-
],
|
|
785
|
-
]
|
|
786
|
-
`);
|
|
787
|
-
});
|
|
788
550
|
});
|
|
789
551
|
|
|
790
552
|
describe('GC action', () => {
|
|
@@ -11,12 +11,12 @@ import {
|
|
|
11
11
|
INVALIDATEALL_TYPE,
|
|
12
12
|
} from '../../actionTypes.js';
|
|
13
13
|
import type Controller from '../../controller/Controller.js';
|
|
14
|
-
import type {
|
|
14
|
+
import type { ActionTypes, State } from '../../types.js';
|
|
15
15
|
|
|
16
16
|
export default function createReducer(controller: Controller): ReducerType {
|
|
17
17
|
return function reducer(
|
|
18
18
|
state: State<unknown> | undefined,
|
|
19
|
-
action:
|
|
19
|
+
action: ActionTypes,
|
|
20
20
|
): State<unknown> {
|
|
21
21
|
if (!state) state = initialState;
|
|
22
22
|
switch (action.type) {
|
|
@@ -44,15 +44,7 @@ export default function createReducer(controller: Controller): ReducerType {
|
|
|
44
44
|
return invalidateReducer(state, action);
|
|
45
45
|
|
|
46
46
|
case RESET_TYPE:
|
|
47
|
-
|
|
48
|
-
process.env.NODE_ENV !== 'production' &&
|
|
49
|
-
action.date === undefined
|
|
50
|
-
) {
|
|
51
|
-
console.warn(
|
|
52
|
-
`${RESET_TYPE} sent without 'date' member. This is deprecated. Please use createReset() action creator to ensure correct action shape.`,
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
return { ...initialState, lastReset: action.date ?? Date.now() };
|
|
47
|
+
return { ...initialState, lastReset: action.date };
|
|
56
48
|
|
|
57
49
|
default:
|
|
58
50
|
// A reducer must always return a valid state.
|
|
@@ -1,31 +1,18 @@
|
|
|
1
1
|
import createOptimistic from '../../controller/createOptimistic.js';
|
|
2
2
|
import type {
|
|
3
|
+
State,
|
|
3
4
|
ReceiveAction,
|
|
4
5
|
OptimisticAction,
|
|
5
6
|
FetchAction,
|
|
6
|
-
} from '../../
|
|
7
|
-
import type { State } from '../../types.js';
|
|
8
|
-
import { createReceive as legacyCreateReceive } from '../legacy-actions/index.js';
|
|
7
|
+
} from '../../types.js';
|
|
9
8
|
|
|
10
9
|
export function fetchReducer(state: State<unknown>, action: FetchAction) {
|
|
11
|
-
const optimisticResponse = action.meta.optimisticResponse;
|
|
12
|
-
const getOptimisticResponse = action.endpoint?.getOptimisticResponse;
|
|
13
10
|
let receiveAction: ReceiveAction | OptimisticAction;
|
|
14
11
|
|
|
15
|
-
if (
|
|
12
|
+
if (action.endpoint.getOptimisticResponse && action.endpoint.sideEffect) {
|
|
16
13
|
receiveAction = createOptimistic(action.endpoint, {
|
|
17
|
-
args: action.meta.args
|
|
18
|
-
fetchedAt:
|
|
19
|
-
typeof action.meta.createdAt !== 'number'
|
|
20
|
-
? action.meta.createdAt.getTime()
|
|
21
|
-
: action.meta.createdAt,
|
|
22
|
-
}) as any;
|
|
23
|
-
} /* istanbul ignore if */ else if (optimisticResponse) {
|
|
24
|
-
// TODO(breaking): this is no longer used, remove this branch
|
|
25
|
-
/* istanbul ignore next */
|
|
26
|
-
receiveAction = legacyCreateReceive(optimisticResponse, {
|
|
27
|
-
...action.meta,
|
|
28
|
-
dataExpiryLength: Infinity,
|
|
14
|
+
args: action.meta.args,
|
|
15
|
+
fetchedAt: action.meta.createdAt,
|
|
29
16
|
});
|
|
30
17
|
} else {
|
|
31
18
|
// If 'fetch' action reaches the reducer there are no middlewares installed to handle it
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { INVALIDATE_TYPE } from '../../actionTypes.js';
|
|
2
2
|
import type {
|
|
3
|
+
State,
|
|
3
4
|
InvalidateAllAction,
|
|
4
5
|
InvalidateAction,
|
|
5
|
-
} from '../../
|
|
6
|
-
import type { State } from '../../types.js';
|
|
6
|
+
} from '../../types.js';
|
|
7
7
|
|
|
8
8
|
export function invalidateReducer(
|
|
9
9
|
state: State<unknown>,
|
|
@@ -2,9 +2,7 @@ import { normalize } from '@data-client/normalizr';
|
|
|
2
2
|
|
|
3
3
|
import { OPTIMISTIC_TYPE } from '../../actionTypes.js';
|
|
4
4
|
import type Controller from '../../controller/Controller.js';
|
|
5
|
-
import type { ReceiveAction, OptimisticAction } from '../../
|
|
6
|
-
import type { State } from '../../types.js';
|
|
7
|
-
import applyUpdatersToResults from '../applyUpdatersToResults.js';
|
|
5
|
+
import type { State, ReceiveAction, OptimisticAction } from '../../types.js';
|
|
8
6
|
|
|
9
7
|
export function setReducer(
|
|
10
8
|
state: State<unknown>,
|
|
@@ -18,14 +16,14 @@ export function setReducer(
|
|
|
18
16
|
let payload: any;
|
|
19
17
|
// for true receives payload is contained in action
|
|
20
18
|
if (action.type === OPTIMISTIC_TYPE) {
|
|
19
|
+
// this should never happen
|
|
21
20
|
if (!action.endpoint.getOptimisticResponse) return state;
|
|
22
21
|
try {
|
|
23
22
|
// compute optimistic response based on current state
|
|
24
23
|
payload = action.endpoint.getOptimisticResponse.call(
|
|
25
24
|
action.endpoint,
|
|
26
25
|
controller.snapshot(state, action.meta.fetchedAt),
|
|
27
|
-
|
|
28
|
-
...(action.meta.args as any[]),
|
|
26
|
+
...action.meta.args,
|
|
29
27
|
);
|
|
30
28
|
} catch (e: any) {
|
|
31
29
|
// AbortOptimistic means 'do nothing', otherwise we count the exception as endpoint failure
|
|
@@ -39,30 +37,20 @@ export function setReducer(
|
|
|
39
37
|
}
|
|
40
38
|
const { result, entities, indexes, entityMeta } = normalize(
|
|
41
39
|
payload,
|
|
42
|
-
action.
|
|
40
|
+
action.endpoint.schema,
|
|
43
41
|
action.meta.args as any,
|
|
44
42
|
state.entities,
|
|
45
43
|
state.indexes,
|
|
46
44
|
state.entityMeta,
|
|
47
|
-
|
|
45
|
+
action.meta,
|
|
48
46
|
);
|
|
49
|
-
|
|
47
|
+
const results = {
|
|
50
48
|
...state.results,
|
|
51
49
|
[action.meta.key]: result,
|
|
52
50
|
};
|
|
53
51
|
try {
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
results,
|
|
57
|
-
result,
|
|
58
|
-
action.meta.updaters as any,
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
if (action.meta.update) {
|
|
62
|
-
const updaters = action.meta.update(
|
|
63
|
-
result,
|
|
64
|
-
...(action.meta.args || []),
|
|
65
|
-
);
|
|
52
|
+
if (action.endpoint.update) {
|
|
53
|
+
const updaters = action.endpoint.update(result, ...action.meta.args);
|
|
66
54
|
Object.keys(updaters).forEach(key => {
|
|
67
55
|
results[key] = updaters[key](results[key]);
|
|
68
56
|
});
|
|
@@ -97,7 +85,7 @@ export function setReducer(
|
|
|
97
85
|
error.message = `Error processing ${
|
|
98
86
|
action.meta.key
|
|
99
87
|
}\n\nFull Schema: ${JSON.stringify(
|
|
100
|
-
action.
|
|
88
|
+
action.endpoint.schema,
|
|
101
89
|
undefined,
|
|
102
90
|
2,
|
|
103
91
|
)}\n\nError:\n${error.message}`;
|
|
@@ -136,7 +124,7 @@ function reduceError(
|
|
|
136
124
|
date: action.meta.date,
|
|
137
125
|
error,
|
|
138
126
|
expiresAt: action.meta.expiresAt,
|
|
139
|
-
errorPolicy: action.
|
|
127
|
+
errorPolicy: action.endpoint.errorPolicy?.(error),
|
|
140
128
|
},
|
|
141
129
|
},
|
|
142
130
|
optimistic: filterOptimistic(state, action),
|