UNPKG

overmind

Version:
110 lines 3.89 kB
var _a, _b; import isPlainObject from 'is-plain-obj'; import { PATH, PROXY_TREE, VALUE } from 'proxy-state-tree'; const INITIAL_STATE = Symbol('INITIAL_STATE'); const TRANSITIONS = Symbol('TRANSITIONS'); const STATE = Symbol('STATE'); const IS_DISPOSED = Symbol('IS_DISPOSED'); const CURRENT_KEYS = Symbol('CURRENT_KEYS'); const BASE_STATE = Symbol('BASE_STATE'); const TRANSITION_LISTENERS = Symbol('TRANSITION_LISTENERS'); // We have to export here to avoid a circular dependency issue with "utils" export function deepCopy(obj) { if (obj instanceof StateMachine) { return obj.clone(); } else if (isPlainObject(obj)) { return Object.keys(obj).reduce((aggr, key) => { if (key === '__esModule') { return aggr; } const originalDescriptor = Object.getOwnPropertyDescriptor(obj, key); const isAGetter = originalDescriptor && 'get' in originalDescriptor; const value = obj[key]; if (isAGetter) { Object.defineProperty(aggr, key, originalDescriptor); } else { aggr[key] = deepCopy(value); } return aggr; }, {}); } else if (Array.isArray(obj)) { return obj.map((item) => deepCopy(item)); } return obj; } export class StateMachine { clone() { return new StateMachine(this[TRANSITIONS], deepCopy(this[STATE]), deepCopy(this[BASE_STATE])); } dispose() { this[VALUE][TRANSITION_LISTENERS] = []; Object.keys(this[VALUE]).forEach((key) => { if (this[VALUE][key] instanceof StateMachine) { this[key].dispose(); } }); this[VALUE][IS_DISPOSED] = true; } constructor(transitions, state, baseState) { this[_a] = []; this[_b] = false; this[STATE] = state; this[BASE_STATE] = baseState; this[INITIAL_STATE] = state.current; this[BASE_STATE] = baseState; this[TRANSITIONS] = transitions; this[CURRENT_KEYS] = Object.keys(state); Object.assign(this, state, baseState); } send(type, data) { if (this[VALUE][IS_DISPOSED]) { if (process.env.NODE_ENV === 'development') { console.warn(`Overmind - The statemachine at "${this[PATH]}" has been disposed, but you tried to transition on it`); } return this; } const tree = this[PROXY_TREE].master.mutationTree || this[PROXY_TREE]; tree.enableMutations(); let result; if (typeof this[VALUE][TRANSITIONS] === 'function') { const transition = this[VALUE][TRANSITIONS]; result = transition({ type, data }, this); } else if (this[VALUE][TRANSITIONS][this[VALUE].current][type]) { const transition = this[VALUE][TRANSITIONS][this[VALUE].current][type]; result = transition(data, this); } if (result) { this[VALUE][CURRENT_KEYS].forEach((key) => { if (key !== 'current') { delete this[key]; } }); this[VALUE][CURRENT_KEYS] = Object.keys(result); Object.assign(this, result); this[VALUE][TRANSITION_LISTENERS].forEach((listener) => listener(this)); } tree.blockMutations(); return this; } matches(state) { if (this.current === state) { return this; } } onTransition(listener) { this[VALUE][TRANSITION_LISTENERS].push(listener); } } _a = TRANSITION_LISTENERS, _b = IS_DISPOSED; export function statemachine(transitions) { return { create(state, baseState) { return new StateMachine(transitions, state, baseState); }, }; } //# sourceMappingURL=statemachine.js.map