@thi.ng/memoize 3.3.13 → 4.0.1
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/CHANGELOG.md +15 -1
- package/README.md +23 -11
- package/memoize.d.ts +9 -5
- package/memoize.js +8 -1
- package/memoize1.d.ts +8 -1
- package/memoize1.js +6 -1
- package/memoizej.d.ts +9 -5
- package/memoizej.js +10 -0
- package/memoizeo.d.ts +21 -21
- package/memoizeo.js +13 -16
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2024-
|
|
3
|
+
- **Last updated**: 2024-11-03T16:41:34Z
|
|
4
4
|
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
|
|
5
5
|
|
|
6
6
|
All notable changes to this project will be documented in this file.
|
|
@@ -9,6 +9,20 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
|
|
|
9
9
|
**Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
|
|
10
10
|
and/or version bumps of transitive dependencies.
|
|
11
11
|
|
|
12
|
+
# [4.0.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/memoize@4.0.0) (2024-10-31)
|
|
13
|
+
|
|
14
|
+
#### 🛑 Breaking changes
|
|
15
|
+
|
|
16
|
+
- add async versions of all memoize functions ([#493](https://github.com/thi-ng/umbrella/issues/493)) ([e31543c](https://github.com/thi-ng/umbrella/commit/e31543c))
|
|
17
|
+
- BREAKING CHANGE: remove obsolete arity overrides (i.e. 2/3/4 suffixed versions)
|
|
18
|
+
- add memoizeAsync()
|
|
19
|
+
- add memoizeAsync1()
|
|
20
|
+
- add memoizeAsyncJ()
|
|
21
|
+
- add memoizeAsyncO()
|
|
22
|
+
- refactor memoize fns to be variadic
|
|
23
|
+
- remove obsolete fixed arity versions (e.g. `memoize2O`, 3O, 4O etc.)
|
|
24
|
+
- update tests
|
|
25
|
+
|
|
12
26
|
### [3.3.5](https://github.com/thi-ng/umbrella/tree/@thi.ng/memoize@3.3.5) (2024-06-21)
|
|
13
27
|
|
|
14
28
|
#### ♻️ Refactoring
|
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
|
|
31
31
|
## About
|
|
32
32
|
|
|
33
|
-
Function memoization with configurable caching.
|
|
33
|
+
Function memoization with configurable caching and support for async functions.
|
|
34
34
|
|
|
35
35
|
This package provides different function memoization implementations for
|
|
36
36
|
functions with arbitrary arguments and custom result caching using ES6
|
|
@@ -48,10 +48,10 @@ based on different strategies. See doc strings for further details.
|
|
|
48
48
|
- [defOnce()](https://docs.thi.ng/umbrella/memoize/functions/defOnce.html)
|
|
49
49
|
- [delay()](https://docs.thi.ng/umbrella/memoize/functions/delay.html)
|
|
50
50
|
- [doOnce()](https://docs.thi.ng/umbrella/memoize/functions/doOnce.html)
|
|
51
|
-
- [memoize()](https://docs.thi.ng/umbrella/memoize/functions/memoize.html)
|
|
52
|
-
- [memoize1()](https://docs.thi.ng/umbrella/memoize/functions/memoize1.html)
|
|
53
|
-
- [memoizeJ()](https://docs.thi.ng/umbrella/memoize/functions/memoizeJ.html)
|
|
54
|
-
- [memoizeO()](https://docs.thi.ng/umbrella/memoize/functions/memoizeO.html)
|
|
51
|
+
- [memoize()](https://docs.thi.ng/umbrella/memoize/functions/memoize.html) / [memoizeAsync()](https://docs.thi.ng/umbrella/memoize/functions/memoizeAsync.html)
|
|
52
|
+
- [memoize1()](https://docs.thi.ng/umbrella/memoize/functions/memoize1.html) / [memoizeAsync1()](https://docs.thi.ng/umbrella/memoize/functions/memoizeAsync1.html)
|
|
53
|
+
- [memoizeJ()](https://docs.thi.ng/umbrella/memoize/functions/memoizeJ.html) / [memoizeAsyncJ()](https://docs.thi.ng/umbrella/memoize/functions/memoizeAsyncJ.html)
|
|
54
|
+
- [memoizeO()](https://docs.thi.ng/umbrella/memoize/functions/memoizeO.html) / [memoizeAsyncO()](https://docs.thi.ng/umbrella/memoize/functions/memoizeAsyncO.html)
|
|
55
55
|
|
|
56
56
|
## Status
|
|
57
57
|
|
|
@@ -89,7 +89,7 @@ For Node.js REPL:
|
|
|
89
89
|
const mem = await import("@thi.ng/memoize");
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
-
Package sizes (brotli'd, pre-treeshake): ESM:
|
|
92
|
+
Package sizes (brotli'd, pre-treeshake): ESM: 507 bytes
|
|
93
93
|
|
|
94
94
|
## Dependencies
|
|
95
95
|
|
|
@@ -126,7 +126,10 @@ import { LRUCache } from "@thi.ng/cache";
|
|
|
126
126
|
```ts
|
|
127
127
|
import { memoize1 } from "@thi.ng/memoize";
|
|
128
128
|
|
|
129
|
-
foo = memoize1((x) =>
|
|
129
|
+
foo = memoize1((x: number) => {
|
|
130
|
+
console.log("exec");
|
|
131
|
+
return x * 10;
|
|
132
|
+
});
|
|
130
133
|
|
|
131
134
|
foo(1);
|
|
132
135
|
// exec
|
|
@@ -138,7 +141,7 @@ import { EquivMap } from "@thi.ng/associative";
|
|
|
138
141
|
|
|
139
142
|
// with custom cache
|
|
140
143
|
foo = memoize1(
|
|
141
|
-
(x) => (console.log("exec"), x[0] * 10),
|
|
144
|
+
(x: number[]) => (console.log("exec"), x[0] * 10),
|
|
142
145
|
// custom ES6 Map impl which compares by value, not by reference
|
|
143
146
|
new EquivMap()
|
|
144
147
|
);
|
|
@@ -148,6 +151,7 @@ foo([1]);
|
|
|
148
151
|
// 10
|
|
149
152
|
|
|
150
153
|
// would be a cache miss w/ native ES6 Map
|
|
154
|
+
// due to lack of value equality semantics
|
|
151
155
|
foo([1]);
|
|
152
156
|
// 10
|
|
153
157
|
|
|
@@ -155,7 +159,7 @@ import { LRUCache } from "@thi.ng/cache";
|
|
|
155
159
|
|
|
156
160
|
// use LRU cache to limit cache size
|
|
157
161
|
foo = memoize1(
|
|
158
|
-
(x) => (console.log("exec"), x[0] * 10),
|
|
162
|
+
(x: number[]) => (console.log("exec"), x[0] * 10),
|
|
159
163
|
new LRUCache(null, { maxlen: 3 })
|
|
160
164
|
);
|
|
161
165
|
```
|
|
@@ -167,7 +171,10 @@ import { memoize } from "@thi.ng/memoize";
|
|
|
167
171
|
import { EquivMap } from "@thi.ng/associative";
|
|
168
172
|
|
|
169
173
|
const dotProduct = memoize(
|
|
170
|
-
(x
|
|
174
|
+
(x: number[], y: number[]) => {
|
|
175
|
+
console.log("exec");
|
|
176
|
+
return x[0] * y[0] + x[1] * y[1];
|
|
177
|
+
},
|
|
171
178
|
new EquivMap()
|
|
172
179
|
);
|
|
173
180
|
|
|
@@ -184,11 +191,16 @@ dotProduct([1,2], [3,4]);
|
|
|
184
191
|
import { memoizeJ } from "@thi.ng/memoize";
|
|
185
192
|
|
|
186
193
|
const dotProduct = memoizeJ(
|
|
187
|
-
(x
|
|
194
|
+
(x: number[], y: number[]) => {
|
|
195
|
+
console.log("exec");
|
|
196
|
+
return x[0] * y[0] + x[1] * y[1];
|
|
197
|
+
}
|
|
188
198
|
);
|
|
199
|
+
|
|
189
200
|
dotProduct([1, 2], [3, 4]);
|
|
190
201
|
// exec
|
|
191
202
|
// 11
|
|
203
|
+
|
|
192
204
|
dotProduct([1, 2], [3, 4]);
|
|
193
205
|
// 11
|
|
194
206
|
```
|
package/memoize.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FnAny } from "@thi.ng/api";
|
|
2
2
|
import type { MapLike } from "./api.js";
|
|
3
3
|
/**
|
|
4
4
|
* Function memoization for arbitrary argument counts. Returns augmented
|
|
@@ -17,8 +17,12 @@ import type { MapLike } from "./api.js";
|
|
|
17
17
|
* @param fn -
|
|
18
18
|
* @param cache -
|
|
19
19
|
*/
|
|
20
|
-
export declare function memoize<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
export declare function memoize<T extends FnAny<any>>(fn: T, cache: MapLike<any, any>): T;
|
|
21
|
+
/**
|
|
22
|
+
* Async version of {@link memoize}.
|
|
23
|
+
*
|
|
24
|
+
* @param fn
|
|
25
|
+
* @param cache
|
|
26
|
+
*/
|
|
27
|
+
export declare function memoizeAsync<T extends FnAny<any>>(fn: T, cache: MapLike<any, any>): (...xs: Parameters<T>) => Promise<Awaited<ReturnType<T>>>;
|
|
24
28
|
//# sourceMappingURL=memoize.d.ts.map
|
package/memoize.js
CHANGED
|
@@ -4,6 +4,13 @@ function memoize(fn, cache) {
|
|
|
4
4
|
return cache.has(args) ? cache.get(args) : (cache.set(args, res = fn.apply(null, args)), res);
|
|
5
5
|
};
|
|
6
6
|
}
|
|
7
|
+
function memoizeAsync(fn, cache) {
|
|
8
|
+
return async (...args) => {
|
|
9
|
+
let res;
|
|
10
|
+
return cache.has(args) ? cache.get(args) : (cache.set(args, res = await fn.apply(null, args)), res);
|
|
11
|
+
};
|
|
12
|
+
}
|
|
7
13
|
export {
|
|
8
|
-
memoize
|
|
14
|
+
memoize,
|
|
15
|
+
memoizeAsync
|
|
9
16
|
};
|
package/memoize1.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Fn } from "@thi.ng/api";
|
|
1
|
+
import type { Fn, MaybePromise } from "@thi.ng/api";
|
|
2
2
|
import type { MapLike } from "./api.js";
|
|
3
3
|
/**
|
|
4
4
|
* Optimized memoization for single arg functions.
|
|
@@ -16,4 +16,11 @@ import type { MapLike } from "./api.js";
|
|
|
16
16
|
* @param cache -
|
|
17
17
|
*/
|
|
18
18
|
export declare const memoize1: <A, B>(fn: Fn<A, B>, cache?: MapLike<A, B>) => (x: A) => B;
|
|
19
|
+
/**
|
|
20
|
+
* Async version of {@link memoize1}.
|
|
21
|
+
*
|
|
22
|
+
* @param fn
|
|
23
|
+
* @param cache
|
|
24
|
+
*/
|
|
25
|
+
export declare const memoizeAsync1: <A, B>(fn: Fn<A, MaybePromise<B>>, cache?: MapLike<A, B>) => (x: A) => Promise<B>;
|
|
19
26
|
//# sourceMappingURL=memoize1.d.ts.map
|
package/memoize1.js
CHANGED
|
@@ -2,6 +2,11 @@ const memoize1 = (fn, cache = /* @__PURE__ */ new Map()) => (x) => {
|
|
|
2
2
|
let res;
|
|
3
3
|
return cache.has(x) ? cache.get(x) : (cache.set(x, res = fn(x)), res);
|
|
4
4
|
};
|
|
5
|
+
const memoizeAsync1 = (fn, cache = /* @__PURE__ */ new Map()) => async (x) => {
|
|
6
|
+
let res;
|
|
7
|
+
return cache.has(x) ? cache.get(x) : (cache.set(x, res = await fn(x)), res);
|
|
8
|
+
};
|
|
5
9
|
export {
|
|
6
|
-
memoize1
|
|
10
|
+
memoize1,
|
|
11
|
+
memoizeAsync1
|
|
7
12
|
};
|
package/memoizej.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FnAny, IObjectOf } from "@thi.ng/api";
|
|
2
2
|
/**
|
|
3
3
|
* Function memoization for arbitrary argument counts. Returns augmented
|
|
4
4
|
* function, which uses `JSON.stringify()` to obtain (and store)
|
|
@@ -14,8 +14,12 @@ import type { Fn, Fn2, Fn3, Fn4, IObjectOf } from "@thi.ng/api";
|
|
|
14
14
|
* @param fn -
|
|
15
15
|
* @param cache -
|
|
16
16
|
*/
|
|
17
|
-
export declare function memoizeJ<
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
export declare function memoizeJ<T extends FnAny<any>>(fn: T, cache?: IObjectOf<any>): T;
|
|
18
|
+
/**
|
|
19
|
+
* Async version of {@link memoizeJ}.
|
|
20
|
+
*
|
|
21
|
+
* @param fn
|
|
22
|
+
* @param cache
|
|
23
|
+
*/
|
|
24
|
+
export declare function memoizeAsyncJ<T extends FnAny<any>>(fn: T, cache?: IObjectOf<any>): (...xs: Parameters<T>) => Promise<Awaited<ReturnType<T>>>;
|
|
21
25
|
//# sourceMappingURL=memoizej.d.ts.map
|
package/memoizej.js
CHANGED
|
@@ -7,6 +7,16 @@ function memoizeJ(fn, cache = /* @__PURE__ */ Object.create(null)) {
|
|
|
7
7
|
return fn.apply(null, args);
|
|
8
8
|
};
|
|
9
9
|
}
|
|
10
|
+
function memoizeAsyncJ(fn, cache = /* @__PURE__ */ Object.create(null)) {
|
|
11
|
+
return async (...args) => {
|
|
12
|
+
const key = JSON.stringify(args);
|
|
13
|
+
if (key !== void 0) {
|
|
14
|
+
return key in cache ? cache[key] : cache[key] = await fn.apply(null, args);
|
|
15
|
+
}
|
|
16
|
+
return await fn.apply(null, args);
|
|
17
|
+
};
|
|
18
|
+
}
|
|
10
19
|
export {
|
|
20
|
+
memoizeAsyncJ,
|
|
11
21
|
memoizeJ
|
|
12
22
|
};
|
package/memoizeo.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import type { Fn, Fn2, Fn3, Fn4, NumOrString } from "@thi.ng/api";
|
|
1
|
+
import type { Fn, Fn2, Fn3, Fn4, IObjectOf, MaybePromise, NumOrString } from "@thi.ng/api";
|
|
2
2
|
/**
|
|
3
|
-
* The most minimalistic
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* The most minimalistic memoization function of this package, but only supports
|
|
4
|
+
* numbers or strings as arguments (max. 4) and uses a vanilla JS object as
|
|
5
|
+
* cache.
|
|
6
6
|
*
|
|
7
7
|
* @remarks
|
|
8
|
-
*
|
|
8
|
+
* If `fn` throws an error, no result value will be cached and no memoization
|
|
9
|
+
* happens for this invocation using the given arguments.
|
|
10
|
+
*
|
|
11
|
+
* Use {@link memoizeAsyncO} for async functions or other functions returning
|
|
12
|
+
* promises.
|
|
9
13
|
*
|
|
10
14
|
* @example
|
|
11
15
|
* ```ts tangle:../export/memoizeo.ts
|
|
@@ -28,26 +32,22 @@ import type { Fn, Fn2, Fn3, Fn4, NumOrString } from "@thi.ng/api";
|
|
|
28
32
|
* @param fn
|
|
29
33
|
* @param cache
|
|
30
34
|
*/
|
|
31
|
-
export declare
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
* @param fn
|
|
36
|
-
* @param cache
|
|
37
|
-
*/
|
|
38
|
-
export declare const memoize2O: <A extends NumOrString, B extends NumOrString, C>(fn: Fn2<A, B, C>, cache?: Record<string, C>) => (a: A, b: B) => C;
|
|
35
|
+
export declare function memoizeO<A extends NumOrString, B>(fn: Fn<A, B>, cache?: IObjectOf<B>): Fn<A, B>;
|
|
36
|
+
export declare function memoizeO<A extends NumOrString, B extends NumOrString, C>(fn: Fn2<A, B, C>, cache?: IObjectOf<C>): Fn2<A, B, C>;
|
|
37
|
+
export declare function memoizeO<A extends NumOrString, B extends NumOrString, C extends NumOrString, D>(fn: Fn3<A, B, C, D>, cache?: IObjectOf<D>): Fn3<A, B, C, D>;
|
|
38
|
+
export declare function memoizeO<A extends NumOrString, B extends NumOrString, C extends NumOrString, D extends NumOrString, E>(fn: Fn4<A, B, C, D, E>, cache?: IObjectOf<E>): Fn4<A, B, C, D, E>;
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
40
|
+
* Async version of {@link memoizeO}.
|
|
41
41
|
*
|
|
42
|
-
* @
|
|
43
|
-
*
|
|
44
|
-
|
|
45
|
-
export declare const memoize3O: <A extends NumOrString, B extends NumOrString, C extends NumOrString, D>(fn: Fn3<A, B, C, D>, cache?: Record<string, D>) => (a: A, b: B, c: C) => D;
|
|
46
|
-
/**
|
|
47
|
-
* Like {@link memoizeO}, but for functions with 4 arguments.
|
|
42
|
+
* @remarks
|
|
43
|
+
* If `fn` throws an error, no result value will be cached and no memoization
|
|
44
|
+
* happens for this invocation using the given arguments.
|
|
48
45
|
*
|
|
49
46
|
* @param fn
|
|
50
47
|
* @param cache
|
|
51
48
|
*/
|
|
52
|
-
export declare
|
|
49
|
+
export declare function memoizeAsyncO<A extends NumOrString, B>(fn: Fn<A, MaybePromise<B>>, cache?: IObjectOf<B>): Fn<A, Promise<B>>;
|
|
50
|
+
export declare function memoizeAsyncO<A extends NumOrString, B extends NumOrString, C>(fn: Fn2<A, B, MaybePromise<C>>, cache?: IObjectOf<C>): Fn2<A, B, Promise<C>>;
|
|
51
|
+
export declare function memoizeAsyncO<A extends NumOrString, B extends NumOrString, C extends NumOrString, D>(fn: Fn3<A, B, C, MaybePromise<D>>, cache?: IObjectOf<D>): Fn3<A, B, C, Promise<D>>;
|
|
52
|
+
export declare function memoizeAsyncO<A extends NumOrString, B extends NumOrString, C extends NumOrString, D extends NumOrString, E>(fn: Fn4<A, B, C, D, MaybePromise<E>>, cache?: IObjectOf<E>): Fn4<A, B, C, D, Promise<E>>;
|
|
53
53
|
//# sourceMappingURL=memoizeo.d.ts.map
|
package/memoizeo.js
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
return
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
};
|
|
1
|
+
function memoizeO(fn, cache = /* @__PURE__ */ Object.create(null)) {
|
|
2
|
+
return (...xs) => {
|
|
3
|
+
const key = xs.join("-");
|
|
4
|
+
return key in cache ? cache[key] : cache[key] = fn(...xs);
|
|
5
|
+
};
|
|
6
|
+
}
|
|
7
|
+
function memoizeAsyncO(fn, cache = /* @__PURE__ */ Object.create(null)) {
|
|
8
|
+
return async (...xs) => {
|
|
9
|
+
const key = xs.join("-");
|
|
10
|
+
return key in cache ? cache[key] : cache[key] = await fn(...xs);
|
|
11
|
+
};
|
|
12
|
+
}
|
|
14
13
|
export {
|
|
15
|
-
|
|
16
|
-
memoize3O,
|
|
17
|
-
memoize4O,
|
|
14
|
+
memoizeAsyncO,
|
|
18
15
|
memoizeO
|
|
19
16
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/memoize",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Function memoization with configurable caching",
|
|
3
|
+
"version": "4.0.1",
|
|
4
|
+
"description": "Function memoization with configurable caching and support for async functions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
7
7
|
"typings": "./index.d.ts",
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"typescript": "^5.6.2"
|
|
46
46
|
},
|
|
47
47
|
"keywords": [
|
|
48
|
+
"async",
|
|
48
49
|
"cache",
|
|
49
50
|
"functional",
|
|
50
51
|
"memoization",
|
|
@@ -95,5 +96,5 @@
|
|
|
95
96
|
],
|
|
96
97
|
"year": 2018
|
|
97
98
|
},
|
|
98
|
-
"gitHead": "
|
|
99
|
+
"gitHead": "1148f3130b867c65141957b4b7617021d7ac7fc9\n"
|
|
99
100
|
}
|