@data-client/core 0.1.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.
Files changed (308) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +71 -0
  3. package/dist/index.js +1643 -0
  4. package/dist/index.umd.min.js +1 -0
  5. package/dist/next.js +461 -0
  6. package/dist/package.json +1 -0
  7. package/legacy/actionTypes.js +12 -0
  8. package/legacy/compatibleActions.js +2 -0
  9. package/legacy/controller/BaseController.js +289 -0
  10. package/legacy/controller/Controller.js +20 -0
  11. package/legacy/controller/createFetch.js +42 -0
  12. package/legacy/controller/createInvalidate.js +12 -0
  13. package/legacy/controller/createInvalidateAll.js +8 -0
  14. package/legacy/controller/createOptimistic.js +33 -0
  15. package/legacy/controller/createReceive.js +36 -0
  16. package/legacy/controller/createReset.js +8 -0
  17. package/legacy/controller/createSubscription.js +30 -0
  18. package/legacy/controller/types.js +2 -0
  19. package/legacy/endpoint/index.js +2 -0
  20. package/legacy/endpoint/shapes.js +2 -0
  21. package/legacy/endpoint/types.js +2 -0
  22. package/legacy/fsa.js +2 -0
  23. package/legacy/index.js +22 -0
  24. package/legacy/internal.js +4 -0
  25. package/legacy/legacyActions.js +2 -0
  26. package/legacy/manager/ConnectionListener.js +2 -0
  27. package/legacy/manager/DefaultConnectionListener.js +40 -0
  28. package/legacy/manager/DevtoolsManager.js +73 -0
  29. package/legacy/manager/LogoutManager.js +34 -0
  30. package/legacy/manager/NetworkManager.js +291 -0
  31. package/legacy/manager/PollingSubscription.js +159 -0
  32. package/legacy/manager/SubscriptionManager.js +117 -0
  33. package/legacy/manager/applyManager.js +23 -0
  34. package/legacy/manager/devtoolsTypes.js +2 -0
  35. package/legacy/manager/index.js +6 -0
  36. package/legacy/middlewareTypes.js +2 -0
  37. package/legacy/newActions.js +2 -0
  38. package/legacy/next/Controller.js +24 -0
  39. package/legacy/next/index.js +3 -0
  40. package/legacy/previousActions.js +2 -0
  41. package/legacy/state/RIC.js +3 -0
  42. package/legacy/state/applyUpdatersToResults.js +4 -0
  43. package/legacy/state/legacy-actions/createFetch.js +62 -0
  44. package/legacy/state/legacy-actions/createReceive.js +37 -0
  45. package/legacy/state/legacy-actions/createReceiveError.js +28 -0
  46. package/legacy/state/legacy-actions/index.js +4 -0
  47. package/legacy/state/reducer/createReducer.js +54 -0
  48. package/legacy/state/reducer/fetchReducer.js +32 -0
  49. package/legacy/state/reducer/invalidateReducer.js +28 -0
  50. package/legacy/state/reducer/setReducer.js +113 -0
  51. package/legacy/state/reducerInstance.js +9 -0
  52. package/legacy/state/selectMeta.js +4 -0
  53. package/legacy/types.js +8 -0
  54. package/lib/actionTypes.d.ts +11 -0
  55. package/lib/actionTypes.d.ts.map +1 -0
  56. package/lib/actionTypes.js +12 -0
  57. package/lib/compatibleActions.d.ts +47 -0
  58. package/lib/compatibleActions.d.ts.map +1 -0
  59. package/lib/compatibleActions.js +2 -0
  60. package/lib/controller/BaseController.d.ts +128 -0
  61. package/lib/controller/BaseController.d.ts.map +1 -0
  62. package/lib/controller/BaseController.js +289 -0
  63. package/lib/controller/Controller.d.ts +14 -0
  64. package/lib/controller/Controller.d.ts.map +1 -0
  65. package/lib/controller/Controller.js +20 -0
  66. package/lib/controller/createFetch.d.ts +12 -0
  67. package/lib/controller/createFetch.d.ts.map +1 -0
  68. package/lib/controller/createFetch.js +42 -0
  69. package/lib/controller/createInvalidate.d.ts +6 -0
  70. package/lib/controller/createInvalidate.d.ts.map +1 -0
  71. package/lib/controller/createInvalidate.js +12 -0
  72. package/lib/controller/createInvalidateAll.d.ts +3 -0
  73. package/lib/controller/createInvalidateAll.d.ts.map +1 -0
  74. package/lib/controller/createInvalidateAll.js +8 -0
  75. package/lib/controller/createOptimistic.d.ts +10 -0
  76. package/lib/controller/createOptimistic.d.ts.map +1 -0
  77. package/lib/controller/createOptimistic.js +33 -0
  78. package/lib/controller/createReceive.d.ts +20 -0
  79. package/lib/controller/createReceive.d.ts.map +1 -0
  80. package/lib/controller/createReceive.js +36 -0
  81. package/lib/controller/createReset.d.ts +3 -0
  82. package/lib/controller/createReset.d.ts.map +1 -0
  83. package/lib/controller/createReset.js +8 -0
  84. package/lib/controller/createSubscription.d.ts +9 -0
  85. package/lib/controller/createSubscription.d.ts.map +1 -0
  86. package/lib/controller/createSubscription.js +30 -0
  87. package/lib/controller/types.d.ts +6 -0
  88. package/lib/controller/types.d.ts.map +1 -0
  89. package/lib/controller/types.js +2 -0
  90. package/lib/endpoint/index.d.ts +3 -0
  91. package/lib/endpoint/index.d.ts.map +1 -0
  92. package/lib/endpoint/index.js +2 -0
  93. package/lib/endpoint/shapes.d.ts +25 -0
  94. package/lib/endpoint/shapes.d.ts.map +1 -0
  95. package/lib/endpoint/shapes.js +2 -0
  96. package/lib/endpoint/types.d.ts +45 -0
  97. package/lib/endpoint/types.d.ts.map +1 -0
  98. package/lib/endpoint/types.js +2 -0
  99. package/lib/fsa.d.ts +41 -0
  100. package/lib/fsa.d.ts.map +1 -0
  101. package/lib/fsa.js +2 -0
  102. package/lib/index.d.ts +19 -0
  103. package/lib/index.d.ts.map +1 -0
  104. package/lib/index.js +22 -0
  105. package/lib/internal.d.ts +4 -0
  106. package/lib/internal.d.ts.map +1 -0
  107. package/lib/internal.js +4 -0
  108. package/lib/legacyActions.d.ts +92 -0
  109. package/lib/legacyActions.d.ts.map +1 -0
  110. package/lib/legacyActions.js +2 -0
  111. package/lib/manager/ConnectionListener.d.ts +8 -0
  112. package/lib/manager/ConnectionListener.d.ts.map +1 -0
  113. package/lib/manager/ConnectionListener.js +2 -0
  114. package/lib/manager/DefaultConnectionListener.d.ts +20 -0
  115. package/lib/manager/DefaultConnectionListener.d.ts.map +1 -0
  116. package/lib/manager/DefaultConnectionListener.js +40 -0
  117. package/lib/manager/DevtoolsManager.d.ts +24 -0
  118. package/lib/manager/DevtoolsManager.d.ts.map +1 -0
  119. package/lib/manager/DevtoolsManager.js +74 -0
  120. package/lib/manager/LogoutManager.d.ts +25 -0
  121. package/lib/manager/LogoutManager.d.ts.map +1 -0
  122. package/lib/manager/LogoutManager.js +34 -0
  123. package/lib/manager/NetworkManager.d.ts +82 -0
  124. package/lib/manager/NetworkManager.d.ts.map +1 -0
  125. package/lib/manager/NetworkManager.js +295 -0
  126. package/lib/manager/PollingSubscription.d.ts +45 -0
  127. package/lib/manager/PollingSubscription.d.ts.map +1 -0
  128. package/lib/manager/PollingSubscription.js +159 -0
  129. package/lib/manager/SubscriptionManager.d.ts +55 -0
  130. package/lib/manager/SubscriptionManager.d.ts.map +1 -0
  131. package/lib/manager/SubscriptionManager.js +117 -0
  132. package/lib/manager/applyManager.d.ts +10 -0
  133. package/lib/manager/applyManager.d.ts.map +1 -0
  134. package/lib/manager/applyManager.js +23 -0
  135. package/lib/manager/devtoolsTypes.d.ts +205 -0
  136. package/lib/manager/devtoolsTypes.d.ts.map +1 -0
  137. package/lib/manager/devtoolsTypes.js +2 -0
  138. package/lib/manager/index.d.ts +8 -0
  139. package/lib/manager/index.d.ts.map +1 -0
  140. package/lib/manager/index.js +6 -0
  141. package/lib/middlewareTypes.d.ts +18 -0
  142. package/lib/middlewareTypes.d.ts.map +1 -0
  143. package/lib/middlewareTypes.js +2 -0
  144. package/lib/newActions.d.ts +85 -0
  145. package/lib/newActions.d.ts.map +1 -0
  146. package/lib/newActions.js +2 -0
  147. package/lib/next/Controller.d.ts +14 -0
  148. package/lib/next/Controller.d.ts.map +1 -0
  149. package/lib/next/Controller.js +24 -0
  150. package/lib/next/index.d.ts +3 -0
  151. package/lib/next/index.d.ts.map +1 -0
  152. package/lib/next/index.js +3 -0
  153. package/lib/previousActions.d.ts +91 -0
  154. package/lib/previousActions.d.ts.map +1 -0
  155. package/lib/previousActions.js +2 -0
  156. package/lib/state/RIC.d.ts +2 -0
  157. package/lib/state/RIC.js +3 -0
  158. package/lib/state/applyUpdatersToResults.d.ts +13 -0
  159. package/lib/state/applyUpdatersToResults.d.ts.map +1 -0
  160. package/lib/state/applyUpdatersToResults.js +7 -0
  161. package/lib/state/legacy-actions/createFetch.d.ts +19 -0
  162. package/lib/state/legacy-actions/createFetch.d.ts.map +1 -0
  163. package/lib/state/legacy-actions/createFetch.js +62 -0
  164. package/lib/state/legacy-actions/createReceive.d.ts +14 -0
  165. package/lib/state/legacy-actions/createReceive.d.ts.map +1 -0
  166. package/lib/state/legacy-actions/createReceive.js +37 -0
  167. package/lib/state/legacy-actions/createReceiveError.d.ts +9 -0
  168. package/lib/state/legacy-actions/createReceiveError.d.ts.map +1 -0
  169. package/lib/state/legacy-actions/createReceiveError.js +28 -0
  170. package/lib/state/legacy-actions/index.d.ts +4 -0
  171. package/lib/state/legacy-actions/index.d.ts.map +1 -0
  172. package/lib/state/legacy-actions/index.js +4 -0
  173. package/lib/state/reducer/createReducer.d.ts +7 -0
  174. package/lib/state/reducer/createReducer.d.ts.map +1 -0
  175. package/lib/state/reducer/createReducer.js +55 -0
  176. package/lib/state/reducer/fetchReducer.d.ts +4 -0
  177. package/lib/state/reducer/fetchReducer.d.ts.map +1 -0
  178. package/lib/state/reducer/fetchReducer.js +34 -0
  179. package/lib/state/reducer/invalidateReducer.d.ts +37 -0
  180. package/lib/state/reducer/invalidateReducer.d.ts.map +1 -0
  181. package/lib/state/reducer/invalidateReducer.js +34 -0
  182. package/lib/state/reducer/setReducer.d.ts +40 -0
  183. package/lib/state/reducer/setReducer.d.ts.map +1 -0
  184. package/lib/state/reducer/setReducer.js +119 -0
  185. package/lib/state/reducerInstance.d.ts +7 -0
  186. package/lib/state/reducerInstance.d.ts.map +1 -0
  187. package/lib/state/reducerInstance.js +9 -0
  188. package/lib/state/selectMeta.d.ts +3 -0
  189. package/lib/state/selectMeta.d.ts.map +1 -0
  190. package/lib/state/selectMeta.js +4 -0
  191. package/lib/types.d.ts +71 -0
  192. package/lib/types.d.ts.map +1 -0
  193. package/lib/types.js +8 -0
  194. package/node.mjs +1 -0
  195. package/package.json +127 -0
  196. package/src/actionTypes.ts +11 -0
  197. package/src/compatibleActions.ts +96 -0
  198. package/src/controller/BaseController.ts +508 -0
  199. package/src/controller/Controller.ts +32 -0
  200. package/src/controller/__tests__/Controller.ts +29 -0
  201. package/src/controller/__tests__/__snapshots__/getResponse.ts.snap +35 -0
  202. package/src/controller/__tests__/getResponse.ts +182 -0
  203. package/src/controller/createFetch.ts +54 -0
  204. package/src/controller/createInvalidate.ts +16 -0
  205. package/src/controller/createInvalidateAll.ts +11 -0
  206. package/src/controller/createOptimistic.ts +47 -0
  207. package/src/controller/createReceive.ts +85 -0
  208. package/src/controller/createReset.ts +9 -0
  209. package/src/controller/createSubscription.ts +39 -0
  210. package/src/controller/types.ts +22 -0
  211. package/src/endpoint/index.ts +14 -0
  212. package/src/endpoint/shapes.ts +53 -0
  213. package/src/endpoint/types.ts +72 -0
  214. package/src/fsa.ts +99 -0
  215. package/src/index.ts +61 -0
  216. package/src/internal.ts +3 -0
  217. package/src/legacyActions.ts +163 -0
  218. package/src/manager/ConnectionListener.ts +7 -0
  219. package/src/manager/DefaultConnectionListener.ts +54 -0
  220. package/src/manager/DevtoolsManager.ts +99 -0
  221. package/src/manager/LogoutManager.ts +57 -0
  222. package/src/manager/NetworkManager.ts +346 -0
  223. package/src/manager/PollingSubscription.ts +190 -0
  224. package/src/manager/SubscriptionManager.ts +156 -0
  225. package/src/manager/__tests__/__snapshots__/pollingSubscription-endpoint.ts.snap +49 -0
  226. package/src/manager/__tests__/__snapshots__/pollingSubscription.ts.snap +43 -0
  227. package/src/manager/__tests__/logoutManager.ts +112 -0
  228. package/src/manager/__tests__/manager.ts +44 -0
  229. package/src/manager/__tests__/networkManager-legacy.ts +394 -0
  230. package/src/manager/__tests__/networkManager.ts +426 -0
  231. package/src/manager/__tests__/pollingSubscription-endpoint.ts +423 -0
  232. package/src/manager/__tests__/pollingSubscription.ts +313 -0
  233. package/src/manager/__tests__/subscriptionManager.ts +208 -0
  234. package/src/manager/applyManager.ts +33 -0
  235. package/src/manager/devtoolsTypes.ts +210 -0
  236. package/src/manager/index.ts +7 -0
  237. package/src/middlewareTypes.ts +49 -0
  238. package/src/newActions.ts +140 -0
  239. package/src/next/Controller.ts +39 -0
  240. package/src/next/index.ts +2 -0
  241. package/src/package.json +1 -0
  242. package/src/previousActions.ts +159 -0
  243. package/src/state/RIC.d.ts +2 -0
  244. package/src/state/RIC.js +5 -0
  245. package/src/state/__tests__/RIC.web.ts +16 -0
  246. package/src/state/__tests__/__snapshots__/reducer.ts.snap +56 -0
  247. package/src/state/__tests__/applyUpdatersToResults.ts +40 -0
  248. package/src/state/__tests__/reducer.ts +868 -0
  249. package/src/state/applyUpdatersToResults.ts +29 -0
  250. package/src/state/legacy-actions/createFetch.ts +95 -0
  251. package/src/state/legacy-actions/createReceive.ts +68 -0
  252. package/src/state/legacy-actions/createReceiveError.ts +43 -0
  253. package/src/state/legacy-actions/index.ts +3 -0
  254. package/src/state/reducer/createReducer.ts +80 -0
  255. package/src/state/reducer/fetchReducer.ts +48 -0
  256. package/src/state/reducer/invalidateReducer.ts +39 -0
  257. package/src/state/reducer/setReducer.ts +157 -0
  258. package/src/state/reducerInstance.ts +14 -0
  259. package/src/state/selectMeta.ts +8 -0
  260. package/src/types.ts +125 -0
  261. package/ts3.4/actionTypes.d.ts +11 -0
  262. package/ts3.4/compatibleActions.d.ts +47 -0
  263. package/ts3.4/controller/BaseController.d.ts +170 -0
  264. package/ts3.4/controller/Controller.d.ts +14 -0
  265. package/ts3.4/controller/createFetch.d.ts +14 -0
  266. package/ts3.4/controller/createInvalidate.d.ts +8 -0
  267. package/ts3.4/controller/createInvalidateAll.d.ts +3 -0
  268. package/ts3.4/controller/createOptimistic.d.ts +12 -0
  269. package/ts3.4/controller/createReceive.d.ts +24 -0
  270. package/ts3.4/controller/createReset.d.ts +3 -0
  271. package/ts3.4/controller/createSubscription.d.ts +13 -0
  272. package/ts3.4/controller/types.d.ts +6 -0
  273. package/ts3.4/endpoint/index.d.ts +3 -0
  274. package/ts3.4/endpoint/shapes.d.ts +25 -0
  275. package/ts3.4/endpoint/types.d.ts +45 -0
  276. package/ts3.4/fsa.d.ts +41 -0
  277. package/ts3.4/index.d.ts +22 -0
  278. package/ts3.4/internal.d.ts +4 -0
  279. package/ts3.4/legacyActions.d.ts +95 -0
  280. package/ts3.4/manager/ConnectionListener.d.ts +8 -0
  281. package/ts3.4/manager/DefaultConnectionListener.d.ts +20 -0
  282. package/ts3.4/manager/DevtoolsManager.d.ts +24 -0
  283. package/ts3.4/manager/LogoutManager.d.ts +25 -0
  284. package/ts3.4/manager/NetworkManager.d.ts +82 -0
  285. package/ts3.4/manager/PollingSubscription.d.ts +45 -0
  286. package/ts3.4/manager/SubscriptionManager.d.ts +55 -0
  287. package/ts3.4/manager/applyManager.d.ts +10 -0
  288. package/ts3.4/manager/devtoolsTypes.d.ts +205 -0
  289. package/ts3.4/manager/index.d.ts +8 -0
  290. package/ts3.4/middlewareTypes.d.ts +18 -0
  291. package/ts3.4/newActions.d.ts +88 -0
  292. package/ts3.4/next/Controller.d.ts +14 -0
  293. package/ts3.4/next/index.d.ts +3 -0
  294. package/ts3.4/previousActions.d.ts +94 -0
  295. package/ts3.4/state/RIC.d.ts +2 -0
  296. package/ts3.4/state/applyUpdatersToResults.d.ts +13 -0
  297. package/ts3.4/state/legacy-actions/createFetch.d.ts +19 -0
  298. package/ts3.4/state/legacy-actions/createReceive.d.ts +14 -0
  299. package/ts3.4/state/legacy-actions/createReceiveError.d.ts +9 -0
  300. package/ts3.4/state/legacy-actions/index.d.ts +4 -0
  301. package/ts3.4/state/reducer/createReducer.d.ts +7 -0
  302. package/ts3.4/state/reducer/fetchReducer.d.ts +4 -0
  303. package/ts3.4/state/reducer/invalidateReducer.d.ts +37 -0
  304. package/ts3.4/state/reducer/setReducer.d.ts +40 -0
  305. package/ts3.4/state/reducerInstance.d.ts +7 -0
  306. package/ts3.4/state/selectMeta.d.ts +3 -0
  307. package/ts3.4/types.d.ts +73 -0
  308. package/typescript.svg +8 -0
@@ -0,0 +1,29 @@
1
+ import type { Schema, Normalize, UpdateFunction } from '@data-client/normalizr';
2
+
3
+ type ResultStateFromUpdateFunctions<
4
+ SourceSchema extends Schema,
5
+ UpdateFunctions extends {
6
+ [key: string]: UpdateFunction<SourceSchema, any>;
7
+ },
8
+ > = { [K in keyof UpdateFunctions]: any };
9
+
10
+ export default function applyUpdatersToResults<
11
+ SourceSchema extends Schema,
12
+ UpdateFunctions extends {
13
+ [key: string]: UpdateFunction<SourceSchema, any>;
14
+ },
15
+ >(
16
+ results: ResultStateFromUpdateFunctions<SourceSchema, UpdateFunctions>,
17
+ result: Normalize<SourceSchema>,
18
+ updaters: UpdateFunctions,
19
+ ) {
20
+ return {
21
+ ...results,
22
+ ...Object.fromEntries(
23
+ Object.entries(updaters).map(([fetchKey, updater]) => [
24
+ fetchKey,
25
+ updater(result, results[fetchKey]),
26
+ ]),
27
+ ),
28
+ };
29
+ }
@@ -0,0 +1,95 @@
1
+ // TODO(breaking): remove file - not used
2
+ import { Schema } from '@data-client/normalizr';
3
+
4
+ import { FETCH_TYPE } from '../../actionTypes.js';
5
+ import {
6
+ FetchShape,
7
+ SchemaFromShape,
8
+ ParamsFromShape,
9
+ BodyFromShape,
10
+ OptimisticUpdateParams,
11
+ } from '../../endpoint/index.js';
12
+ import { FetchAction } from '../../legacyActions.js';
13
+
14
+ interface Options<
15
+ Shape extends FetchShape<
16
+ Schema | undefined,
17
+ Readonly<object>,
18
+ Readonly<object | string> | void
19
+ >,
20
+ > {
21
+ params: ParamsFromShape<Shape>;
22
+ body?: BodyFromShape<Shape>;
23
+ throttle: boolean;
24
+ updateParams?:
25
+ | OptimisticUpdateParams<
26
+ SchemaFromShape<Shape>,
27
+ FetchShape<Schema | undefined, any, any>
28
+ >[]
29
+ | undefined;
30
+ }
31
+
32
+ /** Requesting a fetch to begin
33
+ *
34
+ * @param fetchShape
35
+ * @param param1 { params, body, throttle, updateParams }
36
+ */
37
+ export default function createFetch<
38
+ Shape extends FetchShape<
39
+ Schema | undefined,
40
+ Readonly<object>,
41
+ Readonly<object | string> | void
42
+ >,
43
+ >(
44
+ fetchShape: Shape & {
45
+ update?: (...args: any) => Record<string, (...args: any) => any>;
46
+ },
47
+ { params, body, throttle, updateParams }: Options<Shape>,
48
+ ): FetchAction {
49
+ const { schema, type, getFetchKey, options } = fetchShape;
50
+
51
+ const key = getFetchKey(params);
52
+ let resolve: (value?: any | PromiseLike<any>) => void = 0 as any;
53
+ let reject: (reason?: any) => void = 0 as any;
54
+ const promise = new Promise<any>((a, b) => {
55
+ [resolve, reject] = [a, b];
56
+ });
57
+ const meta: FetchAction['meta'] = {
58
+ schema,
59
+ type,
60
+ args: [params, body],
61
+ key,
62
+ throttle,
63
+ options,
64
+ resolve,
65
+ reject,
66
+ promise,
67
+ createdAt: Date.now(),
68
+ };
69
+
70
+ if (fetchShape.update) {
71
+ meta.update = fetchShape.update;
72
+ }
73
+
74
+ // for simplicity we simply override if updateParams are defined - usage together is silly to support as we are migrating
75
+ if (updateParams) {
76
+ meta.update = (newresult: any): Record<string, (...args: any) => any> => {
77
+ const updateMap: any = {};
78
+ updateParams.forEach(([toShape, toParams, updateFn]) => {
79
+ updateMap[toShape.getFetchKey(toParams)] = (existing: any) =>
80
+ updateFn(newresult, existing);
81
+ });
82
+ return updateMap;
83
+ };
84
+ }
85
+
86
+ if (options?.optimisticUpdate) {
87
+ meta.optimisticResponse = options.optimisticUpdate(params, body);
88
+ }
89
+
90
+ return {
91
+ type: FETCH_TYPE,
92
+ payload: () => fetchShape.fetch(params, body),
93
+ meta,
94
+ };
95
+ }
@@ -0,0 +1,68 @@
1
+ import type {
2
+ Schema,
3
+ EndpointExtraOptions as FetchOptions,
4
+ } from '@data-client/normalizr';
5
+
6
+ import { RECEIVE_TYPE } from '../../actionTypes.js';
7
+ import { FetchAction, ReceiveAction } from '../../legacyActions.js';
8
+
9
+ interface Options<
10
+ Payload extends object | string | number | null =
11
+ | object
12
+ | string
13
+ | number
14
+ | null,
15
+ S extends Schema | undefined = any,
16
+ > extends Pick<
17
+ FetchAction<Payload, S>['meta'],
18
+ 'schema' | 'key' | 'type' | 'updaters' | 'update' | 'args'
19
+ > {
20
+ dataExpiryLength: NonNullable<FetchOptions['dataExpiryLength']>;
21
+ fetchedAt?: number;
22
+ }
23
+
24
+ /** Update state with data
25
+ *
26
+ * @param data
27
+ * @param param1 { schema, key, type, updaters, dataExpiryLength }
28
+ */
29
+ export default function createReceive<
30
+ Payload extends object | string | number | null =
31
+ | object
32
+ | string
33
+ | number
34
+ | null,
35
+ S extends Schema | undefined = any,
36
+ >(
37
+ data: Payload,
38
+ {
39
+ schema,
40
+ key,
41
+ args,
42
+ updaters,
43
+ fetchedAt = 0,
44
+ update,
45
+ dataExpiryLength,
46
+ }: Options<Payload, S>,
47
+ ): ReceiveAction<Payload, S> {
48
+ /* istanbul ignore next */
49
+ if (process.env.NODE_ENV === 'development' && dataExpiryLength < 0) {
50
+ throw new Error('Negative dataExpiryLength are not allowed.');
51
+ }
52
+ const now = Date.now();
53
+ const meta: ReceiveAction['meta'] = {
54
+ schema,
55
+ key,
56
+ args,
57
+ date: now,
58
+ fetchedAt,
59
+ expiresAt: now + dataExpiryLength,
60
+ };
61
+ meta.updaters = updaters;
62
+ meta.update = update;
63
+ return {
64
+ type: RECEIVE_TYPE,
65
+ payload: data,
66
+ meta,
67
+ };
68
+ }
@@ -0,0 +1,43 @@
1
+ import {
2
+ Schema,
3
+ EndpointExtraOptions as FetchOptions,
4
+ } from '@data-client/normalizr';
5
+
6
+ import { RECEIVE_TYPE } from '../../actionTypes.js';
7
+ import { FetchAction, ReceiveAction } from '../../legacyActions.js';
8
+
9
+ interface Options<S extends Schema | undefined = any>
10
+ extends Pick<FetchAction<any, S>['meta'], 'schema' | 'key' | 'options'> {
11
+ errorExpiryLength?: NonNullable<FetchOptions['errorExpiryLength']>;
12
+ fetchedAt?: number;
13
+ }
14
+
15
+ export default function createReceiveError<S extends Schema | undefined = any>(
16
+ error: Error,
17
+ {
18
+ schema,
19
+ key,
20
+ options,
21
+ errorExpiryLength = 60000,
22
+ fetchedAt = 0,
23
+ }: Options<S>,
24
+ ): ReceiveAction {
25
+ /* istanbul ignore next */
26
+ if (process.env.NODE_ENV === 'development' && errorExpiryLength < 0) {
27
+ throw new Error('Negative errorExpiryLength are not allowed.');
28
+ }
29
+ const now = Date.now();
30
+ return {
31
+ type: RECEIVE_TYPE,
32
+ payload: error,
33
+ meta: {
34
+ schema,
35
+ key,
36
+ date: now,
37
+ fetchedAt,
38
+ expiresAt: now + errorExpiryLength,
39
+ errorPolicy: options?.errorPolicy,
40
+ },
41
+ error: true,
42
+ };
43
+ }
@@ -0,0 +1,3 @@
1
+ export { default as createFetch } from './createFetch.js';
2
+ export { default as createReceive } from './createReceive.js';
3
+ export { default as createReceiveError } from './createReceiveError.js';
@@ -0,0 +1,80 @@
1
+ import { fetchReducer } from './fetchReducer.js';
2
+ import { invalidateReducer } from './invalidateReducer.js';
3
+ import { setReducer } from './setReducer.js';
4
+ import {
5
+ SET_TYPE,
6
+ INVALIDATE_TYPE,
7
+ RESET_TYPE,
8
+ FETCH_TYPE,
9
+ GC_TYPE,
10
+ OPTIMISTIC_TYPE,
11
+ INVALIDATEALL_TYPE,
12
+ } from '../../actionTypes.js';
13
+ import type Controller from '../../controller/Controller.js';
14
+ import type { OldActionTypes, ActionTypes, State } from '../../types.js';
15
+
16
+ export default function createReducer(controller: Controller): ReducerType {
17
+ return function reducer(
18
+ state: State<unknown> | undefined,
19
+ action: OldActionTypes,
20
+ ): State<unknown> {
21
+ if (!state) state = initialState;
22
+ switch (action.type) {
23
+ case GC_TYPE:
24
+ // inline deletes are fine as these should have 0 refcounts
25
+ action.entities.forEach(([key, pk]) => {
26
+ delete (state as any).entities[key]?.[pk];
27
+ delete (state as any).entityMeta[key]?.[pk];
28
+ });
29
+ action.results.forEach(fetchKey => {
30
+ delete (state as any).results[fetchKey];
31
+ delete (state as any).meta[fetchKey];
32
+ });
33
+ return state;
34
+ case FETCH_TYPE:
35
+ return fetchReducer(state, action);
36
+
37
+ case OPTIMISTIC_TYPE:
38
+ // eslint-disable-next-line no-fallthrough
39
+ case SET_TYPE:
40
+ return setReducer(state, action, controller);
41
+
42
+ case INVALIDATEALL_TYPE:
43
+ case INVALIDATE_TYPE:
44
+ return invalidateReducer(state, action);
45
+
46
+ case RESET_TYPE:
47
+ if (
48
+ process.env.NODE_ENV !== 'production' &&
49
+ action.date === undefined
50
+ ) {
51
+ console.warn(
52
+ `${RESET_TYPE} sent without 'date' member. This is deprecated. Please use createReset() action creator to ensure correct action shape.`,
53
+ );
54
+ }
55
+ return { ...initialState, lastReset: action.date ?? Date.now() };
56
+
57
+ default:
58
+ // A reducer must always return a valid state.
59
+ // Alternatively you can throw an error if an invalid action is dispatched.
60
+ return state;
61
+ }
62
+ } as any;
63
+ }
64
+
65
+ export const initialState: State<unknown> = {
66
+ entities: {},
67
+ indexes: {},
68
+ results: {},
69
+ meta: {},
70
+ entityMeta: {},
71
+ optimistic: [],
72
+ lastReset: 0,
73
+ };
74
+
75
+ type ReducerType = (
76
+ state: State<unknown> | undefined,
77
+ action: ActionTypes,
78
+ ) => State<unknown>;
79
+
80
+ type Writable<T> = { [P in keyof T]: NonNullable<Writable<T[P]>> };
@@ -0,0 +1,48 @@
1
+ import createOptimistic from '../../controller/createOptimistic.js';
2
+ import type {
3
+ ReceiveAction,
4
+ OptimisticAction,
5
+ FetchAction,
6
+ } from '../../previousActions.js';
7
+ import type { State } from '../../types.js';
8
+ import { createReceive as legacyCreateReceive } from '../legacy-actions/index.js';
9
+
10
+ export function fetchReducer(state: State<unknown>, action: FetchAction) {
11
+ const optimisticResponse = action.meta.optimisticResponse;
12
+ const getOptimisticResponse = action.endpoint?.getOptimisticResponse;
13
+ let receiveAction: ReceiveAction | OptimisticAction;
14
+
15
+ if (getOptimisticResponse && action.endpoint && action.endpoint.sideEffect) {
16
+ receiveAction = createOptimistic(action.endpoint, {
17
+ args: action.meta.args as readonly any[],
18
+ fetchedAt:
19
+ typeof action.meta.createdAt !== 'number'
20
+ ? action.meta.createdAt.getTime()
21
+ : action.meta.createdAt,
22
+ }) as any;
23
+ } /* istanbul ignore if */ else if (optimisticResponse) {
24
+ // TODO(breaking): this is no longer used, remove this branch
25
+ /* istanbul ignore next */
26
+ receiveAction = legacyCreateReceive(optimisticResponse, {
27
+ ...action.meta,
28
+ dataExpiryLength: Infinity,
29
+ });
30
+ } else {
31
+ // If 'fetch' action reaches the reducer there are no middlewares installed to handle it
32
+ /* istanbul ignore next */
33
+ if (process.env.NODE_ENV !== 'production') {
34
+ console.warn(
35
+ 'Fetch appears unhandled - you are likely missing the NetworkManager middleware',
36
+ );
37
+ console.warn(
38
+ 'See https://resthooks.io/docs/guides/redux#indextsx for hooking up redux',
39
+ );
40
+ }
41
+
42
+ return state;
43
+ }
44
+ return {
45
+ ...state,
46
+ optimistic: [...state.optimistic, receiveAction],
47
+ };
48
+ }
@@ -0,0 +1,39 @@
1
+ import { INVALIDATE_TYPE } from '../../actionTypes.js';
2
+ import type {
3
+ InvalidateAllAction,
4
+ InvalidateAction,
5
+ } from '../../previousActions.js';
6
+ import type { State } from '../../types.js';
7
+
8
+ export function invalidateReducer(
9
+ state: State<unknown>,
10
+ action: InvalidateAction | InvalidateAllAction,
11
+ ) {
12
+ const results = { ...state.results };
13
+ const meta = { ...state.meta };
14
+ const invalidateKey = (key: string) => {
15
+ delete results[key];
16
+ const itemMeta = {
17
+ ...meta[key],
18
+ expiresAt: 0,
19
+ invalidated: true,
20
+ };
21
+ delete itemMeta.error;
22
+ meta[key] = itemMeta;
23
+ };
24
+ if (action.type === INVALIDATE_TYPE) {
25
+ invalidateKey(action.meta.key);
26
+ } else {
27
+ Object.keys(results).forEach(key => {
28
+ if (action.testKey(key)) {
29
+ invalidateKey(key);
30
+ }
31
+ });
32
+ }
33
+
34
+ return {
35
+ ...state,
36
+ results,
37
+ meta,
38
+ };
39
+ }
@@ -0,0 +1,157 @@
1
+ import { normalize } from '@data-client/normalizr';
2
+
3
+ import { OPTIMISTIC_TYPE } from '../../actionTypes.js';
4
+ import type Controller from '../../controller/Controller.js';
5
+ import type { ReceiveAction, OptimisticAction } from '../../previousActions.js';
6
+ import type { State } from '../../types.js';
7
+ import applyUpdatersToResults from '../applyUpdatersToResults.js';
8
+
9
+ export function setReducer(
10
+ state: State<unknown>,
11
+ action: OptimisticAction | ReceiveAction,
12
+ controller: Controller,
13
+ ) {
14
+ if (action.error) {
15
+ return reduceError(state, action, action.payload);
16
+ }
17
+ try {
18
+ let payload: any;
19
+ // for true receives payload is contained in action
20
+ if (action.type === OPTIMISTIC_TYPE) {
21
+ if (!action.endpoint.getOptimisticResponse) return state;
22
+ try {
23
+ // compute optimistic response based on current state
24
+ payload = action.endpoint.getOptimisticResponse.call(
25
+ action.endpoint,
26
+ controller.snapshot(state, action.meta.fetchedAt),
27
+ // if endpoint exists, so must args; TODO: fix typing
28
+ ...(action.meta.args as any[]),
29
+ );
30
+ } catch (e: any) {
31
+ // AbortOptimistic means 'do nothing', otherwise we count the exception as endpoint failure
32
+ if (e.constructor?.name === 'AbortOptimistic') {
33
+ return state;
34
+ }
35
+ throw e;
36
+ }
37
+ } else {
38
+ payload = action.payload;
39
+ }
40
+ const { result, entities, indexes, entityMeta } = normalize(
41
+ payload,
42
+ action.meta.schema,
43
+ action.meta.args as any,
44
+ state.entities,
45
+ state.indexes,
46
+ state.entityMeta,
47
+ { fetchedAt: action.meta.date, ...action.meta },
48
+ );
49
+ let results = {
50
+ ...state.results,
51
+ [action.meta.key]: result,
52
+ };
53
+ try {
54
+ if ('updaters' in action.meta && action.meta.updaters) {
55
+ results = applyUpdatersToResults(
56
+ results,
57
+ result,
58
+ action.meta.updaters as any,
59
+ );
60
+ }
61
+ if (action.meta.update) {
62
+ const updaters = action.meta.update(
63
+ result,
64
+ ...(action.meta.args || []),
65
+ );
66
+ Object.keys(updaters).forEach(key => {
67
+ results[key] = updaters[key](results[key]);
68
+ });
69
+ }
70
+ // no reason to completely fail because of user-code error
71
+ // integrity of this state update is still guaranteed
72
+ } catch (error) {
73
+ console.error(
74
+ `The following error occured during Endpoint.update() for ${action.meta.key}`,
75
+ );
76
+ console.error(error);
77
+ }
78
+ return {
79
+ entities,
80
+ indexes,
81
+ results,
82
+ entityMeta,
83
+ meta: {
84
+ ...state.meta,
85
+ [action.meta.key]: {
86
+ date: action.meta.date,
87
+ expiresAt: action.meta.expiresAt,
88
+ prevExpiresAt: state.meta[action.meta.key]?.expiresAt,
89
+ },
90
+ },
91
+ optimistic: filterOptimistic(state, action),
92
+ lastReset: state.lastReset,
93
+ };
94
+ // reducer must update the state, so in case of processing errors we simply compute the results inline
95
+ } catch (error: any) {
96
+ if (typeof error === 'object') {
97
+ error.message = `Error processing ${
98
+ action.meta.key
99
+ }\n\nFull Schema: ${JSON.stringify(
100
+ action.meta.schema,
101
+ undefined,
102
+ 2,
103
+ )}\n\nError:\n${error.message}`;
104
+ if ('payload' in action) error.payload = action.payload;
105
+ error.status = 400;
106
+ }
107
+
108
+ // this is not always bubbled up, so let's double sure this doesn't fail silently
109
+ /* istanbul ignore else */
110
+ if (process.env.NODE_ENV !== 'production') {
111
+ console.error(error);
112
+ }
113
+ return reduceError(state, action, error);
114
+ }
115
+ }
116
+
117
+ function reduceError(
118
+ state: State<unknown>,
119
+ action: ReceiveAction | OptimisticAction,
120
+ error: any,
121
+ ): State<unknown> {
122
+ if (error.name === 'AbortError') {
123
+ // In case we abort simply undo the optimistic update and act like no fetch even occured
124
+ // We still want those watching promises from fetch directly to observed the abort, but we don't want to
125
+ // Trigger errors in this case. This means theoretically improperly built abortes useResource() could suspend forever.
126
+ return {
127
+ ...state,
128
+ optimistic: filterOptimistic(state, action),
129
+ };
130
+ }
131
+ return {
132
+ ...state,
133
+ meta: {
134
+ ...state.meta,
135
+ [action.meta.key]: {
136
+ date: action.meta.date,
137
+ error,
138
+ expiresAt: action.meta.expiresAt,
139
+ errorPolicy: action.meta.errorPolicy?.(error),
140
+ },
141
+ },
142
+ optimistic: filterOptimistic(state, action),
143
+ };
144
+ }
145
+ /** Filter all requests with same serialization that did not start after the resolving request */
146
+ function filterOptimistic(
147
+ state: State<unknown>,
148
+ resolvingAction: ReceiveAction | OptimisticAction,
149
+ ) {
150
+ return state.optimistic.filter(
151
+ optimisticAction =>
152
+ optimisticAction.meta.key !== resolvingAction.meta.key ||
153
+ (optimisticAction.type === OPTIMISTIC_TYPE
154
+ ? optimisticAction.meta.fetchedAt !== resolvingAction.meta.fetchedAt
155
+ : optimisticAction.meta.date > resolvingAction.meta.date),
156
+ );
157
+ }
@@ -0,0 +1,14 @@
1
+ /* istanbul ignore file */
2
+ import createReducer from './reducer/createReducer.js';
3
+ import Controller from '../controller/Controller.js';
4
+ import { ActionTypes, State } from '../types.js';
5
+
6
+ /**
7
+ * @deprecated use createReducer instead
8
+ */
9
+ const reducer: (
10
+ state: State<unknown> | undefined,
11
+ action: ActionTypes,
12
+ ) => State<unknown> = createReducer(new Controller());
13
+
14
+ export default reducer;
@@ -0,0 +1,8 @@
1
+ import type { State } from '../types.js';
2
+
3
+ export default function selectMeta<R = any>(
4
+ state: State<R>,
5
+ fetchKey: string,
6
+ ): State<R>['meta'][string] {
7
+ return state.meta[fetchKey];
8
+ }