UNPKG

@domx/dataelement

Version:

A DataElement base class for handling data state changes

81 lines 2.71 kB
export { RootState }; 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) { RootState.current = state; } /** Returns the state at the given state path */ static get(path) { const value = path.split(".").reduce((state, prop) => state !== undefined ? state[prop] : undefined, RootState.current); return value === undefined ? null : value; } /** Sets the state at the given state path */ static set(path, value) { setState(RootState.current, path, value); } /** Removes the state at the given state path */ static delete(path) { 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, value) { 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]; } static set current(state) { window[stateProp] = state; } static snapshot(name) { window.dispatchEvent(new CustomEvent("rootstate-snapshot", { detail: { name, state: RootState.current } })); } } /** Used for setting, deleting, and drafting state */ const setState = (state, path, value) => { let currentState = state; const pathParts = path.split("."); let deleteElStatePath = null; pathParts.forEach((prop, index) => { 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] = Object.assign({}, value); } } else if (currentState[prop] === undefined) { currentState[prop] = {}; } currentState = currentState[prop]; }); if (deleteElStatePath) { return setState(RootState.current, deleteElStatePath, undefined); } return state; }; //# sourceMappingURL=RootState.js.map