cached-factory 0.2.0 → 0.3.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/README.md +26 -2
- package/lib/CachedFactory.d.ts +12 -0
- package/lib/CachedFactory.d.ts.map +1 -0
- package/lib/CachedFactory.js +25 -0
- package/lib/CachedFactory.js.map +1 -0
- package/lib/WeakCachedFactory.d.ts +12 -0
- package/lib/WeakCachedFactory.d.ts.map +1 -0
- package/lib/WeakCachedFactory.js +22 -0
- package/lib/WeakCachedFactory.js.map +1 -0
- package/lib/index.d.ts +3 -12
- package/lib/index.js +3 -25
- package/package.json +14 -14
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -20,10 +20,14 @@
|
|
|
20
20
|
|
|
21
21
|
## Usage
|
|
22
22
|
|
|
23
|
+
### `CachedFactory`
|
|
24
|
+
|
|
23
25
|
`cached-factory` exports a `CachedFactory` class that takes in "factory" function in its constructor.
|
|
24
26
|
Each time a factory's `.get(key)` is called with any `key` for the first time, that factory is used to create a value under the `key`.
|
|
25
27
|
|
|
26
28
|
```ts
|
|
29
|
+
import { CachedFactory } from "cached-factory";
|
|
30
|
+
|
|
27
31
|
const cache = new CachedFactory((key) => `Cached: ${key}!`);
|
|
28
32
|
|
|
29
33
|
// "Cached: apple!"
|
|
@@ -33,6 +37,8 @@ cache.get("apple");
|
|
|
33
37
|
Values are cached so that subsequent `.get(key)` calls with the same `key` instantly return the same value.
|
|
34
38
|
|
|
35
39
|
```ts
|
|
40
|
+
import { CachedFactory } from "cached-factory";
|
|
41
|
+
|
|
36
42
|
const cache = new CachedFactory((key) => ({ key }));
|
|
37
43
|
|
|
38
44
|
// { key: "banana" }
|
|
@@ -42,7 +48,25 @@ cache.get("banana");
|
|
|
42
48
|
cache.get("banana") === cache.get("banana");
|
|
43
49
|
```
|
|
44
50
|
|
|
45
|
-
###
|
|
51
|
+
### `WeakCachedFactory`
|
|
52
|
+
|
|
53
|
+
The package also exports a `WeakCachedFactory` class that provides the same behavior as `CachedFactory` but uses a `WeakMap` as its underlying data structure.
|
|
54
|
+
As such, only objects can be used for keys (no primitives), and there is no `entries()` function.
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
import { WeakCachedFactory } from "cached-factory";
|
|
58
|
+
|
|
59
|
+
const cache = new WeakCachedFactory((key: Context) =>
|
|
60
|
+
createSomeResultObject(key),
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const result = cache.get(someContext);
|
|
64
|
+
|
|
65
|
+
// true
|
|
66
|
+
result === cache.get(someContext);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Asynchronous Factories
|
|
46
70
|
|
|
47
71
|
`CachedFactory` does not itself handle `Promise` logic, but it doesn't have to!
|
|
48
72
|
Provided factory functions can themselves be `async` / return `Promise` values.
|
|
@@ -71,7 +95,7 @@ cache.clear();
|
|
|
71
95
|
|
|
72
96
|
### TypeScript
|
|
73
97
|
|
|
74
|
-
`
|
|
98
|
+
`cached-factory` is written in TypeScript and ships with strong typing.
|
|
75
99
|
💪
|
|
76
100
|
|
|
77
101
|
> 👉 Tip: if you're working with [`noImplicitAny`](https://aka.ms/tsconfig#noImplicitAny) enabled _(which is generally a good idea)_, an inline function provided as an argument to `CachedFactory` may need an explicit type annotation for its key.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/CachedFactory.d.ts
|
|
2
|
+
type Factory<Key, Value> = (key: Key) => Value;
|
|
3
|
+
declare class CachedFactory<Key, Value> {
|
|
4
|
+
#private;
|
|
5
|
+
constructor(factory: Factory<Key, Value>);
|
|
6
|
+
clear(): void;
|
|
7
|
+
entries(): MapIterator<[Key, Value]>;
|
|
8
|
+
get(key: Key): Value;
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { CachedFactory, Factory };
|
|
12
|
+
//# sourceMappingURL=CachedFactory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CachedFactory.d.ts","names":[],"sources":["../src/CachedFactory.ts"],"mappings":";KAAY,OAAA,gBAAuB,GAAA,EAAK,GAAA,KAAQ,KAAK;AAAA,cAExC,aAAA;EAAA;cAIA,OAAA,EAAS,OAAA,CAAQ,GAAA,EAAK,KAAA;EAIlC,KAAA;EAIA,OAAA,IAAO,WAAA,EAAA,GAAA,EAAA,KAAA;EAIP,GAAA,CAAI,GAAA,EAAK,GAAA,GAAG,KAAA;AAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region src/CachedFactory.ts
|
|
2
|
+
var CachedFactory = class {
|
|
3
|
+
#cache = /* @__PURE__ */ new Map();
|
|
4
|
+
#getter;
|
|
5
|
+
constructor(factory) {
|
|
6
|
+
this.#getter = factory;
|
|
7
|
+
}
|
|
8
|
+
clear() {
|
|
9
|
+
this.#cache.clear();
|
|
10
|
+
}
|
|
11
|
+
entries() {
|
|
12
|
+
return this.#cache.entries();
|
|
13
|
+
}
|
|
14
|
+
get(key) {
|
|
15
|
+
const existing = this.#cache.get(key);
|
|
16
|
+
if (existing) return existing;
|
|
17
|
+
const value = this.#getter(key);
|
|
18
|
+
this.#cache.set(key, value);
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
//#endregion
|
|
23
|
+
export { CachedFactory };
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=CachedFactory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CachedFactory.js","names":["#getter","#cache"],"sources":["../src/CachedFactory.ts"],"sourcesContent":["export type Factory<Key, Value> = (key: Key) => Value;\n\nexport class CachedFactory<Key, Value> {\n\t#cache = new Map<Key, Value>();\n\t#getter: Factory<Key, Value>;\n\n\tconstructor(factory: Factory<Key, Value>) {\n\t\tthis.#getter = factory;\n\t}\n\n\tclear() {\n\t\tthis.#cache.clear();\n\t}\n\n\tentries() {\n\t\treturn this.#cache.entries();\n\t}\n\n\tget(key: Key) {\n\t\tconst existing = this.#cache.get(key);\n\t\tif (existing) {\n\t\t\treturn existing;\n\t\t}\n\n\t\tconst value = this.#getter(key);\n\t\tthis.#cache.set(key, value);\n\t\treturn value;\n\t}\n}\n"],"mappings":";AAEA,IAAa,gBAAb,MAAuC;CACtC,yBAAS,IAAI,IAAgB;CAC7B;CAEA,YAAY,SAA8B;EACzC,KAAKA,UAAU;CAChB;CAEA,QAAQ;EACP,KAAKC,OAAO,MAAM;CACnB;CAEA,UAAU;EACT,OAAO,KAAKA,OAAO,QAAQ;CAC5B;CAEA,IAAI,KAAU;EACb,MAAM,WAAW,KAAKA,OAAO,IAAI,GAAG;EACpC,IAAI,UACH,OAAO;EAGR,MAAM,QAAQ,KAAKD,QAAQ,GAAG;EAC9B,KAAKC,OAAO,IAAI,KAAK,KAAK;EAC1B,OAAO;CACR;AACD"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Factory } from "./CachedFactory.js";
|
|
2
|
+
|
|
3
|
+
//#region src/WeakCachedFactory.d.ts
|
|
4
|
+
declare class WeakCachedFactory<Key extends WeakKey, Value> {
|
|
5
|
+
#private;
|
|
6
|
+
constructor(factory: Factory<Key, Value>);
|
|
7
|
+
clear(): void;
|
|
8
|
+
get(key: Key): Value;
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { WeakCachedFactory };
|
|
12
|
+
//# sourceMappingURL=WeakCachedFactory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WeakCachedFactory.d.ts","names":[],"sources":["../src/WeakCachedFactory.ts"],"mappings":";;;cAEa,iBAAA,aAA8B,OAAA;EAAA;cAI9B,OAAA,EAAS,OAAA,CAAQ,GAAA,EAAK,KAAA;EAIlC,KAAA;EAIA,GAAA,CAAI,GAAA,EAAK,GAAA,GAAG,KAAA;AAAA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region src/WeakCachedFactory.ts
|
|
2
|
+
var WeakCachedFactory = class {
|
|
3
|
+
#cache = /* @__PURE__ */ new WeakMap();
|
|
4
|
+
#getter;
|
|
5
|
+
constructor(factory) {
|
|
6
|
+
this.#getter = factory;
|
|
7
|
+
}
|
|
8
|
+
clear() {
|
|
9
|
+
this.#cache = /* @__PURE__ */ new WeakMap();
|
|
10
|
+
}
|
|
11
|
+
get(key) {
|
|
12
|
+
const existing = this.#cache.get(key);
|
|
13
|
+
if (existing) return existing;
|
|
14
|
+
const value = this.#getter(key);
|
|
15
|
+
this.#cache.set(key, value);
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
//#endregion
|
|
20
|
+
export { WeakCachedFactory };
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=WeakCachedFactory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WeakCachedFactory.js","names":["#getter","#cache"],"sources":["../src/WeakCachedFactory.ts"],"sourcesContent":["import { Factory } from \"./CachedFactory.ts\";\n\nexport class WeakCachedFactory<Key extends WeakKey, Value> {\n\t#cache = new WeakMap<Key, Value>();\n\t#getter: Factory<Key, Value>;\n\n\tconstructor(factory: Factory<Key, Value>) {\n\t\tthis.#getter = factory;\n\t}\n\n\tclear() {\n\t\tthis.#cache = new WeakMap<Key, Value>();\n\t}\n\n\tget(key: Key) {\n\t\tconst existing = this.#cache.get(key);\n\t\tif (existing) {\n\t\t\treturn existing;\n\t\t}\n\n\t\tconst value = this.#getter(key);\n\t\tthis.#cache.set(key, value);\n\t\treturn value;\n\t}\n}\n"],"mappings":";AAEA,IAAa,oBAAb,MAA2D;CAC1D,yBAAS,IAAI,QAAoB;CACjC;CAEA,YAAY,SAA8B;EACzC,KAAKA,UAAU;CAChB;CAEA,QAAQ;EACP,KAAKC,yBAAS,IAAI,QAAoB;CACvC;CAEA,IAAI,KAAU;EACb,MAAM,WAAW,KAAKA,OAAO,IAAI,GAAG;EACpC,IAAI,UACH,OAAO;EAGR,MAAM,QAAQ,KAAKD,QAAQ,GAAG;EAC9B,KAAKC,OAAO,IAAI,KAAK,KAAK;EAC1B,OAAO;CACR;AACD"}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
#private;
|
|
5
|
-
constructor(factory: Factory<Key, Value>);
|
|
6
|
-
clear(): void;
|
|
7
|
-
entries(): MapIterator<[Key, Value]>;
|
|
8
|
-
get(key: Key): Value;
|
|
9
|
-
}
|
|
10
|
-
//#endregion
|
|
11
|
-
export { CachedFactory, Factory };
|
|
12
|
-
//# sourceMappingURL=index.d.ts.map
|
|
1
|
+
import { CachedFactory, Factory } from "./CachedFactory.js";
|
|
2
|
+
import { WeakCachedFactory } from "./WeakCachedFactory.js";
|
|
3
|
+
export { CachedFactory, type Factory, WeakCachedFactory };
|
package/lib/index.js
CHANGED
|
@@ -1,25 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
#getter;
|
|
5
|
-
constructor(factory) {
|
|
6
|
-
this.#getter = factory;
|
|
7
|
-
}
|
|
8
|
-
clear() {
|
|
9
|
-
this.#cache.clear();
|
|
10
|
-
}
|
|
11
|
-
entries() {
|
|
12
|
-
return this.#cache.entries();
|
|
13
|
-
}
|
|
14
|
-
get(key) {
|
|
15
|
-
const existing = this.#cache.get(key);
|
|
16
|
-
if (existing) return existing;
|
|
17
|
-
const value = this.#getter(key);
|
|
18
|
-
this.#cache.set(key, value);
|
|
19
|
-
return value;
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
//#endregion
|
|
23
|
-
export { CachedFactory };
|
|
24
|
-
|
|
25
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
import { CachedFactory } from "./CachedFactory.js";
|
|
2
|
+
import { WeakCachedFactory } from "./WeakCachedFactory.js";
|
|
3
|
+
export { CachedFactory, WeakCachedFactory };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cached-factory",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Creates and caches values under keys. 🏭",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -36,35 +36,35 @@
|
|
|
36
36
|
"@eslint/js": "10.0.1",
|
|
37
37
|
"@eslint/markdown": "8.0.1",
|
|
38
38
|
"@release-it/conventional-changelog": "11.0.0",
|
|
39
|
-
"@types/node": "25.
|
|
39
|
+
"@types/node": "25.9.0",
|
|
40
40
|
"@vitest/coverage-v8": "4.1.5",
|
|
41
41
|
"@vitest/eslint-plugin": "1.6.16",
|
|
42
42
|
"console-fail-test": "0.6.1",
|
|
43
43
|
"create-typescript-app": "2.60.1",
|
|
44
44
|
"cspell": "10.0.0",
|
|
45
|
-
"eslint": "10.
|
|
46
|
-
"eslint-plugin-jsdoc": "
|
|
47
|
-
"eslint-plugin-jsonc": "3.
|
|
48
|
-
"eslint-plugin-n": "
|
|
49
|
-
"eslint-plugin-package-json": "
|
|
45
|
+
"eslint": "10.4.0",
|
|
46
|
+
"eslint-plugin-jsdoc": "63.0.0",
|
|
47
|
+
"eslint-plugin-jsonc": "3.2.0",
|
|
48
|
+
"eslint-plugin-n": "18.1.0",
|
|
49
|
+
"eslint-plugin-package-json": "1.3.0",
|
|
50
50
|
"eslint-plugin-perfectionist": "5.9.0",
|
|
51
51
|
"eslint-plugin-regexp": "3.1.0",
|
|
52
|
-
"eslint-plugin-yml": "3.
|
|
52
|
+
"eslint-plugin-yml": "3.4.0",
|
|
53
53
|
"husky": "9.1.7",
|
|
54
|
-
"knip": "6.
|
|
55
|
-
"lint-staged": "
|
|
54
|
+
"knip": "6.16.0",
|
|
55
|
+
"lint-staged": "17.0.2",
|
|
56
56
|
"prettier": "3.8.3",
|
|
57
57
|
"prettier-plugin-curly": "0.4.1",
|
|
58
58
|
"prettier-plugin-packagejson": "3.0.2",
|
|
59
59
|
"prettier-plugin-sentences-per-line": "0.2.3",
|
|
60
60
|
"prettier-plugin-sh": "0.18.1",
|
|
61
|
-
"release-it": "20.0
|
|
62
|
-
"tsdown": "0.
|
|
61
|
+
"release-it": "20.2.0",
|
|
62
|
+
"tsdown": "0.22.0",
|
|
63
63
|
"typescript": "6.0.3",
|
|
64
|
-
"typescript-eslint": "8.
|
|
64
|
+
"typescript-eslint": "8.61.0",
|
|
65
65
|
"vitest": "4.1.5"
|
|
66
66
|
},
|
|
67
|
-
"packageManager": "pnpm@
|
|
67
|
+
"packageManager": "pnpm@11.5.0",
|
|
68
68
|
"engines": {
|
|
69
69
|
"node": ">=18"
|
|
70
70
|
},
|
package/lib/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";KAAY,OAAA,gBAAuB,GAAA,EAAK,GAAA,KAAQ,KAAA;AAAA,cAEnC,aAAA;EAAA;cAIA,OAAA,EAAS,OAAA,CAAQ,GAAA,EAAK,KAAA;EAIlC,KAAA,CAAA;EAIA,OAAA,CAAA,GAAO,WAAA,EAAA,GAAA,EAAA,KAAA;EAIP,GAAA,CAAI,GAAA,EAAK,GAAA,GAAG,KAAA;AAAA"}
|
package/lib/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["#getter","#cache"],"sources":["../src/index.ts"],"sourcesContent":["export type Factory<Key, Value> = (key: Key) => Value;\n\nexport class CachedFactory<Key, Value> {\n\t#cache = new Map<Key, Value>();\n\t#getter: Factory<Key, Value>;\n\n\tconstructor(factory: Factory<Key, Value>) {\n\t\tthis.#getter = factory;\n\t}\n\n\tclear() {\n\t\tthis.#cache.clear();\n\t}\n\n\tentries() {\n\t\treturn this.#cache.entries();\n\t}\n\n\tget(key: Key) {\n\t\tconst existing = this.#cache.get(key);\n\t\tif (existing) {\n\t\t\treturn existing;\n\t\t}\n\n\t\tconst value = this.#getter(key);\n\t\tthis.#cache.set(key, value);\n\t\treturn value;\n\t}\n}\n"],"mappings":";AAEA,IAAa,gBAAb,MAAuC;CACtC,yBAAS,IAAI,KAAiB;CAC9B;CAEA,YAAY,SAA8B;AACzC,QAAA,SAAe;;CAGhB,QAAQ;AACP,QAAA,MAAY,OAAO;;CAGpB,UAAU;AACT,SAAO,MAAA,MAAY,SAAS;;CAG7B,IAAI,KAAU;EACb,MAAM,WAAW,MAAA,MAAY,IAAI,IAAI;AACrC,MAAI,SACH,QAAO;EAGR,MAAM,QAAQ,MAAA,OAAa,IAAI;AAC/B,QAAA,MAAY,IAAI,KAAK,MAAM;AAC3B,SAAO"}
|