UNPKG

reshow-return

Version:

reshow-return (simple connect component with reshow-flux)

182 lines (170 loc) 4.66 kB
import _toConsumableArray from "reshow-runtime/es/helpers/toConsumableArray"; //@ts-check import get from "get-object-value"; import { toJS } from "reshow-flux"; import { IS_ARRAY, KEYS, T_UNDEFINED } from "reshow-constant"; /** * @param {object} props * @param {object} [more] * @returns {object} */ var reset = function reset(props, more) { var cleanKeys = ["immutable", "initStates", "pathStates", "renewProps", "store", "storeLocator", "shouldComponentUpdate"].concat(_toConsumableArray(more || [])); var i = cleanKeys.length; /** * Why use undefined? * https://github.com/react-atomic/reshow/issues/117 * * Why could use undefined? * because reshow-build have remove empty to clean undefined. * if u use react directly, react will complain error. * */ while (i--) { var key = cleanKeys[i]; props[key] && (props[key] = T_UNDEFINED); } return props; }; /** * @param {any} state */ var stateValueGetter = function stateValueGetter(state) { return ( /** * @param {any} k * @returns {any} */ function (k) { return get(state, [k]); } ); }; /** * @typedef {Record<string, string>} InitStateObject */ /** * @typedef { string[] | InitStateObject } InitStatesType */ /** * @param {InitStatesType?} initStates * @returns {[initStates extends string[] ? initStates : (keyof InitStateObject)[], function(string):string]} */ export var stateKeyLocator = function stateKeyLocator(initStates) { var keys; var getNewKey; if (IS_ARRAY(initStates)) { keys = initStates; getNewKey = function getNewKey(/** @type any*/key) { return key; }; } else { var nextStates = null == initStates ? {} : initStates; keys = KEYS(nextStates); getNewKey = function getNewKey(/** @type any*/key) { return null != nextStates[key] ? nextStates[key] : key; }; } return [keys, getNewKey]; }; /** * If not immutable, convert to js object. * * @param {boolean} immutable * @returns {function(any):any} */ var restoreToJS = function restoreToJS(immutable) { return function (data) { return immutable ? data : toJS(data); }; }; /** * @typedef {Object<string, string[]>} PathStates */ /** * @template StateType * @template ActionType * * @typedef {object} calculateOptions * @property {InitStatesType?} initStates * @property {import("reshow-flux-base").StoreObject<StateType, ActionType>} store * @property {PathStates=} pathStates * @property {boolean=} immutable */ /** * @template StateType * @template ActionType * * @param {StateType} prevState * @param {calculateOptions<StateType, ActionType>} calculateOptions * @returns {StateType} */ var calculateState = function calculateState(prevState, calculateOptions) { /** * Why not support multi stores? * Because multi stores need handle complex data merge. * If that case need create custom calculateState functoin. */ var { initStates, pathStates, immutable: optImmutable, store } = calculateOptions; var getStateValue = stateValueGetter(store.getState()); var immutable = optImmutable !== null && optImmutable !== void 0 ? optImmutable : getStateValue("immutable"); var handleRestoreJS = restoreToJS(immutable); var [stateKeys, toNewKey] = stateKeyLocator(initStates); var extracData = function extracData(/**@type any[]*/arrKey) { var results = {}; arrKey.forEach( /** * @param {string} key */ function (key) { var data = getStateValue(key); results[toNewKey(key)] = handleRestoreJS(data); }); return results; }; // Test pathStates all first key exists in stateKeys var additionalKeys = []; var results; if (pathStates) { var pathKeys = KEYS(pathStates); pathKeys.forEach(function (pathKey) { var firstKey = pathStates[pathKey][0]; if (-1 === stateKeys.indexOf(firstKey)) { if (firstKey !== pathKey) { additionalKeys.push(firstKey); } stateKeys.push(firstKey); } }); results = extracData(stateKeys); pathKeys.forEach(function (key) { return results[key] = get(results, pathStates[key]); }); var _i = additionalKeys.length; while (_i--) { delete results[additionalKeys[_i]]; } } else { results = extracData(stateKeys); } var bSame = true; var resultKeys = KEYS(results); var i = resultKeys.length; while (i--) { var key = resultKeys[i]; if (results[key] !== prevState[key]) { bSame = false; break; } } return /**@type StateType*/bSame ? prevState : results; }; export default { calculateState, reset };