{"version":3,"file":"aspect.mjs","sourceRoot":"","sources":["../../src/aspect.ts"],"names":[],"mappings":"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","sourcesContent":["import { Handle } from './interfaces';\nimport WeakMap from '@dojo/shim/WeakMap';\nimport { createHandle } from './lang';\n\n/**\n * An object that provides the necessary APIs to be MapLike\n */\nexport interface MapLike<K, V> {\n\tget(key: K): V;\n\tset(key: K, value?: V): this;\n}\n\n/**\n * An internal type guard that determines if an value is MapLike or not\n *\n * @param value The value to guard against\n */\nfunction isMapLike(value: any): value is MapLike<any, any> {\n\treturn value && typeof value.get === 'function' && typeof value.set === 'function';\n}\n\nexport interface Indexable {\n\t[method: string]: any;\n}\n\n/**\n * The types of objects or maps where advice can be applied\n */\nexport type Targetable = MapLike<string | symbol, any> | Indexable;\n\ntype AdviceType = 'before' | 'after' | 'around';\n\n/**\n * A meta data structure when applying advice\n */\ninterface Advised {\n\treadonly id?: number;\n\tadvice?: Function;\n\tprevious?: Advised;\n\tnext?: Advised;\n\treadonly receiveArguments?: boolean;\n}\n\n/**\n * A function that dispatches advice which is decorated with additional\n * meta data about the advice to apply\n */\ninterface Dispatcher {\n\t[type: string]: Advised | undefined;\n\t(): any;\n\ttarget: any;\n\tbefore?: Advised;\n\taround?: Advised;\n\tafter?: Advised;\n}\n\nexport interface JoinPointDispatchAdvice<T> {\n\tbefore?: JoinPointBeforeAdvice[];\n\tafter?: JoinPointAfterAdvice<T>[];\n\treadonly joinPoint: Function;\n}\n\nexport interface JoinPointAfterAdvice<T> {\n\t/**\n\t * Advice which is applied *after*, receiving the result and arguments from the join point.\n\t *\n\t * @param result The result from the function being advised\n\t * @param args The arguments that were supplied to the advised function\n\t * @returns The value returned from the advice is then the result of calling the method\n\t */\n\t(result: T, ...args: any[]): T;\n}\n\nexport interface JoinPointAroundAdvice<T> {\n\t/**\n\t * Advice which is applied *around*.  The advising function receives the original function and\n\t * needs to return a new function which will then invoke the original function.\n\t *\n\t * @param origFn The original function\n\t * @returns A new function which will invoke the original function.\n\t */\n\t(origFn: GenericFunction<T>): (...args: any[]) => T;\n}\n\nexport interface JoinPointBeforeAdvice {\n\t/**\n\t * Advice which is applied *before*, receiving the original arguments, if the advising\n\t * function returns a value, it is passed further along taking the place of the original\n\t * arguments.\n\t *\n\t * @param args The arguments the method was called with\n\t */\n\t(...args: any[]): any[] | void;\n}\n\nexport interface GenericFunction<T> {\n\t(...args: any[]): T;\n}\n\n/**\n * A weak map of dispatchers used to apply the advice\n */\nconst dispatchAdviceMap = new WeakMap<Function, JoinPointDispatchAdvice<any>>();\n\n/**\n * A UID for tracking advice ordering\n */\nlet nextId = 0;\n\n/**\n * Internal function that advises a join point\n *\n * @param dispatcher The current advice dispatcher\n * @param type The type of before or after advice to apply\n * @param advice The advice to apply\n * @param receiveArguments If true, the advice will receive the arguments passed to the join point\n * @return The handle that will remove the advice\n */\nfunction adviseObject(\n\tdispatcher: Dispatcher | undefined,\n\ttype: AdviceType,\n\tadvice: Function | undefined,\n\treceiveArguments?: boolean\n): Handle {\n\tlet previous = dispatcher && dispatcher[type];\n\tlet advised: Advised | undefined = {\n\t\tid: nextId++,\n\t\tadvice: advice,\n\t\treceiveArguments: receiveArguments\n\t};\n\n\tif (previous) {\n\t\tif (type === 'after') {\n\t\t\t// add the listener to the end of the list\n\t\t\t// note that we had to change this loop a little bit to workaround a bizarre IE10 JIT bug\n\t\t\twhile (previous.next && (previous = previous.next)) {}\n\t\t\tprevious.next = advised;\n\t\t\tadvised.previous = previous;\n\t\t} else {\n\t\t\t// add to the beginning\n\t\t\tif (dispatcher) {\n\t\t\t\tdispatcher.before = advised;\n\t\t\t}\n\t\t\tadvised.next = previous;\n\t\t\tprevious.previous = advised;\n\t\t}\n\t} else {\n\t\tdispatcher && (dispatcher[type] = advised);\n\t}\n\n\tadvice = previous = undefined;\n\n\treturn createHandle(function() {\n\t\tlet { previous = undefined, next = undefined } = advised || {};\n\n\t\tif (dispatcher && !previous && !next) {\n\t\t\tdispatcher[type] = undefined;\n\t\t} else {\n\t\t\tif (previous) {\n\t\t\t\tprevious.next = next;\n\t\t\t} else {\n\t\t\t\tdispatcher && (dispatcher[type] = next);\n\t\t\t}\n\n\t\t\tif (next) {\n\t\t\t\tnext.previous = previous;\n\t\t\t}\n\t\t}\n\t\tif (advised) {\n\t\t\tdelete advised.advice;\n\t\t}\n\t\tdispatcher = advised = undefined;\n\t});\n}\n\n/**\n * Advise a join point (function) with supplied advice\n *\n * @param joinPoint The function to be advised\n * @param type The type of advice to be applied\n * @param advice The advice to apply\n */\nfunction adviseJoinPoint<F extends GenericFunction<T>, T>(\n\tthis: any,\n\tjoinPoint: F,\n\ttype: AdviceType,\n\tadvice: JoinPointBeforeAdvice | JoinPointAfterAdvice<T> | JoinPointAroundAdvice<T>\n): F {\n\tlet dispatcher: F;\n\tif (type === 'around') {\n\t\tdispatcher = getJoinPointDispatcher(advice.apply(this, [joinPoint]));\n\t} else {\n\t\tdispatcher = getJoinPointDispatcher(joinPoint);\n\t\t// cannot have undefined in map due to code logic, using !\n\t\tconst adviceMap = dispatchAdviceMap.get(dispatcher)!;\n\t\tif (type === 'before') {\n\t\t\t(adviceMap.before || (adviceMap.before = [])).unshift(<JoinPointBeforeAdvice>advice);\n\t\t} else {\n\t\t\t(adviceMap.after || (adviceMap.after = [])).push(advice);\n\t\t}\n\t}\n\treturn dispatcher;\n}\n\n/**\n * An internal function that resolves or creates the dispatcher for a given join point\n *\n * @param target The target object or map\n * @param methodName The name of the method that the dispatcher should be resolved for\n * @return The dispatcher\n */\nfunction getDispatcherObject(target: Targetable, methodName: string | symbol): Dispatcher {\n\tconst existing = isMapLike(target) ? target.get(methodName) : target && target[methodName];\n\tlet dispatcher: Dispatcher;\n\n\tif (!existing || existing.target !== target) {\n\t\t/* There is no existing dispatcher, therefore we will create one */\n\t\tdispatcher = <Dispatcher>function(this: Dispatcher): any {\n\t\t\tlet executionId = nextId;\n\t\t\tlet args = arguments;\n\t\t\tlet results: any;\n\t\t\tlet before = dispatcher.before;\n\n\t\t\twhile (before) {\n\t\t\t\tif (before.advice) {\n\t\t\t\t\targs = before.advice.apply(this, args) || args;\n\t\t\t\t}\n\t\t\t\tbefore = before.next;\n\t\t\t}\n\n\t\t\tif (dispatcher.around && dispatcher.around.advice) {\n\t\t\t\tresults = dispatcher.around.advice(this, args);\n\t\t\t}\n\n\t\t\tlet after = dispatcher.after;\n\t\t\twhile (after && after.id !== undefined && after.id < executionId) {\n\t\t\t\tif (after.advice) {\n\t\t\t\t\tif (after.receiveArguments) {\n\t\t\t\t\t\tlet newResults = after.advice.apply(this, args);\n\t\t\t\t\t\tresults = newResults === undefined ? results : newResults;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresults = after.advice.call(this, results, args);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tafter = after.next;\n\t\t\t}\n\n\t\t\treturn results;\n\t\t};\n\n\t\tif (isMapLike(target)) {\n\t\t\ttarget.set(methodName, dispatcher);\n\t\t} else {\n\t\t\ttarget && (target[methodName] = dispatcher);\n\t\t}\n\n\t\tif (existing) {\n\t\t\tdispatcher.around = {\n\t\t\t\tadvice: function(target: any, args: any[]): any {\n\t\t\t\t\treturn existing.apply(target, args);\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\tdispatcher.target = target;\n\t} else {\n\t\tdispatcher = existing;\n\t}\n\n\treturn dispatcher;\n}\n\n/**\n * Returns the dispatcher function for a given joinPoint (method/function)\n *\n * @param joinPoint The function that is to be advised\n */\nfunction getJoinPointDispatcher<F extends GenericFunction<T>, T>(joinPoint: F): F {\n\tfunction dispatcher(this: Function, ...args: any[]): T {\n\t\t// cannot have undefined in map due to code logic, using !\n\t\tconst { before, after, joinPoint } = dispatchAdviceMap.get(dispatcher)!;\n\t\tif (before) {\n\t\t\targs = before.reduce((previousArgs, advice) => {\n\t\t\t\tconst currentArgs = advice.apply(this, previousArgs);\n\t\t\t\treturn currentArgs || previousArgs;\n\t\t\t}, args);\n\t\t}\n\t\tlet result = joinPoint.apply(this, args);\n\t\tif (after) {\n\t\t\tresult = after.reduce((previousResult, advice) => {\n\t\t\t\treturn advice.apply(this, [previousResult].concat(args));\n\t\t\t}, result);\n\t\t}\n\t\treturn result;\n\t}\n\n\t/* We want to \"clone\" the advice that has been applied already, if this\n\t * joinPoint is already advised */\n\tif (dispatchAdviceMap.has(joinPoint)) {\n\t\t// cannot have undefined in map due to code logic, using !\n\t\tconst adviceMap = dispatchAdviceMap.get(joinPoint)!;\n\t\tlet { before, after } = adviceMap;\n\t\tif (before) {\n\t\t\tbefore = before.slice(0);\n\t\t}\n\t\tif (after) {\n\t\t\tafter = after.slice(0);\n\t\t}\n\t\tdispatchAdviceMap.set(dispatcher, {\n\t\t\tjoinPoint: adviceMap.joinPoint,\n\t\t\tbefore,\n\t\t\tafter\n\t\t});\n\t} else {\n\t\t/* Otherwise, this is a new joinPoint, so we will create the advice map afresh */\n\t\tdispatchAdviceMap.set(dispatcher, { joinPoint });\n\t}\n\n\treturn dispatcher as F;\n}\n\n/**\n * Apply advice *after* the supplied joinPoint (function)\n *\n * @param joinPoint A function that should have advice applied to\n * @param advice The after advice\n */\nfunction afterJoinPoint<F extends GenericFunction<T>, T>(joinPoint: F, advice: JoinPointAfterAdvice<T>): F {\n\treturn adviseJoinPoint(joinPoint, 'after', advice);\n}\n\n/**\n * Attaches \"after\" advice to be executed after the original method.\n * The advising function will receive the original method's return value and arguments object.\n * The value it returns will be returned from the method when it is called (even if the return value is undefined).\n *\n * @param target Object whose method will be aspected\n * @param methodName Name of method to aspect\n * @param advice Advising function which will receive the original method's return value and arguments object\n * @return A handle which will remove the aspect when destroy is called\n */\nfunction afterObject(\n\ttarget: Targetable,\n\tmethodName: string | symbol,\n\tadvice: (originalReturn: any, originalArgs: IArguments) => any\n): Handle {\n\treturn adviseObject(getDispatcherObject(target, methodName), 'after', advice);\n}\n\n/**\n * Attaches \"after\" advice to be executed after the original method.\n * The advising function will receive the original method's return value and arguments object.\n * The value it returns will be returned from the method when it is called (even if the return value is undefined).\n *\n * @param target Object whose method will be aspected\n * @param methodName Name of method to aspect\n * @param advice Advising function which will receive the original method's return value and arguments object\n * @return A handle which will remove the aspect when destroy is called\n */\nexport function after(\n\ttarget: Targetable,\n\tmethodName: string | symbol,\n\tadvice: (originalReturn: any, originalArgs: IArguments) => any\n): Handle;\n/**\n * Apply advice *after* the supplied joinPoint (function)\n *\n * @param joinPoint A function that should have advice applied to\n * @param advice The after advice\n */\nexport function after<F extends GenericFunction<T>, T>(joinPoint: F, advice: JoinPointAfterAdvice<T>): F;\nexport function after<F extends GenericFunction<T>, T>(\n\tjoinPointOrTarget: F | Targetable,\n\tmethodNameOrAdvice: string | symbol | JoinPointAfterAdvice<T>,\n\tobjectAdvice?: (originalReturn: any, originalArgs: IArguments) => any\n): Handle | F {\n\tif (typeof joinPointOrTarget === 'function') {\n\t\treturn afterJoinPoint(joinPointOrTarget, <JoinPointAfterAdvice<T>>methodNameOrAdvice);\n\t} else {\n\t\treturn afterObject(joinPointOrTarget, <string | symbol>methodNameOrAdvice, objectAdvice!);\n\t}\n}\n\n/**\n * Apply advice *around* the supplied joinPoint (function)\n *\n * @param joinPoint A function that should have advice applied to\n * @param advice The around advice\n */\nexport function aroundJoinPoint<F extends GenericFunction<T>, T>(joinPoint: F, advice: JoinPointAroundAdvice<T>): F {\n\treturn adviseJoinPoint<F, T>(joinPoint, 'around', advice);\n}\n\n/**\n * Attaches \"around\" advice around the original method.\n *\n * @param target Object whose method will be aspected\n * @param methodName Name of method to aspect\n * @param advice Advising function which will receive the original function\n * @return A handle which will remove the aspect when destroy is called\n */\nexport function aroundObject(\n\ttarget: Targetable,\n\tmethodName: string | symbol,\n\tadvice: ((previous: Function) => Function)\n): Handle {\n\tlet dispatcher: Dispatcher | undefined = getDispatcherObject(target, methodName);\n\tlet previous = dispatcher.around;\n\tlet advised: Function | undefined;\n\tif (advice) {\n\t\tadvised = advice(function(this: Dispatcher): any {\n\t\t\tif (previous && previous.advice) {\n\t\t\t\treturn previous.advice(this, arguments);\n\t\t\t}\n\t\t});\n\t}\n\n\tdispatcher.around = {\n\t\tadvice: function(target: any, args: any[]): any {\n\t\t\treturn advised ? advised.apply(target, args) : previous && previous.advice && previous.advice(target, args);\n\t\t}\n\t};\n\n\treturn createHandle(function() {\n\t\tadvised = dispatcher = undefined;\n\t});\n}\n\n/**\n * Attaches \"around\" advice around the original method.\n *\n * @param target Object whose method will be aspected\n * @param methodName Name of method to aspect\n * @param advice Advising function which will receive the original function\n * @return A handle which will remove the aspect when destroy is called\n */\nexport function around(\n\ttarget: Targetable,\n\tmethodName: string | symbol,\n\tadvice: ((previous: Function) => Function)\n): Handle;\n/**\n * Apply advice *around* the supplied joinPoint (function)\n *\n * @param joinPoint A function that should have advice applied to\n * @param advice The around advice\n */\nexport function around<F extends GenericFunction<T>, T>(joinPoint: F, advice: JoinPointAroundAdvice<T>): F;\nexport function around<F extends GenericFunction<T>, T>(\n\tjoinPointOrTarget: F | Targetable,\n\tmethodNameOrAdvice: string | symbol | JoinPointAroundAdvice<T>,\n\tobjectAdvice?: ((previous: Function) => Function)\n): Handle | F {\n\tif (typeof joinPointOrTarget === 'function') {\n\t\treturn aroundJoinPoint(joinPointOrTarget, <JoinPointAroundAdvice<T>>methodNameOrAdvice);\n\t} else {\n\t\treturn aroundObject(joinPointOrTarget, <string | symbol>methodNameOrAdvice, objectAdvice!);\n\t}\n}\n\n/**\n * Apply advice *before* the supplied joinPoint (function)\n *\n * @param joinPoint A function that should have advice applied to\n * @param advice The before advice\n */\nexport function beforeJoinPoint<F extends GenericFunction<any>>(joinPoint: F, advice: JoinPointBeforeAdvice): F {\n\treturn adviseJoinPoint(joinPoint, 'before', advice);\n}\n\n/**\n * Attaches \"before\" advice to be executed before the original method.\n *\n * @param target Object whose method will be aspected\n * @param methodName Name of method to aspect\n * @param advice Advising function which will receive the same arguments as the original, and may return new arguments\n * @return A handle which will remove the aspect when destroy is called\n */\nexport function beforeObject(\n\ttarget: Targetable,\n\tmethodName: string | symbol,\n\tadvice: (...originalArgs: any[]) => any[] | void\n): Handle {\n\treturn adviseObject(getDispatcherObject(target, methodName), 'before', advice);\n}\n\n/**\n * Attaches \"before\" advice to be executed before the original method.\n *\n * @param target Object whose method will be aspected\n * @param methodName Name of method to aspect\n * @param advice Advising function which will receive the same arguments as the original, and may return new arguments\n * @return A handle which will remove the aspect when destroy is called\n */\nexport function before(\n\ttarget: Targetable,\n\tmethodName: string | symbol,\n\tadvice: (...originalArgs: any[]) => any[] | void\n): Handle;\n/**\n * Apply advice *before* the supplied joinPoint (function)\n *\n * @param joinPoint A function that should have advice applied to\n * @param advice The before advice\n */\nexport function before<F extends GenericFunction<any>>(joinPoint: F, advice: JoinPointBeforeAdvice): F;\nexport function before<F extends GenericFunction<T>, T>(\n\tjoinPointOrTarget: F | Targetable,\n\tmethodNameOrAdvice: string | symbol | JoinPointBeforeAdvice,\n\tobjectAdvice?: ((...originalArgs: any[]) => any[] | void)\n): Handle | F {\n\tif (typeof joinPointOrTarget === 'function') {\n\t\treturn beforeJoinPoint(joinPointOrTarget, <JoinPointBeforeAdvice>methodNameOrAdvice);\n\t} else {\n\t\treturn beforeObject(joinPointOrTarget, <string | symbol>methodNameOrAdvice, objectAdvice!);\n\t}\n}\n\n/**\n * Attaches advice to be executed after the original method.\n * The advising function will receive the same arguments as the original method.\n * The value it returns will be returned from the method when it is called *unless* its return value is undefined.\n *\n * @param target Object whose method will be aspected\n * @param methodName Name of method to aspect\n * @param advice Advising function which will receive the same arguments as the original method\n * @return A handle which will remove the aspect when destroy is called\n */\nexport function on(target: Targetable, methodName: string | symbol, advice: (...originalArgs: any[]) => any): Handle {\n\treturn adviseObject(getDispatcherObject(target, methodName), 'after', advice, true);\n}\n"]}