Veikedo

Untitled

Mar 16th, 2017
198
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const MEMOIZED_VALUE_KEY = "_memoizedValue";
  2. const notMemoized = {};
  3.  
  4. export function memoize(expirationTimeMs = 30000) {
  5.     return (target: any, propertyName?: string, descriptor?: TypedPropertyDescriptor<any>) => {
  6.         if (!propertyName) {
  7.             memoizeClass(target, expirationTimeMs)
  8.         } else if (descriptor.value != null) {
  9.             memoizeImpl(expirationTimeMs, descriptor, "value");
  10.         } else {
  11.             throw "Only put the @memoize decorator on a class or method.";
  12.         }
  13.     };
  14. }
  15.  
  16. export function notMemoize(target: any, propertyName: string, descriptor: TypedPropertyDescriptor<any>) {
  17.     const className = target.constructor;
  18.  
  19.     if (notMemoized[className]) {
  20.         notMemoized[className].push(propertyName);
  21.     } else {
  22.         notMemoized[className] = [propertyName];
  23.     }
  24. }
  25.  
  26. export function clearMemoizedValue(method) {
  27.     delete method[MEMOIZED_VALUE_KEY];
  28. }
  29.  
  30. function memoizeClass(target: any, expirationTimeMs: number) {
  31.     const names = Object.getOwnPropertyNames(target.prototype);
  32.     for (const name of names) {
  33.         const needMemoize =
  34.                   name !== "constructor"
  35.                   && typeof target.prototype[name] == "function"
  36.                   && (!notMemoized[target] || !notMemoized[target].includes(name));
  37.  
  38.         if (needMemoize) {
  39.             memoizeImpl(expirationTimeMs, target.prototype, name);
  40.         }
  41.     }
  42. }
  43.  
  44. function memoizeImpl(expirationTimeMs: number, target: Object, methodName: string) {
  45.     const originalMethod = target[methodName];
  46.     let fn = function (...args: any[]) {
  47.         if (!fn[MEMOIZED_VALUE_KEY]) {
  48.             fn[MEMOIZED_VALUE_KEY] = originalMethod.apply(this, args);
  49.             setTimeout(() => clearMemoizedValue(fn), expirationTimeMs);
  50.         }
  51.         return fn[MEMOIZED_VALUE_KEY];
  52.     };
  53.  
  54.     target[methodName] = fn;
  55. }
Advertisement
Add Comment
Please, Sign In to add comment