reshow-return
Version:
reshow-return (simple connect component with reshow-flux)
182 lines (170 loc) • 4.66 kB
JavaScript
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
};