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 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
- ### Asynchronous Factories
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
- `CachedFactory` is written in TypeScript and ships with strong typing.
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
- //#region src/index.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=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
- //#region src/index.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=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.2.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.6.0",
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.2.1",
46
- "eslint-plugin-jsdoc": "62.9.0",
47
- "eslint-plugin-jsonc": "3.1.2",
48
- "eslint-plugin-n": "17.24.0",
49
- "eslint-plugin-package-json": "0.91.1",
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.3.1",
52
+ "eslint-plugin-yml": "3.4.0",
53
53
  "husky": "9.1.7",
54
- "knip": "6.7.0",
55
- "lint-staged": "16.4.0",
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.1",
62
- "tsdown": "0.21.10",
61
+ "release-it": "20.2.0",
62
+ "tsdown": "0.22.0",
63
63
  "typescript": "6.0.3",
64
- "typescript-eslint": "8.59.0",
64
+ "typescript-eslint": "8.61.0",
65
65
  "vitest": "4.1.5"
66
66
  },
67
- "packageManager": "pnpm@10.33.2",
67
+ "packageManager": "pnpm@11.5.0",
68
68
  "engines": {
69
69
  "node": ">=18"
70
70
  },
@@ -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"}