UNPKG

@universis/common

Version:

Universis - common directives and services

132 lines 15.8 kB
import { SHA1 } from 'crypto-js'; /** * Returns a string which represents a key generated by @asyncMemoize() or @memoize() decorators * @param target - The target object * @param propertyKey - A string which represents the method that is going to be called * @param args - An optional param array of arguments * @example * // calculate memoized key for myObject.getFunc1(100, true) * const key = getMemoizeKey(myObject, 'getFunc1', 100, true); */ export function getMemoizeKey(target, propertyKey, ...args) { let computedHash; // get arguments hash if (args.length) { computedHash = SHA1(JSON.stringify(args)); } let targetConstructor = target.constructor.name; // validate static function if (targetConstructor === 'Function') { targetConstructor = target.prototype.constructor.name; } if (computedHash) { // add computed hash to key return `${targetConstructor}.${propertyKey}.${computedHash}`; } else { return `${targetConstructor}.${propertyKey}`; } } /** * Removes a key-value pair generated by @asyncMemoize() or @memoize() decorators * @param target - The target object * @param propertyKey - A string which represents the method that is going to be called * @param args - An optional param array of arguments * @example * // removes memoized key for myObject.getFunc1(100, true) * removeMemoizeKey(myObject, 'getFunc1', 100, true); */ export function removeMemoizeKey(target, propertyKey, ...args) { // get key const key = getMemoizeKey(target, propertyKey, ...args); // remove item from storage sessionStorage.removeItem(key); } /** * Use @asyncMemoize() decorator to memoize the result of an async method to storage * @example * class TestClass1 { * @asyncMemoize() * async getItems() { * return ['apple', 'lemon', 'orange']; * } * } */ export function asyncMemoize() { return function (target, propertyKey, descriptor) { // validate that descriptor.value is a function if (typeof descriptor.value !== 'function') { throw new Error('Invalid decorator descriptor. @memoize() decorator should be applied in class methods.'); } // get original descriptor value (which is a method) const func = descriptor.value; // change descriptor // important: use standard function to avoid error // The 'arguments' object cannot be referenced in an arrow function in ES3 and ES5. descriptor.value = function () { const args = Array.from(arguments); const thisArg = this; return new Promise(function (resolve, reject) { const key = getMemoizeKey(target, propertyKey, ...args); // try to get item from storage const valueString = sessionStorage.getItem(key); // parse value string if (valueString) { try { return resolve(JSON.parse(valueString)); } catch (err) { return reject(err); } } // call method return func.apply(thisArg, args).then(function (value) { // set item to storage if (typeof value !== 'undefined') { sessionStorage.setItem(key, JSON.stringify(value)); } // and finally return result return resolve(value); }).catch(reason => { return reject(reason); }); }); }; }; } /** * Use @memoize() decorator to memoize the result of an async method to storage * @example * class TestClass1 { * @memoize() * getItems() { * return ['apple', 'lemon', 'orange']; * } * } */ export function memoize() { return function (target, propertyKey, descriptor) { // validate that descriptor.value is a function if (typeof descriptor.value !== 'function') { throw new Error('Invalid decorator descriptor. @memoize() decorator should be applied in class methods.'); } // get original descriptor value (which is a method) const func = descriptor.value; // change descriptor descriptor.value = function () { const key = getMemoizeKey(target, propertyKey, ...arguments); // try to get item from storage const valueString = sessionStorage.getItem(key); if (valueString) { return JSON.parse(valueString); } // call method const value = func.apply(this, arguments); // set item to session storage sessionStorage.setItem(key, JSON.stringify(value)); // and finally return result return value; }; }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVjb3JhdG9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9oZWxwZXJzL2RlY29yYXRvcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNqQzs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxhQUFhLENBQUMsTUFBVyxFQUFFLFdBQW1CLEVBQUUsR0FBRyxJQUFXO0lBQzFFLElBQUksWUFBWSxDQUFDO0lBQ2pCLHFCQUFxQjtJQUNyQixJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7UUFDYixZQUFZLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztLQUM3QztJQUNELElBQUksaUJBQWlCLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUM7SUFDaEQsMkJBQTJCO0lBQzNCLElBQUksaUJBQWlCLEtBQUssVUFBVSxFQUFFO1FBQ2xDLGlCQUFpQixHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQztLQUN6RDtJQUNELElBQUksWUFBWSxFQUFFO1FBQ2QsMkJBQTJCO1FBQzNCLE9BQU0sR0FBRyxpQkFBaUIsSUFBSSxXQUFXLElBQUksWUFBWSxFQUFFLENBQUM7S0FDL0Q7U0FBTTtRQUNILE9BQU8sR0FBRyxpQkFBaUIsSUFBSSxXQUFXLEVBQUUsQ0FBQztLQUNoRDtBQUNMLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxNQUFXLEVBQUUsV0FBbUIsRUFBRSxHQUFHLElBQVc7SUFDN0UsVUFBVTtJQUNWLE1BQU0sR0FBRyxHQUFHLGFBQWEsQ0FBQyxNQUFNLEVBQUUsV0FBVyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7SUFDeEQsMkJBQTJCO0lBQzNCLGNBQWMsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7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QixjQUFjLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDbkQsNEJBQTRCO1lBQzVCLE9BQU8sS0FBSyxDQUFDO1FBQ2pCLENBQUMsQ0FBQztJQUNOLENBQUMsQ0FBQztBQUNOLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTSEExIH0gZnJvbSAnY3J5cHRvLWpzJztcbi8qKlxuICogUmV0dXJucyBhIHN0cmluZyB3aGljaCByZXByZXNlbnRzIGEga2V5IGdlbmVyYXRlZCBieSBAYXN5bmNNZW1vaXplKCkgb3IgQG1lbW9pemUoKSBkZWNvcmF0b3JzXG4gKiBAcGFyYW0gdGFyZ2V0IC0gVGhlIHRhcmdldCBvYmplY3RcbiAqIEBwYXJhbSBwcm9wZXJ0eUtleSAtIEEgc3RyaW5nIHdoaWNoIHJlcHJlc2VudHMgdGhlIG1ldGhvZCB0aGF0IGlzIGdvaW5nIHRvIGJlIGNhbGxlZFxuICogQHBhcmFtIGFyZ3MgLSBBbiBvcHRpb25hbCBwYXJhbSBhcnJheSBvZiBhcmd1bWVudHNcbiAqIEBleGFtcGxlXG4gKiAvLyBjYWxjdWxhdGUgbWVtb2l6ZWQga2V5IGZvciBteU9iamVjdC5nZXRGdW5jMSgxMDAsIHRydWUpXG4gKiBjb25zdCBrZXkgPSBnZXRNZW1vaXplS2V5KG15T2JqZWN0LCAnZ2V0RnVuYzEnLCAxMDAsIHRydWUpO1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWVtb2l6ZUtleSh0YXJnZXQ6IGFueSwgcHJvcGVydHlLZXk6IHN0cmluZywgLi4uYXJnczogYW55W10pIHtcbiAgICBsZXQgY29tcHV0ZWRIYXNoO1xuICAgIC8vIGdldCBhcmd1bWVudHMgaGFzaFxuICAgIGlmIChhcmdzLmxlbmd0aCkge1xuICAgICAgICBjb21wdXRlZEhhc2ggPSBTSEExKEpTT04uc3RyaW5naWZ5KGFyZ3MpKTtcbiAgICB9XG4gICAgbGV0IHRhcmdldENvbnN0cnVjdG9yID0gdGFyZ2V0LmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgLy8gdmFsaWRhdGUgc3RhdGljIGZ1bmN0aW9uXG4gICAgaWYgKHRhcmdldENvbnN0cnVjdG9yID09PSAnRnVuY3Rpb24nKSB7XG4gICAgICAgIHRhcmdldENvbnN0cnVjdG9yID0gdGFyZ2V0LnByb3RvdHlwZS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgIH1cbiAgICBpZiAoY29tcHV0ZWRIYXNoKSB7XG4gICAgICAgIC8vIGFkZCBjb21wdXRlZCBoYXNoIHRvIGtleVxuICAgICAgICByZXR1cm5gJHt0YXJnZXRDb25zdHJ1Y3Rvcn0uJHtwcm9wZXJ0eUtleX0uJHtjb21wdXRlZEhhc2h9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gYCR7dGFyZ2V0Q29uc3RydWN0b3J9LiR7cHJvcGVydHlLZXl9YDtcbiAgICB9XG59XG5cbi8qKlxuICogUmVtb3ZlcyBhIGtleS12YWx1ZSBwYWlyIGdlbmVyYXRlZCBieSBAYXN5bmNNZW1vaXplKCkgb3IgQG1lbW9pemUoKSBkZWNvcmF0b3JzXG4gKiBAcGFyYW0gdGFyZ2V0IC0gVGhlIHRhcmdldCBvYmplY3RcbiAqIEBwYXJhbSBwcm9wZXJ0eUtleSAtIEEgc3RyaW5nIHdoaWNoIHJlcHJlc2VudHMgdGhlIG1ldGhvZCB0aGF0IGlzIGdvaW5nIHRvIGJlIGNhbGxlZFxuICogQHBhcmFtIGFyZ3MgLSBBbiBvcHRpb25hbCBwYXJhbSBhcnJheSBvZiBhcmd1bWVudHNcbiAqIEBleGFtcGxlXG4gKiAvLyByZW1vdmVzIG1lbW9pemVkIGtleSBmb3IgbXlPYmplY3QuZ2V0RnVuYzEoMTAwLCB0cnVlKVxuICogcmVtb3ZlTWVtb2l6ZUtleShteU9iamVjdCwgJ2dldEZ1bmMxJywgMTAwLCB0cnVlKTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZU1lbW9pemVLZXkodGFyZ2V0OiBhbnksIHByb3BlcnR5S2V5OiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgLy8gZ2V0IGtleVxuICAgIGNvbnN0IGtleSA9IGdldE1lbW9pemVLZXkodGFyZ2V0LCBwcm9wZXJ0eUtleSwgLi4uYXJncyk7XG4gICAgLy8gcmVtb3ZlIGl0ZW0gZnJvbSBzdG9yYWdlXG4gICAgc2Vzc2lvblN0b3JhZ2UucmVtb3ZlSXRlbShrZXkpO1xufVxuXG4vKipcbiAqIFVzZSBAYXN5bmNNZW1vaXplKCkgZGVjb3JhdG9yIHRvIG1lbW9pemUgdGhlIHJlc3VsdCBvZiBhbiBhc3luYyBtZXRob2QgdG8gc3RvcmFnZVxuICogQGV4YW1wbGVcbiAqIGNsYXNzIFRlc3RDbGFzczEge1xuICogICAgIEBhc3luY01lbW9pemUoKVxuICogICAgIGFzeW5jIGdldEl0ZW1zKCkge1xuICogICAgICAgICByZXR1cm4gWydhcHBsZScsICdsZW1vbicsICdvcmFuZ2UnXTtcbiAqICAgICB9XG4gKiB9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc3luY01lbW9pemUoKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQ6IGFueSwgcHJvcGVydHlLZXk6IHN0cmluZywgZGVzY3JpcHRvcjogUHJvcGVydHlEZXNjcmlwdG9yKSB7XG4gICAgICAgIC8vIHZhbGlkYXRlIHRoYXQgZGVzY3JpcHRvci52YWx1ZSBpcyBhIGZ1bmN0aW9uXG4gICAgICAgIGlmICh0eXBlb2YgZGVzY3JpcHRvci52YWx1ZSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRlY29yYXRvciBkZXNjcmlwdG9yLiBAbWVtb2l6ZSgpIGRlY29yYXRvciBzaG91bGQgYmUgYXBwbGllZCBpbiBjbGFzcyBtZXRob2RzLicpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGdldCBvcmlnaW5hbCBkZXNjcmlwdG9yIHZhbHVlICh3aGljaCBpcyBhIG1ldGhvZClcbiAgICAgICAgY29uc3QgZnVuYyA9IGRlc2NyaXB0b3IudmFsdWU7XG4gICAgICAgIC8vIGNoYW5nZSBkZXNjcmlwdG9yXG4gICAgICAgIC8vIGltcG9ydGFudDogdXNlIHN0YW5kYXJkIGZ1bmN0aW9uIHRvIGF2b2lkIGVycm9yXG4gICAgICAgIC8vIFRoZSAnYXJndW1lbnRzJyBvYmplY3QgY2Fubm90IGJlIHJlZmVyZW5jZWQgaW4gYW4gYXJyb3cgZnVuY3Rpb24gaW4gRVMzIGFuZCBFUzUuXG4gICAgICAgIGRlc2NyaXB0b3IudmFsdWUgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGNvbnN0IGFyZ3MgPSBBcnJheS5mcm9tKGFyZ3VtZW50cyk7XG4gICAgICAgICAgICBjb25zdCB0aGlzQXJnID0gdGhpcztcbiAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBrZXkgPSBnZXRNZW1vaXplS2V5KHRhcmdldCwgcHJvcGVydHlLZXksIC4uLmFyZ3MpO1xuICAgICAgICAgICAgICAgIC8vIHRyeSB0byBnZXQgaXRlbSBmcm9tIHN0b3JhZ2VcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZVN0cmluZyA9IHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oa2V5KTtcbiAgICAgICAgICAgICAgICAvLyBwYXJzZSB2YWx1ZSBzdHJpbmdcbiAgICAgICAgICAgICAgICBpZiAodmFsdWVTdHJpbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKEpTT04ucGFyc2UodmFsdWVTdHJpbmcpKTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gY2FsbCBtZXRob2RcbiAgICAgICAgICAgICAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzQXJnLCBhcmdzKS50aGVuKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHNldCBpdGVtIHRvIHN0b3JhZ2VcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oa2V5LCBKU09OLnN0cmluZ2lmeSh2YWx1ZSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIGFuZCBmaW5hbGx5IHJldHVybiByZXN1bHRcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUodmFsdWUpO1xuICAgICAgICAgICAgICAgIH0pLmNhdGNoKHJlYXNvbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QocmVhc29uKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH07XG4gICAgfTtcbn1cblxuLyoqXG4gKiBVc2UgQG1lbW9pemUoKSBkZWNvcmF0b3IgdG8gbWVtb2l6ZSB0aGUgcmVzdWx0IG9mIGFuIGFzeW5jIG1ldGhvZCB0byBzdG9yYWdlXG4gKiBAZXhhbXBsZVxuICogY2xhc3MgVGVzdENsYXNzMSB7XG4gKiAgICAgQG1lbW9pemUoKVxuICogICAgIGdldEl0ZW1zKCkge1xuICogICAgICAgICByZXR1cm4gWydhcHBsZScsICdsZW1vbicsICdvcmFuZ2UnXTtcbiAqICAgICB9XG4gKiB9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZW1vaXplKCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0OiBhbnksIHByb3BlcnR5S2V5OiBzdHJpbmcsIGRlc2NyaXB0b3I6IFByb3BlcnR5RGVzY3JpcHRvcikge1xuICAgICAgICAvLyB2YWxpZGF0ZSB0aGF0IGRlc2NyaXB0b3IudmFsdWUgaXMgYSBmdW5jdGlvblxuICAgICAgICBpZiAodHlwZW9mIGRlc2NyaXB0b3IudmFsdWUgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBkZWNvcmF0b3IgZGVzY3JpcHRvci4gQG1lbW9pemUoKSBkZWNvcmF0b3Igc2hvdWxkIGJlIGFwcGxpZWQgaW4gY2xhc3MgbWV0aG9kcy4nKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBnZXQgb3JpZ2luYWwgZGVzY3JpcHRvciB2YWx1ZSAod2hpY2ggaXMgYSBtZXRob2QpXG4gICAgICAgIGNvbnN0IGZ1bmMgPSBkZXNjcmlwdG9yLnZhbHVlO1xuICAgICAgICAvLyBjaGFuZ2UgZGVzY3JpcHRvclxuICAgICAgICBkZXNjcmlwdG9yLnZhbHVlID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCBrZXkgPSBnZXRNZW1vaXplS2V5KHRhcmdldCwgcHJvcGVydHlLZXksIC4uLmFyZ3VtZW50cyk7XG4gICAgICAgICAgICAvLyB0cnkgdG8gZ2V0IGl0ZW0gZnJvbSBzdG9yYWdlXG4gICAgICAgICAgICBjb25zdCB2YWx1ZVN0cmluZyA9IHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oa2V5KTtcbiAgICAgICAgICAgIGlmICh2YWx1ZVN0cmluZykge1xuICAgICAgICAgICAgICAgIHJldHVybiBKU09OLnBhcnNlKHZhbHVlU3RyaW5nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGNhbGwgbWV0aG9kXG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIC8vIHNldCBpdGVtIHRvIHNlc3Npb24gc3RvcmFnZVxuICAgICAgICAgICAgc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShrZXksIEpTT04uc3RyaW5naWZ5KHZhbHVlKSk7XG4gICAgICAgICAgICAvLyBhbmQgZmluYWxseSByZXR1cm4gcmVzdWx0XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH07XG4gICAgfTtcbn1cbiJdfQ==