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.
@@ -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 const memoizeFunction: <const A extends readonly unknown[], R, K extends Primitive>(fn: (...args: A) => R, argsToCacheKey: (...args: A) => K) => ((...args: A) => R);
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,eAAO,MAAM,eAAe,GAC1B,KAAK,CAAC,CAAC,SAAS,SAAS,OAAO,EAAE,EAClC,CAAC,EACD,CAAC,SAAS,SAAS,EAEnB,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,EACrB,gBAAgB,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,KAChC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAiBpB,CAAC"}
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
- if (mut_cache.has(key)) {
34
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
35
- return mut_cache.get(key);
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":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BG;MACU,eAAe,GAAG,CAK7B,EAAqB,EACrB,cAAiC,KACV;AACvB,IAAA,MAAM,SAAS,GAAG,IAAI,GAAG,EAAQ;AAEjC,IAAA,OAAO,CAAC,GAAG,IAAO,KAAO;AACvB,QAAA,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,IAAI,CAAC;AAEnC,QAAA,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;;AAEtB,YAAA,OAAO,SAAS,CAAC,GAAG,CAAC,GAAG,CAAE;QAC5B;aAAO;AACL,YAAA,MAAM,MAAM,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC;AAE1B,YAAA,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC;AAE1B,YAAA,OAAO,MAAM;QACf;AACF,IAAA,CAAC;AACH;;;;"}
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-data-forge",
3
- "version": "6.3.1",
3
+ "version": "6.4.0",
4
4
  "private": false,
5
5
  "keywords": [
6
6
  "typescript",
@@ -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 const memoizeFunction = <
30
- const A extends readonly unknown[],
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: A) => R,
35
- argsToCacheKey: (...args: A) => K,
36
- ): ((...args: A) => R) => {
37
- const mut_cache = new Map<K, R>();
46
+ fn: (...args: Args) => R,
47
+ argsToCacheKey?: (...args: Args) => K,
48
+ ): (...args: Args) => R {
49
+ type CacheEntry = Readonly<{ value: R }>;
38
50
 
39
- return (...args: A): R => {
40
- const key = argsToCacheKey(...args);
51
+ const mut_cache = new Map<K | symbol, CacheEntry>();
41
52
 
42
- if (mut_cache.has(key)) {
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
- mut_cache.set(key, result);
55
+ return (...args: Args): R => {
56
+ const key: K | symbol =
57
+ argsToCacheKey === undefined ? defaultKey : argsToCacheKey(...args);
49
58
 
50
- return result;
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