ts-data-forge 6.3.1 → 6.4.0
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.
- package/dist/others/memoize-function.d.mts +3 -2
- package/dist/others/memoize-function.d.mts.map +1 -1
- package/dist/others/memoize-function.mjs +10 -39
- package/dist/others/memoize-function.mjs.map +1 -1
- package/package.json +1 -1
- package/src/others/memoize-function.mts +35 -17
- package/src/others/memoize-function.test.mts +25 -0
|
@@ -21,10 +21,11 @@
|
|
|
21
21
|
* key)
|
|
22
22
|
* @param fn - The pure function to memoize
|
|
23
23
|
* @param argsToCacheKey - Function that converts arguments to a unique cache
|
|
24
|
-
* key
|
|
24
|
+
* key. Optional for zero-argument functions.
|
|
25
25
|
* @returns A memoized version of the input function with the same signature
|
|
26
26
|
*
|
|
27
27
|
* @see https://en.wikipedia.org/wiki/Memoization
|
|
28
28
|
*/
|
|
29
|
-
export declare
|
|
29
|
+
export declare function memoizeFunction<R>(fn: () => R): () => R;
|
|
30
|
+
export declare function memoizeFunction<Arg0, const RestArgs extends readonly unknown[], R, K extends Primitive>(fn: (arg0: Arg0, ...args: RestArgs) => R, argsToCacheKey: (arg0: Arg0, ...args: RestArgs) => K): (arg0: Arg0, ...args: RestArgs) => R;
|
|
30
31
|
//# sourceMappingURL=memoize-function.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memoize-function.d.mts","sourceRoot":"","sources":["../../src/others/memoize-function.mts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,
|
|
1
|
+
{"version":3,"file":"memoize-function.d.mts","sourceRoot":"","sources":["../../src/others/memoize-function.mts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;AAEzD,wBAAgB,eAAe,CAC7B,IAAI,EACJ,KAAK,CAAC,QAAQ,SAAS,SAAS,OAAO,EAAE,EACzC,CAAC,EACD,CAAC,SAAS,SAAS,EAEnB,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,QAAQ,KAAK,CAAC,EACxC,cAAc,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,QAAQ,KAAK,CAAC,GACnD,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,QAAQ,KAAK,CAAC,CAAC"}
|
|
@@ -1,46 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
* Creates a memoized version of a function that caches results based on input
|
|
3
|
-
* arguments.
|
|
4
|
-
*
|
|
5
|
-
* The memoized function stores results in an internal Map and returns cached
|
|
6
|
-
* values for repeated calls with the same arguments. This can significantly
|
|
7
|
-
* improve performance for expensive computations or I/O operations.
|
|
8
|
-
*
|
|
9
|
-
* **Important considerations:**
|
|
10
|
-
*
|
|
11
|
-
* - The cache grows unbounded - consider memory implications for long-running
|
|
12
|
-
* applications
|
|
13
|
-
* - Cache keys must be primitives (string, number, boolean, symbol, null,
|
|
14
|
-
* undefined, bigint)
|
|
15
|
-
* - Object arguments require careful key generation to ensure uniqueness
|
|
16
|
-
* - Pure functions only - memoizing functions with side effects can lead to bugs
|
|
17
|
-
*
|
|
18
|
-
* @template A - The tuple type of the function arguments
|
|
19
|
-
* @template R - The return type of the function
|
|
20
|
-
* @template K - The primitive type used as the cache key (must be valid Map
|
|
21
|
-
* key)
|
|
22
|
-
* @param fn - The pure function to memoize
|
|
23
|
-
* @param argsToCacheKey - Function that converts arguments to a unique cache
|
|
24
|
-
* key
|
|
25
|
-
* @returns A memoized version of the input function with the same signature
|
|
26
|
-
*
|
|
27
|
-
* @see https://en.wikipedia.org/wiki/Memoization
|
|
28
|
-
*/
|
|
29
|
-
const memoizeFunction = (fn, argsToCacheKey) => {
|
|
1
|
+
function memoizeFunction(fn, argsToCacheKey) {
|
|
30
2
|
const mut_cache = new Map();
|
|
3
|
+
const defaultKey = Symbol('memoize-default-key');
|
|
31
4
|
return (...args) => {
|
|
32
|
-
const key = argsToCacheKey(...args);
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
const result = fn(...args);
|
|
39
|
-
mut_cache.set(key, result);
|
|
40
|
-
return result;
|
|
5
|
+
const key = argsToCacheKey === undefined ? defaultKey : argsToCacheKey(...args);
|
|
6
|
+
const cached = mut_cache.get(key);
|
|
7
|
+
if (cached !== undefined) {
|
|
8
|
+
return cached.value;
|
|
41
9
|
}
|
|
10
|
+
const result = fn(...args);
|
|
11
|
+
mut_cache.set(key, { value: result });
|
|
12
|
+
return result;
|
|
42
13
|
};
|
|
43
|
-
}
|
|
14
|
+
}
|
|
44
15
|
|
|
45
16
|
export { memoizeFunction };
|
|
46
17
|
//# sourceMappingURL=memoize-function.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memoize-function.mjs","sources":["../../src/others/memoize-function.mts"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"memoize-function.mjs","sources":["../../src/others/memoize-function.mts"],"sourcesContent":[null],"names":[],"mappings":"AAwCM,SAAU,eAAe,CAK7B,EAAwB,EACxB,cAAqC,EAAA;AAIrC,IAAA,MAAM,SAAS,GAAG,IAAI,GAAG,EAA0B;AAEnD,IAAA,MAAM,UAAU,GAAG,MAAM,CAAC,qBAAqB,CAAC;AAEhD,IAAA,OAAO,CAAC,GAAG,IAAU,KAAO;AAC1B,QAAA,MAAM,GAAG,GACP,cAAc,KAAK,SAAS,GAAG,UAAU,GAAG,cAAc,CAAC,GAAG,IAAI,CAAC;QAErE,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;AAEjC,QAAA,IAAI,MAAM,KAAK,SAAS,EAAE;YACxB,OAAO,MAAM,CAAC,KAAK;QACrB;AAEA,QAAA,MAAM,MAAM,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC;QAE1B,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAErC,QAAA,OAAO,MAAM;AACf,IAAA,CAAC;AACH;;;;"}
|
package/package.json
CHANGED
|
@@ -21,33 +21,51 @@
|
|
|
21
21
|
* key)
|
|
22
22
|
* @param fn - The pure function to memoize
|
|
23
23
|
* @param argsToCacheKey - Function that converts arguments to a unique cache
|
|
24
|
-
* key
|
|
24
|
+
* key. Optional for zero-argument functions.
|
|
25
25
|
* @returns A memoized version of the input function with the same signature
|
|
26
26
|
*
|
|
27
27
|
* @see https://en.wikipedia.org/wiki/Memoization
|
|
28
28
|
*/
|
|
29
|
-
export
|
|
30
|
-
|
|
29
|
+
export function memoizeFunction<R>(fn: () => R): () => R;
|
|
30
|
+
|
|
31
|
+
export function memoizeFunction<
|
|
32
|
+
Arg0,
|
|
33
|
+
const RestArgs extends readonly unknown[],
|
|
34
|
+
R,
|
|
35
|
+
K extends Primitive,
|
|
36
|
+
>(
|
|
37
|
+
fn: (arg0: Arg0, ...args: RestArgs) => R,
|
|
38
|
+
argsToCacheKey: (arg0: Arg0, ...args: RestArgs) => K,
|
|
39
|
+
): (arg0: Arg0, ...args: RestArgs) => R;
|
|
40
|
+
|
|
41
|
+
export function memoizeFunction<
|
|
42
|
+
const Args extends readonly unknown[],
|
|
31
43
|
R,
|
|
32
44
|
K extends Primitive,
|
|
33
45
|
>(
|
|
34
|
-
fn: (...args:
|
|
35
|
-
argsToCacheKey
|
|
36
|
-
): (
|
|
37
|
-
|
|
46
|
+
fn: (...args: Args) => R,
|
|
47
|
+
argsToCacheKey?: (...args: Args) => K,
|
|
48
|
+
): (...args: Args) => R {
|
|
49
|
+
type CacheEntry = Readonly<{ value: R }>;
|
|
38
50
|
|
|
39
|
-
|
|
40
|
-
const key = argsToCacheKey(...args);
|
|
51
|
+
const mut_cache = new Map<K | symbol, CacheEntry>();
|
|
41
52
|
|
|
42
|
-
|
|
43
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
44
|
-
return mut_cache.get(key)!;
|
|
45
|
-
} else {
|
|
46
|
-
const result = fn(...args);
|
|
53
|
+
const defaultKey = Symbol('memoize-default-key');
|
|
47
54
|
|
|
48
|
-
|
|
55
|
+
return (...args: Args): R => {
|
|
56
|
+
const key: K | symbol =
|
|
57
|
+
argsToCacheKey === undefined ? defaultKey : argsToCacheKey(...args);
|
|
49
58
|
|
|
50
|
-
|
|
59
|
+
const cached = mut_cache.get(key);
|
|
60
|
+
|
|
61
|
+
if (cached !== undefined) {
|
|
62
|
+
return cached.value;
|
|
51
63
|
}
|
|
64
|
+
|
|
65
|
+
const result = fn(...args);
|
|
66
|
+
|
|
67
|
+
mut_cache.set(key, { value: result });
|
|
68
|
+
|
|
69
|
+
return result;
|
|
52
70
|
};
|
|
53
|
-
}
|
|
71
|
+
}
|
|
@@ -148,6 +148,31 @@ describe(memoizeFunction, () => {
|
|
|
148
148
|
expect(mockFn).toHaveBeenCalledTimes(2);
|
|
149
149
|
});
|
|
150
150
|
|
|
151
|
+
test('should work with zero-argument functions without key mapper', () => {
|
|
152
|
+
const mockFn = vi.fn(() => Math.random());
|
|
153
|
+
|
|
154
|
+
const memoized = memoizeFunction(mockFn);
|
|
155
|
+
|
|
156
|
+
// First call
|
|
157
|
+
const result1 = memoized();
|
|
158
|
+
|
|
159
|
+
expect(mockFn).toHaveBeenCalledOnce();
|
|
160
|
+
|
|
161
|
+
// Second call - should use cache and return the same random value
|
|
162
|
+
const result2 = memoized();
|
|
163
|
+
|
|
164
|
+
expect(mockFn).toHaveBeenCalledOnce();
|
|
165
|
+
|
|
166
|
+
expect(result2).toBe(result1);
|
|
167
|
+
|
|
168
|
+
// Third call - still using cache
|
|
169
|
+
const result3 = memoized();
|
|
170
|
+
|
|
171
|
+
expect(mockFn).toHaveBeenCalledOnce();
|
|
172
|
+
|
|
173
|
+
expect(result3).toBe(result1);
|
|
174
|
+
});
|
|
175
|
+
|
|
151
176
|
test('should maintain separate caches for different memoized functions', () => {
|
|
152
177
|
const fn1 = vi.fn((x: number) => x * 2);
|
|
153
178
|
|