@data-client/core 0.13.5 → 0.14.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 +164 -191
- package/dist/index.umd.min.js +1 -1
- package/legacy/actions.js +1 -1
- package/legacy/controller/Controller.js +8 -17
- package/legacy/controller/actions/createExpireAll.js +8 -0
- package/legacy/controller/actions/createFetch.js +27 -0
- package/legacy/controller/actions/createInvalidate.js +10 -0
- package/legacy/controller/actions/createInvalidateAll.js +8 -0
- package/legacy/controller/actions/createMeta.js +9 -0
- package/legacy/controller/actions/createOptimistic.js +17 -0
- package/legacy/controller/actions/createReset.js +8 -0
- package/legacy/controller/actions/createSet.js +17 -0
- package/legacy/controller/actions/createSetResponse.js +26 -0
- package/legacy/controller/actions/createSubscription.js +22 -0
- package/legacy/controller/actions/index.js +11 -0
- package/legacy/index.js +3 -4
- package/legacy/manager/LogoutManager.js +2 -2
- package/legacy/manager/NetworkManager.js +27 -29
- package/legacy/manager/PollingSubscription.js +3 -3
- package/legacy/manager/SubscriptionManager.js +3 -3
- package/legacy/state/reducer/fetchReducer.js +6 -10
- package/legacy/state/reducer/invalidateReducer.js +2 -2
- package/legacy/state/reducer/setReducer.js +3 -3
- package/legacy/state/reducer/setResponseReducer.js +17 -17
- package/legacy/types.js +1 -1
- package/lib/actions.d.ts +34 -40
- package/lib/actions.d.ts.map +1 -1
- package/lib/actions.js +1 -1
- package/lib/controller/Controller.d.ts +1 -1
- package/lib/controller/Controller.d.ts.map +1 -1
- package/lib/controller/Controller.js +8 -17
- package/lib/controller/actions/createExpireAll.d.ts +3 -0
- package/lib/controller/actions/createExpireAll.d.ts.map +1 -0
- package/lib/controller/actions/createExpireAll.js +8 -0
- package/lib/controller/{createFetch.d.ts → actions/createFetch.d.ts} +3 -3
- package/lib/controller/actions/createFetch.d.ts.map +1 -0
- package/lib/controller/actions/createFetch.js +27 -0
- package/lib/controller/actions/createInvalidate.d.ts +6 -0
- package/lib/controller/actions/createInvalidate.d.ts.map +1 -0
- package/lib/controller/actions/createInvalidate.js +10 -0
- package/lib/controller/actions/createInvalidateAll.d.ts +3 -0
- package/lib/controller/actions/createInvalidateAll.d.ts.map +1 -0
- package/lib/controller/actions/createInvalidateAll.js +8 -0
- package/lib/controller/actions/createMeta.d.ts +3 -0
- package/lib/controller/actions/createMeta.d.ts.map +1 -0
- package/lib/controller/actions/createMeta.js +9 -0
- package/lib/controller/actions/createOptimistic.d.ts +7 -0
- package/lib/controller/actions/createOptimistic.d.ts.map +1 -0
- package/lib/controller/actions/createOptimistic.js +17 -0
- package/lib/controller/actions/createReset.d.ts +3 -0
- package/lib/controller/actions/createReset.d.ts.map +1 -0
- package/lib/controller/actions/createReset.js +8 -0
- package/lib/controller/{createSet.d.ts → actions/createSet.d.ts} +2 -2
- package/lib/controller/actions/createSet.d.ts.map +1 -0
- package/lib/controller/actions/createSet.js +17 -0
- package/lib/controller/{createSetResponse.d.ts → actions/createSetResponse.d.ts} +4 -4
- package/lib/controller/actions/createSetResponse.d.ts.map +1 -0
- package/lib/controller/actions/createSetResponse.js +26 -0
- package/lib/controller/{createSubscription.d.ts → actions/createSubscription.d.ts} +1 -1
- package/lib/controller/actions/createSubscription.d.ts.map +1 -0
- package/lib/controller/actions/createSubscription.js +22 -0
- package/lib/controller/actions/index.d.ts +11 -0
- package/lib/controller/actions/index.d.ts.map +1 -0
- package/lib/controller/actions/index.js +11 -0
- package/lib/index.d.ts +1 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -4
- package/lib/manager/LogoutManager.js +2 -2
- package/lib/manager/NetworkManager.d.ts +2 -2
- package/lib/manager/NetworkManager.d.ts.map +1 -1
- package/lib/manager/NetworkManager.js +27 -29
- package/lib/manager/PollingSubscription.js +3 -3
- package/lib/manager/SubscriptionManager.js +3 -3
- package/lib/state/reducer/expireReducer.d.ts +2 -2
- package/lib/state/reducer/fetchReducer.d.ts.map +1 -1
- package/lib/state/reducer/fetchReducer.js +8 -12
- package/lib/state/reducer/invalidateReducer.d.ts +2 -2
- package/lib/state/reducer/invalidateReducer.js +2 -2
- package/lib/state/reducer/setReducer.d.ts.map +1 -1
- package/lib/state/reducer/setReducer.js +3 -3
- package/lib/state/reducer/setResponseReducer.d.ts.map +1 -1
- package/lib/state/reducer/setResponseReducer.js +17 -17
- package/lib/types.d.ts +3 -3
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js +1 -1
- package/package.json +2 -2
- package/src/actions.ts +36 -42
- package/src/controller/Controller.ts +15 -22
- package/src/controller/__tests__/Controller.ts +2 -2
- package/src/controller/actions/createExpireAll.ts +11 -0
- package/src/controller/{createFetch.ts → actions/createFetch.ts} +9 -13
- package/src/controller/actions/createInvalidate.ts +14 -0
- package/src/controller/actions/createInvalidateAll.ts +11 -0
- package/src/controller/actions/createMeta.ts +13 -0
- package/src/controller/actions/createOptimistic.ts +32 -0
- package/src/controller/actions/createReset.ts +9 -0
- package/src/controller/actions/createSet.ts +31 -0
- package/src/controller/{createSetResponse.ts → actions/createSetResponse.ts} +17 -23
- package/src/controller/{createSubscription.ts → actions/createSubscription.ts} +6 -10
- package/src/controller/actions/index.ts +13 -0
- package/src/index.ts +1 -3
- package/src/manager/LogoutManager.ts +1 -1
- package/src/manager/NetworkManager.ts +26 -27
- package/src/manager/PollingSubscription.ts +2 -2
- package/src/manager/SubscriptionManager.ts +2 -2
- package/src/manager/__tests__/__snapshots__/pollingSubscription.ts.snap +4 -10
- package/src/manager/__tests__/logoutManager.ts +1 -1
- package/src/manager/__tests__/networkManager.ts +37 -25
- package/src/manager/__tests__/pollingSubscription.ts +3 -3
- package/src/manager/__tests__/subscriptionManager.ts +22 -27
- package/src/state/__tests__/reducer.ts +42 -45
- package/src/state/reducer/fetchReducer.ts +12 -18
- package/src/state/reducer/invalidateReducer.ts +1 -1
- package/src/state/reducer/setReducer.ts +4 -10
- package/src/state/reducer/setResponseReducer.ts +18 -20
- package/src/types.ts +4 -4
- package/ts3.4/actions.d.ts +35 -41
- package/ts3.4/controller/Controller.d.ts +1 -1
- package/ts3.4/controller/actions/createExpireAll.d.ts +3 -0
- package/ts3.4/controller/{createFetch.d.ts → actions/createFetch.d.ts} +3 -3
- package/ts3.4/controller/{createInvalidate.d.ts → actions/createInvalidate.d.ts} +2 -2
- package/ts3.4/controller/actions/createInvalidateAll.d.ts +3 -0
- package/ts3.4/controller/actions/createMeta.d.ts +3 -0
- package/ts3.4/controller/actions/createOptimistic.d.ts +9 -0
- package/ts3.4/controller/actions/createReset.d.ts +3 -0
- package/ts3.4/controller/{createSet.d.ts → actions/createSet.d.ts} +2 -2
- package/ts3.4/controller/{createSetResponse.d.ts → actions/createSetResponse.d.ts} +4 -4
- package/ts3.4/controller/{createSubscription.d.ts → actions/createSubscription.d.ts} +1 -1
- package/ts3.4/controller/actions/index.d.ts +11 -0
- package/ts3.4/index.d.ts +2 -3
- package/ts3.4/manager/NetworkManager.d.ts +2 -2
- package/ts3.4/state/reducer/expireReducer.d.ts +2 -2
- package/ts3.4/state/reducer/invalidateReducer.d.ts +2 -2
- package/ts3.4/types.d.ts +3 -3
- package/legacy/controller/createExpireAll.js +0 -8
- package/legacy/controller/createFetch.js +0 -31
- package/legacy/controller/createInvalidate.js +0 -12
- package/legacy/controller/createInvalidateAll.js +0 -8
- package/legacy/controller/createOptimistic.js +0 -27
- package/legacy/controller/createReset.js +0 -8
- package/legacy/controller/createSet.js +0 -28
- package/legacy/controller/createSetResponse.js +0 -32
- package/legacy/controller/createSubscription.js +0 -26
- package/lib/controller/createExpireAll.d.ts +0 -3
- package/lib/controller/createExpireAll.d.ts.map +0 -1
- package/lib/controller/createExpireAll.js +0 -8
- package/lib/controller/createFetch.d.ts.map +0 -1
- package/lib/controller/createFetch.js +0 -31
- package/lib/controller/createInvalidate.d.ts +0 -6
- package/lib/controller/createInvalidate.d.ts.map +0 -1
- package/lib/controller/createInvalidate.js +0 -12
- package/lib/controller/createInvalidateAll.d.ts +0 -3
- package/lib/controller/createInvalidateAll.d.ts.map +0 -1
- package/lib/controller/createInvalidateAll.js +0 -8
- package/lib/controller/createOptimistic.d.ts +0 -10
- package/lib/controller/createOptimistic.d.ts.map +0 -1
- package/lib/controller/createOptimistic.js +0 -27
- package/lib/controller/createReset.d.ts +0 -3
- package/lib/controller/createReset.d.ts.map +0 -1
- package/lib/controller/createReset.js +0 -8
- package/lib/controller/createSet.d.ts.map +0 -1
- package/lib/controller/createSet.js +0 -28
- package/lib/controller/createSetResponse.d.ts.map +0 -1
- package/lib/controller/createSetResponse.js +0 -32
- package/lib/controller/createSubscription.d.ts.map +0 -1
- package/lib/controller/createSubscription.js +0 -26
- package/src/controller/createExpireAll.ts +0 -11
- package/src/controller/createInvalidate.ts +0 -16
- package/src/controller/createInvalidateAll.ts +0 -11
- package/src/controller/createOptimistic.ts +0 -41
- package/src/controller/createReset.ts +0 -9
- package/src/controller/createSet.ts +0 -43
- package/ts3.4/controller/createExpireAll.d.ts +0 -3
- package/ts3.4/controller/createInvalidateAll.d.ts +0 -3
- package/ts3.4/controller/createOptimistic.d.ts +0 -12
- package/ts3.4/controller/createReset.d.ts +0 -3
|
@@ -2,11 +2,11 @@ import { Endpoint } from '@data-client/endpoint';
|
|
|
2
2
|
import { Article, ArticleResource } from '__tests__/new';
|
|
3
3
|
|
|
4
4
|
import { SET_RESPONSE_TYPE } from '../../actionTypes';
|
|
5
|
+
import { createFetch } from '../../controller/actions';
|
|
5
6
|
import Controller from '../../controller/Controller';
|
|
6
|
-
import createFetch from '../../controller/createFetch';
|
|
7
7
|
import NetworkManager from '../../manager/NetworkManager';
|
|
8
8
|
import { initialState } from '../../state/reducer/createReducer';
|
|
9
|
-
import { Middleware } from '../../types';
|
|
9
|
+
import { Middleware, SetResponseAction } from '../../types';
|
|
10
10
|
|
|
11
11
|
describe('NetworkManager', () => {
|
|
12
12
|
const manager = new NetworkManager();
|
|
@@ -154,18 +154,21 @@ describe('NetworkManager', () => {
|
|
|
154
154
|
|
|
155
155
|
middleware(API)(next)(fetchResolveAction);
|
|
156
156
|
|
|
157
|
-
const
|
|
157
|
+
const response = await fetchResolveAction.endpoint(
|
|
158
|
+
...fetchResolveAction.args,
|
|
159
|
+
);
|
|
158
160
|
|
|
159
161
|
// mutations resolve before dispatch, so we must wait for next tick to see set
|
|
160
162
|
await new Promise(resolve => setTimeout(resolve, 0));
|
|
161
163
|
|
|
162
|
-
const action = {
|
|
164
|
+
const action: SetResponseAction = {
|
|
163
165
|
type: SET_RESPONSE_TYPE,
|
|
164
166
|
endpoint: fetchResolveAction.endpoint,
|
|
165
|
-
|
|
167
|
+
response,
|
|
168
|
+
args: fetchResolveAction.args,
|
|
169
|
+
key: fetchResolveAction.key,
|
|
170
|
+
error: expect.anything(),
|
|
166
171
|
meta: {
|
|
167
|
-
args: fetchResolveAction.meta.args,
|
|
168
|
-
key: fetchResolveAction.meta.key,
|
|
169
172
|
date: expect.any(Number),
|
|
170
173
|
expiresAt: expect.any(Number),
|
|
171
174
|
fetchedAt: expect.any(Number),
|
|
@@ -187,18 +190,21 @@ describe('NetworkManager', () => {
|
|
|
187
190
|
|
|
188
191
|
middleware(API)(next)(fetchSetWithUpdatersAction);
|
|
189
192
|
|
|
190
|
-
const
|
|
193
|
+
const response = await fetchSetWithUpdatersAction.endpoint(
|
|
194
|
+
...fetchSetWithUpdatersAction.args,
|
|
195
|
+
);
|
|
191
196
|
|
|
192
197
|
// mutations resolve before dispatch, so we must wait for next tick to see set
|
|
193
198
|
await new Promise(resolve => setTimeout(resolve, 0));
|
|
194
199
|
|
|
195
|
-
const action = {
|
|
200
|
+
const action: SetResponseAction = {
|
|
196
201
|
type: SET_RESPONSE_TYPE,
|
|
197
202
|
endpoint: fetchSetWithUpdatersAction.endpoint,
|
|
198
|
-
|
|
203
|
+
response,
|
|
204
|
+
args: fetchSetWithUpdatersAction.args,
|
|
205
|
+
key: fetchSetWithUpdatersAction.key,
|
|
206
|
+
error: expect.anything(),
|
|
199
207
|
meta: {
|
|
200
|
-
args: fetchSetWithUpdatersAction.meta.args,
|
|
201
|
-
key: fetchSetWithUpdatersAction.meta.key,
|
|
202
208
|
date: expect.any(Number),
|
|
203
209
|
expiresAt: expect.any(Number),
|
|
204
210
|
fetchedAt: expect.any(Number),
|
|
@@ -220,18 +226,21 @@ describe('NetworkManager', () => {
|
|
|
220
226
|
|
|
221
227
|
middleware(API)(next)(fetchRpcWithUpdatersAction);
|
|
222
228
|
|
|
223
|
-
const
|
|
229
|
+
const response = await fetchRpcWithUpdatersAction.endpoint(
|
|
230
|
+
...fetchRpcWithUpdatersAction.args,
|
|
231
|
+
);
|
|
224
232
|
|
|
225
233
|
// mutations resolve before dispatch, so we must wait for next tick to see set
|
|
226
234
|
await new Promise(resolve => setTimeout(resolve, 0));
|
|
227
235
|
|
|
228
|
-
const action = {
|
|
236
|
+
const action: SetResponseAction = {
|
|
229
237
|
type: SET_RESPONSE_TYPE,
|
|
230
238
|
endpoint: fetchRpcWithUpdatersAction.endpoint,
|
|
231
|
-
|
|
239
|
+
response,
|
|
240
|
+
args: fetchRpcWithUpdatersAction.args,
|
|
241
|
+
key: fetchRpcWithUpdatersAction.key,
|
|
242
|
+
error: expect.anything(),
|
|
232
243
|
meta: {
|
|
233
|
-
args: fetchRpcWithUpdatersAction.meta.args,
|
|
234
|
-
key: fetchRpcWithUpdatersAction.meta.key,
|
|
235
244
|
date: expect.any(Number),
|
|
236
245
|
expiresAt: expect.any(Number),
|
|
237
246
|
fetchedAt: expect.any(Number),
|
|
@@ -253,7 +262,9 @@ describe('NetworkManager', () => {
|
|
|
253
262
|
|
|
254
263
|
middleware(API)(next)(fetchRpcWithUpdatersAndOptimisticAction);
|
|
255
264
|
|
|
256
|
-
const
|
|
265
|
+
const response = await fetchRpcWithUpdatersAndOptimisticAction.endpoint(
|
|
266
|
+
...fetchRpcWithUpdatersAndOptimisticAction.args,
|
|
267
|
+
);
|
|
257
268
|
|
|
258
269
|
expect(next).toHaveBeenCalled();
|
|
259
270
|
// mutations resolve before dispatch, so we must wait for next tick to see set
|
|
@@ -261,10 +272,11 @@ describe('NetworkManager', () => {
|
|
|
261
272
|
expect(dispatch).toHaveBeenCalledWith({
|
|
262
273
|
type: SET_RESPONSE_TYPE,
|
|
263
274
|
endpoint: fetchRpcWithUpdatersAndOptimisticAction.endpoint,
|
|
264
|
-
|
|
275
|
+
response,
|
|
276
|
+
args: fetchRpcWithUpdatersAndOptimisticAction.args,
|
|
277
|
+
key: fetchRpcWithUpdatersAndOptimisticAction.key,
|
|
278
|
+
error: expect.anything(),
|
|
265
279
|
meta: {
|
|
266
|
-
args: fetchRpcWithUpdatersAndOptimisticAction.meta.args,
|
|
267
|
-
key: fetchRpcWithUpdatersAndOptimisticAction.meta.key,
|
|
268
280
|
date: expect.any(Number),
|
|
269
281
|
expiresAt: expect.any(Number),
|
|
270
282
|
fetchedAt: expect.any(Number),
|
|
@@ -286,7 +298,7 @@ describe('NetworkManager', () => {
|
|
|
286
298
|
endpoint: detailEndpoint.extend({ dataExpiryLength: 314 }),
|
|
287
299
|
});
|
|
288
300
|
|
|
289
|
-
await fetchResolveAction.
|
|
301
|
+
await fetchResolveAction.endpoint(...fetchResolveAction.args);
|
|
290
302
|
|
|
291
303
|
expect(dispatch).toHaveBeenCalled();
|
|
292
304
|
const { meta } = dispatch.mock.calls[0][0];
|
|
@@ -307,7 +319,7 @@ describe('NetworkManager', () => {
|
|
|
307
319
|
endpoint: detailEndpoint.extend({ dataExpiryLength: undefined }),
|
|
308
320
|
});
|
|
309
321
|
|
|
310
|
-
await fetchResolveAction.
|
|
322
|
+
await fetchResolveAction.endpoint(...fetchResolveAction.args);
|
|
311
323
|
|
|
312
324
|
expect(dispatch).toHaveBeenCalled();
|
|
313
325
|
const { meta } = dispatch.mock.calls[0][0];
|
|
@@ -330,9 +342,9 @@ describe('NetworkManager', () => {
|
|
|
330
342
|
expect(next).not.toHaveBeenCalled();
|
|
331
343
|
expect(dispatch).toHaveBeenCalledWith({
|
|
332
344
|
type: SET_RESPONSE_TYPE,
|
|
333
|
-
|
|
345
|
+
response: error,
|
|
346
|
+
key: fetchRejectAction.key,
|
|
334
347
|
meta: {
|
|
335
|
-
key: fetchRejectAction.meta.key,
|
|
336
348
|
date: expect.any(Number),
|
|
337
349
|
expiresAt: expect.any(Number),
|
|
338
350
|
},
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Endpoint } from '@data-client/endpoint';
|
|
2
2
|
import { Article, PollingArticleResource } from '__tests__/new';
|
|
3
3
|
|
|
4
|
+
import { createSubscription } from '../../controller/actions/createSubscription';
|
|
4
5
|
import Controller from '../../controller/Controller';
|
|
5
|
-
import { createSubscription } from '../../controller/createSubscription';
|
|
6
6
|
import { initialState } from '../../state/reducer/createReducer';
|
|
7
7
|
import ConnectionListener from '../ConnectionListener';
|
|
8
8
|
import DefaultConnectionListener from '../DefaultConnectionListener';
|
|
@@ -178,13 +178,13 @@ describe('PollingSubscription', () => {
|
|
|
178
178
|
jest.advanceTimersByTime(5000);
|
|
179
179
|
expect(dispatch.mock.calls.length).toBe(1);
|
|
180
180
|
dispatch.mock.calls[0].forEach((element: any) => {
|
|
181
|
-
delete element?.meta?.
|
|
181
|
+
delete element?.meta?.fetchedAt;
|
|
182
182
|
});
|
|
183
183
|
expect(dispatch.mock.calls[0]).toMatchSnapshot();
|
|
184
184
|
jest.advanceTimersByTime(5000);
|
|
185
185
|
expect(dispatch.mock.calls.length).toBe(2);
|
|
186
186
|
dispatch.mock.calls[1].forEach((element: any) => {
|
|
187
|
-
delete element?.meta?.
|
|
187
|
+
delete element?.meta?.fetchedAt;
|
|
188
188
|
});
|
|
189
189
|
|
|
190
190
|
expect(dispatch.mock.calls[1]).toMatchSnapshot();
|
|
@@ -48,32 +48,28 @@ describe('SubscriptionManager', () => {
|
|
|
48
48
|
|
|
49
49
|
describe('middleware', () => {
|
|
50
50
|
function createSubscribeAction(
|
|
51
|
-
|
|
51
|
+
response: Record<string, any>,
|
|
52
52
|
reject = false,
|
|
53
53
|
): SubscribeAction {
|
|
54
54
|
const fetch =
|
|
55
55
|
reject ?
|
|
56
56
|
() => Promise.reject(new Error('Failed'))
|
|
57
|
-
: () => Promise.resolve(
|
|
57
|
+
: () => Promise.resolve(response);
|
|
58
58
|
return {
|
|
59
59
|
type: SUBSCRIBE_TYPE,
|
|
60
|
-
endpoint: PollingArticleResource.get,
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
args: [{ id: payload.id }],
|
|
64
|
-
},
|
|
60
|
+
endpoint: PollingArticleResource.get.extend({ fetch }),
|
|
61
|
+
args: [{ id: response.id }],
|
|
62
|
+
key: PollingArticleResource.get.key({ id: response.id }),
|
|
65
63
|
};
|
|
66
64
|
}
|
|
67
65
|
function createUnsubscribeAction(
|
|
68
|
-
|
|
66
|
+
response: Record<string, any>,
|
|
69
67
|
): UnsubscribeAction {
|
|
70
68
|
return {
|
|
71
69
|
type: UNSUBSCRIBE_TYPE,
|
|
72
70
|
endpoint: PollingArticleResource.get,
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
args: [{ id: payload.id }],
|
|
76
|
-
},
|
|
71
|
+
key: PollingArticleResource.get.key({ id: response.id }),
|
|
72
|
+
args: [{ id: response.id }],
|
|
77
73
|
};
|
|
78
74
|
}
|
|
79
75
|
|
|
@@ -93,14 +89,14 @@ describe('SubscriptionManager', () => {
|
|
|
93
89
|
middleware(API)(next)(action);
|
|
94
90
|
|
|
95
91
|
expect(next).not.toHaveBeenCalled();
|
|
96
|
-
expect((manager as any).subscriptions[action.
|
|
92
|
+
expect((manager as any).subscriptions[action.key]).toBeDefined();
|
|
97
93
|
});
|
|
98
94
|
it('subscribe should add a subscription (no frequency)', () => {
|
|
99
95
|
const action = createSubscribeAction({ id: 597 });
|
|
100
96
|
middleware(API)(next)(action);
|
|
101
97
|
|
|
102
98
|
expect(next).not.toHaveBeenCalled();
|
|
103
|
-
expect((manager as any).subscriptions[action.
|
|
99
|
+
expect((manager as any).subscriptions[action.key]).toBeDefined();
|
|
104
100
|
});
|
|
105
101
|
|
|
106
102
|
it('subscribe with same should call subscription.add', () => {
|
|
@@ -108,20 +104,20 @@ describe('SubscriptionManager', () => {
|
|
|
108
104
|
middleware(API)(next)(action);
|
|
109
105
|
|
|
110
106
|
expect(
|
|
111
|
-
(manager as any).subscriptions[action.
|
|
107
|
+
(manager as any).subscriptions[action.key].add.mock.calls.length,
|
|
112
108
|
).toBe(1);
|
|
113
109
|
middleware(API)(next)(action);
|
|
114
110
|
expect(
|
|
115
|
-
(manager as any).subscriptions[action.
|
|
111
|
+
(manager as any).subscriptions[action.key].add.mock.calls.length,
|
|
116
112
|
).toBe(2);
|
|
117
113
|
});
|
|
118
114
|
it('subscribe with another should create another', () => {
|
|
119
115
|
const action = createSubscribeAction({ id: 7, title: 'four cakes' });
|
|
120
116
|
middleware(API)(next)(action);
|
|
121
117
|
|
|
122
|
-
expect((manager as any).subscriptions[action.
|
|
118
|
+
expect((manager as any).subscriptions[action.key]).toBeDefined();
|
|
123
119
|
expect(
|
|
124
|
-
(manager as any).subscriptions[action.
|
|
120
|
+
(manager as any).subscriptions[action.key].add.mock.calls.length,
|
|
125
121
|
).toBe(0);
|
|
126
122
|
});
|
|
127
123
|
it('subscribe with another should not call previous', () => {
|
|
@@ -134,13 +130,13 @@ describe('SubscriptionManager', () => {
|
|
|
134
130
|
|
|
135
131
|
it('unsubscribe should delete when remove returns true', () => {
|
|
136
132
|
const action = createUnsubscribeAction({ id: 7, title: 'four cakes' });
|
|
137
|
-
(manager as any).subscriptions[action.
|
|
133
|
+
(manager as any).subscriptions[action.key].remove.mockImplementation(
|
|
138
134
|
() => true,
|
|
139
135
|
);
|
|
140
136
|
|
|
141
137
|
middleware(API)(next)(action);
|
|
142
138
|
|
|
143
|
-
expect((manager as any).subscriptions[action.
|
|
139
|
+
expect((manager as any).subscriptions[action.key]).not.toBeDefined();
|
|
144
140
|
});
|
|
145
141
|
|
|
146
142
|
it('unsubscribe should delete when remove returns true (no frequency)', () => {
|
|
@@ -149,27 +145,26 @@ describe('SubscriptionManager', () => {
|
|
|
149
145
|
);
|
|
150
146
|
|
|
151
147
|
const action = createUnsubscribeAction({ id: 50, title: 'four cakes' });
|
|
152
|
-
(manager as any).subscriptions[action.
|
|
148
|
+
(manager as any).subscriptions[action.key].remove.mockImplementation(
|
|
153
149
|
() => true,
|
|
154
150
|
);
|
|
155
151
|
|
|
156
152
|
middleware(API)(next)(action);
|
|
157
153
|
|
|
158
|
-
expect((manager as any).subscriptions[action.
|
|
154
|
+
expect((manager as any).subscriptions[action.key]).not.toBeDefined();
|
|
159
155
|
});
|
|
160
156
|
|
|
161
157
|
it('unsubscribe should not delete when remove returns false', () => {
|
|
162
158
|
const action = createUnsubscribeAction({ id: 5, title: 'four cakes' });
|
|
163
|
-
(manager as any).subscriptions[action.
|
|
159
|
+
(manager as any).subscriptions[action.key].remove.mockImplementation(
|
|
164
160
|
() => false,
|
|
165
161
|
);
|
|
166
162
|
|
|
167
163
|
middleware(API)(next)(action);
|
|
168
164
|
|
|
169
|
-
expect((manager as any).subscriptions[action.
|
|
165
|
+
expect((manager as any).subscriptions[action.key]).toBeDefined();
|
|
170
166
|
expect(
|
|
171
|
-
(manager as any).subscriptions[action.
|
|
172
|
-
.length,
|
|
167
|
+
(manager as any).subscriptions[action.key].remove.mock.calls.length,
|
|
173
168
|
).toBe(1);
|
|
174
169
|
});
|
|
175
170
|
|
|
@@ -181,7 +176,7 @@ describe('SubscriptionManager', () => {
|
|
|
181
176
|
|
|
182
177
|
middleware(API)(next)(action);
|
|
183
178
|
|
|
184
|
-
expect((manager as any).subscriptions[action.
|
|
179
|
+
expect((manager as any).subscriptions[action.key]).not.toBeDefined();
|
|
185
180
|
|
|
186
181
|
expect(spy.mock.calls[0]).toMatchInlineSnapshot(`
|
|
187
182
|
[
|
|
@@ -34,22 +34,22 @@ describe('reducer', () => {
|
|
|
34
34
|
|
|
35
35
|
describe('singles', () => {
|
|
36
36
|
const id = 20;
|
|
37
|
-
const
|
|
37
|
+
const response = { id, title: 'hi', content: 'this is the content' };
|
|
38
38
|
const action: SetResponseAction = {
|
|
39
39
|
type: SET_RESPONSE_TYPE,
|
|
40
|
-
|
|
40
|
+
response,
|
|
41
41
|
endpoint: ArticleResource.get,
|
|
42
|
+
args: [{ id }],
|
|
43
|
+
key: ArticleResource.get.url({ id }),
|
|
42
44
|
meta: {
|
|
43
|
-
args: [{ id }],
|
|
44
|
-
key: ArticleResource.get.url({ id }),
|
|
45
45
|
date: 5000000000,
|
|
46
46
|
expiresAt: 5000500000,
|
|
47
47
|
fetchedAt: 5000000000,
|
|
48
48
|
},
|
|
49
49
|
};
|
|
50
|
-
const partialResultAction = {
|
|
50
|
+
const partialResultAction: SetResponseAction = {
|
|
51
51
|
...action,
|
|
52
|
-
|
|
52
|
+
response: { id, title: 'hello' },
|
|
53
53
|
};
|
|
54
54
|
const iniState = initialState;
|
|
55
55
|
let newState = initialState;
|
|
@@ -59,7 +59,7 @@ describe('reducer', () => {
|
|
|
59
59
|
});
|
|
60
60
|
it('should overwrite existing entity', () => {
|
|
61
61
|
const getEntity = (state: any): Article =>
|
|
62
|
-
state.entities[Article.key][`${Article.pk(action.
|
|
62
|
+
state.entities[Article.key][`${Article.pk(action.response)}`];
|
|
63
63
|
const prevEntity = getEntity(newState);
|
|
64
64
|
expect(prevEntity).toBeDefined();
|
|
65
65
|
const nextState = reducer(newState, action);
|
|
@@ -69,7 +69,7 @@ describe('reducer', () => {
|
|
|
69
69
|
});
|
|
70
70
|
it('should merge partial entity with existing entity', () => {
|
|
71
71
|
const getEntity = (state: any): Article =>
|
|
72
|
-
state.entities[Article.key][`${Article.pk(action.
|
|
72
|
+
state.entities[Article.key][`${Article.pk(action.response)}`];
|
|
73
73
|
const prevEntity = getEntity(newState);
|
|
74
74
|
expect(prevEntity).toBeDefined();
|
|
75
75
|
const nextState = reducer(newState, partialResultAction);
|
|
@@ -78,16 +78,17 @@ describe('reducer', () => {
|
|
|
78
78
|
expect(nextEntity).toBeDefined();
|
|
79
79
|
|
|
80
80
|
expect(nextEntity.title).not.toBe(prevEntity.title);
|
|
81
|
-
expect(nextEntity.title).toBe(partialResultAction.
|
|
81
|
+
expect(nextEntity.title).toBe(partialResultAction.response.title);
|
|
82
82
|
|
|
83
83
|
expect(nextEntity.content).toBe(prevEntity.content);
|
|
84
84
|
expect(nextEntity.content).not.toBe(undefined);
|
|
85
85
|
|
|
86
86
|
expect(
|
|
87
|
-
nextState.entityMeta[Article.key][`${Article.pk(action.
|
|
87
|
+
nextState.entityMeta[Article.key][`${Article.pk(action.response)}`],
|
|
88
88
|
).toBeDefined();
|
|
89
89
|
expect(
|
|
90
|
-
nextState.entityMeta[Article.key][`${Article.pk(action.
|
|
90
|
+
nextState.entityMeta[Article.key][`${Article.pk(action.response)}`]
|
|
91
|
+
.date,
|
|
91
92
|
).toBe(action.meta.date);
|
|
92
93
|
});
|
|
93
94
|
|
|
@@ -101,7 +102,7 @@ describe('reducer', () => {
|
|
|
101
102
|
},
|
|
102
103
|
};
|
|
103
104
|
const getMeta = (state: any): { expiresAt: number } =>
|
|
104
|
-
state.entityMeta[Article.key][`${Article.pk(action.
|
|
105
|
+
state.entityMeta[Article.key][`${Article.pk(action.response)}`];
|
|
105
106
|
const prevMeta = getMeta(newState);
|
|
106
107
|
expect(prevMeta).toBeDefined();
|
|
107
108
|
const nextState = reducer(newState, localAction);
|
|
@@ -122,9 +123,9 @@ describe('reducer', () => {
|
|
|
122
123
|
},
|
|
123
124
|
};
|
|
124
125
|
const getMeta = (state: any): { date: number } =>
|
|
125
|
-
state.entityMeta[Article.key][`${Article.pk(action.
|
|
126
|
+
state.entityMeta[Article.key][`${Article.pk(action.response)}`];
|
|
126
127
|
const getEntity = (state: any): Article =>
|
|
127
|
-
state.entities[Article.key][`${Article.pk(action.
|
|
128
|
+
state.entities[Article.key][`${Article.pk(action.response)}`];
|
|
128
129
|
const prevEntity = getEntity(newState);
|
|
129
130
|
const prevMeta = getMeta(newState);
|
|
130
131
|
expect(prevMeta).toBeDefined();
|
|
@@ -181,9 +182,9 @@ describe('reducer', () => {
|
|
|
181
182
|
},
|
|
182
183
|
};
|
|
183
184
|
const getMeta = (state: any): { date: number; expiresAt: number } =>
|
|
184
|
-
state.entityMeta[ExpiresSoon.key][`${ExpiresSoon.pk(action.
|
|
185
|
+
state.entityMeta[ExpiresSoon.key][`${ExpiresSoon.pk(action.response)}`];
|
|
185
186
|
const getEntity = (state: any): ExpiresSoon =>
|
|
186
|
-
state.entities[ExpiresSoon.key][`${ExpiresSoon.pk(action.
|
|
187
|
+
state.entities[ExpiresSoon.key][`${ExpiresSoon.pk(action.response)}`];
|
|
187
188
|
|
|
188
189
|
const prevEntity = getEntity(newState);
|
|
189
190
|
const prevMeta = getMeta(newState);
|
|
@@ -220,8 +221,8 @@ describe('reducer', () => {
|
|
|
220
221
|
type: SET_TYPE,
|
|
221
222
|
value,
|
|
222
223
|
schema: Counter,
|
|
224
|
+
args: [{ id }],
|
|
223
225
|
meta: {
|
|
224
|
-
args: [{ id }],
|
|
225
226
|
date: 0,
|
|
226
227
|
fetchedAt: 0,
|
|
227
228
|
expiresAt: 1000000000000,
|
|
@@ -250,8 +251,8 @@ describe('reducer', () => {
|
|
|
250
251
|
type: SET_TYPE,
|
|
251
252
|
value,
|
|
252
253
|
schema: Counter,
|
|
254
|
+
args: [{ id }],
|
|
253
255
|
meta: {
|
|
254
|
-
args: [{ id }],
|
|
255
256
|
date: 0,
|
|
256
257
|
fetchedAt: 0,
|
|
257
258
|
expiresAt: 1000000000000,
|
|
@@ -278,8 +279,8 @@ describe('reducer', () => {
|
|
|
278
279
|
type: SET_TYPE,
|
|
279
280
|
value,
|
|
280
281
|
schema: Article,
|
|
282
|
+
args: [{ id }],
|
|
281
283
|
meta: {
|
|
282
|
-
args: [{ id }],
|
|
283
284
|
date: 0,
|
|
284
285
|
fetchedAt: 0,
|
|
285
286
|
expiresAt: 1000000000000,
|
|
@@ -300,8 +301,8 @@ describe('reducer', () => {
|
|
|
300
301
|
type: SET_TYPE,
|
|
301
302
|
value,
|
|
302
303
|
schema: Article,
|
|
304
|
+
args: [{ id }],
|
|
303
305
|
meta: {
|
|
304
|
-
args: [{ id }],
|
|
305
306
|
date: 0,
|
|
306
307
|
fetchedAt: 0,
|
|
307
308
|
expiresAt: 1000000000000,
|
|
@@ -317,14 +318,14 @@ describe('reducer', () => {
|
|
|
317
318
|
|
|
318
319
|
it('mutate should never change endpoints', () => {
|
|
319
320
|
const id = 20;
|
|
320
|
-
const
|
|
321
|
+
const response = { id, title: 'hi', content: 'this is the content' };
|
|
321
322
|
const action: SetResponseAction = {
|
|
322
323
|
type: SET_RESPONSE_TYPE,
|
|
323
|
-
|
|
324
|
+
response,
|
|
324
325
|
endpoint: ArticleResource.get,
|
|
326
|
+
args: [{ id }],
|
|
327
|
+
key: ArticleResource.get.key(response),
|
|
325
328
|
meta: {
|
|
326
|
-
args: [{ id }],
|
|
327
|
-
key: ArticleResource.get.key(payload),
|
|
328
329
|
date: 0,
|
|
329
330
|
fetchedAt: 0,
|
|
330
331
|
expiresAt: 1000000000000,
|
|
@@ -332,7 +333,7 @@ describe('reducer', () => {
|
|
|
332
333
|
};
|
|
333
334
|
const iniState = {
|
|
334
335
|
...initialState,
|
|
335
|
-
endpoints: { abc: '5', [ArticleResource.get.key(
|
|
336
|
+
endpoints: { abc: '5', [ArticleResource.get.key(response)]: `${id}` },
|
|
336
337
|
};
|
|
337
338
|
const newState = reducer(iniState, action);
|
|
338
339
|
expect(newState.endpoints).toStrictEqual(iniState.endpoints);
|
|
@@ -341,11 +342,11 @@ describe('reducer', () => {
|
|
|
341
342
|
const id = 20;
|
|
342
343
|
const action: SetResponseAction = {
|
|
343
344
|
type: SET_RESPONSE_TYPE,
|
|
344
|
-
|
|
345
|
+
response: { id },
|
|
345
346
|
endpoint: ArticleResource.delete,
|
|
347
|
+
args: [{ id }],
|
|
348
|
+
key: ArticleResource.delete.key({ id }),
|
|
346
349
|
meta: {
|
|
347
|
-
args: [{ id }],
|
|
348
|
-
key: ArticleResource.delete.key({ id }),
|
|
349
350
|
fetchedAt: 0,
|
|
350
351
|
date: 0,
|
|
351
352
|
expiresAt: 0,
|
|
@@ -491,9 +492,7 @@ describe('reducer', () => {
|
|
|
491
492
|
const id = 20;
|
|
492
493
|
const action: InvalidateAction = {
|
|
493
494
|
type: INVALIDATE_TYPE,
|
|
494
|
-
|
|
495
|
-
key: id.toString(),
|
|
496
|
-
},
|
|
495
|
+
key: id.toString(),
|
|
497
496
|
};
|
|
498
497
|
const iniState: any = {
|
|
499
498
|
...initialState,
|
|
@@ -530,11 +529,11 @@ describe('reducer', () => {
|
|
|
530
529
|
const error = new Error('hi');
|
|
531
530
|
const action: SetResponseAction = {
|
|
532
531
|
type: SET_RESPONSE_TYPE,
|
|
533
|
-
|
|
532
|
+
response: error,
|
|
534
533
|
endpoint: ArticleResource.get,
|
|
534
|
+
args: [{ id }],
|
|
535
|
+
key: ArticleResource.get.key({ id }),
|
|
535
536
|
meta: {
|
|
536
|
-
args: [{ id }],
|
|
537
|
-
key: ArticleResource.get.key({ id }),
|
|
538
537
|
fetchedAt: 5000000000,
|
|
539
538
|
date: 5000000000,
|
|
540
539
|
expiresAt: 5000500000,
|
|
@@ -550,11 +549,11 @@ describe('reducer', () => {
|
|
|
550
549
|
const error = new Error('hi');
|
|
551
550
|
const action: SetResponseAction = {
|
|
552
551
|
type: SET_RESPONSE_TYPE,
|
|
553
|
-
|
|
552
|
+
response: error,
|
|
554
553
|
endpoint: ArticleResource.get,
|
|
554
|
+
args: [{ id }],
|
|
555
|
+
key: ArticleResource.get.key({ id }),
|
|
555
556
|
meta: {
|
|
556
|
-
args: [{ id }],
|
|
557
|
-
key: ArticleResource.get.key({ id }),
|
|
558
557
|
fetchedAt: 0,
|
|
559
558
|
date: 0,
|
|
560
559
|
expiresAt: 10000000000000000000,
|
|
@@ -571,11 +570,11 @@ describe('reducer', () => {
|
|
|
571
570
|
const error = new Error('hi');
|
|
572
571
|
const action: SetResponseAction = {
|
|
573
572
|
type: SET_RESPONSE_TYPE,
|
|
574
|
-
|
|
573
|
+
response: error,
|
|
575
574
|
endpoint: ArticleResource.delete,
|
|
575
|
+
args: [{ id }],
|
|
576
|
+
key: ArticleResource.delete.key({ id }),
|
|
576
577
|
meta: {
|
|
577
|
-
args: [{ id }],
|
|
578
|
-
key: ArticleResource.delete.key({ id }),
|
|
579
578
|
fetchedAt: 0,
|
|
580
579
|
date: 0,
|
|
581
580
|
expiresAt: 0,
|
|
@@ -603,16 +602,14 @@ describe('reducer', () => {
|
|
|
603
602
|
try {
|
|
604
603
|
const action: FetchAction = {
|
|
605
604
|
type: FETCH_TYPE,
|
|
606
|
-
payload: () => new Promise<any>(() => null),
|
|
607
605
|
endpoint: ArticleResource.get,
|
|
606
|
+
args: [{ id: 5 }],
|
|
607
|
+
key: ArticleResource.get.url({ id: 5 }),
|
|
608
608
|
meta: {
|
|
609
|
-
args: [{ id: 5 }],
|
|
610
|
-
key: ArticleResource.get.url({ id: 5 }),
|
|
611
|
-
throttle: true,
|
|
612
609
|
reject: (v: any) => null,
|
|
613
610
|
resolve: (v: any) => null,
|
|
614
611
|
promise: new Promise((v: any) => null),
|
|
615
|
-
|
|
612
|
+
fetchedAt: 0,
|
|
616
613
|
},
|
|
617
614
|
};
|
|
618
615
|
const iniState = {
|
|
@@ -1,19 +1,17 @@
|
|
|
1
|
-
import createOptimistic from '../../controller/createOptimistic.js';
|
|
2
|
-
import type {
|
|
3
|
-
State,
|
|
4
|
-
SetResponseAction,
|
|
5
|
-
OptimisticAction,
|
|
6
|
-
FetchAction,
|
|
7
|
-
} from '../../types.js';
|
|
1
|
+
import { createOptimistic } from '../../controller/actions/createOptimistic.js';
|
|
2
|
+
import type { State, FetchAction } from '../../types.js';
|
|
8
3
|
|
|
9
4
|
export function fetchReducer(state: State<unknown>, action: FetchAction) {
|
|
10
|
-
let setAction: SetResponseAction | OptimisticAction;
|
|
11
|
-
|
|
12
5
|
if (action.endpoint.getOptimisticResponse && action.endpoint.sideEffect) {
|
|
13
|
-
setAction = createOptimistic(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
6
|
+
const setAction = createOptimistic(
|
|
7
|
+
action.endpoint,
|
|
8
|
+
action.args,
|
|
9
|
+
action.meta.fetchedAt,
|
|
10
|
+
);
|
|
11
|
+
return {
|
|
12
|
+
...state,
|
|
13
|
+
optimistic: [...state.optimistic, setAction],
|
|
14
|
+
};
|
|
17
15
|
} else {
|
|
18
16
|
// If 'fetch' action reaches the reducer there are no middlewares installed to handle it
|
|
19
17
|
/* istanbul ignore next */
|
|
@@ -22,14 +20,10 @@ export function fetchReducer(state: State<unknown>, action: FetchAction) {
|
|
|
22
20
|
'Fetch appears unhandled - you are likely missing the NetworkManager middleware',
|
|
23
21
|
);
|
|
24
22
|
console.warn(
|
|
25
|
-
'See https://dataclient.io/docs/guides/redux
|
|
23
|
+
'See https://dataclient.io/docs/guides/redux for hooking up redux',
|
|
26
24
|
);
|
|
27
25
|
}
|
|
28
26
|
|
|
29
27
|
return state;
|
|
30
28
|
}
|
|
31
|
-
return {
|
|
32
|
-
...state,
|
|
33
|
-
optimistic: [...state.optimistic, setAction],
|
|
34
|
-
};
|
|
35
29
|
}
|
|
@@ -10,11 +10,7 @@ export function setReducer(
|
|
|
10
10
|
) {
|
|
11
11
|
let value: any;
|
|
12
12
|
if (typeof action.value === 'function') {
|
|
13
|
-
const previousValue = controller.get(
|
|
14
|
-
action.schema,
|
|
15
|
-
...action.meta.args,
|
|
16
|
-
state,
|
|
17
|
-
);
|
|
13
|
+
const previousValue = controller.get(action.schema, ...action.args, state);
|
|
18
14
|
if (previousValue === undefined) return state;
|
|
19
15
|
value = action.value(previousValue);
|
|
20
16
|
} else {
|
|
@@ -22,12 +18,10 @@ export function setReducer(
|
|
|
22
18
|
}
|
|
23
19
|
try {
|
|
24
20
|
const { entities, indexes, entityMeta } = normalize(
|
|
25
|
-
value,
|
|
26
21
|
action.schema,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
state
|
|
30
|
-
state.entityMeta,
|
|
22
|
+
value,
|
|
23
|
+
action.args,
|
|
24
|
+
state,
|
|
31
25
|
action.meta,
|
|
32
26
|
);
|
|
33
27
|
return {
|