@data-client/core 0.1.0 → 0.2.1

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.
Files changed (247) hide show
  1. package/dist/index.js +134 -409
  2. package/dist/index.umd.min.js +1 -1
  3. package/dist/next.js +61 -101
  4. package/legacy/actionTypes.js +2 -2
  5. package/legacy/controller/Controller.js +276 -6
  6. package/legacy/controller/createFetch.js +3 -14
  7. package/legacy/controller/createInvalidate.js +1 -1
  8. package/legacy/controller/createInvalidateAll.js +1 -1
  9. package/legacy/controller/createOptimistic.js +1 -7
  10. package/legacy/controller/createReset.js +1 -1
  11. package/legacy/controller/createSet.js +31 -0
  12. package/legacy/controller/createSubscription.js +3 -7
  13. package/legacy/index.js +2 -5
  14. package/legacy/internal.js +2 -2
  15. package/legacy/manager/DevtoolsManager.js +2 -2
  16. package/legacy/manager/LogoutManager.js +2 -2
  17. package/legacy/manager/NetworkManager.js +28 -59
  18. package/legacy/manager/PollingSubscription.js +18 -27
  19. package/legacy/manager/SubscriptionManager.js +16 -42
  20. package/legacy/manager/applyManager.js +2 -1
  21. package/legacy/middlewareTypes.js +1 -1
  22. package/legacy/newActions.js +1 -1
  23. package/legacy/next/index.js +3 -3
  24. package/legacy/state/reducer/createReducer.js +2 -6
  25. package/legacy/state/reducer/fetchReducer.js +3 -13
  26. package/legacy/state/reducer/invalidateReducer.js +1 -1
  27. package/legacy/state/reducer/setReducer.js +9 -16
  28. package/legacy/types.js +2 -6
  29. package/lib/actionTypes.d.ts +1 -0
  30. package/lib/actionTypes.d.ts.map +1 -1
  31. package/lib/actionTypes.js +2 -2
  32. package/lib/controller/Controller.d.ts +126 -6
  33. package/lib/controller/Controller.d.ts.map +1 -1
  34. package/lib/controller/Controller.js +276 -6
  35. package/lib/controller/createFetch.d.ts +2 -2
  36. package/lib/controller/createFetch.d.ts.map +1 -1
  37. package/lib/controller/createFetch.js +3 -14
  38. package/lib/controller/createInvalidate.d.ts +1 -1
  39. package/lib/controller/createInvalidate.d.ts.map +1 -1
  40. package/lib/controller/createInvalidate.js +1 -1
  41. package/lib/controller/createInvalidateAll.d.ts +1 -1
  42. package/lib/controller/createInvalidateAll.d.ts.map +1 -1
  43. package/lib/controller/createInvalidateAll.js +1 -1
  44. package/lib/controller/createOptimistic.d.ts +2 -2
  45. package/lib/controller/createOptimistic.d.ts.map +1 -1
  46. package/lib/controller/createOptimistic.js +1 -7
  47. package/lib/controller/createReset.d.ts +1 -1
  48. package/lib/controller/createReset.d.ts.map +1 -1
  49. package/lib/controller/createReset.js +1 -1
  50. package/lib/controller/{createReceive.d.ts → createSet.d.ts} +6 -6
  51. package/lib/controller/createSet.d.ts.map +1 -0
  52. package/lib/controller/createSet.js +31 -0
  53. package/lib/controller/createSubscription.d.ts +3 -3
  54. package/lib/controller/createSubscription.d.ts.map +1 -1
  55. package/lib/controller/createSubscription.js +3 -7
  56. package/lib/index.d.ts +2 -6
  57. package/lib/index.d.ts.map +1 -1
  58. package/lib/index.js +2 -5
  59. package/lib/internal.d.ts +1 -1
  60. package/lib/internal.d.ts.map +1 -1
  61. package/lib/internal.js +2 -2
  62. package/lib/manager/DevtoolsManager.d.ts +1 -1
  63. package/lib/manager/DevtoolsManager.js +2 -2
  64. package/lib/manager/LogoutManager.d.ts +4 -5
  65. package/lib/manager/LogoutManager.d.ts.map +1 -1
  66. package/lib/manager/LogoutManager.js +2 -2
  67. package/lib/manager/NetworkManager.d.ts +4 -5
  68. package/lib/manager/NetworkManager.d.ts.map +1 -1
  69. package/lib/manager/NetworkManager.js +28 -61
  70. package/lib/manager/PollingSubscription.d.ts +9 -9
  71. package/lib/manager/PollingSubscription.d.ts.map +1 -1
  72. package/lib/manager/PollingSubscription.js +18 -27
  73. package/lib/manager/SubscriptionManager.d.ts +10 -15
  74. package/lib/manager/SubscriptionManager.d.ts.map +1 -1
  75. package/lib/manager/SubscriptionManager.js +16 -42
  76. package/lib/manager/applyManager.d.ts.map +1 -1
  77. package/lib/manager/applyManager.js +2 -1
  78. package/lib/middlewareTypes.d.ts +5 -5
  79. package/lib/middlewareTypes.d.ts.map +1 -1
  80. package/lib/middlewareTypes.js +1 -1
  81. package/lib/newActions.d.ts +26 -18
  82. package/lib/newActions.d.ts.map +1 -1
  83. package/lib/newActions.js +1 -1
  84. package/lib/next/index.d.ts +2 -2
  85. package/lib/next/index.d.ts.map +1 -1
  86. package/lib/next/index.js +3 -3
  87. package/lib/state/reducer/createReducer.d.ts.map +1 -1
  88. package/lib/state/reducer/createReducer.js +2 -6
  89. package/lib/state/reducer/fetchReducer.d.ts +1 -2
  90. package/lib/state/reducer/fetchReducer.d.ts.map +1 -1
  91. package/lib/state/reducer/fetchReducer.js +3 -14
  92. package/lib/state/reducer/invalidateReducer.d.ts +3 -4
  93. package/lib/state/reducer/invalidateReducer.d.ts.map +1 -1
  94. package/lib/state/reducer/invalidateReducer.js +1 -1
  95. package/lib/state/reducer/setReducer.d.ts +2 -38
  96. package/lib/state/reducer/setReducer.d.ts.map +1 -1
  97. package/lib/state/reducer/setReducer.js +9 -17
  98. package/lib/types.d.ts +9 -30
  99. package/lib/types.d.ts.map +1 -1
  100. package/lib/types.js +2 -6
  101. package/package.json +10 -7
  102. package/src/actionTypes.ts +1 -1
  103. package/src/controller/Controller.ts +491 -10
  104. package/src/controller/createFetch.ts +4 -19
  105. package/src/controller/createInvalidate.ts +1 -1
  106. package/src/controller/createInvalidateAll.ts +1 -1
  107. package/src/controller/createOptimistic.ts +3 -9
  108. package/src/controller/createReset.ts +1 -1
  109. package/src/controller/{createReceive.ts → createSet.ts} +9 -17
  110. package/src/controller/createSubscription.ts +3 -10
  111. package/src/index.ts +2 -16
  112. package/src/internal.ts +1 -1
  113. package/src/manager/DevtoolsManager.ts +1 -1
  114. package/src/manager/LogoutManager.ts +4 -5
  115. package/src/manager/NetworkManager.ts +31 -80
  116. package/src/manager/PollingSubscription.ts +40 -38
  117. package/src/manager/SubscriptionManager.ts +22 -54
  118. package/src/manager/__tests__/__snapshots__/pollingSubscription.ts.snap +10 -8
  119. package/src/manager/__tests__/logoutManager.ts +5 -5
  120. package/src/manager/__tests__/manager.ts +2 -4
  121. package/src/manager/__tests__/networkManager.ts +8 -42
  122. package/src/manager/__tests__/pollingSubscription.ts +259 -151
  123. package/src/manager/__tests__/subscriptionManager.ts +7 -13
  124. package/src/manager/applyManager.ts +1 -0
  125. package/src/middlewareTypes.ts +5 -10
  126. package/src/newActions.ts +33 -23
  127. package/src/next/index.ts +2 -2
  128. package/src/state/__tests__/reducer.ts +59 -297
  129. package/src/state/reducer/createReducer.ts +3 -11
  130. package/src/state/reducer/fetchReducer.ts +5 -18
  131. package/src/state/reducer/invalidateReducer.ts +2 -2
  132. package/src/state/reducer/setReducer.ts +10 -22
  133. package/src/types.ts +9 -78
  134. package/ts3.4/actionTypes.d.ts +1 -0
  135. package/ts3.4/controller/Controller.d.ts +168 -6
  136. package/ts3.4/controller/createFetch.d.ts +2 -2
  137. package/ts3.4/controller/createInvalidate.d.ts +1 -1
  138. package/ts3.4/controller/createInvalidateAll.d.ts +1 -1
  139. package/ts3.4/controller/createOptimistic.d.ts +1 -1
  140. package/ts3.4/controller/createReset.d.ts +1 -1
  141. package/ts3.4/controller/{createReceive.d.ts → createSet.d.ts} +6 -6
  142. package/ts3.4/controller/createSubscription.d.ts +3 -3
  143. package/ts3.4/index.d.ts +2 -7
  144. package/ts3.4/internal.d.ts +1 -1
  145. package/ts3.4/manager/DevtoolsManager.d.ts +1 -1
  146. package/ts3.4/manager/LogoutManager.d.ts +4 -5
  147. package/ts3.4/manager/NetworkManager.d.ts +4 -5
  148. package/ts3.4/manager/PollingSubscription.d.ts +9 -9
  149. package/ts3.4/manager/SubscriptionManager.d.ts +10 -15
  150. package/ts3.4/middlewareTypes.d.ts +5 -5
  151. package/ts3.4/newActions.d.ts +26 -18
  152. package/ts3.4/next/index.d.ts +2 -2
  153. package/ts3.4/state/reducer/fetchReducer.d.ts +1 -2
  154. package/ts3.4/state/reducer/invalidateReducer.d.ts +3 -4
  155. package/ts3.4/state/reducer/setReducer.d.ts +2 -38
  156. package/ts3.4/types.d.ts +8 -30
  157. package/legacy/compatibleActions.js +0 -2
  158. package/legacy/controller/BaseController.js +0 -289
  159. package/legacy/controller/createReceive.js +0 -36
  160. package/legacy/endpoint/index.js +0 -2
  161. package/legacy/endpoint/shapes.js +0 -2
  162. package/legacy/endpoint/types.js +0 -2
  163. package/legacy/legacyActions.js +0 -2
  164. package/legacy/next/Controller.js +0 -24
  165. package/legacy/previousActions.js +0 -2
  166. package/legacy/state/applyUpdatersToResults.js +0 -4
  167. package/legacy/state/legacy-actions/createFetch.js +0 -62
  168. package/legacy/state/legacy-actions/createReceive.js +0 -37
  169. package/legacy/state/legacy-actions/createReceiveError.js +0 -28
  170. package/legacy/state/legacy-actions/index.js +0 -4
  171. package/legacy/state/reducerInstance.js +0 -9
  172. package/lib/compatibleActions.d.ts +0 -47
  173. package/lib/compatibleActions.d.ts.map +0 -1
  174. package/lib/compatibleActions.js +0 -2
  175. package/lib/controller/BaseController.d.ts +0 -128
  176. package/lib/controller/BaseController.d.ts.map +0 -1
  177. package/lib/controller/BaseController.js +0 -289
  178. package/lib/controller/createReceive.d.ts.map +0 -1
  179. package/lib/controller/createReceive.js +0 -36
  180. package/lib/endpoint/index.d.ts +0 -3
  181. package/lib/endpoint/index.d.ts.map +0 -1
  182. package/lib/endpoint/index.js +0 -2
  183. package/lib/endpoint/shapes.d.ts +0 -25
  184. package/lib/endpoint/shapes.d.ts.map +0 -1
  185. package/lib/endpoint/shapes.js +0 -2
  186. package/lib/endpoint/types.d.ts +0 -45
  187. package/lib/endpoint/types.d.ts.map +0 -1
  188. package/lib/endpoint/types.js +0 -2
  189. package/lib/legacyActions.d.ts +0 -92
  190. package/lib/legacyActions.d.ts.map +0 -1
  191. package/lib/legacyActions.js +0 -2
  192. package/lib/next/Controller.d.ts +0 -14
  193. package/lib/next/Controller.d.ts.map +0 -1
  194. package/lib/next/Controller.js +0 -24
  195. package/lib/previousActions.d.ts +0 -91
  196. package/lib/previousActions.d.ts.map +0 -1
  197. package/lib/previousActions.js +0 -2
  198. package/lib/state/applyUpdatersToResults.d.ts +0 -13
  199. package/lib/state/applyUpdatersToResults.d.ts.map +0 -1
  200. package/lib/state/applyUpdatersToResults.js +0 -7
  201. package/lib/state/legacy-actions/createFetch.d.ts +0 -19
  202. package/lib/state/legacy-actions/createFetch.d.ts.map +0 -1
  203. package/lib/state/legacy-actions/createFetch.js +0 -62
  204. package/lib/state/legacy-actions/createReceive.d.ts +0 -14
  205. package/lib/state/legacy-actions/createReceive.d.ts.map +0 -1
  206. package/lib/state/legacy-actions/createReceive.js +0 -37
  207. package/lib/state/legacy-actions/createReceiveError.d.ts +0 -9
  208. package/lib/state/legacy-actions/createReceiveError.d.ts.map +0 -1
  209. package/lib/state/legacy-actions/createReceiveError.js +0 -28
  210. package/lib/state/legacy-actions/index.d.ts +0 -4
  211. package/lib/state/legacy-actions/index.d.ts.map +0 -1
  212. package/lib/state/legacy-actions/index.js +0 -4
  213. package/lib/state/reducerInstance.d.ts +0 -7
  214. package/lib/state/reducerInstance.d.ts.map +0 -1
  215. package/lib/state/reducerInstance.js +0 -9
  216. package/src/compatibleActions.ts +0 -96
  217. package/src/controller/BaseController.ts +0 -508
  218. package/src/endpoint/index.ts +0 -14
  219. package/src/endpoint/shapes.ts +0 -53
  220. package/src/endpoint/types.ts +0 -72
  221. package/src/legacyActions.ts +0 -163
  222. package/src/manager/__tests__/__snapshots__/pollingSubscription-endpoint.ts.snap +0 -49
  223. package/src/manager/__tests__/networkManager-legacy.ts +0 -394
  224. package/src/manager/__tests__/pollingSubscription-endpoint.ts +0 -423
  225. package/src/next/Controller.ts +0 -39
  226. package/src/previousActions.ts +0 -159
  227. package/src/state/__tests__/applyUpdatersToResults.ts +0 -40
  228. package/src/state/applyUpdatersToResults.ts +0 -29
  229. package/src/state/legacy-actions/createFetch.ts +0 -95
  230. package/src/state/legacy-actions/createReceive.ts +0 -68
  231. package/src/state/legacy-actions/createReceiveError.ts +0 -43
  232. package/src/state/legacy-actions/index.ts +0 -3
  233. package/src/state/reducerInstance.ts +0 -14
  234. package/ts3.4/compatibleActions.d.ts +0 -47
  235. package/ts3.4/controller/BaseController.d.ts +0 -170
  236. package/ts3.4/endpoint/index.d.ts +0 -3
  237. package/ts3.4/endpoint/shapes.d.ts +0 -25
  238. package/ts3.4/endpoint/types.d.ts +0 -45
  239. package/ts3.4/legacyActions.d.ts +0 -95
  240. package/ts3.4/next/Controller.d.ts +0 -14
  241. package/ts3.4/previousActions.d.ts +0 -94
  242. package/ts3.4/state/applyUpdatersToResults.d.ts +0 -13
  243. package/ts3.4/state/legacy-actions/createFetch.d.ts +0 -19
  244. package/ts3.4/state/legacy-actions/createReceive.d.ts +0 -14
  245. package/ts3.4/state/legacy-actions/createReceiveError.d.ts +0 -9
  246. package/ts3.4/state/legacy-actions/index.d.ts +0 -4
  247. package/ts3.4/state/reducerInstance.d.ts +0 -7
@@ -1,163 +0,0 @@
1
- import type {
2
- UpdateFunction,
3
- Schema,
4
- EndpointExtraOptions,
5
- EndpointInterface,
6
- } from '@data-client/normalizr';
7
- import { FSAWithPayloadAndMeta, FSAWithMeta } from 'flux-standard-action';
8
-
9
- import {
10
- RECEIVE_TYPE,
11
- RESET_TYPE,
12
- FETCH_TYPE,
13
- SUBSCRIBE_TYPE,
14
- UNSUBSCRIBE_TYPE,
15
- INVALIDATE_TYPE,
16
- GC_TYPE,
17
- OPTIMISTIC_TYPE,
18
- } from './actionTypes.js';
19
- import type { EndpointUpdateFunction } from './controller/types.js';
20
- import { FetchShape } from './endpoint/index.js';
21
- import { ErrorableFSAWithPayloadAndMeta } from './fsa.js';
22
-
23
- export interface ReceiveMeta<S extends Schema | undefined> {
24
- schema?: S;
25
- key: string;
26
- args?: readonly any[];
27
- updaters?: Record<string, UpdateFunction<S, any>>;
28
- update?: (result: any, ...args: any) => Record<string, (...args: any) => any>;
29
- fetchedAt?: number;
30
- date: number;
31
- expiresAt: number;
32
- errorPolicy?: (error: any) => 'hard' | 'soft' | undefined;
33
- }
34
-
35
- export type ReceiveAction<
36
- Payload extends object | string | number | null =
37
- | object
38
- | string
39
- | number
40
- | null,
41
- S extends Schema | undefined = any,
42
- > = ErrorableFSAWithPayloadAndMeta<
43
- typeof RECEIVE_TYPE,
44
- Payload,
45
- ReceiveMeta<S>
46
- >;
47
-
48
- export type OptimisticAction<
49
- E extends EndpointInterface & {
50
- update?: EndpointUpdateFunction<E>;
51
- } = EndpointInterface & {
52
- update?: EndpointUpdateFunction<EndpointInterface>;
53
- },
54
- > = {
55
- type: typeof OPTIMISTIC_TYPE;
56
- meta: {
57
- schema: E['schema'];
58
- key: string;
59
- args: readonly any[];
60
- update?: (
61
- result: any,
62
- ...args: any
63
- ) => Record<string, (...args: any) => any>;
64
- fetchedAt: number;
65
- date: number;
66
- expiresAt: number;
67
- errorPolicy?: (error: any) => 'hard' | 'soft' | undefined;
68
- };
69
- endpoint: E;
70
- error?: undefined;
71
- };
72
-
73
- export interface ResetAction {
74
- type: typeof RESET_TYPE;
75
- date: number | Date;
76
- }
77
-
78
- interface FetchMeta<
79
- Payload extends object | string | number | null =
80
- | object
81
- | string
82
- | number
83
- | null,
84
- S extends Schema | undefined = any,
85
- > {
86
- type: FetchShape<any, any>['type'];
87
- schema?: S;
88
- key: string;
89
- args?: readonly any[];
90
- updaters?: Record<string, UpdateFunction<S, any>>;
91
- update?: (result: any, ...args: any) => Record<string, (...args: any) => any>;
92
- options?: EndpointExtraOptions;
93
- throttle: boolean;
94
- resolve: (value?: any | PromiseLike<any>) => void;
95
- reject: (reason?: any) => void;
96
- promise: PromiseLike<any>;
97
- createdAt: number | Date;
98
- optimisticResponse?: Payload;
99
- // indicates whether network manager processed it
100
- nm?: boolean;
101
- }
102
-
103
- export interface FetchAction<
104
- Payload extends object | string | number | null =
105
- | object
106
- | string
107
- | number
108
- | null,
109
- S extends Schema | undefined = any,
110
- > extends FSAWithPayloadAndMeta<
111
- typeof FETCH_TYPE,
112
- () => Promise<Payload>,
113
- FetchMeta<any, any>
114
- > {
115
- meta: FetchMeta<Payload, S>;
116
- endpoint?: undefined;
117
- }
118
-
119
- export interface SubscribeAction
120
- extends FSAWithMeta<typeof SUBSCRIBE_TYPE, undefined, any> {
121
- meta: {
122
- args?: readonly any[];
123
- schema: Schema | undefined;
124
- fetch: () => Promise<any>;
125
- key: string;
126
- options: EndpointExtraOptions | undefined;
127
- };
128
- endpoint?: undefined;
129
- }
130
-
131
- export interface UnsubscribeAction
132
- extends FSAWithMeta<typeof UNSUBSCRIBE_TYPE, undefined, any> {
133
- meta: {
134
- args?: readonly any[];
135
- key: string;
136
- options: EndpointExtraOptions | undefined;
137
- };
138
- endpoint?: undefined;
139
- }
140
-
141
- export interface InvalidateAction
142
- extends FSAWithMeta<typeof INVALIDATE_TYPE, undefined, any> {
143
- meta: {
144
- key: string;
145
- };
146
- }
147
-
148
- export interface GCAction {
149
- type: typeof GC_TYPE;
150
- entities: [string, string][];
151
- results: string[];
152
- }
153
-
154
- // put other actions here in union
155
- export type ActionTypes =
156
- | FetchAction
157
- | OptimisticAction
158
- | ReceiveAction
159
- | SubscribeAction
160
- | UnsubscribeAction
161
- | InvalidateAction
162
- | ResetAction
163
- | GCAction;
@@ -1,49 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`PollingSubscription fresh data cleanup() should not run even if interval not cancelled 1`] = `
4
- [
5
- "Poll intervalId for test.com2 still running, but intervalId deleted",
6
- ]
7
- `;
8
-
9
- exports[`PollingSubscription fresh data should call after period 1`] = `
10
- [
11
- {
12
- "endpoint": [Function],
13
- "meta": {
14
- "args": [],
15
- "key": "test.com",
16
- "options": [Function],
17
- "promise": Promise {},
18
- "reject": [Function],
19
- "resolve": [Function],
20
- "schema": [Function],
21
- "throttle": true,
22
- "type": "read",
23
- },
24
- "payload": [Function],
25
- "type": "rest-hooks/fetch",
26
- },
27
- ]
28
- `;
29
-
30
- exports[`PollingSubscription fresh data should call after period 2`] = `
31
- [
32
- {
33
- "endpoint": [Function],
34
- "meta": {
35
- "args": [],
36
- "key": "test.com",
37
- "options": [Function],
38
- "promise": Promise {},
39
- "reject": [Function],
40
- "resolve": [Function],
41
- "schema": [Function],
42
- "throttle": true,
43
- "type": "read",
44
- },
45
- "payload": [Function],
46
- "type": "rest-hooks/fetch",
47
- },
48
- ]
49
- `;
@@ -1,394 +0,0 @@
1
- import { ArticleResource } from '__tests__/legacy-3';
2
-
3
- import { RECEIVE_TYPE } from '../../actionTypes';
4
- import Controller from '../../controller/Controller';
5
- import { FetchAction } from '../../legacyActions';
6
- import { createFetch } from '../../state/legacy-actions';
7
- import { initialState } from '../../state/reducer/createReducer';
8
- import { Middleware } from '../../types';
9
- import NetworkManager from '../NetworkManager';
10
-
11
- describe('NetworkManager', () => {
12
- const manager = new NetworkManager();
13
- const getState = () => initialState;
14
-
15
- afterAll(() => {
16
- manager.cleanup();
17
- });
18
- let errorspy: jest.SpyInstance;
19
- beforeEach(() => {
20
- errorspy = jest.spyOn(global.console, 'error');
21
- });
22
- afterEach(() => {
23
- errorspy.mockRestore();
24
- });
25
-
26
- it('getState() should have initialState before middleware run', () => {
27
- class Hacked extends NetworkManager {
28
- getHacked() {
29
- return this.getState();
30
- }
31
- }
32
- const hacked = new Hacked();
33
- expect(hacked.getHacked()).toEqual(initialState);
34
- });
35
-
36
- describe('getMiddleware()', () => {
37
- it('should return the same value every call', () => {
38
- const a = manager.getMiddleware();
39
- expect(a).toBe(manager.getMiddleware());
40
- expect(a).toBe(manager.getMiddleware());
41
- });
42
- it('should return the different value for a different instance', () => {
43
- const a = manager.getMiddleware();
44
- const manager2 = new NetworkManager();
45
- const a2 = manager2.getMiddleware();
46
- expect(a).not.toBe(a2);
47
- expect(a2).toBe(manager2.getMiddleware());
48
- manager2.cleanup();
49
- });
50
- });
51
-
52
- describe('middleware', () => {
53
- const detailShape = ArticleResource.detailShape();
54
- detailShape.fetch = () => Promise.resolve({ id: 5, title: 'hi' });
55
- const fetchResolveAction = createFetch(detailShape, {
56
- params: { id: 5 },
57
- throttle: false,
58
- });
59
-
60
- const updaters = {
61
- [ArticleResource.listShape().getFetchKey({})]:
62
- () => (result: string[], oldResults: string[] | undefined) =>
63
- [...(oldResults || []), result] as any,
64
- };
65
- const fetchReceiveWithUpdatersAction: FetchAction = {
66
- ...fetchResolveAction,
67
- meta: {
68
- ...fetchResolveAction.meta,
69
- updaters,
70
- },
71
- };
72
-
73
- const updateShape = ArticleResource.updateShape();
74
- updateShape.fetch = (params, body) => Promise.resolve(body);
75
- const fetchRpcWithUpdatersAction = createFetch(updateShape, {
76
- params: { id: 5 },
77
- body: { id: 5, title: 'hi' },
78
- throttle: false,
79
- updateParams: [
80
- [
81
- ArticleResource.listShape(),
82
- {},
83
- () => (result: string[], oldResults: string[] | undefined) =>
84
- [...(oldResults || []), result],
85
- ],
86
- ],
87
- });
88
- const partialUpdateShape = ArticleResource.partialUpdateShape();
89
- partialUpdateShape.fetch = (params, body) => Promise.resolve(body);
90
- const fetchRpcWithUpdatersAndOptimisticAction = createFetch(
91
- partialUpdateShape,
92
- {
93
- params: { id: 5 },
94
- body: { id: 5, title: 'hi' },
95
- throttle: false,
96
- updateParams: [
97
- [
98
- ArticleResource.listShape(),
99
- {},
100
- () => (result: string[], oldResults: string[] | undefined) =>
101
- [...(oldResults || []), result],
102
- ],
103
- ],
104
- },
105
- );
106
-
107
- const errorUpdateShape = ArticleResource.updateShape();
108
- errorUpdateShape.fetch = () => Promise.reject(new Error('Failed'));
109
- const fetchRejectAction = createFetch(errorUpdateShape, {
110
- params: { id: 5 },
111
- body: { id: 5, title: 'hi' },
112
- throttle: false,
113
- });
114
- (fetchRejectAction.meta.promise as any).catch(e => {});
115
-
116
- let NM: NetworkManager;
117
- let middleware: Middleware;
118
- beforeEach(() => {
119
- NM = new NetworkManager(42, 7);
120
- middleware = NM.getMiddleware();
121
- });
122
- afterEach(() => {
123
- NM.cleanup();
124
- });
125
-
126
- it('should handle fetch actions and dispatch on success', async () => {
127
- const next = jest.fn();
128
- const dispatch = jest.fn();
129
- const controller = new Controller({ dispatch, getState });
130
- const API: Controller & { controller: Controller } = Object.create(
131
- controller,
132
- {
133
- controller: { value: controller },
134
- },
135
- );
136
-
137
- middleware(API)(next)(fetchResolveAction);
138
-
139
- const data = await fetchResolveAction.payload();
140
-
141
- const action = {
142
- type: RECEIVE_TYPE,
143
- payload: data,
144
- meta: {
145
- schema: fetchResolveAction.meta.schema,
146
- args: fetchResolveAction.meta.args,
147
- update: fetchResolveAction.meta.update,
148
- key: fetchResolveAction.meta.key,
149
- date: expect.any(Number),
150
- expiresAt: expect.any(Number),
151
- fetchedAt: expect.any(Number),
152
- },
153
- };
154
- expect(dispatch).toHaveBeenCalledWith(action);
155
- expect(next).not.toHaveBeenCalledWith(action);
156
- });
157
- it('should handle fetch receive action and dispatch on success with updaters', async () => {
158
- const next = jest.fn();
159
- const dispatch = jest.fn();
160
- const controller = new Controller({ dispatch, getState });
161
- const API: Controller & { controller: Controller } = Object.create(
162
- controller,
163
- {
164
- controller: { value: controller },
165
- },
166
- );
167
- middleware(API)(next)(fetchReceiveWithUpdatersAction);
168
-
169
- const data = await fetchReceiveWithUpdatersAction.payload();
170
-
171
- const action = {
172
- type: RECEIVE_TYPE,
173
- payload: data,
174
- meta: {
175
- updaters: {
176
- [ArticleResource.listShape().getFetchKey({})]: expect.any(Function),
177
- },
178
- args: fetchReceiveWithUpdatersAction.meta.args,
179
- update: fetchReceiveWithUpdatersAction.meta.update,
180
- schema: fetchReceiveWithUpdatersAction.meta.schema,
181
- key: fetchReceiveWithUpdatersAction.meta.key,
182
- date: expect.any(Number),
183
- expiresAt: expect.any(Number),
184
- fetchedAt: expect.any(Number),
185
- },
186
- };
187
- expect(dispatch).toHaveBeenCalledWith(action);
188
- expect(next).not.toHaveBeenCalledWith(action);
189
- });
190
- it('should handle fetch rpc action and dispatch on success with updaters', async () => {
191
- const next = jest.fn();
192
- const dispatch = jest.fn();
193
- const controller = new Controller({ dispatch, getState });
194
- const API: Controller & { controller: Controller } = Object.create(
195
- controller,
196
- {
197
- controller: { value: controller },
198
- },
199
- );
200
- middleware(API)(next)(fetchRpcWithUpdatersAction);
201
-
202
- const data = await fetchRpcWithUpdatersAction.payload();
203
-
204
- const action = {
205
- type: RECEIVE_TYPE,
206
- payload: data,
207
- meta: {
208
- updaters: undefined,
209
- args: fetchRpcWithUpdatersAction.meta.args,
210
- update: expect.any(Function),
211
- schema: fetchRpcWithUpdatersAction.meta.schema,
212
- key: fetchRpcWithUpdatersAction.meta.key,
213
- date: expect.any(Number),
214
- expiresAt: expect.any(Number),
215
- fetchedAt: expect.any(Number),
216
- },
217
- };
218
- expect(dispatch).toHaveBeenCalledWith(action);
219
- expect(next).not.toHaveBeenCalledWith(action);
220
- });
221
- it('should handle fetch rpc action with optimistic response and dispatch on success with updaters', async () => {
222
- const next = jest.fn();
223
- const dispatch = jest.fn();
224
- const controller = new Controller({ dispatch, getState });
225
- const API: Controller & { controller: Controller } = Object.create(
226
- controller,
227
- {
228
- controller: { value: controller },
229
- },
230
- );
231
- middleware(API)(next)(fetchRpcWithUpdatersAndOptimisticAction);
232
-
233
- const data = await fetchRpcWithUpdatersAndOptimisticAction.payload();
234
-
235
- expect(next).toHaveBeenCalled();
236
- expect(dispatch).toHaveBeenCalledWith({
237
- type: RECEIVE_TYPE,
238
- payload: data,
239
- meta: {
240
- updaters: undefined,
241
- args: fetchRpcWithUpdatersAndOptimisticAction.meta.args,
242
- update: expect.any(Function),
243
- schema: fetchRpcWithUpdatersAndOptimisticAction.meta.schema,
244
- key: fetchRpcWithUpdatersAndOptimisticAction.meta.key,
245
- date: expect.any(Number),
246
- expiresAt: expect.any(Number),
247
- fetchedAt: expect.any(Number),
248
- },
249
- });
250
- });
251
- it('should use dataExpireLength from action if specified', async () => {
252
- const dispatch = jest.fn();
253
- const controller = new Controller({ dispatch, getState });
254
- const API: Controller & { controller: Controller } = Object.create(
255
- controller,
256
- {
257
- controller: { value: controller },
258
- },
259
- );
260
- middleware(API)(() => Promise.resolve())({
261
- ...fetchResolveAction,
262
- meta: {
263
- ...fetchResolveAction.meta,
264
- options: { dataExpiryLength: 314 },
265
- },
266
- });
267
-
268
- await fetchResolveAction.payload();
269
-
270
- expect(dispatch).toHaveBeenCalled();
271
- const { meta } = dispatch.mock.calls[0][0];
272
- expect(meta.expiresAt - meta.date).toBe(314);
273
- });
274
- it('should use dataExpireLength from NetworkManager if not specified in action', async () => {
275
- const dispatch = jest.fn();
276
- const controller = new Controller({ dispatch, getState });
277
- const API: Controller & { controller: Controller } = Object.create(
278
- controller,
279
- {
280
- controller: { value: controller },
281
- },
282
- );
283
- middleware(API)(() => Promise.resolve())({
284
- ...fetchResolveAction,
285
- meta: {
286
- ...fetchResolveAction.meta,
287
- options: { dataExpiryLength: undefined },
288
- },
289
- });
290
-
291
- await fetchResolveAction.payload();
292
-
293
- expect(dispatch).toHaveBeenCalled();
294
- const { meta } = dispatch.mock.calls[0][0];
295
- expect(meta.expiresAt - meta.date).toBe(42);
296
- });
297
- it('should handle fetch actions and dispatch on error', async () => {
298
- const next = jest.fn();
299
- const dispatch = jest.fn();
300
- const controller = new Controller({ dispatch, getState });
301
- const API: Controller & { controller: Controller } = Object.create(
302
- controller,
303
- {
304
- controller: { value: controller },
305
- },
306
- );
307
- try {
308
- await middleware(API)(next)(fetchRejectAction);
309
- } catch (error) {
310
- expect(next).not.toHaveBeenCalled();
311
- expect(dispatch).toHaveBeenCalledWith({
312
- type: RECEIVE_TYPE,
313
- payload: error,
314
- meta: {
315
- schema: fetchRejectAction.meta.schema,
316
- key: fetchRejectAction.meta.key,
317
- date: expect.any(Number),
318
- expiresAt: expect.any(Number),
319
- },
320
- error: true,
321
- });
322
- }
323
- });
324
- it('should use errorExpireLength from action if specified', async () => {
325
- const dispatch = jest.fn();
326
- const controller = new Controller({ dispatch, getState });
327
- const API: Controller & { controller: Controller } = Object.create(
328
- controller,
329
- {
330
- controller: { value: controller },
331
- },
332
- );
333
- try {
334
- await middleware(API)(() => Promise.resolve())({
335
- ...fetchRejectAction,
336
- meta: {
337
- ...fetchRejectAction.meta,
338
- options: { errorExpiryLength: 1234 },
339
- },
340
- });
341
- } catch (error) {
342
- expect(dispatch).toHaveBeenCalled();
343
- const { meta } = dispatch.mock.calls[0][0];
344
- expect(meta.expiresAt - meta.date).toBe(1234);
345
- }
346
- });
347
- it('should use errorExpireLength from NetworkManager if not specified in action', async () => {
348
- const dispatch = jest.fn();
349
- const controller = new Controller({ dispatch, getState });
350
- const API: Controller & { controller: Controller } = Object.create(
351
- controller,
352
- {
353
- controller: { value: controller },
354
- },
355
- );
356
- try {
357
- await middleware(API)(() => Promise.resolve())({
358
- ...fetchRejectAction,
359
- meta: {
360
- ...fetchRejectAction.meta,
361
- options: {
362
- ...fetchRejectAction.meta.options,
363
- errorExpiryLength: undefined,
364
- },
365
- },
366
- });
367
- } catch (error) {
368
- expect(dispatch).toHaveBeenCalled();
369
- const { meta } = dispatch.mock.calls[0][0];
370
- expect(meta.expiresAt - meta.date).toBe(7);
371
- }
372
- });
373
-
374
- it('getLastReset() should handle Date object', async () => {
375
- const mgr = new NetworkManager();
376
- jest.spyOn(mgr, 'getState' as any).mockImplementation((): any => ({
377
- ...initialState,
378
- lastReset: new Date(0),
379
- }));
380
-
381
- expect((mgr as any).getLastReset()).toBeLessThan(Date.now());
382
- });
383
-
384
- it('getLastReset() should handle null', async () => {
385
- const mgr = new NetworkManager();
386
- jest.spyOn(mgr, 'getState' as any).mockImplementation((): any => ({
387
- ...initialState,
388
- lastReset: null,
389
- }));
390
-
391
- expect((mgr as any).getLastReset()).toBeLessThan(Date.now());
392
- });
393
- });
394
- });