UNPKG

kibana-123

Version:

Kibana is an open source (Apache Licensed), browser based analytics and search dashboard for Elasticsearch. Kibana is a snap to setup and start using. Kibana strives to be easy to get started with, while also being flexible and powerful, just like Elastic

105 lines (82 loc) 2.94 kB
import { cloneDeep, isEqual, set, isPlainObject } from 'lodash'; export default { create: (state, customInitialState) => stateMonitor(state, customInitialState) }; function stateMonitor(state, customInitialState) { let destroyed = false; let ignoredProps = []; let changeHandlers = []; let initialState; setInitialState(customInitialState); function setInitialState(customInitialState) { // state.toJSON returns a reference, clone so we can mutate it safely initialState = cloneDeep(customInitialState) || cloneDeep(state.toJSON()); } function removeIgnoredProps(state) { ignoredProps.forEach(path => { set(state, path, true); }); return state; } function getStatus() { // state.toJSON returns a reference, clone so we can mutate it safely const currentState = removeIgnoredProps(cloneDeep(state.toJSON())); const isClean = isEqual(currentState, initialState); return { clean: isClean, dirty: !isClean, }; } function dispatchChange(type = null, keys = []) { const status = getStatus(); changeHandlers.forEach(changeHandler => { changeHandler(status, type, keys); }); } function dispatchFetch(keys) { dispatchChange('fetch_with_changes', keys); }; function dispatchSave(keys) { dispatchChange('save_with_changes', keys); }; function dispatchReset(keys) { dispatchChange('reset_with_changes', keys); }; return { setInitialState(customInitialState) { if (!isPlainObject(customInitialState)) throw new TypeError('The default state must be an object'); // check the current status const previousStatus = getStatus(); // update the initialState and apply ignoredProps setInitialState(customInitialState); removeIgnoredProps(initialState); // fire the change handler if the status has changed if (!isEqual(previousStatus, getStatus())) dispatchChange(); }, ignoreProps(props) { ignoredProps = ignoredProps.concat(props); removeIgnoredProps(initialState); return this; }, onChange(callback) { if (destroyed) throw new Error('Monitor has been destroyed'); if (typeof callback !== 'function') throw new Error('onChange handler must be a function'); changeHandlers.push(callback); // Listen for state events. state.on('fetch_with_changes', dispatchFetch); state.on('save_with_changes', dispatchSave); state.on('reset_with_changes', dispatchReset); // if the state is already dirty, fire the change handler immediately const status = getStatus(); if (status.dirty) dispatchChange(); return this; }, destroy() { destroyed = true; changeHandlers = undefined; state.off('fetch_with_changes', dispatchFetch); state.off('save_with_changes', dispatchSave); state.off('reset_with_changes', dispatchReset); } }; }