@data-client/core 0.14.0 → 0.14.2
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/README.md +2 -1
- package/dist/index.js +43 -21
- package/dist/index.umd.min.js +1 -1
- package/legacy/controller/actions/createFetch.js +3 -3
- package/legacy/controller/actions/createOptimistic.js +3 -3
- package/legacy/controller/actions/createSet.js +2 -2
- package/legacy/controller/actions/createSetResponse.js +3 -3
- package/legacy/controller/actions/createSubscription.js +3 -3
- package/legacy/manager/DevtoolsManager.js +24 -2
- package/legacy/manager/applyManager.js +12 -4
- package/legacy/manager/devtoolsTypes.js +1 -1
- package/legacy/state/reducer/fetchReducer.js +2 -9
- package/lib/controller/actions/createFetch.js +3 -3
- package/lib/controller/actions/createOptimistic.js +3 -3
- package/lib/controller/actions/createSet.js +2 -2
- package/lib/controller/actions/createSetResponse.js +3 -3
- package/lib/controller/actions/createSubscription.js +3 -3
- package/lib/manager/DevtoolsManager.d.ts.map +1 -1
- package/lib/manager/DevtoolsManager.js +24 -2
- package/lib/manager/applyManager.d.ts.map +1 -1
- package/lib/manager/applyManager.js +12 -4
- package/lib/manager/devtoolsTypes.d.ts +5 -3
- package/lib/manager/devtoolsTypes.d.ts.map +1 -1
- package/lib/manager/devtoolsTypes.js +1 -1
- package/lib/state/reducer/fetchReducer.d.ts.map +1 -1
- package/lib/state/reducer/fetchReducer.js +2 -9
- package/lib/state/reducer/setReducer.d.ts +26 -1
- package/lib/state/reducer/setReducer.d.ts.map +1 -1
- package/lib/state/reducer/setResponseReducer.d.ts +28 -1
- package/lib/state/reducer/setResponseReducer.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/controller/actions/createFetch.ts +2 -2
- package/src/controller/actions/createOptimistic.ts +2 -2
- package/src/controller/actions/createSet.ts +1 -1
- package/src/controller/actions/createSetResponse.ts +2 -2
- package/src/controller/actions/createSubscription.ts +2 -2
- package/src/manager/DevtoolsManager.ts +14 -1
- package/src/manager/__tests__/applyManager.ts +38 -0
- package/src/manager/applyManager.ts +16 -3
- package/src/manager/devtoolsTypes.ts +9 -3
- package/src/state/__tests__/reducer.ts +3 -2
- package/src/state/reducer/fetchReducer.ts +1 -13
- package/ts3.4/manager/devtoolsTypes.d.ts +5 -3
- package/ts3.4/state/reducer/setReducer.d.ts +26 -1
- package/ts3.4/state/reducer/setResponseReducer.d.ts +28 -1
|
@@ -37,6 +37,18 @@ if (process.env.NODE_ENV !== 'production') {
|
|
|
37
37
|
DEFAULT_CONFIG = {
|
|
38
38
|
name: `Data Client: ${globalThis.document?.title}`,
|
|
39
39
|
autoPause: true,
|
|
40
|
+
features: {
|
|
41
|
+
pause: true, // start/pause recording of dispatched actions
|
|
42
|
+
lock: true, // lock/unlock dispatching actions and side effects
|
|
43
|
+
persist: false, // persist states on page reloading
|
|
44
|
+
export: true, // export history of actions in a file
|
|
45
|
+
import: 'custom', // import history of actions from a file
|
|
46
|
+
jump: true, // jump back and forth (time travelling)
|
|
47
|
+
skip: true, // skip (cancel) actions
|
|
48
|
+
reorder: true, // drag and drop actions in the history list
|
|
49
|
+
dispatch: false, // dispatch custom actions or action creators
|
|
50
|
+
test: false, // generate tests for the selected actions
|
|
51
|
+
},
|
|
40
52
|
actionSanitizer: (action: ActionTypes) => {
|
|
41
53
|
if (!('endpoint' in action)) return action;
|
|
42
54
|
return {
|
|
@@ -131,6 +143,7 @@ export default class DevToolsManager implements Manager {
|
|
|
131
143
|
const reducer = createReducer(controller as any);
|
|
132
144
|
let state = controller.getState();
|
|
133
145
|
return next => action => {
|
|
146
|
+
const shouldSkip = skipLogging?.(action);
|
|
134
147
|
const ret = next(action);
|
|
135
148
|
if (this.started) {
|
|
136
149
|
// we track state changes here since getState() will only update after a batch commit
|
|
@@ -139,7 +152,7 @@ export default class DevToolsManager implements Manager {
|
|
|
139
152
|
state = controller.getState();
|
|
140
153
|
}
|
|
141
154
|
ret.then(() => {
|
|
142
|
-
if (
|
|
155
|
+
if (shouldSkip) return;
|
|
143
156
|
this.handleAction(action, state.optimistic.reduce(reducer, state));
|
|
144
157
|
});
|
|
145
158
|
return ret;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import Controller from '../../controller/Controller';
|
|
2
|
+
import applyManager from '../applyManager';
|
|
3
|
+
import NetworkManager from '../NetworkManager';
|
|
4
|
+
|
|
5
|
+
function onError(e: any) {
|
|
6
|
+
e.preventDefault();
|
|
7
|
+
}
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
if (typeof addEventListener === 'function')
|
|
10
|
+
addEventListener('error', onError);
|
|
11
|
+
});
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
if (typeof removeEventListener === 'function')
|
|
14
|
+
removeEventListener('error', onError);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('applyManagers should console.warn() when no NetworkManager is provided', () => {
|
|
18
|
+
const warnspy = jest
|
|
19
|
+
.spyOn(global.console, 'warn')
|
|
20
|
+
.mockImplementation(() => {});
|
|
21
|
+
try {
|
|
22
|
+
applyManager([], new Controller());
|
|
23
|
+
expect(warnspy.mock.calls.length).toBe(2);
|
|
24
|
+
} finally {
|
|
25
|
+
warnspy.mockRestore();
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
it('applyManagers should not console.warn() when NetworkManager is provided', () => {
|
|
29
|
+
const warnspy = jest
|
|
30
|
+
.spyOn(global.console, 'warn')
|
|
31
|
+
.mockImplementation(() => {});
|
|
32
|
+
try {
|
|
33
|
+
applyManager([new NetworkManager()], new Controller());
|
|
34
|
+
expect(warnspy.mock.calls.length).toBe(0);
|
|
35
|
+
} finally {
|
|
36
|
+
warnspy.mockRestore();
|
|
37
|
+
}
|
|
38
|
+
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import NetworkManager from './NetworkManager.js';
|
|
1
2
|
import type Controller from '../controller/Controller.js';
|
|
2
3
|
import type { Reducer, Dispatch, ReducerState } from '../middlewareTypes.js';
|
|
3
4
|
import { Manager } from '../types.js';
|
|
@@ -6,11 +7,23 @@ export default function applyManager(
|
|
|
6
7
|
managers: Manager[],
|
|
7
8
|
controller: Controller,
|
|
8
9
|
): Middleware[] {
|
|
9
|
-
|
|
10
|
+
/* istanbul ignore next */
|
|
11
|
+
if (
|
|
12
|
+
process.env.NODE_ENV !== 'production' &&
|
|
13
|
+
!managers.find(mgr => mgr instanceof NetworkManager)
|
|
14
|
+
) {
|
|
15
|
+
console.warn('NetworkManager not found; this is a required manager.');
|
|
16
|
+
console.warn(
|
|
17
|
+
'See https://dataclient.io/docs/guides/redux for hooking up redux',
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
return managers.map((manager, i) => {
|
|
10
21
|
const middleware = manager.getMiddleware();
|
|
11
22
|
return ({ dispatch, getState }) => {
|
|
12
|
-
(
|
|
13
|
-
|
|
23
|
+
if (i === 0) {
|
|
24
|
+
(controller as any).dispatch = dispatch;
|
|
25
|
+
(controller as any).getState = getState;
|
|
26
|
+
}
|
|
14
27
|
// controller is a superset of the middleware API
|
|
15
28
|
return middleware(controller as Controller<any>);
|
|
16
29
|
};
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import { ActionTypes } from '../actions.js';
|
|
2
|
+
import { State } from '../types.js';
|
|
3
|
+
|
|
4
|
+
type Action = ActionTypes;
|
|
2
5
|
type ActionCreator<T> = any;
|
|
3
6
|
|
|
4
7
|
// taken from https://github.com/reduxjs/redux-devtools/blob/main/packages/redux-devtools-extension/src/index.ts
|
|
@@ -78,7 +81,7 @@ export interface EnhancerOptions {
|
|
|
78
81
|
/**
|
|
79
82
|
* function which takes `state` object and index as arguments, and should return `state` object back.
|
|
80
83
|
*/
|
|
81
|
-
stateSanitizer?: <S
|
|
84
|
+
stateSanitizer?: <S extends State<unknown>>(state: S, index: number) => S;
|
|
82
85
|
/**
|
|
83
86
|
* *string or array of strings as regex* - actions types to be hidden / shown in the monitors (while passed to the reducers).
|
|
84
87
|
* If `actionsWhitelist` specified, `actionsBlacklist` is ignored.
|
|
@@ -105,7 +108,10 @@ export interface EnhancerOptions {
|
|
|
105
108
|
* called for every action before sending, takes `state` and `action` object, and returns `true` in case it allows sending the current data to the monitor.
|
|
106
109
|
* Use it as a more advanced version of `actionsDenylist`/`actionsAllowlist` parameters.
|
|
107
110
|
*/
|
|
108
|
-
predicate?: <S
|
|
111
|
+
predicate?: <S extends State<unknown>, A extends Action>(
|
|
112
|
+
state: S,
|
|
113
|
+
action: A,
|
|
114
|
+
) => boolean;
|
|
109
115
|
/**
|
|
110
116
|
* if specified as `false`, it will not record the changes till clicking on `Start recording` button.
|
|
111
117
|
* Available only for Redux enhancer, for others use `autoPause`.
|
|
@@ -595,7 +595,7 @@ describe('reducer', () => {
|
|
|
595
595
|
const newState = reducer(iniState, action);
|
|
596
596
|
expect(newState.entities).toBe(iniState.entities);
|
|
597
597
|
});
|
|
598
|
-
it('rdc/fetch should console.warn()', () => {
|
|
598
|
+
it('rdc/fetch should not console.warn()', () => {
|
|
599
599
|
const warnspy = jest
|
|
600
600
|
.spyOn(global.console, 'warn')
|
|
601
601
|
.mockImplementation(() => {});
|
|
@@ -618,7 +618,8 @@ describe('reducer', () => {
|
|
|
618
618
|
};
|
|
619
619
|
const newState = reducer(iniState, action);
|
|
620
620
|
expect(newState).toBe(iniState);
|
|
621
|
-
|
|
621
|
+
// moved warns to applyManager() vv
|
|
622
|
+
expect(warnspy.mock.calls.length).toBe(0);
|
|
622
623
|
} finally {
|
|
623
624
|
warnspy.mockRestore();
|
|
624
625
|
}
|
|
@@ -12,18 +12,6 @@ export function fetchReducer(state: State<unknown>, action: FetchAction) {
|
|
|
12
12
|
...state,
|
|
13
13
|
optimistic: [...state.optimistic, setAction],
|
|
14
14
|
};
|
|
15
|
-
} else {
|
|
16
|
-
// If 'fetch' action reaches the reducer there are no middlewares installed to handle it
|
|
17
|
-
/* istanbul ignore next */
|
|
18
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
19
|
-
console.warn(
|
|
20
|
-
'Fetch appears unhandled - you are likely missing the NetworkManager middleware',
|
|
21
|
-
);
|
|
22
|
-
console.warn(
|
|
23
|
-
'See https://dataclient.io/docs/guides/redux for hooking up redux',
|
|
24
|
-
);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return state;
|
|
28
15
|
}
|
|
16
|
+
return state;
|
|
29
17
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { ActionTypes } from '../actions.js';
|
|
2
|
+
import { State } from '../types.js';
|
|
3
|
+
type Action = ActionTypes;
|
|
2
4
|
type ActionCreator<T> = any;
|
|
3
5
|
export interface EnhancerOptions {
|
|
4
6
|
/**
|
|
@@ -72,7 +74,7 @@ export interface EnhancerOptions {
|
|
|
72
74
|
/**
|
|
73
75
|
* function which takes `state` object and index as arguments, and should return `state` object back.
|
|
74
76
|
*/
|
|
75
|
-
stateSanitizer?: <S
|
|
77
|
+
stateSanitizer?: <S extends State<unknown>>(state: S, index: number) => S;
|
|
76
78
|
/**
|
|
77
79
|
* *string or array of strings as regex* - actions types to be hidden / shown in the monitors (while passed to the reducers).
|
|
78
80
|
* If `actionsWhitelist` specified, `actionsBlacklist` is ignored.
|
|
@@ -99,7 +101,7 @@ export interface EnhancerOptions {
|
|
|
99
101
|
* called for every action before sending, takes `state` and `action` object, and returns `true` in case it allows sending the current data to the monitor.
|
|
100
102
|
* Use it as a more advanced version of `actionsDenylist`/`actionsAllowlist` parameters.
|
|
101
103
|
*/
|
|
102
|
-
predicate?: <S
|
|
104
|
+
predicate?: <S extends State<unknown>, A extends Action>(state: S, action: A) => boolean;
|
|
103
105
|
/**
|
|
104
106
|
* if specified as `false`, it will not record the changes till clicking on `Start recording` button.
|
|
105
107
|
* Available only for Redux enhancer, for others use `autoPause`.
|
|
@@ -1,4 +1,29 @@
|
|
|
1
1
|
import Controller from '../../controller/Controller.js';
|
|
2
2
|
import { State, SetAction } from '../../types.js';
|
|
3
|
-
export declare function setReducer(state: State<unknown>, action: SetAction, controller: Controller): State<unknown
|
|
3
|
+
export declare function setReducer(state: State<unknown>, action: SetAction, controller: Controller): State<unknown> | {
|
|
4
|
+
entities: {
|
|
5
|
+
[x: string]: any;
|
|
6
|
+
};
|
|
7
|
+
indexes: import("@data-client/normalizr").NormalizedIndex;
|
|
8
|
+
endpoints: {
|
|
9
|
+
readonly [key: string]: unknown;
|
|
10
|
+
};
|
|
11
|
+
entityMeta: import("packages/normalizr/lib/types.js").EntitiesToMeta<{
|
|
12
|
+
[x: string]: any;
|
|
13
|
+
}>;
|
|
14
|
+
meta: {
|
|
15
|
+
readonly [key: string]: {
|
|
16
|
+
readonly date: number;
|
|
17
|
+
readonly expiresAt: number;
|
|
18
|
+
readonly prevExpiresAt?: number;
|
|
19
|
+
readonly error?: import("@data-client/normalizr").ErrorTypes;
|
|
20
|
+
readonly invalidated?: boolean;
|
|
21
|
+
readonly errorPolicy?: "hard" | "soft" | undefined;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
optimistic: (import("../../actions.js").SetResponseAction | import("../../actions.js").OptimisticAction<import("@data-client/normalizr").EndpointInterface<import("@data-client/normalizr").FetchFunction, import("@data-client/normalizr").Schema | undefined, boolean | undefined> & {
|
|
25
|
+
update?: import("../../index.js").EndpointUpdateFunction<import("@data-client/normalizr").EndpointInterface>;
|
|
26
|
+
}>)[];
|
|
27
|
+
lastReset: number;
|
|
28
|
+
};
|
|
4
29
|
//# sourceMappingURL=setReducer.d.ts.map
|
|
@@ -1,4 +1,31 @@
|
|
|
1
1
|
import Controller from '../../controller/Controller.js';
|
|
2
2
|
import { State, SetResponseAction, OptimisticAction } from '../../types.js';
|
|
3
|
-
export declare function setResponseReducer(state: State<unknown>, action: OptimisticAction | SetResponseAction, controller: Controller): State<unknown
|
|
3
|
+
export declare function setResponseReducer(state: State<unknown>, action: OptimisticAction | SetResponseAction, controller: Controller): State<unknown> | {
|
|
4
|
+
entities: {
|
|
5
|
+
[x: string]: any;
|
|
6
|
+
};
|
|
7
|
+
indexes: import("@data-client/normalizr").NormalizedIndex;
|
|
8
|
+
endpoints: Record<string, unknown>;
|
|
9
|
+
entityMeta: import("packages/normalizr/lib/types.js").EntitiesToMeta<{
|
|
10
|
+
[x: string]: any;
|
|
11
|
+
}>;
|
|
12
|
+
meta: {
|
|
13
|
+
[x: string]: {
|
|
14
|
+
readonly date: number;
|
|
15
|
+
readonly expiresAt: number;
|
|
16
|
+
readonly prevExpiresAt?: number;
|
|
17
|
+
readonly error?: import("@data-client/normalizr").ErrorTypes;
|
|
18
|
+
readonly invalidated?: boolean;
|
|
19
|
+
readonly errorPolicy?: "hard" | "soft" | undefined;
|
|
20
|
+
} | {
|
|
21
|
+
date: number;
|
|
22
|
+
expiresAt: number;
|
|
23
|
+
prevExpiresAt: number;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
optimistic: (SetResponseAction | OptimisticAction<import("@data-client/normalizr").EndpointInterface<import("@data-client/normalizr").FetchFunction, import("@data-client/normalizr").Schema | undefined, boolean | undefined> & {
|
|
27
|
+
update?: import("../../index.js").EndpointUpdateFunction<import("@data-client/normalizr").EndpointInterface>;
|
|
28
|
+
}>)[];
|
|
29
|
+
lastReset: number;
|
|
30
|
+
};
|
|
4
31
|
//# sourceMappingURL=setResponseReducer.d.ts.map
|