UNPKG

@zedux/core

Version:

A high-level, declarative, composable form of Redux

114 lines (113 loc) 4.67 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.wrapStoreInReducer = exports.hierarchyDescriptorToHierarchy = exports.getHierarchyType = void 0; const createStore_1 = require("../api/createStore"); const detailedTypeof_1 = require("../api/detailedTypeof"); const is_1 = require("../api/is"); const isPlainObject_1 = require("../api/isPlainObject"); const zeduxTypes_1 = require("../api/zeduxTypes"); const general_1 = require("../utils/general"); /** * Converts a Branch hierarchy descriptor to a HierarchyNode's children * * Really should only be used from `hierarchyDescriptorToHierarchy()` */ const branchToHierarchyChildren = (branch, registerSubStore, currentPath) => { const children = {}; Object.entries(branch).forEach(([key, val]) => { const newPath = [...currentPath, key]; children[key] = (0, exports.hierarchyDescriptorToHierarchy)(val, registerSubStore, newPath); }); return children; }; /** * Turns a non-branch node from a user-supplied hierarchy descriptor into a * HierarchyNode object */ const nonBranchToHierarchyNode = (type, hierarchy, registerSubStore, currentPath) => { if (type === general_1.NullNodeType) { return { type }; } if (type === general_1.ReducerNodeType) { return { type, reducer: hierarchy }; } // It's a Store hierarchy descriptor return { type: type, destroy: registerSubStore(currentPath, hierarchy), reducer: (0, exports.wrapStoreInReducer)(hierarchy), store: hierarchy, }; }; /** * Determines the HierarchyNodeType of the given hierarchy descriptor. * * Throws a TypeError if the descriptor is invalid. */ const getHierarchyType = (descriptor) => { if (typeof descriptor === 'function') return general_1.ReducerNodeType; if (descriptor && (0, is_1.is)(descriptor, createStore_1.Store)) return general_1.StoreNodeType; if ((0, isPlainObject_1.isPlainObject)(descriptor)) return general_1.BranchNodeType; if (true /* DEV */ && descriptor != null) { throw new TypeError(`Zedux: store.use() - Hierarchy descriptor nodes must be reducers, stores, plain objects, or null. Received ${(0, detailedTypeof_1.detailedTypeof)(descriptor)}`); } return general_1.NullNodeType; }; exports.getHierarchyType = getHierarchyType; /** * Turns a normal, user-supplied hierarchy descriptor into a Hierarchy for easy * reducer hierarchy creating, diffing, merging, and destroying. * * Also figures out the reducer for non-branch nodes. */ const hierarchyDescriptorToHierarchy = (hierarchy, registerSubStore, currentPath = []) => { const type = (0, exports.getHierarchyType)(hierarchy); if (type !== general_1.BranchNodeType) { return nonBranchToHierarchyNode(type, hierarchy, registerSubStore, currentPath); } // It's a Branch; recursively convert the whole tree. We don't need to supply // a reducer for this branch 'cause the merge process does that for us return { type, children: branchToHierarchyChildren(hierarchy, registerSubStore, currentPath), }; }; exports.hierarchyDescriptorToHierarchy = hierarchyDescriptorToHierarchy; /** * Creates a reducer that wraps the entry points of the given store. * * This reducer will propagate actions down the child store's reducers. * * Wraps all actions in the special `inherit` meta node to inform the child * store's effects subscribers that this action was received from its parent * store. * * Since the parent store also registers an effects subscriber on this child * store, it will know not to propagate the inherited action from the child * store. UPDATE: Actually, it doesn't even need to check - the parent store * knows that it _isDispatching and can ignore child store actions while it is. */ const wrapStoreInReducer = (store) => { const reducer = (state, action) => { // If this is the special hydrate or partial hydrate action, re-create the // action's payload using the current state slice if (action.type === zeduxTypes_1.zeduxTypes.hydrate || action.type === zeduxTypes_1.zeduxTypes.merge) { action = { type: zeduxTypes_1.zeduxTypes.hydrate, payload: state, }; } // Tell the child store's effect subscribers that this action is inherited const inheritedAction = { metaType: zeduxTypes_1.zeduxTypes.inherit, payload: action, }; return store.dispatch(inheritedAction); }; return reducer; }; exports.wrapStoreInReducer = wrapStoreInReducer;