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