UNPKG

@empathyco/x-components

Version:
103 lines (100 loc) 4.07 kB
import { reduce } from '@empathyco/x-utils'; let cache = {}; /** * Creates or return a proxy object of the getters of the storeModule passed. * * @param getters - The Vuex Store Getters. * @param moduleName - The name of the module. * @param storeModule - The store module. * @returns A {@link GettersTree} object with only the getters of the {@link XModule}. * * @internal * * @remarks This proxy will be used by the stateSelector, of the module. This is done to ensure that * a Vuex stateSelector can only access the getters of the {@link XModule} where it is registered. * This function task can be done with {@link getGettersProxy}, just without passing the * storeModule. But in that case every time we register emitters in a module, it will loop over all * the getters of all the store. This way, passing the moduleNeeded, it only loops over the getters * of that module. It is a performance question to have this two different implementations. * */ function getGettersProxyFromModule(getters, moduleName, storeModule) { /* TODO: Review why TS is not able to exclude undefined types from the Getters cache */ const cachedGetter = cache[moduleName]; if (isCacheGetterDefined(cachedGetter)) { return cachedGetter; } const modulePath = `x/${moduleName}/`; const safeGetters = reduce(storeModule.getters, (safeGettersProxy, getterName) => defineGetterProxy(safeGettersProxy, getterName, `${modulePath}${getterName}`, getters), {}); cache[moduleName] = safeGetters; return safeGetters; } /** * Creates or return a proxy object of the getters of the module with the moduleName passed. * * @param getters - The Vuex Store Getters. * @param moduleName - The name of the module. * @returns A {@link GettersTree} object with only the getters of the {@link XModule}. * * @internal * * @remarks This proxy will be used wireCommit to pass the module state and getters, to a function * that will return the payload to commit the mutation. */ function getGettersProxy(getters, moduleName) { /* TODO: Review why TS is not able to exclude undefined types from the Getters cache */ const cachedGetter = cache[moduleName]; if (isCacheGetterDefined(cachedGetter)) { return cachedGetter; } const modulePath = `x/${moduleName}/`; const getterKeys = Object.keys(getters).filter(getterKey => getterKey.startsWith(modulePath)); const safeGetters = getterKeys.reduce((safeGettersProxy, fullPathGetterName) => { const getterName = fullPathGetterName.replace(modulePath, ''); return defineGetterProxy(safeGettersProxy, getterName, fullPathGetterName, getters); }, {}); cache[moduleName] = safeGetters; return safeGetters; } /** * Defines a JS getter in safeGettersProxy object that returns the Vuex getter value. * * @param safeGettersProxy - The object where the proxy will be defined. * @param getterName - The name of the Getter without path. For example: 'trimQuery'. * @param fullPathGetterName - The name of the getter to be accessed with the full path. * For example: 'x/searchBox/trimmedQuery'. * @param getters - The Vuex Store Getters. * @returns The same safeGetterProxy with new get defined. * * @internal */ function defineGetterProxy(safeGettersProxy, getterName, fullPathGetterName, getters) { return Object.defineProperty(safeGettersProxy, getterName, { get() { // eslint-disable-next-line ts/no-unsafe-return return getters[fullPathGetterName]; }, enumerable: true, }); } /** * Clean the cache (This is for testing purpose). * * @internal */ function cleanGettersProxyCache() { cache = {}; } /** * Checks if the getter cached is defined. * * @param cachedGetter - The getter cached. * @returns If the getters is defined or not. * * @internal */ function isCacheGetterDefined(cachedGetter) { return cachedGetter !== undefined; } export { cleanGettersProxyCache, getGettersProxy, getGettersProxyFromModule }; //# sourceMappingURL=getters-proxy.utils.js.map