@veekhere/just-cache-it 1.0.3

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/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Vitaliy Kuguenko
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,285 @@
1
+ # just-cache-it
2
+
3
+ A generic cache implementation with optional TTL support and subscriptions
4
+
5
+ - **Immutable** values
6
+ - **Lightweight** and "**zero-dependency**"
7
+ - **TTL** support
8
+ - **Cache update** subscriptions
9
+ - **Cache value update** subscriptions
10
+ - **Cache key** utilities
11
+ - **TypeScript** support
12
+
13
+ ## Dependencies
14
+
15
+ **Runtime**
16
+
17
+ - [uuid](https://github.com/uuidjs/uuid) for UUID generation (zero-dependency)
18
+ - [lodash.clonedeep](https://github.com/lodash/lodash) for deep cloning (zero-dependency)
19
+
20
+ **Development**
21
+
22
+ - [jest](https://github.com/facebook/jest)
23
+ - [ts-jest](https://github.com/kulshekhar/ts-jest)
24
+ - [prettier](https://github.com/prettier/prettier)
25
+ - [typescript](https://github.com/microsoft/TypeScript)
26
+
27
+ ## Quickstart
28
+
29
+ **1. Install**
30
+
31
+ ```bash
32
+ npm i @veekhere/just-cache-it
33
+ ```
34
+
35
+ **2. Create a cache**
36
+
37
+ ```typescript
38
+ import { CacheIt } from '@veekhere/just-cache-it';
39
+
40
+ const cache = new CacheIt<string>();
41
+
42
+ const cacheValue: CacheValue<string> = cache.set('key', 'value');
43
+
44
+ cacheValue.unwrapPrevious(); // ⇨ undefined
45
+ cacheValue.unwrapCurrent(); // ⇨ 'value'
46
+
47
+ cacheValue.subscribe({
48
+ next: (value: CacheValue<string>) => {
49
+ const previousValue = value.unwrapPrevious();
50
+ const currentValue = value.unwrapCurrent();
51
+
52
+ // Do something with the previous and current values
53
+ },
54
+ complete: () => {
55
+ // Trigger something when the subscription is cancelled
56
+ },
57
+ });
58
+ ```
59
+
60
+ ## API Summary
61
+
62
+ **Main cache**
63
+
64
+ | | | |
65
+ | ------------------------------------------------------- | -------------------------------------------------- | --------------- |
66
+ | [`CacheIt`](#cacheit) | The main cache class | New in `v1.0.0` |
67
+ | [`CacheSubscriptionHandler`](#cachesubscriptionhandler) | Represents a handler to call when cache is updated | New in `v1.0.0` |
68
+ | [`CacheSubscription`](#cachesubscription) | Represents a subscription to cache changes | New in `v1.0.0` |
69
+
70
+ **Cache values**
71
+
72
+ | | | |
73
+ | ------------------------------------------------------------------- | --------------------------------------------------------------- | --------------- |
74
+ | [`CacheValue`](#cachevalue) | Represents a cached value that can be updated and subscribed to | New in `v1.0.0` |
75
+ | [`UnwrapHandlers`](#unwraphandlers) | Represents the handlers to call when unwrapping a cache value | New in `v1.0.0` |
76
+ | [`CacheValueSubscriptionHandlers`](#cachevaluesubscriptionhandlers) | Represents the handlers to call when cache value changes | New in `v1.0.0` |
77
+ | [`CacheValueSubscription`](#cachevaluesubscription) | Represents a subscription to a cache value | New in `v1.0.0` |
78
+
79
+ **Types and utilities**
80
+
81
+ | | | |
82
+ | ------------------------------- | ------------------------------------------------- | --------------- |
83
+ | [`CacheItUtils`](#cacheitutils) | Utility functions for working with cache entries | New in `v1.0.0` |
84
+ | [`Maybe`](#maybe) | Represents a value that may or may not be present | New in `v1.0.0` |
85
+
86
+ ## API
87
+
88
+ ### CacheIt
89
+
90
+ Main cache class. Returned values are immutable
91
+
92
+ **1. Primitive values**
93
+
94
+ ```typescript
95
+ import { CacheIt } from '@veekhere/just-cache-it';
96
+
97
+ const cache = new CacheIt<string>(); // string cache
98
+
99
+ cache.set('key', 'value');
100
+
101
+ cache.get('key'); // ⇨ 'value'
102
+ ```
103
+
104
+ **2. User defined values**
105
+
106
+ ```typescript
107
+ import { CacheIt } from '@veekhere/just-cache-it';
108
+
109
+ class User {
110
+ constructor(public name: string) {}
111
+
112
+ whois(): string {
113
+ return `Hello, my name is ${this.name}`;
114
+ }
115
+ }
116
+
117
+ const cache = new CacheIt<User>(); // User cache
118
+
119
+ cache.set('key', new User('John'));
120
+
121
+ cache.get('key')?.unwrapCurrent(); // ⇨ User { name: 'John' }
122
+ ```
123
+
124
+ **3. Arrays**
125
+
126
+ ```typescript
127
+ import { CacheIt } from '@veekhere/just-cache-it';
128
+
129
+ const cache = new CacheIt<string[]>(); // string[] cache
130
+
131
+ cache.set('key', ['value']);
132
+
133
+ cache.get('key'); // ⇨ ['value']
134
+ ```
135
+
136
+ **And so on...**
137
+
138
+ ### CacheSubscriptionHandler
139
+
140
+ Represents a handler to call when cache is updated
141
+
142
+ ```typescript
143
+ import { CacheIt } from '@veekhere/just-cache-it';
144
+
145
+ const cache = new CacheIt<string>();
146
+
147
+ const handler: CacheSubscriptionHandler = () => {
148
+ // Trigger something when the cache is updated
149
+ };
150
+
151
+ const subscription = cache.subscribe(handler);
152
+ ```
153
+
154
+ ### CacheSubscription
155
+
156
+ Represents a subscription to cache changes
157
+
158
+ ```typescript
159
+ import { CacheIt } from '@veekhere/just-cache-it';
160
+
161
+ const cache = new CacheIt<string>();
162
+
163
+ const subscription = cache.subscribe(() => {
164
+ // Trigger something when the cache changes
165
+ });
166
+ ```
167
+
168
+ ### CacheValue
169
+
170
+ Represents a cached value that can be updated and subscribed to
171
+
172
+ ```typescript
173
+ import { CacheIt, CacheValue } from '@veekhere/just-cache-it';
174
+
175
+ const cache = new CacheIt<string>();
176
+
177
+ const cacheValue: CacheValue<string> = cache.set('key', 'value');
178
+
179
+ cacheValue.unwrapPrevious(); // ⇨ undefined
180
+ cacheValue.unwrapCurrent(); // ⇨ 'value'
181
+
182
+ cacheValue.subscribe({
183
+ next: (value: CacheValue<string>) => {
184
+ // Do something with the previous and current values
185
+ },
186
+ complete: () => {
187
+ // Trigger something when the subscription is cancelled
188
+ },
189
+ });
190
+ ```
191
+
192
+ ### UnwrapHandlers
193
+
194
+ Represents the handlers to call when unwrapping a cache value
195
+
196
+ ```typescript
197
+ import { CacheIt, CacheValue } from '@veekhere/just-cache-it';
198
+
199
+ const cache = new CacheIt<string>();
200
+
201
+ const cacheValue: CacheValue<string> = cache.set('key', 'value');
202
+
203
+ const handlers: UnwrapHandlers<string> = {
204
+ onPresent: (value: string) => {
205
+ // Do something with the value
206
+ },
207
+ onAbsent: () => {
208
+ // Do something when the value is absent
209
+ },
210
+ };
211
+
212
+ cacheValue.unwrapPrevious(handlers);
213
+ cacheValue.unwrapCurrent(handlers);
214
+ ```
215
+
216
+ ### CacheValueSubscriptionHandlers
217
+
218
+ Represents the handlers to call when cache value changes
219
+
220
+ ```typescript
221
+ import { CacheValue, CacheValueSubscriptionHandlers } from '@veekhere/just-cache-it';
222
+
223
+ const handlers: CacheValueSubscriptionHandlers<string> = {
224
+ next: (value: CacheValue<string>) => {
225
+ // Do something with the previous and current values
226
+ },
227
+ complete: () => {
228
+ // Trigger something when the subscription is cancelled
229
+ },
230
+ };
231
+
232
+ // register cache ...
233
+
234
+ cache.subscribe(handlers);
235
+ ```
236
+
237
+ ### CacheValueSubscription
238
+
239
+ Represents a subscription to a cache value
240
+
241
+ ```typescript
242
+ import { CacheIt, CacheValue } from '@veekhere/just-cache-it';
243
+
244
+ const cache = new CacheIt<string>();
245
+
246
+ const cacheValue: CacheValue<string> = cache.set('key', 'value');
247
+
248
+ const subscription = cacheValue.subscribe({
249
+ // handlers
250
+ });
251
+
252
+ // some complex logic
253
+
254
+ subscription.unsubscribe();
255
+ ```
256
+
257
+ ### CacheItUtils
258
+
259
+ Utility functions for working with cache entries
260
+
261
+ ```typescript
262
+ import { CacheItUtils } from '@veekhere/just-cache-it';
263
+
264
+ const keyGenerator = CacheItUtils.addBaseKey('BASE#KEY');
265
+
266
+ keyGenerator.generateKey('my', 'additional', 'parts'); // ⇨ '$CACHE-IT_BASE#KEY_my-additional-parts_2a4f54b2-700a-41b3-8008-ac641a550ee5'
267
+ ```
268
+
269
+ ### Maybe
270
+
271
+ Represents a value that may or may not be present
272
+
273
+ ```typescript
274
+ import { Maybe } from '@veekhere/just-cache-it';
275
+
276
+ const maybe: Maybe<string> = getData(); // ⇨ string | undefined
277
+ ```
278
+
279
+ ## Contributing
280
+
281
+ Contributions are welcome! Please open an issue or submit a pull request.
282
+
283
+ ## License
284
+
285
+ [MIT](https://github.com/veekhere/just-cache-it/blob/master/LICENSE.md)
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Cache-It is a generic cache implementation with optional TTL support and subscriptions. It can be used to cache any value, including objects, arrays, and primitives.
3
+ * @template T The type of values stored in the cache
4
+ * @see https://github.com/veekhere/cache-it
5
+ * @author veekhere
6
+ * @license MIT
7
+ * @version 1.0.0
8
+ */
9
+ /**
10
+ * Represents a value that may or may not be present
11
+ * @template T The type of the value
12
+ */
13
+ type Maybe<T> = T | undefined;
14
+ /**
15
+ * Represents the handlers to call when unwrapping a cache value
16
+ * @template T The type of the value
17
+ */
18
+ type UnwrapHandlers<T> = {
19
+ /**
20
+ * Called when the value is present
21
+ * @param value The value
22
+ */
23
+ onPresent?: (value: T) => void;
24
+ /**
25
+ * Called when the value is absent
26
+ */
27
+ onAbsent?: () => void;
28
+ };
29
+ /**
30
+ * Subscription to a cache value
31
+ */
32
+ type CacheValueSubscription = {
33
+ /**
34
+ * Unsubscribes from the cache value
35
+ */
36
+ unsubscribe: () => void;
37
+ };
38
+ /**
39
+ * Represents the handlers to call when cache value changes
40
+ */
41
+ type CacheValueSubscriptionHandlers<T> = {
42
+ /**
43
+ * Called when the value changes
44
+ * @param value The new value of the cache
45
+ */
46
+ next?: (value: Omit<CacheValue<T>, "subscribe" | "unsubscribeAll">) => void;
47
+ /**
48
+ * Called when the subscription is cancelled
49
+ */
50
+ complete?: () => void;
51
+ };
52
+ /**
53
+ * Represents a value that can be cached and subscribed to
54
+ * @template T The type of the value
55
+ */
56
+ declare class CacheValue<T> {
57
+ private readonly value;
58
+ private readonly subscribers;
59
+ /**
60
+ * Creates a new cache value
61
+ * @param ttl The time-to-live in milliseconds
62
+ */
63
+ constructor(ttl?: number);
64
+ /**
65
+ * Updates the value in the cache
66
+ * @param value The new value to set
67
+ */
68
+ update(value: Maybe<T>): void;
69
+ /**
70
+ * Returns the current value, or undefined if not present
71
+ */
72
+ unwrapCurrent(): Maybe<T>;
73
+ /**
74
+ * Calls the provided handlers with the current value, or undefined if not present
75
+ * @param handlers The handlers to call
76
+ */
77
+ unwrapCurrent(handlers: UnwrapHandlers<T>): void;
78
+ /**
79
+ * Returns the previous value, or undefined if not present
80
+ */
81
+ unwrapPrevious(): Maybe<T>;
82
+ /**
83
+ * Calls the provided handlers with the previous value, or undefined if not present
84
+ * @param handlers The handlers to call
85
+ */
86
+ unwrapPrevious(handlers: UnwrapHandlers<T>): void;
87
+ /**
88
+ * Removes the current and previous values
89
+ */
90
+ clear(): void;
91
+ /**
92
+ * Subscribes to changes in the cache value
93
+ * @param handlers The handlers to call when the value changes
94
+ * @returns A subscription object that can be used to unsubscribe
95
+ */
96
+ subscribe(handlers: CacheValueSubscriptionHandlers<T>): CacheValueSubscription;
97
+ /**
98
+ * Unsubscribes from all subscribers
99
+ */
100
+ unsubscribeAll(): void;
101
+ private notifySubscribers;
102
+ }
103
+ /**
104
+ * Subscription to a cache changes
105
+ */
106
+ type CacheSubscription = {
107
+ /**
108
+ * Unsubscribes from the cache changes
109
+ */
110
+ unsubscribe: () => void;
111
+ };
112
+ /**
113
+ * Represents a handler to call when cache is updated
114
+ */
115
+ type CacheSubscriptionHandler = () => void;
116
+ /**
117
+ * A generic cache implementation with optional TTL support
118
+ * @template T The type of values stored in the cache
119
+ */
120
+ declare class CacheIt<T> {
121
+ private readonly cache;
122
+ private readonly subscribers;
123
+ /**
124
+ * Sets a value in the cache
125
+ * @param key The key to store the value under
126
+ * @param value The value to store
127
+ * @param ttl Optional time-to-live in milliseconds
128
+ */
129
+ set(key: string, value: T, ttl?: number): CacheValue<T>;
130
+ /**
131
+ * Retrieves a value from the cache
132
+ * @param key The key to lookup
133
+ * @returns The stored value, or undefined if not found or expired
134
+ */
135
+ get(key: string): CacheValue<T> | undefined;
136
+ /**
137
+ * Removes a value from the cache
138
+ * @param key The key to remove
139
+ * @returns true if the key was found and removed, false otherwise
140
+ */
141
+ delete(key: string): boolean;
142
+ /**
143
+ * Removes all entries from the cache
144
+ */
145
+ clear(): void;
146
+ /**
147
+ * Returns the number of entries in the cache
148
+ */
149
+ size(): number;
150
+ /**
151
+ * Checks if a key exists in the cache and is not expired
152
+ * @param key The key to check
153
+ * @returns true if the key exists and is not expired
154
+ */
155
+ has(key: string): boolean;
156
+ /**
157
+ * Subscribes to changes in the cache
158
+ * @param handler The handler to call when the cache changes
159
+ * @returns A subscription object that can be used to unsubscribe
160
+ */
161
+ subscribe(handler: CacheSubscriptionHandler): CacheSubscription;
162
+ /**
163
+ * Unsubscribes from all subscribers without emitting any events
164
+ */
165
+ unsubscribeAll(): void;
166
+ private notifySubscribers;
167
+ }
168
+ /**
169
+ * Represents a key generator for cache entries
170
+ */
171
+ type CacheKeyGenerator = {
172
+ /**
173
+ * Generates a key with additional parts
174
+ * @param additional Additional parts to add to the key
175
+ */
176
+ generateKey: (...additional: string[]) => string;
177
+ };
178
+ /**
179
+ * Utility functions for working with cache entries
180
+ */
181
+ declare class CacheItUtils {
182
+ /**
183
+ * Adds a base key to a key generator
184
+ * @param baseKey The base key to add
185
+ * @returns A key generator with the base key added
186
+ */
187
+ static addBaseKey(baseKey: string): CacheKeyGenerator;
188
+ /**
189
+ * Generates a key with additional parts
190
+ * @param additional Additional parts to add to the key
191
+ */
192
+ static generateKey(...additional: string[]): string;
193
+ private static generateKeyWithBase;
194
+ }
195
+ export { CacheIt, CacheItUtils, CacheValue, CacheValueSubscription, UnwrapHandlers };
package/dist/index.js ADDED
@@ -0,0 +1,237 @@
1
+ import cloneDeep from 'lodash.clonedeep';
2
+ import { v4 as uuidv4 } from 'uuid';
3
+ /**
4
+ * Represents a value that can be cached and subscribed to
5
+ * @template T The type of the value
6
+ */
7
+ class CacheValue {
8
+ /**
9
+ * Creates a new cache value
10
+ * @param ttl The time-to-live in milliseconds
11
+ */
12
+ constructor(ttl) {
13
+ this.value = {
14
+ current: undefined,
15
+ previous: undefined,
16
+ };
17
+ this.subscribers = new Map();
18
+ if (ttl != null) {
19
+ setTimeout(() => {
20
+ this.update(undefined);
21
+ }, ttl);
22
+ }
23
+ }
24
+ /**
25
+ * Updates the value in the cache
26
+ * @param value The new value to set
27
+ */
28
+ update(value) {
29
+ const oldValue = typeof this.value.current === 'object' && this.value.current != null
30
+ ? cloneDeep(this.value.current)
31
+ : this.value.current;
32
+ const newValue = typeof value === 'object' && value != null
33
+ ? cloneDeep(value)
34
+ : value;
35
+ this.value.previous = oldValue;
36
+ this.value.current = newValue;
37
+ this.notifySubscribers();
38
+ }
39
+ unwrapCurrent(handlers) {
40
+ var _a, _b;
41
+ if (handlers) {
42
+ if (this.value.current) {
43
+ (_a = handlers.onPresent) === null || _a === void 0 ? void 0 : _a.call(handlers, this.value.current);
44
+ }
45
+ else {
46
+ (_b = handlers.onAbsent) === null || _b === void 0 ? void 0 : _b.call(handlers);
47
+ }
48
+ }
49
+ else {
50
+ return this.value.current;
51
+ }
52
+ }
53
+ unwrapPrevious(handlers) {
54
+ var _a, _b;
55
+ if (handlers) {
56
+ if (this.value.previous) {
57
+ (_a = handlers.onPresent) === null || _a === void 0 ? void 0 : _a.call(handlers, this.value.previous);
58
+ }
59
+ else {
60
+ (_b = handlers.onAbsent) === null || _b === void 0 ? void 0 : _b.call(handlers);
61
+ }
62
+ }
63
+ else {
64
+ return this.value.previous;
65
+ }
66
+ }
67
+ /**
68
+ * Removes the current and previous values
69
+ */
70
+ clear() {
71
+ this.value.current = undefined;
72
+ this.value.previous = undefined;
73
+ this.notifySubscribers();
74
+ }
75
+ /**
76
+ * Subscribes to changes in the cache value
77
+ * @param handlers The handlers to call when the value changes
78
+ * @returns A subscription object that can be used to unsubscribe
79
+ */
80
+ subscribe(handlers) {
81
+ const symbol = Symbol();
82
+ this.subscribers.set(symbol, handlers);
83
+ return {
84
+ unsubscribe: () => {
85
+ var _a;
86
+ (_a = handlers === null || handlers === void 0 ? void 0 : handlers.complete) === null || _a === void 0 ? void 0 : _a.call(handlers);
87
+ this.subscribers.delete(symbol);
88
+ },
89
+ };
90
+ }
91
+ /**
92
+ * Unsubscribes from all subscribers
93
+ */
94
+ unsubscribeAll() {
95
+ this.notifySubscribers(true);
96
+ this.subscribers.clear();
97
+ }
98
+ notifySubscribers(isComplete) {
99
+ this.subscribers.forEach((handlers) => {
100
+ var _a, _b;
101
+ if (isComplete) {
102
+ (_a = handlers.complete) === null || _a === void 0 ? void 0 : _a.call(handlers);
103
+ }
104
+ else {
105
+ (_b = handlers.next) === null || _b === void 0 ? void 0 : _b.call(handlers, this);
106
+ }
107
+ });
108
+ }
109
+ }
110
+ /**
111
+ * A generic cache implementation with optional TTL support
112
+ * @template T The type of values stored in the cache
113
+ */
114
+ class CacheIt {
115
+ constructor() {
116
+ this.cache = new Map();
117
+ this.subscribers = new Map();
118
+ }
119
+ /**
120
+ * Sets a value in the cache
121
+ * @param key The key to store the value under
122
+ * @param value The value to store
123
+ * @param ttl Optional time-to-live in milliseconds
124
+ */
125
+ set(key, value, ttl) {
126
+ const cacheValue = new CacheValue(ttl);
127
+ cacheValue.update(value);
128
+ this.cache.set(key, cacheValue);
129
+ this.notifySubscribers();
130
+ return cacheValue;
131
+ }
132
+ /**
133
+ * Retrieves a value from the cache
134
+ * @param key The key to lookup
135
+ * @returns The stored value, or undefined if not found or expired
136
+ */
137
+ get(key) {
138
+ const cacheValue = this.cache.get(key);
139
+ if (!cacheValue) {
140
+ return undefined;
141
+ }
142
+ return cacheValue;
143
+ }
144
+ /**
145
+ * Removes a value from the cache
146
+ * @param key The key to remove
147
+ * @returns true if the key was found and removed, false otherwise
148
+ */
149
+ delete(key) {
150
+ const isDeleted = this.cache.delete(key);
151
+ if (isDeleted) {
152
+ this.notifySubscribers();
153
+ }
154
+ return isDeleted;
155
+ }
156
+ /**
157
+ * Removes all entries from the cache
158
+ */
159
+ clear() {
160
+ this.cache.clear();
161
+ this.notifySubscribers();
162
+ }
163
+ /**
164
+ * Returns the number of entries in the cache
165
+ */
166
+ size() {
167
+ return this.cache.size;
168
+ }
169
+ /**
170
+ * Checks if a key exists in the cache and is not expired
171
+ * @param key The key to check
172
+ * @returns true if the key exists and is not expired
173
+ */
174
+ has(key) {
175
+ const cacheValue = this.cache.get(key);
176
+ if (!cacheValue) {
177
+ return false;
178
+ }
179
+ return true;
180
+ }
181
+ /**
182
+ * Subscribes to changes in the cache
183
+ * @param handler The handler to call when the cache changes
184
+ * @returns A subscription object that can be used to unsubscribe
185
+ */
186
+ subscribe(handler) {
187
+ const symbol = Symbol();
188
+ this.subscribers.set(symbol, handler);
189
+ return {
190
+ unsubscribe: () => {
191
+ this.subscribers.delete(symbol);
192
+ },
193
+ };
194
+ }
195
+ /**
196
+ * Unsubscribes from all subscribers without emitting any events
197
+ */
198
+ unsubscribeAll() {
199
+ this.subscribers.clear();
200
+ }
201
+ notifySubscribers() {
202
+ this.subscribers.forEach((handler) => handler());
203
+ }
204
+ }
205
+ /**
206
+ * Utility functions for working with cache entries
207
+ */
208
+ class CacheItUtils {
209
+ /**
210
+ * Adds a base key to a key generator
211
+ * @param baseKey The base key to add
212
+ * @returns A key generator with the base key added
213
+ */
214
+ static addBaseKey(baseKey) {
215
+ if (!baseKey) {
216
+ throw new Error('Base key cannot be empty');
217
+ }
218
+ return {
219
+ generateKey: (...additional) => CacheItUtils.generateKeyWithBase(baseKey, ...additional),
220
+ };
221
+ }
222
+ /**
223
+ * Generates a key with additional parts
224
+ * @param additional Additional parts to add to the key
225
+ */
226
+ static generateKey(...additional) {
227
+ return CacheItUtils.generateKeyWithBase(undefined, ...additional);
228
+ }
229
+ static generateKeyWithBase(baseKey, ...additional) {
230
+ const baseKeyPart = baseKey != null ? `${baseKey}_` : '';
231
+ const additionalPart = additional != null && (additional === null || additional === void 0 ? void 0 : additional.length) > 0
232
+ ? `${additional === null || additional === void 0 ? void 0 : additional.join('-')}_`
233
+ : '';
234
+ return `$CACHE-IT_${baseKeyPart}${additionalPart}${uuidv4()}`;
235
+ }
236
+ }
237
+ export { CacheIt, CacheItUtils, CacheValue };
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@veekhere/just-cache-it",
3
+ "version": "1.0.3",
4
+ "description": "A generic cache implementation with optional TTL support and subscriptions",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "type": "module",
8
+ "scripts": {
9
+ "build": "tsc",
10
+ "test": "jest"
11
+ },
12
+ "keywords": [
13
+ "cache",
14
+ "ttl",
15
+ "subscriptions",
16
+ "immutable",
17
+ "zero-dependency",
18
+ "typescript"
19
+ ],
20
+ "author": "veekhere",
21
+ "license": "MIT",
22
+ "files": [
23
+ "dist",
24
+ "LICENSE",
25
+ "README.md",
26
+ "package.json"
27
+ ],
28
+ "devDependencies": {
29
+ "@types/jest": "^29.5.14",
30
+ "@types/node": "^22.13.4",
31
+ "jest": "^29.7.0",
32
+ "prettier": "^3.5.1",
33
+ "ts-jest": "^29.2.5",
34
+ "typescript": "^5.0.4"
35
+ },
36
+ "dependencies": {
37
+ "@types/lodash.clonedeep": "^4.5.9",
38
+ "lodash.clonedeep": "^4.5.0",
39
+ "uuid": "^11.0.0"
40
+ }
41
+ }