@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.
- package/LICENSE +201 -0
- package/README.md +71 -0
- package/dist/index.js +1643 -0
- package/dist/index.umd.min.js +1 -0
- package/dist/next.js +461 -0
- package/dist/package.json +1 -0
- package/legacy/actionTypes.js +12 -0
- package/legacy/compatibleActions.js +2 -0
- package/legacy/controller/BaseController.js +289 -0
- package/legacy/controller/Controller.js +20 -0
- package/legacy/controller/createFetch.js +42 -0
- package/legacy/controller/createInvalidate.js +12 -0
- package/legacy/controller/createInvalidateAll.js +8 -0
- package/legacy/controller/createOptimistic.js +33 -0
- package/legacy/controller/createReceive.js +36 -0
- package/legacy/controller/createReset.js +8 -0
- package/legacy/controller/createSubscription.js +30 -0
- package/legacy/controller/types.js +2 -0
- package/legacy/endpoint/index.js +2 -0
- package/legacy/endpoint/shapes.js +2 -0
- package/legacy/endpoint/types.js +2 -0
- package/legacy/fsa.js +2 -0
- package/legacy/index.js +22 -0
- package/legacy/internal.js +4 -0
- package/legacy/legacyActions.js +2 -0
- package/legacy/manager/ConnectionListener.js +2 -0
- package/legacy/manager/DefaultConnectionListener.js +40 -0
- package/legacy/manager/DevtoolsManager.js +73 -0
- package/legacy/manager/LogoutManager.js +34 -0
- package/legacy/manager/NetworkManager.js +291 -0
- package/legacy/manager/PollingSubscription.js +159 -0
- package/legacy/manager/SubscriptionManager.js +117 -0
- package/legacy/manager/applyManager.js +23 -0
- package/legacy/manager/devtoolsTypes.js +2 -0
- package/legacy/manager/index.js +6 -0
- package/legacy/middlewareTypes.js +2 -0
- package/legacy/newActions.js +2 -0
- package/legacy/next/Controller.js +24 -0
- package/legacy/next/index.js +3 -0
- package/legacy/previousActions.js +2 -0
- package/legacy/state/RIC.js +3 -0
- package/legacy/state/applyUpdatersToResults.js +4 -0
- package/legacy/state/legacy-actions/createFetch.js +62 -0
- package/legacy/state/legacy-actions/createReceive.js +37 -0
- package/legacy/state/legacy-actions/createReceiveError.js +28 -0
- package/legacy/state/legacy-actions/index.js +4 -0
- package/legacy/state/reducer/createReducer.js +54 -0
- package/legacy/state/reducer/fetchReducer.js +32 -0
- package/legacy/state/reducer/invalidateReducer.js +28 -0
- package/legacy/state/reducer/setReducer.js +113 -0
- package/legacy/state/reducerInstance.js +9 -0
- package/legacy/state/selectMeta.js +4 -0
- package/legacy/types.js +8 -0
- package/lib/actionTypes.d.ts +11 -0
- package/lib/actionTypes.d.ts.map +1 -0
- package/lib/actionTypes.js +12 -0
- package/lib/compatibleActions.d.ts +47 -0
- package/lib/compatibleActions.d.ts.map +1 -0
- package/lib/compatibleActions.js +2 -0
- package/lib/controller/BaseController.d.ts +128 -0
- package/lib/controller/BaseController.d.ts.map +1 -0
- package/lib/controller/BaseController.js +289 -0
- package/lib/controller/Controller.d.ts +14 -0
- package/lib/controller/Controller.d.ts.map +1 -0
- package/lib/controller/Controller.js +20 -0
- package/lib/controller/createFetch.d.ts +12 -0
- package/lib/controller/createFetch.d.ts.map +1 -0
- package/lib/controller/createFetch.js +42 -0
- package/lib/controller/createInvalidate.d.ts +6 -0
- package/lib/controller/createInvalidate.d.ts.map +1 -0
- package/lib/controller/createInvalidate.js +12 -0
- package/lib/controller/createInvalidateAll.d.ts +3 -0
- package/lib/controller/createInvalidateAll.d.ts.map +1 -0
- package/lib/controller/createInvalidateAll.js +8 -0
- package/lib/controller/createOptimistic.d.ts +10 -0
- package/lib/controller/createOptimistic.d.ts.map +1 -0
- package/lib/controller/createOptimistic.js +33 -0
- package/lib/controller/createReceive.d.ts +20 -0
- package/lib/controller/createReceive.d.ts.map +1 -0
- package/lib/controller/createReceive.js +36 -0
- package/lib/controller/createReset.d.ts +3 -0
- package/lib/controller/createReset.d.ts.map +1 -0
- package/lib/controller/createReset.js +8 -0
- package/lib/controller/createSubscription.d.ts +9 -0
- package/lib/controller/createSubscription.d.ts.map +1 -0
- package/lib/controller/createSubscription.js +30 -0
- package/lib/controller/types.d.ts +6 -0
- package/lib/controller/types.d.ts.map +1 -0
- package/lib/controller/types.js +2 -0
- package/lib/endpoint/index.d.ts +3 -0
- package/lib/endpoint/index.d.ts.map +1 -0
- package/lib/endpoint/index.js +2 -0
- package/lib/endpoint/shapes.d.ts +25 -0
- package/lib/endpoint/shapes.d.ts.map +1 -0
- package/lib/endpoint/shapes.js +2 -0
- package/lib/endpoint/types.d.ts +45 -0
- package/lib/endpoint/types.d.ts.map +1 -0
- package/lib/endpoint/types.js +2 -0
- package/lib/fsa.d.ts +41 -0
- package/lib/fsa.d.ts.map +1 -0
- package/lib/fsa.js +2 -0
- package/lib/index.d.ts +19 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +22 -0
- package/lib/internal.d.ts +4 -0
- package/lib/internal.d.ts.map +1 -0
- package/lib/internal.js +4 -0
- package/lib/legacyActions.d.ts +92 -0
- package/lib/legacyActions.d.ts.map +1 -0
- package/lib/legacyActions.js +2 -0
- package/lib/manager/ConnectionListener.d.ts +8 -0
- package/lib/manager/ConnectionListener.d.ts.map +1 -0
- package/lib/manager/ConnectionListener.js +2 -0
- package/lib/manager/DefaultConnectionListener.d.ts +20 -0
- package/lib/manager/DefaultConnectionListener.d.ts.map +1 -0
- package/lib/manager/DefaultConnectionListener.js +40 -0
- package/lib/manager/DevtoolsManager.d.ts +24 -0
- package/lib/manager/DevtoolsManager.d.ts.map +1 -0
- package/lib/manager/DevtoolsManager.js +74 -0
- package/lib/manager/LogoutManager.d.ts +25 -0
- package/lib/manager/LogoutManager.d.ts.map +1 -0
- package/lib/manager/LogoutManager.js +34 -0
- package/lib/manager/NetworkManager.d.ts +82 -0
- package/lib/manager/NetworkManager.d.ts.map +1 -0
- package/lib/manager/NetworkManager.js +295 -0
- package/lib/manager/PollingSubscription.d.ts +45 -0
- package/lib/manager/PollingSubscription.d.ts.map +1 -0
- package/lib/manager/PollingSubscription.js +159 -0
- package/lib/manager/SubscriptionManager.d.ts +55 -0
- package/lib/manager/SubscriptionManager.d.ts.map +1 -0
- package/lib/manager/SubscriptionManager.js +117 -0
- package/lib/manager/applyManager.d.ts +10 -0
- package/lib/manager/applyManager.d.ts.map +1 -0
- package/lib/manager/applyManager.js +23 -0
- package/lib/manager/devtoolsTypes.d.ts +205 -0
- package/lib/manager/devtoolsTypes.d.ts.map +1 -0
- package/lib/manager/devtoolsTypes.js +2 -0
- package/lib/manager/index.d.ts +8 -0
- package/lib/manager/index.d.ts.map +1 -0
- package/lib/manager/index.js +6 -0
- package/lib/middlewareTypes.d.ts +18 -0
- package/lib/middlewareTypes.d.ts.map +1 -0
- package/lib/middlewareTypes.js +2 -0
- package/lib/newActions.d.ts +85 -0
- package/lib/newActions.d.ts.map +1 -0
- package/lib/newActions.js +2 -0
- package/lib/next/Controller.d.ts +14 -0
- package/lib/next/Controller.d.ts.map +1 -0
- package/lib/next/Controller.js +24 -0
- package/lib/next/index.d.ts +3 -0
- package/lib/next/index.d.ts.map +1 -0
- package/lib/next/index.js +3 -0
- package/lib/previousActions.d.ts +91 -0
- package/lib/previousActions.d.ts.map +1 -0
- package/lib/previousActions.js +2 -0
- package/lib/state/RIC.d.ts +2 -0
- package/lib/state/RIC.js +3 -0
- package/lib/state/applyUpdatersToResults.d.ts +13 -0
- package/lib/state/applyUpdatersToResults.d.ts.map +1 -0
- package/lib/state/applyUpdatersToResults.js +7 -0
- package/lib/state/legacy-actions/createFetch.d.ts +19 -0
- package/lib/state/legacy-actions/createFetch.d.ts.map +1 -0
- package/lib/state/legacy-actions/createFetch.js +62 -0
- package/lib/state/legacy-actions/createReceive.d.ts +14 -0
- package/lib/state/legacy-actions/createReceive.d.ts.map +1 -0
- package/lib/state/legacy-actions/createReceive.js +37 -0
- package/lib/state/legacy-actions/createReceiveError.d.ts +9 -0
- package/lib/state/legacy-actions/createReceiveError.d.ts.map +1 -0
- package/lib/state/legacy-actions/createReceiveError.js +28 -0
- package/lib/state/legacy-actions/index.d.ts +4 -0
- package/lib/state/legacy-actions/index.d.ts.map +1 -0
- package/lib/state/legacy-actions/index.js +4 -0
- package/lib/state/reducer/createReducer.d.ts +7 -0
- package/lib/state/reducer/createReducer.d.ts.map +1 -0
- package/lib/state/reducer/createReducer.js +55 -0
- package/lib/state/reducer/fetchReducer.d.ts +4 -0
- package/lib/state/reducer/fetchReducer.d.ts.map +1 -0
- package/lib/state/reducer/fetchReducer.js +34 -0
- package/lib/state/reducer/invalidateReducer.d.ts +37 -0
- package/lib/state/reducer/invalidateReducer.d.ts.map +1 -0
- package/lib/state/reducer/invalidateReducer.js +34 -0
- package/lib/state/reducer/setReducer.d.ts +40 -0
- package/lib/state/reducer/setReducer.d.ts.map +1 -0
- package/lib/state/reducer/setReducer.js +119 -0
- package/lib/state/reducerInstance.d.ts +7 -0
- package/lib/state/reducerInstance.d.ts.map +1 -0
- package/lib/state/reducerInstance.js +9 -0
- package/lib/state/selectMeta.d.ts +3 -0
- package/lib/state/selectMeta.d.ts.map +1 -0
- package/lib/state/selectMeta.js +4 -0
- package/lib/types.d.ts +71 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +8 -0
- package/node.mjs +1 -0
- package/package.json +127 -0
- package/src/actionTypes.ts +11 -0
- package/src/compatibleActions.ts +96 -0
- package/src/controller/BaseController.ts +508 -0
- package/src/controller/Controller.ts +32 -0
- package/src/controller/__tests__/Controller.ts +29 -0
- package/src/controller/__tests__/__snapshots__/getResponse.ts.snap +35 -0
- package/src/controller/__tests__/getResponse.ts +182 -0
- package/src/controller/createFetch.ts +54 -0
- package/src/controller/createInvalidate.ts +16 -0
- package/src/controller/createInvalidateAll.ts +11 -0
- package/src/controller/createOptimistic.ts +47 -0
- package/src/controller/createReceive.ts +85 -0
- package/src/controller/createReset.ts +9 -0
- package/src/controller/createSubscription.ts +39 -0
- package/src/controller/types.ts +22 -0
- package/src/endpoint/index.ts +14 -0
- package/src/endpoint/shapes.ts +53 -0
- package/src/endpoint/types.ts +72 -0
- package/src/fsa.ts +99 -0
- package/src/index.ts +61 -0
- package/src/internal.ts +3 -0
- package/src/legacyActions.ts +163 -0
- package/src/manager/ConnectionListener.ts +7 -0
- package/src/manager/DefaultConnectionListener.ts +54 -0
- package/src/manager/DevtoolsManager.ts +99 -0
- package/src/manager/LogoutManager.ts +57 -0
- package/src/manager/NetworkManager.ts +346 -0
- package/src/manager/PollingSubscription.ts +190 -0
- package/src/manager/SubscriptionManager.ts +156 -0
- package/src/manager/__tests__/__snapshots__/pollingSubscription-endpoint.ts.snap +49 -0
- package/src/manager/__tests__/__snapshots__/pollingSubscription.ts.snap +43 -0
- package/src/manager/__tests__/logoutManager.ts +112 -0
- package/src/manager/__tests__/manager.ts +44 -0
- package/src/manager/__tests__/networkManager-legacy.ts +394 -0
- package/src/manager/__tests__/networkManager.ts +426 -0
- package/src/manager/__tests__/pollingSubscription-endpoint.ts +423 -0
- package/src/manager/__tests__/pollingSubscription.ts +313 -0
- package/src/manager/__tests__/subscriptionManager.ts +208 -0
- package/src/manager/applyManager.ts +33 -0
- package/src/manager/devtoolsTypes.ts +210 -0
- package/src/manager/index.ts +7 -0
- package/src/middlewareTypes.ts +49 -0
- package/src/newActions.ts +140 -0
- package/src/next/Controller.ts +39 -0
- package/src/next/index.ts +2 -0
- package/src/package.json +1 -0
- package/src/previousActions.ts +159 -0
- package/src/state/RIC.d.ts +2 -0
- package/src/state/RIC.js +5 -0
- package/src/state/__tests__/RIC.web.ts +16 -0
- package/src/state/__tests__/__snapshots__/reducer.ts.snap +56 -0
- package/src/state/__tests__/applyUpdatersToResults.ts +40 -0
- package/src/state/__tests__/reducer.ts +868 -0
- package/src/state/applyUpdatersToResults.ts +29 -0
- package/src/state/legacy-actions/createFetch.ts +95 -0
- package/src/state/legacy-actions/createReceive.ts +68 -0
- package/src/state/legacy-actions/createReceiveError.ts +43 -0
- package/src/state/legacy-actions/index.ts +3 -0
- package/src/state/reducer/createReducer.ts +80 -0
- package/src/state/reducer/fetchReducer.ts +48 -0
- package/src/state/reducer/invalidateReducer.ts +39 -0
- package/src/state/reducer/setReducer.ts +157 -0
- package/src/state/reducerInstance.ts +14 -0
- package/src/state/selectMeta.ts +8 -0
- package/src/types.ts +125 -0
- package/ts3.4/actionTypes.d.ts +11 -0
- package/ts3.4/compatibleActions.d.ts +47 -0
- package/ts3.4/controller/BaseController.d.ts +170 -0
- package/ts3.4/controller/Controller.d.ts +14 -0
- package/ts3.4/controller/createFetch.d.ts +14 -0
- package/ts3.4/controller/createInvalidate.d.ts +8 -0
- package/ts3.4/controller/createInvalidateAll.d.ts +3 -0
- package/ts3.4/controller/createOptimistic.d.ts +12 -0
- package/ts3.4/controller/createReceive.d.ts +24 -0
- package/ts3.4/controller/createReset.d.ts +3 -0
- package/ts3.4/controller/createSubscription.d.ts +13 -0
- package/ts3.4/controller/types.d.ts +6 -0
- package/ts3.4/endpoint/index.d.ts +3 -0
- package/ts3.4/endpoint/shapes.d.ts +25 -0
- package/ts3.4/endpoint/types.d.ts +45 -0
- package/ts3.4/fsa.d.ts +41 -0
- package/ts3.4/index.d.ts +22 -0
- package/ts3.4/internal.d.ts +4 -0
- package/ts3.4/legacyActions.d.ts +95 -0
- package/ts3.4/manager/ConnectionListener.d.ts +8 -0
- package/ts3.4/manager/DefaultConnectionListener.d.ts +20 -0
- package/ts3.4/manager/DevtoolsManager.d.ts +24 -0
- package/ts3.4/manager/LogoutManager.d.ts +25 -0
- package/ts3.4/manager/NetworkManager.d.ts +82 -0
- package/ts3.4/manager/PollingSubscription.d.ts +45 -0
- package/ts3.4/manager/SubscriptionManager.d.ts +55 -0
- package/ts3.4/manager/applyManager.d.ts +10 -0
- package/ts3.4/manager/devtoolsTypes.d.ts +205 -0
- package/ts3.4/manager/index.d.ts +8 -0
- package/ts3.4/middlewareTypes.d.ts +18 -0
- package/ts3.4/newActions.d.ts +88 -0
- package/ts3.4/next/Controller.d.ts +14 -0
- package/ts3.4/next/index.d.ts +3 -0
- package/ts3.4/previousActions.d.ts +94 -0
- package/ts3.4/state/RIC.d.ts +2 -0
- package/ts3.4/state/applyUpdatersToResults.d.ts +13 -0
- package/ts3.4/state/legacy-actions/createFetch.d.ts +19 -0
- package/ts3.4/state/legacy-actions/createReceive.d.ts +14 -0
- package/ts3.4/state/legacy-actions/createReceiveError.d.ts +9 -0
- package/ts3.4/state/legacy-actions/index.d.ts +4 -0
- package/ts3.4/state/reducer/createReducer.d.ts +7 -0
- package/ts3.4/state/reducer/fetchReducer.d.ts +4 -0
- package/ts3.4/state/reducer/invalidateReducer.d.ts +37 -0
- package/ts3.4/state/reducer/setReducer.d.ts +40 -0
- package/ts3.4/state/reducerInstance.d.ts +7 -0
- package/ts3.4/state/selectMeta.d.ts +3 -0
- package/ts3.4/types.d.ts +73 -0
- 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,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;
|