@ls-stack/utils 2.9.0 → 2.11.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/dist/cache.cjs +77 -37
- package/dist/cache.d.cts +18 -10
- package/dist/cache.d.ts +18 -10
- package/dist/cache.js +77 -37
- package/package.json +1 -1
package/dist/cache.cjs
CHANGED
|
@@ -50,7 +50,7 @@ function createCache({
|
|
|
50
50
|
} = {}) {
|
|
51
51
|
const cache = /* @__PURE__ */ new Map();
|
|
52
52
|
let lastExpirationCheck = 0;
|
|
53
|
-
function
|
|
53
|
+
function cleanExpiredItems() {
|
|
54
54
|
const now = Date.now();
|
|
55
55
|
if (!maxItemAge || now - lastExpirationCheck < expirationThrottle) return;
|
|
56
56
|
lastExpirationCheck = now;
|
|
@@ -77,45 +77,85 @@ function createCache({
|
|
|
77
77
|
function isExpired(timestamp, now) {
|
|
78
78
|
return maxItemAge !== void 0 && now - timestamp > maxItemAge * 1e3;
|
|
79
79
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
80
|
+
return {
|
|
81
|
+
getOrInsert(cacheKey, val) {
|
|
82
|
+
const now = Date.now();
|
|
83
|
+
const entry = cache.get(cacheKey);
|
|
84
|
+
if (!entry || isExpired(entry.timestamp, now)) {
|
|
85
|
+
const value = val();
|
|
86
|
+
cache.set(cacheKey, { value, timestamp: now });
|
|
87
|
+
trimToSize();
|
|
88
|
+
cleanExpiredItems();
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
if (isPromise(entry.value)) {
|
|
92
|
+
throw new Error(
|
|
93
|
+
"Cache value is a promise, use getOrInsertAsync instead"
|
|
94
|
+
);
|
|
95
|
+
}
|
|
95
96
|
return entry.value;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
},
|
|
98
|
+
async getOrInsertAsync(cacheKey, val) {
|
|
99
|
+
const entry = cache.get(cacheKey);
|
|
100
|
+
if (entry && isPromise(entry.value)) {
|
|
101
|
+
return entry.value;
|
|
102
|
+
}
|
|
103
|
+
const now = Date.now();
|
|
104
|
+
if (entry && !isExpired(entry.timestamp, now)) {
|
|
105
|
+
return entry.value;
|
|
106
|
+
}
|
|
107
|
+
const promise = val().then((result) => {
|
|
108
|
+
cache.set(cacheKey, { value: result, timestamp: Date.now() });
|
|
109
|
+
return result;
|
|
110
|
+
}).catch((error) => {
|
|
111
|
+
cache.delete(cacheKey);
|
|
112
|
+
throw error;
|
|
113
|
+
});
|
|
114
|
+
cache.set(cacheKey, { value: promise, timestamp: now });
|
|
115
|
+
trimToSize();
|
|
116
|
+
cleanExpiredItems();
|
|
117
|
+
return promise;
|
|
118
|
+
},
|
|
119
|
+
clear() {
|
|
120
|
+
cache.clear();
|
|
121
|
+
},
|
|
122
|
+
get(cacheKey) {
|
|
123
|
+
const entry = cache.get(cacheKey);
|
|
124
|
+
if (!entry || isExpired(entry.timestamp, Date.now())) {
|
|
125
|
+
return void 0;
|
|
126
|
+
}
|
|
127
|
+
if (isPromise(entry.value)) {
|
|
128
|
+
throw new Error("Cache value is a promise, use getAsync instead");
|
|
129
|
+
}
|
|
99
130
|
return entry.value;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
cache.set(cacheKey, { value
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
131
|
+
},
|
|
132
|
+
set(cacheKey, value) {
|
|
133
|
+
cache.set(cacheKey, { value, timestamp: Date.now() });
|
|
134
|
+
trimToSize();
|
|
135
|
+
cleanExpiredItems();
|
|
136
|
+
},
|
|
137
|
+
async getAsync(cacheKey) {
|
|
138
|
+
const entry = cache.get(cacheKey);
|
|
139
|
+
if (!entry || isExpired(entry.timestamp, Date.now())) {
|
|
140
|
+
return void 0;
|
|
141
|
+
}
|
|
142
|
+
return await entry.value;
|
|
143
|
+
},
|
|
144
|
+
setAsync(cacheKey, value) {
|
|
145
|
+
const promise = value().then((result) => {
|
|
146
|
+
cache.set(cacheKey, { value: result, timestamp: Date.now() });
|
|
147
|
+
return result;
|
|
148
|
+
}).catch((error) => {
|
|
149
|
+
cache.delete(cacheKey);
|
|
150
|
+
throw error;
|
|
151
|
+
});
|
|
152
|
+
cache.set(cacheKey, { value: promise, timestamp: Date.now() });
|
|
153
|
+
trimToSize();
|
|
154
|
+
cleanExpiredItems();
|
|
155
|
+
},
|
|
156
|
+
cleanExpiredItems,
|
|
117
157
|
/** @internal */
|
|
118
|
-
"
|
|
158
|
+
" cache": { map: cache }
|
|
119
159
|
};
|
|
120
160
|
}
|
|
121
161
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/cache.d.cts
CHANGED
|
@@ -13,19 +13,27 @@ type Options = {
|
|
|
13
13
|
maxItemAge?: number;
|
|
14
14
|
/**
|
|
15
15
|
* The throttle for checking expired items in milliseconds.
|
|
16
|
-
* @default
|
|
16
|
+
* @default
|
|
17
|
+
* 10_000
|
|
17
18
|
*/
|
|
18
19
|
expirationThrottle?: number;
|
|
19
20
|
};
|
|
20
|
-
|
|
21
|
-
getOrInsert:
|
|
22
|
-
getOrInsertAsync:
|
|
21
|
+
type Cache<T> = {
|
|
22
|
+
getOrInsert: (cacheKey: string, val: () => T) => T;
|
|
23
|
+
getOrInsertAsync: (cacheKey: string, val: () => Promise<T>) => Promise<T>;
|
|
23
24
|
clear: () => void;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
get: (cacheKey: string) => T | undefined;
|
|
26
|
+
set: (cacheKey: string, value: T) => void;
|
|
27
|
+
cleanExpiredItems: () => void;
|
|
28
|
+
getAsync: (cacheKey: string) => Promise<T | undefined>;
|
|
29
|
+
setAsync: (cacheKey: string, value: () => Promise<T>) => void;
|
|
30
|
+
[' cache']: {
|
|
31
|
+
map: Map<string, {
|
|
32
|
+
value: T | Promise<T>;
|
|
33
|
+
timestamp: number;
|
|
34
|
+
}>;
|
|
35
|
+
};
|
|
29
36
|
};
|
|
37
|
+
declare function createCache<T>({ maxCacheSize, maxItemAge, expirationThrottle, }?: Options): Cache<T>;
|
|
30
38
|
|
|
31
|
-
export { cachedGetter, createCache };
|
|
39
|
+
export { type Cache, cachedGetter, createCache };
|
package/dist/cache.d.ts
CHANGED
|
@@ -13,19 +13,27 @@ type Options = {
|
|
|
13
13
|
maxItemAge?: number;
|
|
14
14
|
/**
|
|
15
15
|
* The throttle for checking expired items in milliseconds.
|
|
16
|
-
* @default
|
|
16
|
+
* @default
|
|
17
|
+
* 10_000
|
|
17
18
|
*/
|
|
18
19
|
expirationThrottle?: number;
|
|
19
20
|
};
|
|
20
|
-
|
|
21
|
-
getOrInsert:
|
|
22
|
-
getOrInsertAsync:
|
|
21
|
+
type Cache<T> = {
|
|
22
|
+
getOrInsert: (cacheKey: string, val: () => T) => T;
|
|
23
|
+
getOrInsertAsync: (cacheKey: string, val: () => Promise<T>) => Promise<T>;
|
|
23
24
|
clear: () => void;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
get: (cacheKey: string) => T | undefined;
|
|
26
|
+
set: (cacheKey: string, value: T) => void;
|
|
27
|
+
cleanExpiredItems: () => void;
|
|
28
|
+
getAsync: (cacheKey: string) => Promise<T | undefined>;
|
|
29
|
+
setAsync: (cacheKey: string, value: () => Promise<T>) => void;
|
|
30
|
+
[' cache']: {
|
|
31
|
+
map: Map<string, {
|
|
32
|
+
value: T | Promise<T>;
|
|
33
|
+
timestamp: number;
|
|
34
|
+
}>;
|
|
35
|
+
};
|
|
29
36
|
};
|
|
37
|
+
declare function createCache<T>({ maxCacheSize, maxItemAge, expirationThrottle, }?: Options): Cache<T>;
|
|
30
38
|
|
|
31
|
-
export { cachedGetter, createCache };
|
|
39
|
+
export { type Cache, cachedGetter, createCache };
|
package/dist/cache.js
CHANGED
|
@@ -19,7 +19,7 @@ function createCache({
|
|
|
19
19
|
} = {}) {
|
|
20
20
|
const cache = /* @__PURE__ */ new Map();
|
|
21
21
|
let lastExpirationCheck = 0;
|
|
22
|
-
function
|
|
22
|
+
function cleanExpiredItems() {
|
|
23
23
|
const now = Date.now();
|
|
24
24
|
if (!maxItemAge || now - lastExpirationCheck < expirationThrottle) return;
|
|
25
25
|
lastExpirationCheck = now;
|
|
@@ -46,45 +46,85 @@ function createCache({
|
|
|
46
46
|
function isExpired(timestamp, now) {
|
|
47
47
|
return maxItemAge !== void 0 && now - timestamp > maxItemAge * 1e3;
|
|
48
48
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
49
|
+
return {
|
|
50
|
+
getOrInsert(cacheKey, val) {
|
|
51
|
+
const now = Date.now();
|
|
52
|
+
const entry = cache.get(cacheKey);
|
|
53
|
+
if (!entry || isExpired(entry.timestamp, now)) {
|
|
54
|
+
const value = val();
|
|
55
|
+
cache.set(cacheKey, { value, timestamp: now });
|
|
56
|
+
trimToSize();
|
|
57
|
+
cleanExpiredItems();
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
if (isPromise(entry.value)) {
|
|
61
|
+
throw new Error(
|
|
62
|
+
"Cache value is a promise, use getOrInsertAsync instead"
|
|
63
|
+
);
|
|
64
|
+
}
|
|
64
65
|
return entry.value;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
},
|
|
67
|
+
async getOrInsertAsync(cacheKey, val) {
|
|
68
|
+
const entry = cache.get(cacheKey);
|
|
69
|
+
if (entry && isPromise(entry.value)) {
|
|
70
|
+
return entry.value;
|
|
71
|
+
}
|
|
72
|
+
const now = Date.now();
|
|
73
|
+
if (entry && !isExpired(entry.timestamp, now)) {
|
|
74
|
+
return entry.value;
|
|
75
|
+
}
|
|
76
|
+
const promise = val().then((result) => {
|
|
77
|
+
cache.set(cacheKey, { value: result, timestamp: Date.now() });
|
|
78
|
+
return result;
|
|
79
|
+
}).catch((error) => {
|
|
80
|
+
cache.delete(cacheKey);
|
|
81
|
+
throw error;
|
|
82
|
+
});
|
|
83
|
+
cache.set(cacheKey, { value: promise, timestamp: now });
|
|
84
|
+
trimToSize();
|
|
85
|
+
cleanExpiredItems();
|
|
86
|
+
return promise;
|
|
87
|
+
},
|
|
88
|
+
clear() {
|
|
89
|
+
cache.clear();
|
|
90
|
+
},
|
|
91
|
+
get(cacheKey) {
|
|
92
|
+
const entry = cache.get(cacheKey);
|
|
93
|
+
if (!entry || isExpired(entry.timestamp, Date.now())) {
|
|
94
|
+
return void 0;
|
|
95
|
+
}
|
|
96
|
+
if (isPromise(entry.value)) {
|
|
97
|
+
throw new Error("Cache value is a promise, use getAsync instead");
|
|
98
|
+
}
|
|
68
99
|
return entry.value;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
cache.set(cacheKey, { value
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
100
|
+
},
|
|
101
|
+
set(cacheKey, value) {
|
|
102
|
+
cache.set(cacheKey, { value, timestamp: Date.now() });
|
|
103
|
+
trimToSize();
|
|
104
|
+
cleanExpiredItems();
|
|
105
|
+
},
|
|
106
|
+
async getAsync(cacheKey) {
|
|
107
|
+
const entry = cache.get(cacheKey);
|
|
108
|
+
if (!entry || isExpired(entry.timestamp, Date.now())) {
|
|
109
|
+
return void 0;
|
|
110
|
+
}
|
|
111
|
+
return await entry.value;
|
|
112
|
+
},
|
|
113
|
+
setAsync(cacheKey, value) {
|
|
114
|
+
const promise = value().then((result) => {
|
|
115
|
+
cache.set(cacheKey, { value: result, timestamp: Date.now() });
|
|
116
|
+
return result;
|
|
117
|
+
}).catch((error) => {
|
|
118
|
+
cache.delete(cacheKey);
|
|
119
|
+
throw error;
|
|
120
|
+
});
|
|
121
|
+
cache.set(cacheKey, { value: promise, timestamp: Date.now() });
|
|
122
|
+
trimToSize();
|
|
123
|
+
cleanExpiredItems();
|
|
124
|
+
},
|
|
125
|
+
cleanExpiredItems,
|
|
86
126
|
/** @internal */
|
|
87
|
-
"
|
|
127
|
+
" cache": { map: cache }
|
|
88
128
|
};
|
|
89
129
|
}
|
|
90
130
|
export {
|