@ls-stack/utils 3.41.0 → 3.43.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 CHANGED
@@ -23,7 +23,8 @@ __export(cache_exports, {
23
23
  SkipCaching: () => SkipCaching,
24
24
  WithExpiration: () => WithExpiration,
25
25
  cachedGetter: () => cachedGetter,
26
- createCache: () => createCache
26
+ createCache: () => createCache,
27
+ fastCache: () => fastCache
27
28
  });
28
29
  module.exports = __toCommonJS(cache_exports);
29
30
 
@@ -258,10 +259,31 @@ function createCache({
258
259
  " cache": { map: cache }
259
260
  };
260
261
  }
262
+ function fastCache({ maxCacheSize = 1e3 } = {}) {
263
+ const cache = /* @__PURE__ */ new Map();
264
+ function trimCache() {
265
+ const cacheSize = cache.size;
266
+ if (cacheSize > maxCacheSize) {
267
+ const keys = Array.from(cache.keys());
268
+ for (let i = 0; i < cacheSize - maxCacheSize; i++) {
269
+ cache.delete(keys[i]);
270
+ }
271
+ }
272
+ }
273
+ function getOrInsert(cacheKey, val) {
274
+ if (!cache.has(cacheKey)) {
275
+ cache.set(cacheKey, val());
276
+ trimCache();
277
+ }
278
+ return cache.get(cacheKey);
279
+ }
280
+ return { getOrInsert, clear: () => cache.clear() };
281
+ }
261
282
  // Annotate the CommonJS export names for ESM import in node:
262
283
  0 && (module.exports = {
263
284
  SkipCaching,
264
285
  WithExpiration,
265
286
  cachedGetter,
266
- createCache
287
+ createCache,
288
+ fastCache
267
289
  });
package/dist/cache.d.cts CHANGED
@@ -74,5 +74,12 @@ type Cache<T> = {
74
74
  };
75
75
  };
76
76
  declare function createCache<T>({ maxCacheSize, maxItemAge, expirationThrottle, }?: Options): Cache<T>;
77
+ type FastCacheOptions = {
78
+ maxCacheSize?: number;
79
+ };
80
+ declare function fastCache<T>({ maxCacheSize }?: FastCacheOptions): {
81
+ getOrInsert: (cacheKey: string, val: () => T) => T;
82
+ clear: () => void;
83
+ };
77
84
 
78
- export { type Cache, SkipCaching, WithExpiration, cachedGetter, createCache };
85
+ export { type Cache, SkipCaching, WithExpiration, cachedGetter, createCache, fastCache };
package/dist/cache.d.ts CHANGED
@@ -74,5 +74,12 @@ type Cache<T> = {
74
74
  };
75
75
  };
76
76
  declare function createCache<T>({ maxCacheSize, maxItemAge, expirationThrottle, }?: Options): Cache<T>;
77
+ type FastCacheOptions = {
78
+ maxCacheSize?: number;
79
+ };
80
+ declare function fastCache<T>({ maxCacheSize }?: FastCacheOptions): {
81
+ getOrInsert: (cacheKey: string, val: () => T) => T;
82
+ clear: () => void;
83
+ };
77
84
 
78
- export { type Cache, SkipCaching, WithExpiration, cachedGetter, createCache };
85
+ export { type Cache, SkipCaching, WithExpiration, cachedGetter, createCache, fastCache };
package/dist/cache.js CHANGED
@@ -1,217 +1,19 @@
1
1
  import {
2
- durationObjToMs
3
- } from "./chunk-5MNYPLZI.js";
2
+ SkipCaching,
3
+ WithExpiration,
4
+ cachedGetter,
5
+ createCache,
6
+ fastCache
7
+ } from "./chunk-OIAGLRII.js";
8
+ import "./chunk-5MNYPLZI.js";
4
9
  import "./chunk-HTCYUMDR.js";
5
10
  import "./chunk-II4R3VVX.js";
6
- import {
7
- isPromise
8
- } from "./chunk-C2SVCIWE.js";
11
+ import "./chunk-C2SVCIWE.js";
9
12
  import "./chunk-JF2MDHOJ.js";
10
-
11
- // src/cache.ts
12
- function cachedGetter(getter) {
13
- return {
14
- get value() {
15
- const value = getter();
16
- Object.defineProperty(this, "value", { value });
17
- return value;
18
- }
19
- };
20
- }
21
- var SkipCaching = class {
22
- value;
23
- constructor(value) {
24
- this.value = value;
25
- }
26
- };
27
- var WithExpiration = class {
28
- value;
29
- expiration;
30
- /**
31
- * @param value - The value to store in the cache.
32
- * @param expiration - The expiration time of the value in seconds or a
33
- * duration object.
34
- */
35
- constructor(value, expiration) {
36
- this.value = value;
37
- this.expiration = durationObjToMs(expiration);
38
- }
39
- };
40
- function createCache({
41
- maxCacheSize = 1e3,
42
- maxItemAge,
43
- expirationThrottle = 1e4
44
- } = {}) {
45
- const cache = /* @__PURE__ */ new Map();
46
- let lastExpirationCheck = 0;
47
- const defaultMaxItemAgeMs = maxItemAge && durationObjToMs(maxItemAge);
48
- function cleanExpiredItems() {
49
- const now = Date.now();
50
- if (!defaultMaxItemAgeMs || now - lastExpirationCheck < expirationThrottle)
51
- return;
52
- lastExpirationCheck = now;
53
- for (const [key, item] of cache.entries()) {
54
- if (isExpired(item, now)) {
55
- cache.delete(key);
56
- }
57
- }
58
- }
59
- function trimToSize() {
60
- const currentSize = cache.size;
61
- if (currentSize > maxCacheSize) {
62
- const keysToRemove = currentSize - maxCacheSize;
63
- const iterator = cache.keys();
64
- for (let i = 0; i < keysToRemove; i++) {
65
- const { value: key } = iterator.next();
66
- if (key) {
67
- cache.delete(key);
68
- }
69
- }
70
- }
71
- }
72
- function isExpired(entry, now) {
73
- const maxItemAgeMs = entry.expiration ?? defaultMaxItemAgeMs;
74
- return !!maxItemAgeMs && now - entry.timestamp > maxItemAgeMs;
75
- }
76
- function unwrapValue(value, now) {
77
- if (value instanceof WithExpiration) {
78
- return {
79
- value: value.value,
80
- timestamp: now,
81
- expiration: value.expiration ? typeof value.expiration === "number" ? value.expiration : now + durationObjToMs(value.expiration) : void 0
82
- };
83
- }
84
- return { value, timestamp: now, expiration: void 0 };
85
- }
86
- const utils = {
87
- skipCaching: (value) => new SkipCaching(value),
88
- withExpiration: (value, expiration) => {
89
- return new WithExpiration(value, expiration);
90
- }
91
- };
92
- return {
93
- getOrInsert(cacheKey, val, options) {
94
- const now = Date.now();
95
- const entry = cache.get(cacheKey);
96
- if (!entry || isExpired(entry, now)) {
97
- const value = val(utils);
98
- if (value instanceof SkipCaching) {
99
- return value.value;
100
- }
101
- if (options?.skipCachingWhen?.(value)) {
102
- return value;
103
- }
104
- const unwrappedValue = unwrapValue(value, now);
105
- cache.set(cacheKey, unwrappedValue);
106
- trimToSize();
107
- cleanExpiredItems();
108
- return unwrappedValue.value;
109
- }
110
- if (isPromise(entry.value)) {
111
- throw new Error(
112
- "Cache value is a promise, use getOrInsertAsync instead"
113
- );
114
- }
115
- return entry.value;
116
- },
117
- async getOrInsertAsync(cacheKey, val, options) {
118
- const entry = cache.get(cacheKey);
119
- if (entry && isPromise(entry.value)) {
120
- return entry.value;
121
- }
122
- const now = Date.now();
123
- if (entry && !isExpired(entry, now)) {
124
- return entry.value;
125
- }
126
- const promise = val(utils).then((result) => {
127
- if (result instanceof SkipCaching) {
128
- const cacheValue = cache.get(cacheKey);
129
- if (cacheValue?.value === promise) {
130
- cache.delete(cacheKey);
131
- }
132
- return result.value;
133
- }
134
- if (options?.skipCachingWhen?.(result)) {
135
- const cacheValue = cache.get(cacheKey);
136
- if (cacheValue?.value === promise) {
137
- cache.delete(cacheKey);
138
- }
139
- return result;
140
- }
141
- const unwrappedValue = unwrapValue(result, Date.now());
142
- cache.set(cacheKey, unwrappedValue);
143
- return unwrappedValue.value;
144
- }).catch((error) => {
145
- cache.delete(cacheKey);
146
- throw error;
147
- });
148
- cache.set(cacheKey, {
149
- value: promise,
150
- timestamp: now,
151
- expiration: void 0
152
- });
153
- trimToSize();
154
- cleanExpiredItems();
155
- return promise;
156
- },
157
- clear() {
158
- cache.clear();
159
- },
160
- get(cacheKey) {
161
- const entry = cache.get(cacheKey);
162
- if (!entry || isExpired(entry, Date.now())) {
163
- return void 0;
164
- }
165
- if (isPromise(entry.value)) {
166
- throw new Error("Cache value is a promise, use getAsync instead");
167
- }
168
- return entry.value;
169
- },
170
- set(cacheKey, value) {
171
- cache.set(cacheKey, unwrapValue(value, Date.now()));
172
- trimToSize();
173
- cleanExpiredItems();
174
- },
175
- async getAsync(cacheKey) {
176
- const entry = cache.get(cacheKey);
177
- if (!entry || isExpired(entry, Date.now())) {
178
- return void 0;
179
- }
180
- return entry.value;
181
- },
182
- async setAsync(cacheKey, value) {
183
- const promise = value(utils).then((result) => {
184
- if (result instanceof SkipCaching) {
185
- const cacheValue = cache.get(cacheKey);
186
- if (cacheValue?.value === promise) {
187
- cache.delete(cacheKey);
188
- }
189
- return result.value;
190
- }
191
- const unwrappedValue = unwrapValue(result, Date.now());
192
- cache.set(cacheKey, unwrappedValue);
193
- return unwrappedValue.value;
194
- }).catch((error) => {
195
- cache.delete(cacheKey);
196
- throw error;
197
- });
198
- cache.set(cacheKey, {
199
- value: promise,
200
- timestamp: Date.now(),
201
- expiration: void 0
202
- });
203
- trimToSize();
204
- cleanExpiredItems();
205
- return promise;
206
- },
207
- cleanExpiredItems,
208
- /** @internal */
209
- " cache": { map: cache }
210
- };
211
- }
212
13
  export {
213
14
  SkipCaching,
214
15
  WithExpiration,
215
16
  cachedGetter,
216
- createCache
17
+ createCache,
18
+ fastCache
217
19
  };
@@ -5,6 +5,9 @@ function asNonPartial(obj) {
5
5
  function typedObjectEntries(obj) {
6
6
  return Object.entries(obj);
7
7
  }
8
+ function strictTypedObjectEntries(obj) {
9
+ return Object.entries(obj);
10
+ }
8
11
  function typedObjectKeys(obj) {
9
12
  return Object.keys(obj);
10
13
  }
@@ -33,10 +36,17 @@ function unionsAreTheSame(_diff) {
33
36
  function asPartialUndefinedValues(value) {
34
37
  return value;
35
38
  }
39
+ function isNonEmptyArray(array) {
40
+ return array.length > 0;
41
+ }
42
+ function objectHasKey(obj, key) {
43
+ return key in obj;
44
+ }
36
45
 
37
46
  export {
38
47
  asNonPartial,
39
48
  typedObjectEntries,
49
+ strictTypedObjectEntries,
40
50
  typedObjectKeys,
41
51
  asType,
42
52
  narrowStringToUnion,
@@ -44,5 +54,7 @@ export {
44
54
  isSubTypeOf,
45
55
  isObjKey,
46
56
  unionsAreTheSame,
47
- asPartialUndefinedValues
57
+ asPartialUndefinedValues,
58
+ isNonEmptyArray,
59
+ objectHasKey
48
60
  };
@@ -0,0 +1,236 @@
1
+ import {
2
+ durationObjToMs
3
+ } from "./chunk-5MNYPLZI.js";
4
+ import {
5
+ isPromise
6
+ } from "./chunk-C2SVCIWE.js";
7
+
8
+ // src/cache.ts
9
+ function cachedGetter(getter) {
10
+ return {
11
+ get value() {
12
+ const value = getter();
13
+ Object.defineProperty(this, "value", { value });
14
+ return value;
15
+ }
16
+ };
17
+ }
18
+ var SkipCaching = class {
19
+ value;
20
+ constructor(value) {
21
+ this.value = value;
22
+ }
23
+ };
24
+ var WithExpiration = class {
25
+ value;
26
+ expiration;
27
+ /**
28
+ * @param value - The value to store in the cache.
29
+ * @param expiration - The expiration time of the value in seconds or a
30
+ * duration object.
31
+ */
32
+ constructor(value, expiration) {
33
+ this.value = value;
34
+ this.expiration = durationObjToMs(expiration);
35
+ }
36
+ };
37
+ function createCache({
38
+ maxCacheSize = 1e3,
39
+ maxItemAge,
40
+ expirationThrottle = 1e4
41
+ } = {}) {
42
+ const cache = /* @__PURE__ */ new Map();
43
+ let lastExpirationCheck = 0;
44
+ const defaultMaxItemAgeMs = maxItemAge && durationObjToMs(maxItemAge);
45
+ function cleanExpiredItems() {
46
+ const now = Date.now();
47
+ if (!defaultMaxItemAgeMs || now - lastExpirationCheck < expirationThrottle)
48
+ return;
49
+ lastExpirationCheck = now;
50
+ for (const [key, item] of cache.entries()) {
51
+ if (isExpired(item, now)) {
52
+ cache.delete(key);
53
+ }
54
+ }
55
+ }
56
+ function trimToSize() {
57
+ const currentSize = cache.size;
58
+ if (currentSize > maxCacheSize) {
59
+ const keysToRemove = currentSize - maxCacheSize;
60
+ const iterator = cache.keys();
61
+ for (let i = 0; i < keysToRemove; i++) {
62
+ const { value: key } = iterator.next();
63
+ if (key) {
64
+ cache.delete(key);
65
+ }
66
+ }
67
+ }
68
+ }
69
+ function isExpired(entry, now) {
70
+ const maxItemAgeMs = entry.expiration ?? defaultMaxItemAgeMs;
71
+ return !!maxItemAgeMs && now - entry.timestamp > maxItemAgeMs;
72
+ }
73
+ function unwrapValue(value, now) {
74
+ if (value instanceof WithExpiration) {
75
+ return {
76
+ value: value.value,
77
+ timestamp: now,
78
+ expiration: value.expiration ? typeof value.expiration === "number" ? value.expiration : now + durationObjToMs(value.expiration) : void 0
79
+ };
80
+ }
81
+ return { value, timestamp: now, expiration: void 0 };
82
+ }
83
+ const utils = {
84
+ skipCaching: (value) => new SkipCaching(value),
85
+ withExpiration: (value, expiration) => {
86
+ return new WithExpiration(value, expiration);
87
+ }
88
+ };
89
+ return {
90
+ getOrInsert(cacheKey, val, options) {
91
+ const now = Date.now();
92
+ const entry = cache.get(cacheKey);
93
+ if (!entry || isExpired(entry, now)) {
94
+ const value = val(utils);
95
+ if (value instanceof SkipCaching) {
96
+ return value.value;
97
+ }
98
+ if (options?.skipCachingWhen?.(value)) {
99
+ return value;
100
+ }
101
+ const unwrappedValue = unwrapValue(value, now);
102
+ cache.set(cacheKey, unwrappedValue);
103
+ trimToSize();
104
+ cleanExpiredItems();
105
+ return unwrappedValue.value;
106
+ }
107
+ if (isPromise(entry.value)) {
108
+ throw new Error(
109
+ "Cache value is a promise, use getOrInsertAsync instead"
110
+ );
111
+ }
112
+ return entry.value;
113
+ },
114
+ async getOrInsertAsync(cacheKey, val, options) {
115
+ const entry = cache.get(cacheKey);
116
+ if (entry && isPromise(entry.value)) {
117
+ return entry.value;
118
+ }
119
+ const now = Date.now();
120
+ if (entry && !isExpired(entry, now)) {
121
+ return entry.value;
122
+ }
123
+ const promise = val(utils).then((result) => {
124
+ if (result instanceof SkipCaching) {
125
+ const cacheValue = cache.get(cacheKey);
126
+ if (cacheValue?.value === promise) {
127
+ cache.delete(cacheKey);
128
+ }
129
+ return result.value;
130
+ }
131
+ if (options?.skipCachingWhen?.(result)) {
132
+ const cacheValue = cache.get(cacheKey);
133
+ if (cacheValue?.value === promise) {
134
+ cache.delete(cacheKey);
135
+ }
136
+ return result;
137
+ }
138
+ const unwrappedValue = unwrapValue(result, Date.now());
139
+ cache.set(cacheKey, unwrappedValue);
140
+ return unwrappedValue.value;
141
+ }).catch((error) => {
142
+ cache.delete(cacheKey);
143
+ throw error;
144
+ });
145
+ cache.set(cacheKey, {
146
+ value: promise,
147
+ timestamp: now,
148
+ expiration: void 0
149
+ });
150
+ trimToSize();
151
+ cleanExpiredItems();
152
+ return promise;
153
+ },
154
+ clear() {
155
+ cache.clear();
156
+ },
157
+ get(cacheKey) {
158
+ const entry = cache.get(cacheKey);
159
+ if (!entry || isExpired(entry, Date.now())) {
160
+ return void 0;
161
+ }
162
+ if (isPromise(entry.value)) {
163
+ throw new Error("Cache value is a promise, use getAsync instead");
164
+ }
165
+ return entry.value;
166
+ },
167
+ set(cacheKey, value) {
168
+ cache.set(cacheKey, unwrapValue(value, Date.now()));
169
+ trimToSize();
170
+ cleanExpiredItems();
171
+ },
172
+ async getAsync(cacheKey) {
173
+ const entry = cache.get(cacheKey);
174
+ if (!entry || isExpired(entry, Date.now())) {
175
+ return void 0;
176
+ }
177
+ return entry.value;
178
+ },
179
+ async setAsync(cacheKey, value) {
180
+ const promise = value(utils).then((result) => {
181
+ if (result instanceof SkipCaching) {
182
+ const cacheValue = cache.get(cacheKey);
183
+ if (cacheValue?.value === promise) {
184
+ cache.delete(cacheKey);
185
+ }
186
+ return result.value;
187
+ }
188
+ const unwrappedValue = unwrapValue(result, Date.now());
189
+ cache.set(cacheKey, unwrappedValue);
190
+ return unwrappedValue.value;
191
+ }).catch((error) => {
192
+ cache.delete(cacheKey);
193
+ throw error;
194
+ });
195
+ cache.set(cacheKey, {
196
+ value: promise,
197
+ timestamp: Date.now(),
198
+ expiration: void 0
199
+ });
200
+ trimToSize();
201
+ cleanExpiredItems();
202
+ return promise;
203
+ },
204
+ cleanExpiredItems,
205
+ /** @internal */
206
+ " cache": { map: cache }
207
+ };
208
+ }
209
+ function fastCache({ maxCacheSize = 1e3 } = {}) {
210
+ const cache = /* @__PURE__ */ new Map();
211
+ function trimCache() {
212
+ const cacheSize = cache.size;
213
+ if (cacheSize > maxCacheSize) {
214
+ const keys = Array.from(cache.keys());
215
+ for (let i = 0; i < cacheSize - maxCacheSize; i++) {
216
+ cache.delete(keys[i]);
217
+ }
218
+ }
219
+ }
220
+ function getOrInsert(cacheKey, val) {
221
+ if (!cache.has(cacheKey)) {
222
+ cache.set(cacheKey, val());
223
+ trimCache();
224
+ }
225
+ return cache.get(cacheKey);
226
+ }
227
+ return { getOrInsert, clear: () => cache.clear() };
228
+ }
229
+
230
+ export {
231
+ cachedGetter,
232
+ SkipCaching,
233
+ WithExpiration,
234
+ createCache,
235
+ fastCache
236
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  typedObjectEntries
3
- } from "./chunk-DTE2QMWE.js";
3
+ } from "./chunk-GMJTLFM6.js";
4
4
  import {
5
5
  sortBy
6
6
  } from "./chunk-27AL66CH.js";
@@ -1,12 +1,12 @@
1
+ import {
2
+ safeJsonStringify
3
+ } from "./chunk-VAAMRG4K.js";
1
4
  import {
2
5
  truncateString
3
6
  } from "./chunk-B3KFV2MH.js";
4
7
  import {
5
8
  sleep
6
9
  } from "./chunk-5DZT3Z5Z.js";
7
- import {
8
- safeJsonStringify
9
- } from "./chunk-VAAMRG4K.js";
10
10
  import {
11
11
  truncateArray
12
12
  } from "./chunk-27AL66CH.js";