UNPKG

@shopgate/pwa-common

Version:

Common library for the Shopgate Connect PWA.

58 lines 4.83 kB
import noop from'lodash/noop';import{isObject}from"../validation";/** * @typedef {Object} MutableFunction * @property {Function} replace Replaces the original functionality with a custom function. * @property {Function} restore Restores the original function. * @property {Function} reset Restores the original function and removes all pre-processes steps. * @property {Function} useBefore Adds a pre-processing step func. * @property {Function} original Original function */var BEFORE_ACTION_NEXT='next';var BEFORE_ACTION_SKIP_REST='skipRest';var BEFORE_ACTION_STOP='stop';/** * Defines parameters to be used by the next step or mutable function. * @param {*} args Transforms an argument list to be consumed by the next step or * @returns {Object} */export function next(){for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}return{action:BEFORE_ACTION_NEXT,args:args};}/** * Causes the stack to skip forward to processing the mutable using the given arguments. * @param {*} [args] A number of arguments to be passed to the mutable. This is optional. * @returns {Object} */export function skipRest(){for(var _len2=arguments.length,args=new Array(_len2),_key2=0;_key2<_len2;_key2++){args[_key2]=arguments[_key2];}return{action:BEFORE_ACTION_SKIP_REST,args:args};}/** * Causes the stack to stop processing any further actions. On stop only one return value possible. * @param {*} [arg] Optional final result value. * @returns {Object} */export function stop(arg){return{action:BEFORE_ACTION_STOP,args:arg};}/** * Public api export * @type {{next: Function, stop: Function, skipRest: Function}} */export var mutableActions={next:next,skipRest:skipRest,stop:stop};/** * Takes a function and makes it mutable. * @template {Function} T * @param {T} func Original function to convert to a mutable * @returns {T} */export var mutable=function mutable(func){var original=func;var current=func;var steps=[];/** * Takes the pre-processing steps and calls all step functions, as well as the mutable function * afterwards. Each step can transform the arguments, that are passed in to the next step in the * stack and ultimately to the mutable function. * @param {*} args Arguments passed down to the mutable and its pre-processor actions. * @returns {Function} A function to be consumed by redux */function mutableFunc(){for(var _len3=arguments.length,args=new Array(_len3),_key3=0;_key3<_len3;_key3++){args[_key3]=arguments[_key3];}var mutatedArgs=args;var runAction=true;// Execute pre-processing steps, if any available. if(steps.length>0){mutatedArgs=steps.reduce(function(acc,step,i,arr){// Call next step func in the pipeline with mutated args var res=step.apply(void 0,acc);// Keep params unchanged if the step did not perform any change action at all if(!isObject(res)){return acc;}// Unpack arguments from the "useBefore" pre-processor with "next" action. if(res.action===BEFORE_ACTION_NEXT){if(res.args&&res.args.length>0){res=res.args;}else{res=args;}}// Unpack arguments from the "useBefore" pre-processor with "skipRest" action. if(res.action===BEFORE_ACTION_SKIP_REST){arr.splice(-(arr.length-i));if(res.args&&res.args.length>0){res=res.args;}else{res=args;}}// Check if the step requested to stop any further processing including the action itself if(res.action===BEFORE_ACTION_STOP){// Cut off all following step functions including the mutable func arr.splice(-(arr.length-i));runAction=false;res=res.args;}// Replace arguments for the next step to get. return res;},args);}if(!runAction){// the return value here gets passed to the dispatch() so it must be a function or action obj return noop;}// Call the actual mutable return current.apply(void 0,mutatedArgs);}/** * Replaces the original functionality with a custom function. * @param {Function} customFunc The function to execute instead of the original one. */mutableFunc.replace=function(customFunc){current=customFunc;// Allow access to the current mutation. mutableFunc.current=current;};/** * Restores the original func, while keeping additional functions to be called beforehand. */mutableFunc.restore=function(){current=original;};/** * Resets the whole mutable to its initial state, restoring the original functionality and * dropping all injected functions. */mutableFunc.reset=function(){current=original;steps.length=0;};/** * Adds a pre-processing step func to a list to be called before the actual functionality * executes. Each step can modify the arguments, passed down to the next step or the mutable. * @param {Function} stepFunc The function to be executed before */mutableFunc.useBefore=function(stepFunc){steps.push(stepFunc);};// Allow access to the original function. mutableFunc.original=original;return mutableFunc;};