@zedux/core
Version:
A high-level, declarative, composable form of Redux
69 lines (68 loc) • 2.39 kB
JavaScript
import { detailedTypeof } from './detailedTypeof.js';
const assertActionExists = (action) => {
if (action)
return;
throw new Error(`Zedux: Invalid action chain. The last node in the chain must be either a valid action object with a non-empty "type" property or an effect with a non-empty "effectType" property. Received ${detailedTypeof(action)}`);
};
const getNewRoot = (currentNode, prevNode, rootNode) => {
// If the match is at the top layer, just return the next layer
if (!prevNode || !rootNode)
return currentNode.payload;
// If the match is at least one layer deep, swap out the target layer
// and return the new root of the action chain
prevNode.payload = currentNode.payload;
return rootNode;
};
/**
* Returns the value of the metaData field of the first ActionMeta object in the
* chain with the given metaType.
*/
export const getMetaData = (action, metaType) => {
while (action.metaType) {
if (action.metaType === metaType) {
return action.metaData;
}
action = action.payload;
if (true /* DEV */) {
assertActionExists(action);
}
}
};
/**
* Strips all ActionMeta nodes off an ActionChain and returns the wrapped Action
*/
export const removeAllMeta = (action) => {
while (action.metaType) {
action = action.payload;
if (true /* DEV */) {
assertActionExists(action);
}
}
return action;
};
/**
* Removes the first found meta node with the given metaType in the given action
* chain.
*
* The metaType does not have to exist in the action chain (though this'll be
* pretty inefficient and wasteful if it doesn't).
*/
export const removeMeta = (action, metaType) => {
let currentNode = action;
let prevNode = null;
let rootNode = null;
while (currentNode.metaType) {
if (currentNode.metaType === metaType) {
return getNewRoot(currentNode, prevNode, rootNode);
}
// Move down the chain
const clonedNode = Object.assign({}, currentNode);
prevNode && (prevNode.payload = clonedNode);
prevNode = clonedNode;
currentNode = currentNode.payload;
// If this will be the new root, remember it
rootNode || (rootNode = prevNode);
}
// No match found; return the original action chain
return action;
};