@data-client/core 0.13.1 → 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 +198 -214
- package/dist/index.umd.min.js +1 -1
- package/legacy/actions.js +1 -1
- package/legacy/controller/Controller.js +21 -30
- 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/internal.js +1 -2
- package/legacy/manager/LogoutManager.js +2 -2
- package/legacy/manager/NetworkManager.js +39 -35
- package/legacy/manager/PollingSubscription.js +3 -3
- package/legacy/manager/SubscriptionManager.js +3 -3
- package/legacy/state/reducer/createReducer.js +2 -2
- package/legacy/state/reducer/fetchReducer.js +6 -10
- package/legacy/state/reducer/invalidateReducer.js +2 -2
- package/legacy/state/reducer/setReducer.js +11 -3
- package/legacy/state/reducer/setResponseReducer.js +17 -17
- package/legacy/types.js +1 -1
- package/lib/actions.d.ts +35 -41
- package/lib/actions.d.ts.map +1 -1
- package/lib/actions.js +1 -1
- package/lib/controller/Controller.d.ts +18 -17
- package/lib/controller/Controller.d.ts.map +1 -1
- package/lib/controller/Controller.js +21 -30
- 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/actions/createSet.d.ts +8 -0
- 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/internal.d.ts +0 -1
- package/lib/internal.d.ts.map +1 -1
- package/lib/internal.js +1 -2
- package/lib/manager/LogoutManager.js +2 -2
- package/lib/manager/NetworkManager.d.ts +7 -2
- package/lib/manager/NetworkManager.d.ts.map +1 -1
- package/lib/manager/NetworkManager.js +39 -35
- package/lib/manager/PollingSubscription.js +3 -3
- package/lib/manager/SubscriptionManager.js +3 -3
- package/lib/state/reducer/createReducer.js +2 -2
- package/lib/state/reducer/expireReducer.d.ts +6 -8
- package/lib/state/reducer/expireReducer.d.ts.map +1 -1
- 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 +5 -7
- package/lib/state/reducer/invalidateReducer.d.ts.map +1 -1
- package/lib/state/reducer/invalidateReducer.js +2 -2
- package/lib/state/reducer/setReducer.d.ts +2 -1
- package/lib/state/reducer/setReducer.d.ts.map +1 -1
- package/lib/state/reducer/setReducer.js +11 -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 +37 -43
- package/src/controller/Controller.ts +29 -26
- 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/internal.ts +0 -1
- package/src/manager/LogoutManager.ts +1 -1
- package/src/manager/NetworkManager.ts +41 -32
- 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 +110 -44
- package/src/state/reducer/createReducer.ts +1 -1
- package/src/state/reducer/fetchReducer.ts +12 -18
- package/src/state/reducer/invalidateReducer.ts +1 -1
- package/src/state/reducer/setReducer.ts +17 -6
- package/src/state/reducer/setResponseReducer.ts +18 -20
- package/src/types.ts +4 -4
- package/ts3.4/actions.d.ts +36 -42
- package/ts3.4/controller/Controller.d.ts +23 -19
- 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/actions/createSet.d.ts +10 -0
- 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/internal.d.ts +0 -1
- package/ts3.4/manager/NetworkManager.d.ts +7 -2
- package/ts3.4/state/reducer/expireReducer.d.ts +6 -8
- package/ts3.4/state/reducer/invalidateReducer.d.ts +5 -7
- package/ts3.4/state/reducer/setReducer.d.ts +2 -1
- 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/legacy/state/RIC.js +0 -3
- 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 +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/lib/state/RIC.d.ts +0 -3
- package/lib/state/RIC.d.ts.map +0 -1
- package/lib/state/RIC.js +0 -3
- 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 -39
- package/src/state/RIC.ts +0 -5
- package/src/state/__tests__/RIC.web.ts +0 -16
- 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
- package/ts3.4/controller/createSet.d.ts +0 -10
- package/ts3.4/state/RIC.d.ts +0 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { INVALID } from '@data-client/endpoint';
|
|
1
|
+
import { INVALID, Entity } from '@data-client/endpoint';
|
|
2
2
|
import { ArticleResource, Article, PaginatedArticle } from '__tests__/new';
|
|
3
3
|
|
|
4
4
|
import { Controller } from '../..';
|
|
@@ -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);
|
|
@@ -202,6 +203,75 @@ describe('reducer', () => {
|
|
|
202
203
|
});
|
|
203
204
|
});
|
|
204
205
|
|
|
206
|
+
it('set(function) should do nothing when entity does not exist', () => {
|
|
207
|
+
const id = 20;
|
|
208
|
+
const value = (previous: { counter: number }) => ({
|
|
209
|
+
counter: previous.counter + 1,
|
|
210
|
+
});
|
|
211
|
+
class Counter extends Entity {
|
|
212
|
+
id = 0;
|
|
213
|
+
counter = 0;
|
|
214
|
+
pk() {
|
|
215
|
+
return this.id;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
static key = 'Counter';
|
|
219
|
+
}
|
|
220
|
+
const action: SetAction = {
|
|
221
|
+
type: SET_TYPE,
|
|
222
|
+
value,
|
|
223
|
+
schema: Counter,
|
|
224
|
+
args: [{ id }],
|
|
225
|
+
meta: {
|
|
226
|
+
date: 0,
|
|
227
|
+
fetchedAt: 0,
|
|
228
|
+
expiresAt: 1000000000000,
|
|
229
|
+
},
|
|
230
|
+
};
|
|
231
|
+
const newState = reducer(initialState, action);
|
|
232
|
+
expect(newState).toBe(initialState);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it('set(function) should increment when it is found', () => {
|
|
236
|
+
const id = 20;
|
|
237
|
+
const value = (previous: { id: number; counter: number }) => ({
|
|
238
|
+
id: previous.id,
|
|
239
|
+
counter: previous.counter + 1,
|
|
240
|
+
});
|
|
241
|
+
class Counter extends Entity {
|
|
242
|
+
id = 0;
|
|
243
|
+
counter = 0;
|
|
244
|
+
pk() {
|
|
245
|
+
return this.id;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
static key = 'Counter';
|
|
249
|
+
}
|
|
250
|
+
const action: SetAction = {
|
|
251
|
+
type: SET_TYPE,
|
|
252
|
+
value,
|
|
253
|
+
schema: Counter,
|
|
254
|
+
args: [{ id }],
|
|
255
|
+
meta: {
|
|
256
|
+
date: 0,
|
|
257
|
+
fetchedAt: 0,
|
|
258
|
+
expiresAt: 1000000000000,
|
|
259
|
+
},
|
|
260
|
+
};
|
|
261
|
+
const state = {
|
|
262
|
+
...initialState,
|
|
263
|
+
entities: {
|
|
264
|
+
[Counter.key]: {
|
|
265
|
+
[id]: { id, counter: 5 },
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
const newState = reducer(state, action);
|
|
270
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
271
|
+
// @ts-ignore
|
|
272
|
+
expect(newState.entities[Counter.key]?.[id]?.counter).toBe(6);
|
|
273
|
+
});
|
|
274
|
+
|
|
205
275
|
it('set should add entity when it does not exist', () => {
|
|
206
276
|
const id = 20;
|
|
207
277
|
const value = { id, title: 'hi', content: 'this is the content' };
|
|
@@ -209,8 +279,8 @@ describe('reducer', () => {
|
|
|
209
279
|
type: SET_TYPE,
|
|
210
280
|
value,
|
|
211
281
|
schema: Article,
|
|
282
|
+
args: [{ id }],
|
|
212
283
|
meta: {
|
|
213
|
-
args: [{ id }],
|
|
214
284
|
date: 0,
|
|
215
285
|
fetchedAt: 0,
|
|
216
286
|
expiresAt: 1000000000000,
|
|
@@ -231,8 +301,8 @@ describe('reducer', () => {
|
|
|
231
301
|
type: SET_TYPE,
|
|
232
302
|
value,
|
|
233
303
|
schema: Article,
|
|
304
|
+
args: [{ id }],
|
|
234
305
|
meta: {
|
|
235
|
-
args: [{ id }],
|
|
236
306
|
date: 0,
|
|
237
307
|
fetchedAt: 0,
|
|
238
308
|
expiresAt: 1000000000000,
|
|
@@ -248,14 +318,14 @@ describe('reducer', () => {
|
|
|
248
318
|
|
|
249
319
|
it('mutate should never change endpoints', () => {
|
|
250
320
|
const id = 20;
|
|
251
|
-
const
|
|
321
|
+
const response = { id, title: 'hi', content: 'this is the content' };
|
|
252
322
|
const action: SetResponseAction = {
|
|
253
323
|
type: SET_RESPONSE_TYPE,
|
|
254
|
-
|
|
324
|
+
response,
|
|
255
325
|
endpoint: ArticleResource.get,
|
|
326
|
+
args: [{ id }],
|
|
327
|
+
key: ArticleResource.get.key(response),
|
|
256
328
|
meta: {
|
|
257
|
-
args: [{ id }],
|
|
258
|
-
key: ArticleResource.get.key(payload),
|
|
259
329
|
date: 0,
|
|
260
330
|
fetchedAt: 0,
|
|
261
331
|
expiresAt: 1000000000000,
|
|
@@ -263,7 +333,7 @@ describe('reducer', () => {
|
|
|
263
333
|
};
|
|
264
334
|
const iniState = {
|
|
265
335
|
...initialState,
|
|
266
|
-
endpoints: { abc: '5', [ArticleResource.get.key(
|
|
336
|
+
endpoints: { abc: '5', [ArticleResource.get.key(response)]: `${id}` },
|
|
267
337
|
};
|
|
268
338
|
const newState = reducer(iniState, action);
|
|
269
339
|
expect(newState.endpoints).toStrictEqual(iniState.endpoints);
|
|
@@ -272,11 +342,11 @@ describe('reducer', () => {
|
|
|
272
342
|
const id = 20;
|
|
273
343
|
const action: SetResponseAction = {
|
|
274
344
|
type: SET_RESPONSE_TYPE,
|
|
275
|
-
|
|
345
|
+
response: { id },
|
|
276
346
|
endpoint: ArticleResource.delete,
|
|
347
|
+
args: [{ id }],
|
|
348
|
+
key: ArticleResource.delete.key({ id }),
|
|
277
349
|
meta: {
|
|
278
|
-
args: [{ id }],
|
|
279
|
-
key: ArticleResource.delete.key({ id }),
|
|
280
350
|
fetchedAt: 0,
|
|
281
351
|
date: 0,
|
|
282
352
|
expiresAt: 0,
|
|
@@ -422,9 +492,7 @@ describe('reducer', () => {
|
|
|
422
492
|
const id = 20;
|
|
423
493
|
const action: InvalidateAction = {
|
|
424
494
|
type: INVALIDATE_TYPE,
|
|
425
|
-
|
|
426
|
-
key: id.toString(),
|
|
427
|
-
},
|
|
495
|
+
key: id.toString(),
|
|
428
496
|
};
|
|
429
497
|
const iniState: any = {
|
|
430
498
|
...initialState,
|
|
@@ -461,11 +529,11 @@ describe('reducer', () => {
|
|
|
461
529
|
const error = new Error('hi');
|
|
462
530
|
const action: SetResponseAction = {
|
|
463
531
|
type: SET_RESPONSE_TYPE,
|
|
464
|
-
|
|
532
|
+
response: error,
|
|
465
533
|
endpoint: ArticleResource.get,
|
|
534
|
+
args: [{ id }],
|
|
535
|
+
key: ArticleResource.get.key({ id }),
|
|
466
536
|
meta: {
|
|
467
|
-
args: [{ id }],
|
|
468
|
-
key: ArticleResource.get.key({ id }),
|
|
469
537
|
fetchedAt: 5000000000,
|
|
470
538
|
date: 5000000000,
|
|
471
539
|
expiresAt: 5000500000,
|
|
@@ -481,11 +549,11 @@ describe('reducer', () => {
|
|
|
481
549
|
const error = new Error('hi');
|
|
482
550
|
const action: SetResponseAction = {
|
|
483
551
|
type: SET_RESPONSE_TYPE,
|
|
484
|
-
|
|
552
|
+
response: error,
|
|
485
553
|
endpoint: ArticleResource.get,
|
|
554
|
+
args: [{ id }],
|
|
555
|
+
key: ArticleResource.get.key({ id }),
|
|
486
556
|
meta: {
|
|
487
|
-
args: [{ id }],
|
|
488
|
-
key: ArticleResource.get.key({ id }),
|
|
489
557
|
fetchedAt: 0,
|
|
490
558
|
date: 0,
|
|
491
559
|
expiresAt: 10000000000000000000,
|
|
@@ -502,11 +570,11 @@ describe('reducer', () => {
|
|
|
502
570
|
const error = new Error('hi');
|
|
503
571
|
const action: SetResponseAction = {
|
|
504
572
|
type: SET_RESPONSE_TYPE,
|
|
505
|
-
|
|
573
|
+
response: error,
|
|
506
574
|
endpoint: ArticleResource.delete,
|
|
575
|
+
args: [{ id }],
|
|
576
|
+
key: ArticleResource.delete.key({ id }),
|
|
507
577
|
meta: {
|
|
508
|
-
args: [{ id }],
|
|
509
|
-
key: ArticleResource.delete.key({ id }),
|
|
510
578
|
fetchedAt: 0,
|
|
511
579
|
date: 0,
|
|
512
580
|
expiresAt: 0,
|
|
@@ -534,16 +602,14 @@ describe('reducer', () => {
|
|
|
534
602
|
try {
|
|
535
603
|
const action: FetchAction = {
|
|
536
604
|
type: FETCH_TYPE,
|
|
537
|
-
payload: () => new Promise<any>(() => null),
|
|
538
605
|
endpoint: ArticleResource.get,
|
|
606
|
+
args: [{ id: 5 }],
|
|
607
|
+
key: ArticleResource.get.url({ id: 5 }),
|
|
539
608
|
meta: {
|
|
540
|
-
args: [{ id: 5 }],
|
|
541
|
-
key: ArticleResource.get.url({ id: 5 }),
|
|
542
|
-
throttle: true,
|
|
543
609
|
reject: (v: any) => null,
|
|
544
610
|
resolve: (v: any) => null,
|
|
545
611
|
promise: new Promise((v: any) => null),
|
|
546
|
-
|
|
612
|
+
fetchedAt: 0,
|
|
547
613
|
},
|
|
548
614
|
};
|
|
549
615
|
const iniState = {
|
|
@@ -44,7 +44,7 @@ export default function createReducer(controller: Controller): ReducerType {
|
|
|
44
44
|
return setResponseReducer(state, action, controller);
|
|
45
45
|
|
|
46
46
|
case SET_TYPE:
|
|
47
|
-
return setReducer(state, action);
|
|
47
|
+
return setReducer(state, action, controller);
|
|
48
48
|
|
|
49
49
|
case INVALIDATEALL_TYPE:
|
|
50
50
|
case INVALIDATE_TYPE:
|
|
@@ -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
|
}
|
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
import { normalize } from '@data-client/normalizr';
|
|
2
2
|
|
|
3
|
+
import Controller from '../../controller/Controller.js';
|
|
3
4
|
import type { State, SetAction } from '../../types.js';
|
|
4
5
|
|
|
5
|
-
export function setReducer(
|
|
6
|
+
export function setReducer(
|
|
7
|
+
state: State<unknown>,
|
|
8
|
+
action: SetAction,
|
|
9
|
+
controller: Controller,
|
|
10
|
+
) {
|
|
11
|
+
let value: any;
|
|
12
|
+
if (typeof action.value === 'function') {
|
|
13
|
+
const previousValue = controller.get(action.schema, ...action.args, state);
|
|
14
|
+
if (previousValue === undefined) return state;
|
|
15
|
+
value = action.value(previousValue);
|
|
16
|
+
} else {
|
|
17
|
+
value = action.value;
|
|
18
|
+
}
|
|
6
19
|
try {
|
|
7
20
|
const { entities, indexes, entityMeta } = normalize(
|
|
8
|
-
action.value,
|
|
9
21
|
action.schema,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
state
|
|
13
|
-
state.entityMeta,
|
|
22
|
+
value,
|
|
23
|
+
action.args,
|
|
24
|
+
state,
|
|
14
25
|
action.meta,
|
|
15
26
|
);
|
|
16
27
|
return {
|
|
@@ -15,21 +15,21 @@ export function setResponseReducer(
|
|
|
15
15
|
controller: Controller,
|
|
16
16
|
) {
|
|
17
17
|
if (action.error) {
|
|
18
|
-
return reduceError(state, action, action.
|
|
18
|
+
return reduceError(state, action, action.response);
|
|
19
19
|
}
|
|
20
20
|
try {
|
|
21
|
-
let
|
|
22
|
-
// for true set's
|
|
21
|
+
let response: any;
|
|
22
|
+
// for true set's response is contained in action
|
|
23
23
|
if (action.type === OPTIMISTIC_TYPE) {
|
|
24
24
|
// this should never happen
|
|
25
25
|
/* istanbul ignore if */
|
|
26
26
|
if (!action.endpoint.getOptimisticResponse) return state;
|
|
27
27
|
try {
|
|
28
28
|
// compute optimistic response based on current state
|
|
29
|
-
|
|
29
|
+
response = action.endpoint.getOptimisticResponse.call(
|
|
30
30
|
action.endpoint,
|
|
31
31
|
controller.snapshot(state, action.meta.fetchedAt),
|
|
32
|
-
...action.
|
|
32
|
+
...action.args,
|
|
33
33
|
);
|
|
34
34
|
} catch (e: any) {
|
|
35
35
|
// AbortOptimistic means 'do nothing', otherwise we count the exception as endpoint failure
|
|
@@ -39,24 +39,22 @@ export function setResponseReducer(
|
|
|
39
39
|
throw e;
|
|
40
40
|
}
|
|
41
41
|
} else {
|
|
42
|
-
|
|
42
|
+
response = action.response;
|
|
43
43
|
}
|
|
44
44
|
const { result, entities, indexes, entityMeta } = normalize(
|
|
45
|
-
payload,
|
|
46
45
|
action.endpoint.schema,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
state
|
|
50
|
-
state.entityMeta,
|
|
46
|
+
response,
|
|
47
|
+
action.args,
|
|
48
|
+
state,
|
|
51
49
|
action.meta,
|
|
52
50
|
);
|
|
53
51
|
const endpoints: Record<string, unknown> = {
|
|
54
52
|
...state.endpoints,
|
|
55
|
-
[action.
|
|
53
|
+
[action.key]: result,
|
|
56
54
|
};
|
|
57
55
|
try {
|
|
58
56
|
if (action.endpoint.update) {
|
|
59
|
-
const updaters = action.endpoint.update(result, ...action.
|
|
57
|
+
const updaters = action.endpoint.update(result, ...action.args);
|
|
60
58
|
Object.keys(updaters).forEach(key => {
|
|
61
59
|
endpoints[key] = updaters[key](endpoints[key]);
|
|
62
60
|
});
|
|
@@ -65,7 +63,7 @@ export function setResponseReducer(
|
|
|
65
63
|
// integrity of this state update is still guaranteed
|
|
66
64
|
} catch (error) {
|
|
67
65
|
console.error(
|
|
68
|
-
`The following error occured during Endpoint.update() for ${action.
|
|
66
|
+
`The following error occured during Endpoint.update() for ${action.key}`,
|
|
69
67
|
);
|
|
70
68
|
console.error(error);
|
|
71
69
|
}
|
|
@@ -76,10 +74,10 @@ export function setResponseReducer(
|
|
|
76
74
|
entityMeta,
|
|
77
75
|
meta: {
|
|
78
76
|
...state.meta,
|
|
79
|
-
[action.
|
|
77
|
+
[action.key]: {
|
|
80
78
|
date: action.meta.date,
|
|
81
79
|
expiresAt: action.meta.expiresAt,
|
|
82
|
-
prevExpiresAt: state.meta[action.
|
|
80
|
+
prevExpiresAt: state.meta[action.key]?.expiresAt,
|
|
83
81
|
},
|
|
84
82
|
},
|
|
85
83
|
optimistic: filterOptimistic(state, action),
|
|
@@ -89,13 +87,13 @@ export function setResponseReducer(
|
|
|
89
87
|
} catch (error: any) {
|
|
90
88
|
if (typeof error === 'object') {
|
|
91
89
|
error.message = `Error processing ${
|
|
92
|
-
action.
|
|
90
|
+
action.key
|
|
93
91
|
}\n\nFull Schema: ${JSON.stringify(
|
|
94
92
|
action.endpoint.schema,
|
|
95
93
|
undefined,
|
|
96
94
|
2,
|
|
97
95
|
)}\n\nError:\n${error.message}`;
|
|
98
|
-
if ('
|
|
96
|
+
if ('response' in action) error.response = action.response;
|
|
99
97
|
error.status = 400;
|
|
100
98
|
}
|
|
101
99
|
|
|
@@ -126,7 +124,7 @@ function reduceError(
|
|
|
126
124
|
...state,
|
|
127
125
|
meta: {
|
|
128
126
|
...state.meta,
|
|
129
|
-
[action.
|
|
127
|
+
[action.key]: {
|
|
130
128
|
date: action.meta.date,
|
|
131
129
|
error,
|
|
132
130
|
expiresAt: action.meta.expiresAt,
|
|
@@ -143,7 +141,7 @@ function filterOptimistic(
|
|
|
143
141
|
) {
|
|
144
142
|
return state.optimistic.filter(
|
|
145
143
|
optimisticAction =>
|
|
146
|
-
optimisticAction.
|
|
144
|
+
optimisticAction.key !== resolvingAction.key ||
|
|
147
145
|
(optimisticAction.type === OPTIMISTIC_TYPE ?
|
|
148
146
|
optimisticAction.meta.fetchedAt !== resolvingAction.meta.fetchedAt
|
|
149
147
|
: optimisticAction.meta.date > resolvingAction.meta.date),
|
package/src/types.ts
CHANGED
|
@@ -12,6 +12,8 @@ import type {
|
|
|
12
12
|
} from './actions.js';
|
|
13
13
|
import type { Dispatch, Middleware, MiddlewareAPI } from './middlewareTypes.js';
|
|
14
14
|
|
|
15
|
+
export * from './actions.js';
|
|
16
|
+
|
|
15
17
|
export type { AbstractInstanceType, UpdateFunction };
|
|
16
18
|
|
|
17
19
|
export type PK = string;
|
|
@@ -27,9 +29,9 @@ export interface State<T> {
|
|
|
27
29
|
readonly meta: {
|
|
28
30
|
readonly [key: string]: {
|
|
29
31
|
readonly date: number;
|
|
30
|
-
readonly error?: ErrorTypes;
|
|
31
32
|
readonly expiresAt: number;
|
|
32
33
|
readonly prevExpiresAt?: number;
|
|
34
|
+
readonly error?: ErrorTypes;
|
|
33
35
|
readonly invalidated?: boolean;
|
|
34
36
|
readonly errorPolicy?: 'hard' | 'soft' | undefined;
|
|
35
37
|
};
|
|
@@ -37,9 +39,9 @@ export interface State<T> {
|
|
|
37
39
|
readonly entityMeta: {
|
|
38
40
|
readonly [entityKey: string]: {
|
|
39
41
|
readonly [pk: string]: {
|
|
42
|
+
readonly fetchedAt: number;
|
|
40
43
|
readonly date: number;
|
|
41
44
|
readonly expiresAt: number;
|
|
42
|
-
readonly fetchedAt: number;
|
|
43
45
|
};
|
|
44
46
|
};
|
|
45
47
|
};
|
|
@@ -47,8 +49,6 @@ export interface State<T> {
|
|
|
47
49
|
readonly lastReset: number;
|
|
48
50
|
}
|
|
49
51
|
|
|
50
|
-
export * from './actions.js';
|
|
51
|
-
|
|
52
52
|
export interface Manager<Actions = ActionTypes> {
|
|
53
53
|
getMiddleware(): Middleware<Actions>;
|
|
54
54
|
cleanup(): void;
|