-
Notifications
You must be signed in to change notification settings - Fork 94
Expand file tree
/
Copy pathRealDevTools.ts
More file actions
88 lines (75 loc) · 2.9 KB
/
RealDevTools.ts
File metadata and controls
88 lines (75 loc) · 2.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import type {IDevTools, DevtoolsOptions, DevtoolsConnection, ReduxDevtools} from './types';
import OnyxUtils from '../OnyxUtils';
const ERROR_LABEL = 'Onyx DevTools - Error: ';
/**
* Real implementation of DevTools that connects to Redux DevTools Extension
*/
class RealDevTools implements IDevTools {
private remoteDev?: DevtoolsConnection;
private state: Record<string, unknown>;
private defaultState: Record<string, unknown>;
constructor() {
this.remoteDev = this.connectViaExtension();
this.state = {};
this.defaultState = {};
}
connectViaExtension(options?: DevtoolsOptions): DevtoolsConnection | undefined {
try {
// We don't want to augment the window type in a library code, so we use type assertion instead
// eslint-disable-next-line no-underscore-dangle, @typescript-eslint/no-explicit-any
const reduxDevtools: ReduxDevtools = typeof window === 'undefined' ? undefined : (window as any).__REDUX_DEVTOOLS_EXTENSION__;
if (options?.remote || !reduxDevtools) {
return;
}
return reduxDevtools.connect(options);
} catch (e) {
console.error(ERROR_LABEL, e);
}
}
/**
* Registers an action that updated the current state of the storage
*
* @param type - name of the action
* @param payload - data written to the storage
* @param stateChanges - partial state that got updated after the changes
*/
registerAction(type: string, payload: unknown, stateChanges: Record<string, unknown> | null = {}) {
try {
if (!this.remoteDev) {
return;
}
const newState = {
...this.state,
...stateChanges,
};
this.remoteDev.send({type, payload}, newState);
this.state = newState;
} catch (e) {
console.error(ERROR_LABEL, e);
}
}
initState(initialState: Record<string, unknown> = {}) {
try {
if (!this.remoteDev) {
return;
}
this.remoteDev.init(initialState);
this.state = initialState;
this.defaultState = initialState;
} catch (e) {
console.error(ERROR_LABEL, e);
}
}
/**
* This clears the internal state of the DevTools, preserving the keys included in `keysToPreserve`
*/
clearState(keysToPreserve: string[] = []): void {
const newState = Object.entries(this.state).reduce((obj: Record<string, unknown>, [key, value]) => {
// eslint-disable-next-line no-param-reassign
obj[key] = keysToPreserve.some((preserveKey) => OnyxUtils.isKeyMatch(preserveKey, key)) ? value : this.defaultState[key];
return obj;
}, {});
this.registerAction('CLEAR', undefined, newState);
}
}
export default RealDevTools;