Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | 6x 6x 24x 67x 154x 67x 52x 28x 16x 16x 16x 201x 2x 201x 24x 2x 6x 128x 128x 128x 128x 252x 128x 60x 60x 57x 68x 124x 45x 252x 128x 32x 96x | export { RootState };
interface StateMap {
[key:string]: StateMap|undefined
}
interface Root {
state:StateMap
}
declare global {
interface Window {
[stateProp]: StateMap;
}
}
const stateProp = Symbol();
/**
* Used to keep track of a global state tree
* for data elements.
*/
class RootState {
/** Initializes/resets the root state */
static init(state:StateMap) {
RootState.current = state;
}
/** Returns the state at the given state path */
static get(path:string):object|null {
const value = path.split(".").reduce((state:StateMap|undefined, prop:string) =>
state !== undefined ? state[prop] : undefined, RootState.current);
return value === undefined ? null : value;
}
/** Sets the state at the given state path */
static set(path:string, value: object):void {
setState(RootState.current, path, value);
}
/** Removes the state at the given state path */
static delete(path:string):void {
setState(RootState.current, path, undefined);
}
/**
* Creates a copy of the root state and sets the value at the state path.
* Used for intermediate changes before committing.
*/
static draft(path:string, value: object):StateMap {
const copy = JSON.parse(JSON.stringify(RootState.current));
const state = setState(copy, path, value);
return state;
}
/** The current root state */
static get current() {
if (!window[stateProp]) {
window[stateProp] = {};
}
return window[stateProp];
}
private static set current(state:StateMap) {
window[stateProp] = state;
}
static snapshot(name:string) {
window.dispatchEvent(new CustomEvent("rootstate-snapshot", {
detail: {
name,
state: RootState.current
}
}));
}
}
/** Used for setting, deleting, and drafting state */
const setState = (state:StateMap, path:string, value:object|undefined):StateMap => {
let currentState = state;
const pathParts = path.split(".");
let deleteElStatePath:string|null = null;
pathParts.forEach((prop:string, index:number) => {
if (index === pathParts.length - 1) {
if (value === undefined) {
delete currentState[prop];
// if empty, then delete that part as well
if (Object.keys(currentState).length === 0) {
deleteElStatePath = [...pathParts].splice(0, pathParts.length - 1).join(".");
}
} else {
currentState[prop] = { ...value } as StateMap;
}
} else if (currentState[prop] === undefined) {
currentState[prop] = {};
}
currentState = currentState[prop] as StateMap;
});
if (deleteElStatePath) {
return setState(RootState.current, deleteElStatePath, undefined);
}
return state;
}; |