limited-cache 2.2.0 → 2.3.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.
Files changed (79) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +4 -3
  3. package/dist/cjs/index.cjs +273 -380
  4. package/dist/cjs/index.d.cts +84 -76
  5. package/dist/cjs/index.d.cts.map +1 -0
  6. package/dist/esm/index.d.ts +99 -6
  7. package/dist/esm/index.d.ts.map +1 -1
  8. package/dist/esm/index.js +279 -6
  9. package/dist/esm/index.js.map +1 -1
  10. package/package.json +34 -53
  11. package/src/__tests__/LimitedCache.test.ts +2 -2
  12. package/src/__tests__/LimitedCacheObject.test.ts +30 -27
  13. package/src/__tests__/lowLevelFunctions.test.ts +10 -8
  14. package/src/__tests__/scenarios/keys.test.ts +2 -2
  15. package/src/__tests__/scenarios/maxCacheSize.test.ts +8 -5
  16. package/src/__tests__/scenarios/maxCacheTime.test.ts +58 -58
  17. package/src/__tests__/scenarios/values.test.ts +2 -2
  18. package/src/__tests__/typeChecks/LimitedCacheObjectTypes.test.ts +15 -15
  19. package/src/__tests__/typeChecks/LimitedCacheTypes.test.ts +1 -1
  20. package/src/__tests__/typeChecks/lowLevelFunctionsTypes.test.ts +2 -2
  21. package/src/core/LimitedCache.ts +20 -21
  22. package/src/core/LimitedCacheObject.ts +30 -19
  23. package/src/core/defaultOptions.ts +5 -4
  24. package/src/core/limitedCacheUtil.ts +15 -3
  25. package/src/core/lowLevelFunctions.ts +43 -32
  26. package/src/types.ts +4 -3
  27. package/dist/esm/core/LimitedCache.d.ts +0 -4
  28. package/dist/esm/core/LimitedCache.d.ts.map +0 -1
  29. package/dist/esm/core/LimitedCache.js +0 -29
  30. package/dist/esm/core/LimitedCache.js.map +0 -1
  31. package/dist/esm/core/LimitedCacheObject.d.ts +0 -5
  32. package/dist/esm/core/LimitedCacheObject.d.ts.map +0 -1
  33. package/dist/esm/core/LimitedCacheObject.js +0 -52
  34. package/dist/esm/core/LimitedCacheObject.js.map +0 -1
  35. package/dist/esm/core/builtIns.d.ts +0 -12
  36. package/dist/esm/core/builtIns.d.ts.map +0 -1
  37. package/dist/esm/core/builtIns.js +0 -5
  38. package/dist/esm/core/builtIns.js.map +0 -1
  39. package/dist/esm/core/defaultOptions.d.ts +0 -6
  40. package/dist/esm/core/defaultOptions.d.ts.map +0 -1
  41. package/dist/esm/core/defaultOptions.js +0 -14
  42. package/dist/esm/core/defaultOptions.js.map +0 -1
  43. package/dist/esm/core/limitedCacheUtil.d.ts +0 -13
  44. package/dist/esm/core/limitedCacheUtil.d.ts.map +0 -1
  45. package/dist/esm/core/limitedCacheUtil.js +0 -14
  46. package/dist/esm/core/limitedCacheUtil.js.map +0 -1
  47. package/dist/esm/core/lowLevelFunctions.d.ts +0 -14
  48. package/dist/esm/core/lowLevelFunctions.d.ts.map +0 -1
  49. package/dist/esm/core/lowLevelFunctions.js +0 -240
  50. package/dist/esm/core/lowLevelFunctions.js.map +0 -1
  51. package/dist/esm/types.d.ts +0 -58
  52. package/dist/esm/types.d.ts.map +0 -1
  53. package/dist/esm/types.js +0 -2
  54. package/dist/esm/types.js.map +0 -1
  55. package/legacy-types/ts3.5/dist/esm/core/LimitedCache.d.ts +0 -4
  56. package/legacy-types/ts3.5/dist/esm/core/LimitedCacheObject.d.ts +0 -5
  57. package/legacy-types/ts3.5/dist/esm/core/builtIns.d.ts +0 -12
  58. package/legacy-types/ts3.5/dist/esm/core/defaultOptions.d.ts +0 -6
  59. package/legacy-types/ts3.5/dist/esm/core/limitedCacheUtil.d.ts +0 -13
  60. package/legacy-types/ts3.5/dist/esm/core/lowLevelFunctions.d.ts +0 -14
  61. package/legacy-types/ts3.5/dist/esm/index.d.ts +0 -7
  62. package/legacy-types/ts3.5/dist/esm/types.d.ts +0 -61
  63. package/legacy-types/ts4.0/dist/esm/core/LimitedCache.d.ts +0 -4
  64. package/legacy-types/ts4.0/dist/esm/core/LimitedCacheObject.d.ts +0 -5
  65. package/legacy-types/ts4.0/dist/esm/core/builtIns.d.ts +0 -12
  66. package/legacy-types/ts4.0/dist/esm/core/defaultOptions.d.ts +0 -6
  67. package/legacy-types/ts4.0/dist/esm/core/limitedCacheUtil.d.ts +0 -13
  68. package/legacy-types/ts4.0/dist/esm/core/lowLevelFunctions.d.ts +0 -14
  69. package/legacy-types/ts4.0/dist/esm/index.d.ts +0 -7
  70. package/legacy-types/ts4.0/dist/esm/types.d.ts +0 -61
  71. package/legacy-types/ts4.5/dist/esm/core/LimitedCache.d.ts +0 -4
  72. package/legacy-types/ts4.5/dist/esm/core/LimitedCacheObject.d.ts +0 -5
  73. package/legacy-types/ts4.5/dist/esm/core/builtIns.d.ts +0 -12
  74. package/legacy-types/ts4.5/dist/esm/core/defaultOptions.d.ts +0 -6
  75. package/legacy-types/ts4.5/dist/esm/core/limitedCacheUtil.d.ts +0 -13
  76. package/legacy-types/ts4.5/dist/esm/core/lowLevelFunctions.d.ts +0 -14
  77. package/legacy-types/ts4.5/dist/esm/index.d.ts +0 -7
  78. package/legacy-types/ts4.5/dist/esm/types.d.ts +0 -61
  79. package/src/core/builtIns.ts +0 -9
@@ -1,10 +1,12 @@
1
- import { describe, beforeEach, expect, it, vitest } from 'vitest';
2
- import { LimitedCacheObject, LimitedCacheObjectInstance } from '../../index.js';
1
+ // biome-ignore-all lint/performance/noDelete: Delete is explicitly used to unset items for these tests
2
+
3
+ import { beforeEach, describe, expect, it, vitest } from 'vitest';
4
+ import { LimitedCacheObject, type LimitedCacheObjectInstance } from '../../index.js';
3
5
 
4
6
  // To avoid race conditions or timing issues, since some expect() checks can take 10+ ms when busy,
5
7
  // we use a long cache timeout even for 'immediate' expiration, and use delays slightly longer than that
6
8
  const CACHE_TIMEOUT = 25;
7
- const timeoutPromise = (): Promise<null> =>
9
+ const timeoutPromise = (): Promise<void> =>
8
10
  new Promise((resolve) => setTimeout(resolve, CACHE_TIMEOUT + 2));
9
11
 
10
12
  describe('maxCacheTime scenarios', () => {
@@ -19,41 +21,39 @@ describe('maxCacheTime scenarios', () => {
19
21
  });
20
22
 
21
23
  it("doesn't have keys for expired items", async () => {
22
- myCache.abc = 123;
23
- myCache.def = 456;
24
+ myCache['abc'] = 123;
25
+ myCache['def'] = 456;
24
26
  await timeoutPromise();
25
- myCache.ghi = 789;
27
+ myCache['ghi'] = 789;
26
28
 
27
- const { hasOwnProperty } = Object.prototype;
28
- expect(hasOwnProperty.call(myCache, 'abc')).toEqual(false);
29
- expect(hasOwnProperty.call(myCache, 'def')).toEqual(false);
29
+ expect(Object.hasOwn(myCache, 'abc')).toEqual(false);
30
+ expect(Object.hasOwn(myCache, 'def')).toEqual(false);
30
31
 
31
32
  expect(Object.keys(myCache)).toEqual(['ghi']);
32
33
  });
33
34
 
34
35
  it('removes expired items on get', async () => {
35
- myCache.abc = 123;
36
- myCache.def = 456;
36
+ myCache['abc'] = 123;
37
+ myCache['def'] = 456;
37
38
  await timeoutPromise();
38
39
 
39
- expect(myCache.abc).toEqual(undefined);
40
- expect(myCache.def).toEqual(undefined);
40
+ expect(myCache['abc']).toEqual(undefined);
41
+ expect(myCache['def']).toEqual(undefined);
41
42
  expect(Object.keys(myCache)).toEqual([]);
42
43
  });
43
44
 
44
45
  it('removes expired items on set', async () => {
45
- myCache.abc = 123;
46
- myCache.def = 456;
46
+ myCache['abc'] = 123;
47
+ myCache['def'] = 456;
47
48
  await timeoutPromise();
48
- myCache.ghi = 789;
49
-
50
- const { hasOwnProperty } = Object.prototype;
51
- expect(hasOwnProperty.call(myCache, 'abc')).toEqual(false);
52
- expect(hasOwnProperty.call(myCache, 'def')).toEqual(false);
53
- expect(hasOwnProperty.call(myCache, 'ghi')).toEqual(true);
54
- expect(myCache.abc).toEqual(undefined);
55
- expect(myCache.def).toEqual(undefined);
56
- expect(myCache.ghi).toEqual(789);
49
+ myCache['ghi'] = 789;
50
+
51
+ expect(Object.hasOwn(myCache, 'abc')).toEqual(false);
52
+ expect(Object.hasOwn(myCache, 'def')).toEqual(false);
53
+ expect(Object.hasOwn(myCache, 'ghi')).toEqual(true);
54
+ expect(myCache['abc']).toEqual(undefined);
55
+ expect(myCache['def']).toEqual(undefined);
56
+ expect(myCache['ghi']).toEqual(789);
57
57
  expect(Object.keys(myCache)).toEqual(['ghi']);
58
58
  });
59
59
 
@@ -65,24 +65,24 @@ describe('maxCacheTime scenarios', () => {
65
65
  warnIfItemPurgedBeforeTime: 0,
66
66
  });
67
67
 
68
- myCache.abc = 123;
68
+ myCache['abc'] = 123;
69
69
  await timeoutPromise();
70
- myCache.def = 456;
70
+ myCache['def'] = 456;
71
71
  await timeoutPromise();
72
- myCache.ghi = 789;
72
+ myCache['ghi'] = 789;
73
73
  await timeoutPromise();
74
74
 
75
75
  // Now write over the 'oldest' key to reset its timestamp
76
- myCache.abc = 123;
76
+ myCache['abc'] = 123;
77
77
 
78
78
  // Now, adding a new value (over maxCacheSize) should remove the actual oldest
79
- myCache.newOne = 100;
80
- expect(myCache.def).toEqual(undefined);
79
+ myCache['newOne'] = 100;
80
+ expect(myCache['def']).toEqual(undefined);
81
81
  expect(Object.keys(myCache)).toEqual(['abc', 'ghi', 'newOne']);
82
82
 
83
83
  // And then the next oldest, after that
84
- myCache.newTwo = 200;
85
- expect(myCache.ghi).toEqual(undefined);
84
+ myCache['newTwo'] = 200;
85
+ expect(myCache['ghi']).toEqual(undefined);
86
86
  expect(Object.keys(myCache)).toEqual(['abc', 'newOne', 'newTwo']);
87
87
  });
88
88
 
@@ -94,36 +94,36 @@ describe('maxCacheTime scenarios', () => {
94
94
  });
95
95
 
96
96
  // This first set will expire after the second set gets added
97
- myCache.abc = 123;
98
- myCache.def = 456;
99
- myCache.ghi = 789;
97
+ myCache['abc'] = 123;
98
+ myCache['def'] = 456;
99
+ myCache['ghi'] = 789;
100
100
  await timeoutPromise();
101
- myCache.jkl = 321;
102
- myCache.mno = 654;
103
- myCache.abc = 1000;
101
+ myCache['jkl'] = 321;
102
+ myCache['mno'] = 654;
103
+ myCache['abc'] = 1000;
104
104
 
105
105
  // At this point nothing has been removed, since reusing 'abc' keeps us within maxCacheSize
106
- expect(myCache.abc).toEqual(1000);
107
- expect(myCache.def).toEqual(456);
108
- expect(myCache.ghi).toEqual(789);
106
+ expect(myCache['abc']).toEqual(1000);
107
+ expect(myCache['def']).toEqual(456);
108
+ expect(myCache['ghi']).toEqual(789);
109
109
 
110
110
  await timeoutPromise();
111
111
 
112
112
  // Now, adding a new value (over maxCacheSize) should remove both of the remaining expired values
113
- myCache.newOne = 100;
114
- expect(myCache.def).toEqual(undefined);
115
- expect(myCache.ghi).toEqual(undefined);
113
+ myCache['newOne'] = 100;
114
+ expect(myCache['def']).toEqual(undefined);
115
+ expect(myCache['ghi']).toEqual(undefined);
116
116
  expect(Object.keys(myCache)).toEqual(['abc', 'jkl', 'mno', 'newOne']);
117
117
 
118
118
  // And then the next can go in without having to remove anything
119
- myCache.newTwo = 200;
120
- expect(myCache.jkl).toEqual(321);
121
- expect(myCache.mno).toEqual(654);
122
- expect(myCache.abc).toEqual(1000);
119
+ myCache['newTwo'] = 200;
120
+ expect(myCache['jkl']).toEqual(321);
121
+ expect(myCache['mno']).toEqual(654);
122
+ expect(myCache['abc']).toEqual(1000);
123
123
  expect(Object.keys(myCache)).toEqual(['abc', 'jkl', 'mno', 'newOne', 'newTwo']);
124
124
  });
125
125
 
126
- it('removes keys for already-removed items first', async () => {
126
+ it('removes keys for already-removed items first', () => {
127
127
  myCache = LimitedCacheObject({
128
128
  maxCacheTime: 0,
129
129
  maxCacheSize: 5,
@@ -132,18 +132,18 @@ describe('maxCacheTime scenarios', () => {
132
132
  });
133
133
 
134
134
  // This first set will expire after the second set gets added
135
- myCache.abc = 123;
136
- myCache.def = 456;
137
- myCache.ghi = 789;
138
- myCache.jkl = 321;
139
- myCache.mno = 654;
140
- myCache.abc = 1000;
135
+ myCache['abc'] = 123;
136
+ myCache['def'] = 456;
137
+ myCache['ghi'] = 789;
138
+ myCache['jkl'] = 321;
139
+ myCache['mno'] = 654;
140
+ myCache['abc'] = 1000;
141
141
 
142
- delete myCache.ghi;
143
- delete myCache.jkl;
142
+ delete myCache['ghi'];
143
+ delete myCache['jkl'];
144
144
 
145
145
  // Now, adding a new value (over maxCacheSize) should not remove anything else
146
- myCache.newOne = 100;
146
+ myCache['newOne'] = 100;
147
147
 
148
148
  expect(Object.keys(myCache)).toEqual(['abc', 'def', 'mno', 'newOne']);
149
149
  });
@@ -1,5 +1,5 @@
1
- import { describe, beforeEach, expect, it } from 'vitest';
2
- import { limitedCacheUtil, LimitedCacheMeta } from '../../index.js';
1
+ import { beforeEach, describe, expect, it } from 'vitest';
2
+ import { type LimitedCacheMeta, limitedCacheUtil } from '../../index.js';
3
3
 
4
4
  describe('value types', () => {
5
5
  let myCacheMeta: LimitedCacheMeta;
@@ -7,21 +7,21 @@ import { LimitedCacheObject } from '../../index.js';
7
7
  * Instead, it ensures that the typeChecks are correct.
8
8
  */
9
9
 
10
- let value;
10
+ let value: unknown;
11
11
 
12
12
  const defaultCache = LimitedCacheObject();
13
13
 
14
- defaultCache.number = 1;
15
- defaultCache.string = 'hello';
16
- defaultCache.array = [];
17
- value = defaultCache.number as number;
18
- value = defaultCache.string as string;
19
- value = defaultCache.array as Array<undefined>;
14
+ defaultCache['number'] = 1;
15
+ defaultCache['string'] = 'hello';
16
+ defaultCache['array'] = [];
17
+ value = defaultCache['number'] as number;
18
+ value = defaultCache['string'] as string;
19
+ value = defaultCache['array'] as Array<undefined>;
20
20
 
21
21
  const numberCache = LimitedCacheObject<number>();
22
22
 
23
- numberCache.number = 1;
24
- value = numberCache.number as number;
23
+ numberCache['number'] = 1;
24
+ value = numberCache['number'];
25
25
 
26
26
  // @ts-expect-error Invalid type
27
27
  numberCache.string = 'hello';
@@ -35,10 +35,10 @@ value = numberCache.array as Array<undefined>;
35
35
 
36
36
  const primitiveCache = LimitedCacheObject<boolean | number | string>();
37
37
 
38
- primitiveCache.number = 1;
39
- primitiveCache.string = 'hello';
40
- value = primitiveCache.number as number;
41
- value = primitiveCache.string as string;
38
+ primitiveCache['number'] = 1;
39
+ primitiveCache['string'] = 'hello';
40
+ value = primitiveCache['number'];
41
+ value = primitiveCache['string'];
42
42
 
43
43
  // @ts-expect-error Invalid type
44
44
  primitiveCache.array = [];
@@ -48,8 +48,8 @@ value = primitiveCache.array as Array<undefined>;
48
48
 
49
49
  const arrayCache = LimitedCacheObject<Array<undefined>>();
50
50
 
51
- arrayCache.array = [];
52
- value = arrayCache.array as Array<undefined>;
51
+ arrayCache['array'] = [];
52
+ value = arrayCache['array'];
53
53
 
54
54
  // @ts-expect-error Invalid type
55
55
  arrayCache.number = 1;
@@ -7,7 +7,7 @@ import { LimitedCache } from '../../index.js';
7
7
  * Instead, it ensures that the typeChecks are correct.
8
8
  */
9
9
 
10
- let value;
10
+ let value: unknown;
11
11
 
12
12
  const defaultCache = LimitedCache();
13
13
 
@@ -1,13 +1,13 @@
1
1
  import { describe, it } from 'vitest';
2
2
 
3
- import { lowLevelInit, lowLevelGetOne, lowLevelSet } from '../../index.js';
3
+ import { lowLevelGetOne, lowLevelInit, lowLevelSet } from '../../index.js';
4
4
 
5
5
  /**
6
6
  * This is not a source file or test file.
7
7
  * Instead, it ensures that the typeChecks are correct.
8
8
  */
9
9
 
10
- let value;
10
+ let value: unknown;
11
11
 
12
12
  const defaultCacheMeta = lowLevelInit();
13
13
 
@@ -1,29 +1,28 @@
1
+ import type {
2
+ DefaultItemType,
3
+ LimitedCacheInstance,
4
+ LimitedCacheMeta,
5
+ LimitedCacheOptions,
6
+ LimitedCacheOptionsReadonly,
7
+ } from '../types.js';
1
8
  import {
2
- lowLevelInit,
3
- lowLevelGetOne,
9
+ lowLevelDoMaintenance,
4
10
  lowLevelGetAll,
11
+ lowLevelGetOne,
5
12
  lowLevelHas,
6
- lowLevelSet,
13
+ lowLevelInit,
7
14
  lowLevelRemove,
8
15
  lowLevelReset,
16
+ lowLevelSet,
9
17
  lowLevelSetOptions,
10
- lowLevelDoMaintenance,
11
18
  } from './lowLevelFunctions.js';
12
- import {
13
- LimitedCacheOptions,
14
- LimitedCacheOptionsReadonly,
15
- LimitedCacheInstance,
16
- LimitedCacheMeta,
17
- DefaultItemType,
18
- } from '../types.js';
19
19
 
20
20
  // Most public functions just call a low-level function directly, passing the cacheMeta.
21
21
  // Doing this via a helper function makes the typeChecks easier, and minifies better.
22
- const bindFunctionToCacheMeta = <ItemType>(
23
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
- fn: (cacheMeta: LimitedCacheMeta<ItemType>, ...otherArgs: any) => any,
22
+ const bindFunctionToCacheMeta = <ItemType, OtherArgs extends unknown[], ReturnValue>(
23
+ fn: (cacheMeta: LimitedCacheMeta<ItemType>, ...otherArgs: OtherArgs) => ReturnValue,
25
24
  cacheMeta: LimitedCacheMeta<ItemType>,
26
- ) => fn.bind(null, cacheMeta);
25
+ ): ((...otherArgs: OtherArgs) => ReturnValue) => fn.bind(null, cacheMeta);
27
26
 
28
27
  const LimitedCache = <ItemType = DefaultItemType>(
29
28
  options?: LimitedCacheOptions,
@@ -31,9 +30,9 @@ const LimitedCache = <ItemType = DefaultItemType>(
31
30
  const cacheMeta = lowLevelInit<ItemType>(options);
32
31
 
33
32
  return {
34
- get: bindFunctionToCacheMeta<ItemType>(lowLevelGetOne, cacheMeta),
35
- getAll: bindFunctionToCacheMeta<ItemType>(lowLevelGetAll, cacheMeta),
36
- has: bindFunctionToCacheMeta<ItemType>(lowLevelHas, cacheMeta),
33
+ get: bindFunctionToCacheMeta(lowLevelGetOne, cacheMeta),
34
+ getAll: bindFunctionToCacheMeta(lowLevelGetAll, cacheMeta),
35
+ has: bindFunctionToCacheMeta(lowLevelHas, cacheMeta),
37
36
  set: (cacheKey, item): ItemType => {
38
37
  lowLevelSet(cacheMeta, cacheKey, item);
39
38
  return item;
@@ -42,11 +41,11 @@ const LimitedCache = <ItemType = DefaultItemType>(
42
41
  lowLevelRemove(cacheMeta, cacheKey);
43
42
  return true;
44
43
  },
45
- reset: bindFunctionToCacheMeta<ItemType>(lowLevelReset, cacheMeta),
44
+ reset: bindFunctionToCacheMeta(lowLevelReset, cacheMeta),
46
45
  getCacheMeta: (): LimitedCacheMeta<ItemType> => cacheMeta,
47
46
  getOptions: (): LimitedCacheOptionsReadonly => cacheMeta.options,
48
- setOptions: bindFunctionToCacheMeta<ItemType>(lowLevelSetOptions, cacheMeta),
49
- doMaintenance: bindFunctionToCacheMeta<ItemType>(lowLevelDoMaintenance, cacheMeta),
47
+ setOptions: bindFunctionToCacheMeta(lowLevelSetOptions, cacheMeta),
48
+ doMaintenance: bindFunctionToCacheMeta(lowLevelDoMaintenance, cacheMeta),
50
49
  };
51
50
  };
52
51
 
@@ -1,36 +1,36 @@
1
- import { hasOwnProperty } from './builtIns.js';
1
+ import type {
2
+ DefaultItemType,
3
+ LimitedCacheMeta,
4
+ LimitedCacheObjectInstance,
5
+ LimitedCacheOptions,
6
+ } from '../types.js';
2
7
  import {
3
- lowLevelInit,
4
- lowLevelGetOne,
5
8
  lowLevelGetAll,
9
+ lowLevelGetOne,
6
10
  lowLevelHas,
7
- lowLevelSet,
11
+ lowLevelInit,
8
12
  lowLevelRemove,
13
+ lowLevelSet,
9
14
  } from './lowLevelFunctions.js';
10
- import {
11
- LimitedCacheOptions,
12
- LimitedCacheObjectInstance,
13
- LimitedCacheMeta,
14
- DefaultItemType,
15
- } from '../types.js';
16
15
 
17
- // The `any` here doesn't escape out anywhere: it's overridden by the constructor below
18
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
- const proxyHandler: ProxyHandler<LimitedCacheObjectInstance<any>> = {
16
+ const proxyHandler: ProxyHandler<LimitedCacheMeta> = {
20
17
  get: (cacheMeta: LimitedCacheMeta, cacheKey: string) => {
21
18
  if (cacheKey === 'hasOwnProperty') {
22
- return hasOwnProperty;
19
+ return Object.prototype.hasOwnProperty;
23
20
  }
21
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
24
22
  return lowLevelGetOne(cacheMeta, cacheKey);
25
23
  },
26
24
  getOwnPropertyDescriptor: (cacheMeta: LimitedCacheMeta, cacheKey: string) => {
27
25
  const hasResult = lowLevelHas(cacheMeta, cacheKey);
26
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
28
27
  const getResult = lowLevelGetOne(cacheMeta, cacheKey);
29
28
 
30
29
  if (hasResult) {
31
30
  return {
32
31
  configurable: true,
33
32
  enumerable: hasResult,
33
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
34
34
  value: getResult,
35
35
  writable: true,
36
36
  };
@@ -38,8 +38,7 @@ const proxyHandler: ProxyHandler<LimitedCacheObjectInstance<any>> = {
38
38
  return;
39
39
  },
40
40
  has: lowLevelHas,
41
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
- set: (cacheMeta: LimitedCacheMeta, cacheKey: string, item: any): any => {
41
+ set: <T>(cacheMeta: LimitedCacheMeta, cacheKey: string, item: T): T => {
43
42
  lowLevelSet(cacheMeta, cacheKey, item);
44
43
  return item;
45
44
  },
@@ -50,6 +49,16 @@ const proxyHandler: ProxyHandler<LimitedCacheObjectInstance<any>> = {
50
49
  ownKeys: (cacheMeta: LimitedCacheMeta) => Object.keys(lowLevelGetAll(cacheMeta)),
51
50
  };
52
51
 
52
+ /**
53
+ * TypeScript's Proxy type models the runtime target, but LimitedCacheObject intentionally returns
54
+ * a facade with a different surface from the internal cache metadata target.
55
+ */
56
+ const internal_createLimitedCacheObjectProxy = <ItemType = DefaultItemType>(
57
+ cacheMeta: LimitedCacheMeta<ItemType>,
58
+ ): LimitedCacheObjectInstance<ItemType> => {
59
+ return new Proxy(cacheMeta, proxyHandler) as unknown as LimitedCacheObjectInstance<ItemType>;
60
+ };
61
+
53
62
  /**
54
63
  * So that we can retrieve the cacheMeta for a LimitedCacheObject, without polluting its properties, each proxy
55
64
  * is associated back to its internal cacheMeta here.
@@ -59,15 +68,17 @@ const cacheMetasForProxies = new WeakMap();
59
68
  const LimitedCacheObject = <ItemType = DefaultItemType>(
60
69
  options?: LimitedCacheOptions,
61
70
  ): LimitedCacheObjectInstance<ItemType> => {
62
- const cacheMeta = lowLevelInit(options);
63
- const limitedCacheObject = new Proxy(cacheMeta, proxyHandler);
71
+ const cacheMeta = lowLevelInit<ItemType>(options);
72
+ const limitedCacheObject = internal_createLimitedCacheObjectProxy(cacheMeta);
64
73
 
65
74
  cacheMetasForProxies.set(limitedCacheObject, cacheMeta);
75
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
66
76
  return limitedCacheObject;
67
77
  };
68
78
 
69
79
  const getCacheMetaFromObject = (instance: LimitedCacheObjectInstance): LimitedCacheMeta => {
80
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
70
81
  return cacheMetasForProxies.get(instance);
71
82
  };
72
83
 
73
- export { LimitedCacheObject, getCacheMetaFromObject };
84
+ export { getCacheMetaFromObject, LimitedCacheObject };
@@ -1,7 +1,8 @@
1
- import { LimitedCacheOptionsReadonly } from '../types.js';
1
+ import type { LimitedCacheOptionsReadonly } from '../types.js';
2
2
 
3
- const CURRENT_META_VERSION = 2;
4
- const MAXIMUM_CACHE_TIME = 365 * 86400 * 1000;
3
+ const CURRENT_META_VERSION = 2 as const;
4
+ // Default = 1 year
5
+ const MAXIMUM_CACHE_TIME: number = 365 * 86400 * 1000;
5
6
 
6
7
  const defaultOptions: LimitedCacheOptionsReadonly = {
7
8
  // Public
@@ -14,4 +15,4 @@ const defaultOptions: LimitedCacheOptionsReadonly = {
14
15
  scanLimit: 50,
15
16
  };
16
17
 
17
- export { CURRENT_META_VERSION, MAXIMUM_CACHE_TIME, defaultOptions };
18
+ export { CURRENT_META_VERSION, defaultOptions, MAXIMUM_CACHE_TIME };
@@ -1,16 +1,28 @@
1
1
  import {
2
- lowLevelGetOne,
2
+ lowLevelDoMaintenance,
3
3
  lowLevelGetAll,
4
+ lowLevelGetOne,
4
5
  lowLevelHas,
5
6
  lowLevelInit,
6
- lowLevelDoMaintenance,
7
7
  lowLevelRemove,
8
8
  lowLevelReset,
9
9
  lowLevelSet,
10
10
  lowLevelSetOptions,
11
11
  } from './lowLevelFunctions.js';
12
12
 
13
- const limitedCacheUtil = {
13
+ type LimitedCacheUtil = {
14
+ init: typeof lowLevelInit;
15
+ get: typeof lowLevelGetOne;
16
+ getAll: typeof lowLevelGetAll;
17
+ has: typeof lowLevelHas;
18
+ set: typeof lowLevelSet;
19
+ remove: typeof lowLevelRemove;
20
+ reset: typeof lowLevelReset;
21
+ doMaintenance: typeof lowLevelDoMaintenance;
22
+ setOptions: typeof lowLevelSetOptions;
23
+ };
24
+
25
+ const limitedCacheUtil: LimitedCacheUtil = {
14
26
  init: lowLevelInit,
15
27
  get: lowLevelGetOne,
16
28
  getAll: lowLevelGetAll,