@zedux/core
Version:
A high-level, declarative, composable form of Redux
66 lines (65 loc) • 2.73 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.propagateChange = exports.delegate = void 0;
const meta_1 = require("../api/meta");
const zeduxTypes_1 = require("../api/zeduxTypes");
const general_1 = require("../utils/general");
const getErrorMessage = (subStorePath) => `Zedux: store.dispatch() - Invalid Delegation - Store does not contain a child store at path: ${subStorePath.join(' -> ')}`;
const prodError = 'Minified Error';
/**
* Finds a node in a tree given a node path (array of nodes).
*/
const findChild = (tree, nodePath) => {
for (const node of nodePath) {
if (tree.type !== general_1.BranchNodeType) {
throw new ReferenceError(true /* DEV */ ? getErrorMessage(nodePath) : prodError);
}
tree = tree.children[node];
if (!tree) {
throw new ReferenceError(true /* DEV */ ? getErrorMessage(nodePath) : prodError);
}
}
return tree;
};
/**
* Delegates an action to a child store.
*
* Does nothing if the special `delegate` meta node is not present in the action
* chain.
*
* This expects the `metaData` of the `delegate` meta node to be an array
* containing a path of nodes describing the child store's location in the
* parent store's current hierarchy descriptor.
*
* Delegated actions will not be handled by the parent store at all.
*/
const delegate = (tree, action) => {
const subStorePath = (0, meta_1.getMetaData)(action, zeduxTypes_1.zeduxTypes.delegate);
if (!subStorePath || !tree)
return false;
const child = findChild(tree, subStorePath);
if (child.type !== general_1.StoreNodeType) {
throw new TypeError(true /* DEV */ ? getErrorMessage(subStorePath) : prodError);
}
;
child.store.dispatch((0, meta_1.removeMeta)(action, zeduxTypes_1.zeduxTypes.delegate));
};
exports.delegate = delegate;
/**
* Propagates a state change from a child store to a parent.
*
* Recursively finds the child store's node in the parent store's state tree and
* re-creates all the nodes down that path.
*
* #immutability
*/
const propagateChange = (currentState, subStorePath, newSubStoreState, hierarchyConfig) => {
if (!subStorePath.length)
return newSubStoreState;
// at this point we can assume that currentState is a hierarhical structure
// these "currentState as any" casts should be fine
const newNode = hierarchyConfig.clone(currentState);
const nextNodeKey = subStorePath[0];
return hierarchyConfig.set(newNode, nextNodeKey, (0, exports.propagateChange)(hierarchyConfig.get(currentState, nextNodeKey), subStorePath.slice(1), newSubStoreState, hierarchyConfig));
};
exports.propagateChange = propagateChange;