@openstax/ts-utils 1.20.2 → 1.20.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -80,6 +80,8 @@ export declare const mapFind: <I, R>(array: I[], mapper: (item: I) => R, predica
80
80
  /**
81
81
  * returns a function that will only ever call the given function once, returning the first result for every subsequent call
82
82
  *
83
+ * does not cache rejected promises, to avoid cache poisoning on failed async requests
84
+ *
83
85
  * eg:
84
86
  * const heavyFunction = () => 'hello';
85
87
  * const butOnlyOnce = once(() => 'hello');
@@ -90,6 +92,8 @@ export declare const mapFind: <I, R>(array: I[], mapper: (item: I) => R, predica
90
92
  export declare const once: <F extends (...args: any[]) => any>(fn: F) => F;
91
93
  /**
92
94
  * memoizes a function with any number of arguments
95
+ *
96
+ * does not cache rejected promises, to avoid cache poisoning on failed async requests
93
97
  */
94
98
  export declare const memoize: <F extends (...args: any[]) => any>(fn: F) => F;
95
99
  /**
@@ -96,6 +96,8 @@ export const mapFind = (array, mapper, predicate = (r) => !!r) => {
96
96
  /**
97
97
  * returns a function that will only ever call the given function once, returning the first result for every subsequent call
98
98
  *
99
+ * does not cache rejected promises, to avoid cache poisoning on failed async requests
100
+ *
99
101
  * eg:
100
102
  * const heavyFunction = () => 'hello';
101
103
  * const butOnlyOnce = once(() => 'hello');
@@ -121,6 +123,8 @@ export const once = (fn) => {
121
123
  };
122
124
  /**
123
125
  * memoizes a function with any number of arguments
126
+ *
127
+ * does not cache rejected promises, to avoid cache poisoning on failed async requests
124
128
  */
125
129
  export const memoize = (fn) => {
126
130
  const cache = {};
@@ -143,7 +147,15 @@ export const memoize = (fn) => {
143
147
  };
144
148
  return ((...args) => {
145
149
  const thisCache = resolveCache(cache, args);
146
- return thisCache.result = (thisCache.result || fn(...args));
150
+ if ('result' in thisCache) {
151
+ return thisCache.result;
152
+ }
153
+ thisCache.result = fn(...args);
154
+ if (typeof thisCache.result === 'object' && thisCache.result instanceof Promise) {
155
+ // Clear the result when possible but do not return a Promise that resolves to the initialValue
156
+ thisCache.result.catch(() => delete thisCache.result);
157
+ }
158
+ return thisCache.result;
147
159
  });
148
160
  };
149
161
  /**