@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,6 +1,6 @@
|
|
|
1
1
|
import Controller from '../../controller/Controller';
|
|
2
2
|
import { Middleware } from '../../middlewareTypes';
|
|
3
|
-
import {
|
|
3
|
+
import { ActionTypes } from '../../types';
|
|
4
4
|
import NetworkManager from '../NetworkManager';
|
|
5
5
|
|
|
6
6
|
const middleware: Middleware = new NetworkManager().getMiddleware();
|
|
@@ -9,9 +9,7 @@ it('middlewares should compose with non-rest-hooks middlewares', () => {
|
|
|
9
9
|
type: 'BOB';
|
|
10
10
|
payload: any;
|
|
11
11
|
};
|
|
12
|
-
const dispatch = jest.fn(
|
|
13
|
-
async (action: CombinedActionTypes | AnotherAction) => {},
|
|
14
|
-
);
|
|
12
|
+
const dispatch = jest.fn(async (action: ActionTypes | AnotherAction) => {});
|
|
15
13
|
const ctrl = new Controller({ dispatch });
|
|
16
14
|
const API: typeof ctrl & { controller: typeof ctrl } = Object.create(ctrl, {
|
|
17
15
|
controller: { value: ctrl },
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Endpoint } from '@data-client/endpoint';
|
|
2
2
|
import { Article, ArticleResource } from '__tests__/new';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { SET_TYPE } from '../../actionTypes';
|
|
5
5
|
import Controller from '../../controller/Controller';
|
|
6
6
|
import createFetch from '../../controller/createFetch';
|
|
7
7
|
import NetworkManager from '../../manager/NetworkManager';
|
|
@@ -17,7 +17,7 @@ describe('NetworkManager', () => {
|
|
|
17
17
|
});
|
|
18
18
|
let errorspy: jest.SpyInstance;
|
|
19
19
|
beforeEach(() => {
|
|
20
|
-
errorspy = jest.spyOn(global.console, 'error');
|
|
20
|
+
errorspy = jest.spyOn(global.console, 'error').mockImplementation(() => {});
|
|
21
21
|
});
|
|
22
22
|
afterEach(() => {
|
|
23
23
|
errorspy.mockRestore();
|
|
@@ -26,7 +26,7 @@ describe('NetworkManager', () => {
|
|
|
26
26
|
it('getState() should have initialState before middleware run', () => {
|
|
27
27
|
class Hacked extends NetworkManager {
|
|
28
28
|
getHacked() {
|
|
29
|
-
return this.getState();
|
|
29
|
+
return this.controller.getState();
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
const hacked = new Hacked();
|
|
@@ -162,13 +162,11 @@ describe('NetworkManager', () => {
|
|
|
162
162
|
await new Promise(resolve => setTimeout(resolve, 0));
|
|
163
163
|
|
|
164
164
|
const action = {
|
|
165
|
-
type:
|
|
165
|
+
type: SET_TYPE,
|
|
166
166
|
endpoint: fetchResolveAction.endpoint,
|
|
167
167
|
payload: data,
|
|
168
168
|
meta: {
|
|
169
|
-
schema: fetchResolveAction.meta.schema,
|
|
170
169
|
args: fetchResolveAction.meta.args,
|
|
171
|
-
update: fetchResolveAction.meta.update,
|
|
172
170
|
key: fetchResolveAction.meta.key,
|
|
173
171
|
date: expect.any(Number),
|
|
174
172
|
expiresAt: expect.any(Number),
|
|
@@ -197,13 +195,11 @@ describe('NetworkManager', () => {
|
|
|
197
195
|
await new Promise(resolve => setTimeout(resolve, 0));
|
|
198
196
|
|
|
199
197
|
const action = {
|
|
200
|
-
type:
|
|
198
|
+
type: SET_TYPE,
|
|
201
199
|
endpoint: fetchReceiveWithUpdatersAction.endpoint,
|
|
202
200
|
payload: data,
|
|
203
201
|
meta: {
|
|
204
|
-
update: expect.any(Function),
|
|
205
202
|
args: fetchReceiveWithUpdatersAction.meta.args,
|
|
206
|
-
schema: fetchReceiveWithUpdatersAction.meta.schema,
|
|
207
203
|
key: fetchReceiveWithUpdatersAction.meta.key,
|
|
208
204
|
date: expect.any(Number),
|
|
209
205
|
expiresAt: expect.any(Number),
|
|
@@ -232,13 +228,11 @@ describe('NetworkManager', () => {
|
|
|
232
228
|
await new Promise(resolve => setTimeout(resolve, 0));
|
|
233
229
|
|
|
234
230
|
const action = {
|
|
235
|
-
type:
|
|
231
|
+
type: SET_TYPE,
|
|
236
232
|
endpoint: fetchRpcWithUpdatersAction.endpoint,
|
|
237
233
|
payload: data,
|
|
238
234
|
meta: {
|
|
239
235
|
args: fetchRpcWithUpdatersAction.meta.args,
|
|
240
|
-
update: expect.any(Function),
|
|
241
|
-
schema: fetchRpcWithUpdatersAction.meta.schema,
|
|
242
236
|
key: fetchRpcWithUpdatersAction.meta.key,
|
|
243
237
|
date: expect.any(Number),
|
|
244
238
|
expiresAt: expect.any(Number),
|
|
@@ -267,13 +261,11 @@ describe('NetworkManager', () => {
|
|
|
267
261
|
// mutations resolve before dispatch, so we must wait for next tick to see receive
|
|
268
262
|
await new Promise(resolve => setTimeout(resolve, 0));
|
|
269
263
|
expect(dispatch).toHaveBeenCalledWith({
|
|
270
|
-
type:
|
|
264
|
+
type: SET_TYPE,
|
|
271
265
|
endpoint: fetchRpcWithUpdatersAndOptimisticAction.endpoint,
|
|
272
266
|
payload: data,
|
|
273
267
|
meta: {
|
|
274
268
|
args: fetchRpcWithUpdatersAndOptimisticAction.meta.args,
|
|
275
|
-
update: expect.any(Function),
|
|
276
|
-
schema: fetchRpcWithUpdatersAndOptimisticAction.meta.schema,
|
|
277
269
|
key: fetchRpcWithUpdatersAndOptimisticAction.meta.key,
|
|
278
270
|
date: expect.any(Number),
|
|
279
271
|
expiresAt: expect.any(Number),
|
|
@@ -339,10 +331,9 @@ describe('NetworkManager', () => {
|
|
|
339
331
|
} catch (error) {
|
|
340
332
|
expect(next).not.toHaveBeenCalled();
|
|
341
333
|
expect(dispatch).toHaveBeenCalledWith({
|
|
342
|
-
type:
|
|
334
|
+
type: SET_TYPE,
|
|
343
335
|
payload: error,
|
|
344
336
|
meta: {
|
|
345
|
-
schema: fetchRejectAction.meta.schema,
|
|
346
337
|
key: fetchRejectAction.meta.key,
|
|
347
338
|
date: expect.any(Number),
|
|
348
339
|
expiresAt: expect.any(Number),
|
|
@@ -366,7 +357,6 @@ describe('NetworkManager', () => {
|
|
|
366
357
|
...fetchRejectAction,
|
|
367
358
|
meta: {
|
|
368
359
|
...fetchRejectAction.meta,
|
|
369
|
-
options: { errorExpiryLength: 1234 },
|
|
370
360
|
},
|
|
371
361
|
});
|
|
372
362
|
} catch (error) {
|
|
@@ -390,10 +380,6 @@ describe('NetworkManager', () => {
|
|
|
390
380
|
...fetchRejectAction,
|
|
391
381
|
meta: {
|
|
392
382
|
...fetchRejectAction.meta,
|
|
393
|
-
options: {
|
|
394
|
-
...fetchRejectAction.meta.options,
|
|
395
|
-
errorExpiryLength: undefined,
|
|
396
|
-
},
|
|
397
383
|
},
|
|
398
384
|
});
|
|
399
385
|
} catch (error) {
|
|
@@ -402,25 +388,5 @@ describe('NetworkManager', () => {
|
|
|
402
388
|
expect(meta.expiresAt - meta.date).toBe(7);
|
|
403
389
|
}
|
|
404
390
|
});
|
|
405
|
-
|
|
406
|
-
it('getLastReset() should handle Date object', async () => {
|
|
407
|
-
const mgr = new NetworkManager();
|
|
408
|
-
jest.spyOn(mgr, 'getState' as any).mockImplementation((): any => ({
|
|
409
|
-
...initialState,
|
|
410
|
-
lastReset: new Date(0),
|
|
411
|
-
}));
|
|
412
|
-
|
|
413
|
-
expect((mgr as any).getLastReset()).toBeLessThan(Date.now());
|
|
414
|
-
});
|
|
415
|
-
|
|
416
|
-
it('getLastReset() should handle null', async () => {
|
|
417
|
-
const mgr = new NetworkManager();
|
|
418
|
-
jest.spyOn(mgr, 'getState' as any).mockImplementation((): any => ({
|
|
419
|
-
...initialState,
|
|
420
|
-
lastReset: null,
|
|
421
|
-
}));
|
|
422
|
-
|
|
423
|
-
expect((mgr as any).getLastReset()).toBeLessThan(Date.now());
|
|
424
|
-
});
|
|
425
391
|
});
|
|
426
392
|
});
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Endpoint } from '@data-client/endpoint';
|
|
2
|
+
import { Article, PollingArticleResource } from '__tests__/new';
|
|
2
3
|
|
|
4
|
+
import Controller from '../../controller/Controller';
|
|
5
|
+
import { createSubscription } from '../../controller/createSubscription';
|
|
3
6
|
import { initialState } from '../../state/reducer/createReducer';
|
|
4
7
|
import ConnectionListener from '../ConnectionListener';
|
|
5
8
|
import DefaultConnectionListener from '../DefaultConnectionListener';
|
|
@@ -55,6 +58,11 @@ class MockConnectionListener implements ConnectionListener {
|
|
|
55
58
|
}
|
|
56
59
|
}
|
|
57
60
|
|
|
61
|
+
const makeState = (key: string, time: number) => () => ({
|
|
62
|
+
...initialState,
|
|
63
|
+
meta: { [key]: { date: time, expiresAt: Infinity } },
|
|
64
|
+
});
|
|
65
|
+
|
|
58
66
|
function onError(e: any) {
|
|
59
67
|
e.preventDefault();
|
|
60
68
|
}
|
|
@@ -68,192 +76,277 @@ afterEach(() => {
|
|
|
68
76
|
});
|
|
69
77
|
|
|
70
78
|
describe('PollingSubscription', () => {
|
|
71
|
-
const dispatch = jest.fn();
|
|
72
79
|
const a = () => Promise.resolve({ id: 5, title: 'hi' });
|
|
73
80
|
const fetch = jest.fn(a);
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
sub = new PollingSubscription(
|
|
79
|
-
{
|
|
80
|
-
key: 'test.com',
|
|
81
|
-
schema: PollingArticleResource,
|
|
82
|
-
fetch,
|
|
83
|
-
frequency: 5000,
|
|
84
|
-
getState: () => initialState,
|
|
85
|
-
},
|
|
86
|
-
dispatch,
|
|
87
|
-
);
|
|
88
|
-
});
|
|
89
|
-
afterAll(() => {
|
|
90
|
-
jest.useRealTimers();
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
afterAll(() => {
|
|
94
|
-
sub.cleanup();
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('should throw on undefined frequency in construction', () => {
|
|
98
|
-
expect(
|
|
99
|
-
() =>
|
|
100
|
-
new PollingSubscription(
|
|
101
|
-
{
|
|
102
|
-
key: 'test.com',
|
|
103
|
-
schema: PollingArticleResource,
|
|
104
|
-
fetch,
|
|
105
|
-
getState: () => initialState,
|
|
106
|
-
},
|
|
107
|
-
dispatch,
|
|
108
|
-
),
|
|
109
|
-
).toThrow();
|
|
81
|
+
const endpoint = new Endpoint(fetch, {
|
|
82
|
+
schema: Article,
|
|
83
|
+
key: () => 'test.com',
|
|
84
|
+
pollFrequency: 5000,
|
|
110
85
|
});
|
|
111
86
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
87
|
+
describe('existing data', () => {
|
|
88
|
+
it('should wait to call for fresh data', () => {
|
|
89
|
+
const dispatch = jest.fn();
|
|
90
|
+
const controller = new Controller({ dispatch });
|
|
91
|
+
(controller as any).getState = makeState('test.com', Date.now());
|
|
116
92
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
93
|
+
jest.useFakeTimers();
|
|
94
|
+
const sub2 = new PollingSubscription(
|
|
95
|
+
createSubscription(endpoint, { args: [] }),
|
|
96
|
+
controller,
|
|
97
|
+
);
|
|
98
|
+
expect(dispatch.mock.calls.length).toBe(0);
|
|
99
|
+
jest.advanceTimersByTime(4990);
|
|
100
|
+
expect(dispatch.mock.calls.length).toBe(0);
|
|
101
|
+
jest.advanceTimersByTime(20);
|
|
102
|
+
expect(dispatch.mock.calls.length).toBe(1);
|
|
103
|
+
jest.advanceTimersByTime(5000);
|
|
104
|
+
expect(dispatch.mock.calls.length).toBe(2);
|
|
105
|
+
jest.advanceTimersByTime(2000);
|
|
106
|
+
expect(dispatch.mock.calls.length).toBe(2);
|
|
107
|
+
sub2.cleanup();
|
|
108
|
+
jest.useRealTimers();
|
|
129
109
|
});
|
|
130
110
|
|
|
131
|
-
|
|
132
|
-
|
|
111
|
+
it('should only run once with multiple simultaneous starts', () => {
|
|
112
|
+
const dispatch = jest.fn();
|
|
113
|
+
const controller = new Controller({ dispatch });
|
|
114
|
+
(controller as any).getState = () => initialState;
|
|
133
115
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
116
|
+
jest.useFakeTimers();
|
|
117
|
+
const sub2 = new PollingSubscription(
|
|
118
|
+
createSubscription(endpoint, { args: [] }),
|
|
119
|
+
controller,
|
|
120
|
+
);
|
|
121
|
+
sub2.add(1000);
|
|
122
|
+
sub2.add(1000);
|
|
123
|
+
sub2.add(1000);
|
|
124
|
+
jest.advanceTimersByTime(1);
|
|
125
|
+
expect(dispatch.mock.calls.length).toBe(1);
|
|
126
|
+
jest.advanceTimersByTime(999);
|
|
127
|
+
expect(dispatch.mock.calls.length).toBe(2);
|
|
128
|
+
jest.advanceTimersByTime(10);
|
|
129
|
+
sub2.remove(1000);
|
|
130
|
+
sub2.remove(1000);
|
|
131
|
+
sub2.remove(1000);
|
|
132
|
+
sub2.cleanup();
|
|
133
|
+
jest.useRealTimers();
|
|
139
134
|
});
|
|
135
|
+
});
|
|
140
136
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
137
|
+
describe('fresh data', () => {
|
|
138
|
+
const dispatch = jest.fn();
|
|
139
|
+
const controller = new Controller({ dispatch });
|
|
140
|
+
(controller as any).getState = makeState('test.com', 0);
|
|
141
|
+
let sub: PollingSubscription;
|
|
142
|
+
|
|
143
|
+
beforeAll(() => {
|
|
144
|
+
jest.useFakeTimers();
|
|
145
|
+
sub = new PollingSubscription(
|
|
146
|
+
createSubscription(endpoint, { args: [] }),
|
|
147
|
+
controller,
|
|
148
|
+
);
|
|
146
149
|
});
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
sub.add(7000);
|
|
151
|
-
sub.add(8000);
|
|
152
|
-
jest.advanceTimersByTime(1000 * 13);
|
|
153
|
-
expect(dispatch.mock.calls.length).toBe(13);
|
|
150
|
+
afterAll(() => {
|
|
151
|
+
sub.cleanup();
|
|
152
|
+
jest.useRealTimers();
|
|
154
153
|
});
|
|
155
154
|
|
|
156
|
-
it('should
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
155
|
+
it('should throw on undefined frequency in construction', () => {
|
|
156
|
+
expect(
|
|
157
|
+
() =>
|
|
158
|
+
new PollingSubscription(
|
|
159
|
+
createSubscription(
|
|
160
|
+
new Endpoint(fetch, {
|
|
161
|
+
schema: Article,
|
|
162
|
+
key: () => 'test.com',
|
|
163
|
+
}),
|
|
164
|
+
{ args: [] },
|
|
165
|
+
),
|
|
166
|
+
controller,
|
|
167
|
+
),
|
|
168
|
+
).toThrow();
|
|
161
169
|
});
|
|
162
|
-
});
|
|
163
170
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
dispatch.
|
|
167
|
-
sub.remove(1000);
|
|
168
|
-
jest.advanceTimersByTime(1000 * 13);
|
|
169
|
-
expect(dispatch.mock.calls.length).toBe(13);
|
|
171
|
+
it('should call immediately', () => {
|
|
172
|
+
jest.advanceTimersByTime(1);
|
|
173
|
+
expect(dispatch.mock.calls.length).toBe(1);
|
|
170
174
|
});
|
|
171
175
|
|
|
172
|
-
it('should
|
|
173
|
-
dispatch.
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
176
|
+
it('should call after period', () => {
|
|
177
|
+
dispatch.mockReset();
|
|
178
|
+
jest.advanceTimersByTime(5000);
|
|
179
|
+
expect(dispatch.mock.calls.length).toBe(1);
|
|
180
|
+
dispatch.mock.calls[0].forEach((element: any) => {
|
|
181
|
+
delete element?.meta?.createdAt;
|
|
182
|
+
});
|
|
183
|
+
expect(dispatch.mock.calls[0]).toMatchSnapshot();
|
|
184
|
+
jest.advanceTimersByTime(5000);
|
|
185
|
+
expect(dispatch.mock.calls.length).toBe(2);
|
|
186
|
+
dispatch.mock.calls[1].forEach((element: any) => {
|
|
187
|
+
delete element?.meta?.createdAt;
|
|
188
|
+
});
|
|
178
189
|
|
|
179
|
-
|
|
180
|
-
sub.remove(1000);
|
|
181
|
-
jest.advanceTimersByTime(1000);
|
|
182
|
-
dispatch.mockClear();
|
|
183
|
-
jest.advanceTimersByTime(5000 * 13);
|
|
184
|
-
expect(dispatch.mock.calls.length).toBe(13);
|
|
190
|
+
expect(dispatch.mock.calls[1]).toMatchSnapshot();
|
|
185
191
|
});
|
|
186
192
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
193
|
+
describe('add()', () => {
|
|
194
|
+
it('should take smaller frequency when another is added', () => {
|
|
195
|
+
sub.add(1000);
|
|
196
|
+
jest.advanceTimersByTime(1000 * 4);
|
|
197
|
+
expect(dispatch.mock.calls.length).toBe(2 + 4);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('should not change frequency if same is added', () => {
|
|
201
|
+
dispatch.mockClear();
|
|
202
|
+
sub.add(1000);
|
|
203
|
+
jest.advanceTimersByTime(1000 * 13);
|
|
204
|
+
expect(dispatch.mock.calls.length).toBe(13);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it('should not change frequency if larger is added', () => {
|
|
208
|
+
dispatch.mockClear();
|
|
209
|
+
sub.add(7000);
|
|
210
|
+
sub.add(8000);
|
|
211
|
+
jest.advanceTimersByTime(1000 * 13);
|
|
212
|
+
expect(dispatch.mock.calls.length).toBe(13);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it('should do nothing if frequency is undefined', () => {
|
|
216
|
+
dispatch.mockClear();
|
|
217
|
+
sub.add(undefined);
|
|
218
|
+
jest.advanceTimersByTime(1000 * 13);
|
|
219
|
+
expect(dispatch.mock.calls.length).toBe(13);
|
|
220
|
+
});
|
|
202
221
|
});
|
|
203
222
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
223
|
+
describe('remove()', () => {
|
|
224
|
+
it('should not change frequency if only partially removed', () => {
|
|
225
|
+
dispatch.mockClear();
|
|
226
|
+
sub.remove(1000);
|
|
227
|
+
jest.advanceTimersByTime(1000 * 13);
|
|
228
|
+
expect(dispatch.mock.calls.length).toBe(13);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it('should not change frequency if only larger removed', () => {
|
|
232
|
+
dispatch.mockClear();
|
|
233
|
+
sub.remove(7000);
|
|
234
|
+
jest.advanceTimersByTime(1000 * 13);
|
|
235
|
+
expect(dispatch.mock.calls.length).toBe(13);
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
it('should go back to fastest if smallest frequency is removed completely', () => {
|
|
239
|
+
sub.remove(1000);
|
|
240
|
+
jest.advanceTimersByTime(1000);
|
|
241
|
+
dispatch.mockClear();
|
|
242
|
+
jest.advanceTimersByTime(5000 * 13);
|
|
243
|
+
expect(dispatch.mock.calls.length).toBe(13);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it('should do nothing if frequency is not registered', () => {
|
|
247
|
+
const oldError = console.error;
|
|
248
|
+
const spy = (console.error = jest.fn());
|
|
249
|
+
|
|
250
|
+
sub.remove(1000);
|
|
251
|
+
dispatch.mockClear();
|
|
252
|
+
jest.advanceTimersByTime(5000 * 13);
|
|
253
|
+
expect(dispatch.mock.calls.length).toBe(13);
|
|
254
|
+
|
|
255
|
+
expect(spy.mock.calls[0]).toMatchInlineSnapshot(`
|
|
256
|
+
[
|
|
257
|
+
"Mismatched remove: 1000 is not subscribed for test.com",
|
|
258
|
+
]
|
|
259
|
+
`);
|
|
260
|
+
console.error = oldError;
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it('should do nothing if frequency is undefined', () => {
|
|
264
|
+
sub.remove(undefined);
|
|
265
|
+
dispatch.mockClear();
|
|
266
|
+
jest.advanceTimersByTime(5000 * 13);
|
|
267
|
+
expect(dispatch.mock.calls.length).toBe(13);
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it('should return false until completely empty, then return true', () => {
|
|
271
|
+
const controller = new Controller({ dispatch });
|
|
272
|
+
(controller as any).getState = makeState('test.com', 0);
|
|
273
|
+
|
|
274
|
+
const sub = new PollingSubscription(
|
|
275
|
+
createSubscription(endpoint, { args: [] }),
|
|
276
|
+
controller,
|
|
277
|
+
);
|
|
278
|
+
sub.add(5000);
|
|
279
|
+
sub.add(7000);
|
|
280
|
+
expect(sub.remove(5000)).toBe(false);
|
|
281
|
+
expect(sub.remove(5000)).toBe(false);
|
|
282
|
+
expect(sub.remove(7000)).toBe(true);
|
|
283
|
+
});
|
|
209
284
|
});
|
|
210
285
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
286
|
+
describe('cleanup()', () => {
|
|
287
|
+
let warnSpy: jest.SpyInstance;
|
|
288
|
+
afterEach(() => {
|
|
289
|
+
warnSpy.mockRestore();
|
|
290
|
+
});
|
|
291
|
+
beforeEach(() => (warnSpy = jest.spyOn(console, 'warn')));
|
|
292
|
+
|
|
293
|
+
it('should stop all timers', () => {
|
|
294
|
+
dispatch.mockClear();
|
|
295
|
+
sub.cleanup();
|
|
296
|
+
jest.advanceTimersByTime(5000 * 13);
|
|
297
|
+
expect(dispatch.mock.calls.length).toBe(0);
|
|
298
|
+
});
|
|
299
|
+
it('should be idempotent', () => {
|
|
300
|
+
sub.cleanup();
|
|
301
|
+
});
|
|
302
|
+
it('should not run even if interval not cancelled', () => {
|
|
303
|
+
const controller = new Controller({ dispatch });
|
|
304
|
+
(controller as any).getState = makeState('test.com', 0);
|
|
305
|
+
|
|
306
|
+
sub.cleanup();
|
|
307
|
+
sub = new PollingSubscription(
|
|
308
|
+
createSubscription(endpoint.extend({ key: () => 'test.com2' }), {
|
|
309
|
+
args: [],
|
|
310
|
+
}),
|
|
311
|
+
controller,
|
|
312
|
+
);
|
|
313
|
+
sub.add(5000);
|
|
314
|
+
jest.runOnlyPendingTimers();
|
|
315
|
+
delete (sub as any).intervalId;
|
|
316
|
+
jest.advanceTimersByTime(5000 * 13);
|
|
317
|
+
|
|
318
|
+
expect(dispatch.mock.calls.length).toBe(1);
|
|
319
|
+
expect(warnSpy.mock.calls.length).toBe(13);
|
|
320
|
+
expect(warnSpy.mock.calls[0]).toMatchSnapshot();
|
|
321
|
+
});
|
|
227
322
|
});
|
|
228
323
|
});
|
|
229
324
|
|
|
230
|
-
describe('
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
sub.cleanup();
|
|
234
|
-
jest.advanceTimersByTime(5000 * 13);
|
|
235
|
-
expect(dispatch.mock.calls.length).toBe(0);
|
|
325
|
+
describe('offline support', () => {
|
|
326
|
+
beforeAll(() => {
|
|
327
|
+
jest.useFakeTimers();
|
|
236
328
|
});
|
|
237
|
-
|
|
238
|
-
|
|
329
|
+
afterAll(() => {
|
|
330
|
+
jest.useRealTimers();
|
|
239
331
|
});
|
|
240
|
-
});
|
|
241
332
|
|
|
242
|
-
describe('offline support', () => {
|
|
243
333
|
function createMocks(listener: ConnectionListener) {
|
|
244
334
|
const dispatch = jest.fn();
|
|
245
335
|
const a = () => Promise.resolve({ id: 5, title: 'hi' });
|
|
246
336
|
const fetch = jest.fn(a);
|
|
337
|
+
const endpoint = new Endpoint(fetch, {
|
|
338
|
+
schema: Article,
|
|
339
|
+
key: () => 'test.com',
|
|
340
|
+
pollFrequency: 5000,
|
|
341
|
+
});
|
|
342
|
+
const controller = new Controller({ dispatch });
|
|
343
|
+
(controller as any).getState = makeState('test.com', 0);
|
|
247
344
|
|
|
248
345
|
const pollingSubscription = new PollingSubscription(
|
|
249
|
-
{
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
frequency: 5000,
|
|
254
|
-
getState: () => initialState,
|
|
255
|
-
},
|
|
256
|
-
dispatch,
|
|
346
|
+
createSubscription(endpoint, {
|
|
347
|
+
args: [],
|
|
348
|
+
}),
|
|
349
|
+
controller,
|
|
257
350
|
listener,
|
|
258
351
|
);
|
|
259
352
|
jest.advanceTimersByTime(1);
|
|
@@ -298,6 +391,21 @@ describe('PollingSubscription', () => {
|
|
|
298
391
|
expect(listener.onlineHandlers.length).toBe(0);
|
|
299
392
|
});
|
|
300
393
|
|
|
394
|
+
it('should not run when timeoutId is deleted after coming online', () => {
|
|
395
|
+
const listener = new MockConnectionListener(false);
|
|
396
|
+
const { dispatch, pollingSubscription } = createMocks(listener);
|
|
397
|
+
expect(dispatch.mock.calls.length).toBe(0);
|
|
398
|
+
|
|
399
|
+
listener.trigger('online');
|
|
400
|
+
delete (pollingSubscription as any).startId;
|
|
401
|
+
jest.advanceTimersByTime(1);
|
|
402
|
+
expect(dispatch.mock.calls.length).toBe(0);
|
|
403
|
+
jest.advanceTimersByTime(5000);
|
|
404
|
+
expect(dispatch.mock.calls.length).toBe(0);
|
|
405
|
+
expect(listener.offlineHandlers.length).toBe(1);
|
|
406
|
+
expect(listener.onlineHandlers.length).toBe(0);
|
|
407
|
+
});
|
|
408
|
+
|
|
301
409
|
it('should stop dispatching when offline again', () => {
|
|
302
410
|
const listener = new MockConnectionListener(true);
|
|
303
411
|
const { dispatch } = createMocks(listener);
|