@ls-stack/utils 2.12.0 → 2.14.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 -24
- package/dist/cache.d.cts +36 -11
- package/dist/cache.d.ts +36 -11
- package/dist/cache.js +86 -24
- package/dist/chunk-RK6PT7JY.js +96 -0
- package/dist/createThrottleController.cjs +17 -10
- package/dist/createThrottleController.d.cts +3 -6
- package/dist/createThrottleController.d.ts +3 -6
- package/dist/createThrottleController.js +6 -10
- package/dist/testUtils.js +3 -3
- package/dist/time.cjs +5 -0
- package/dist/time.d.cts +9 -1
- package/dist/time.d.ts +9 -1
- package/dist/time.js +20 -73
- package/package.json +4 -4
package/dist/cache.cjs
CHANGED
|
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var cache_exports = {};
|
|
22
22
|
__export(cache_exports, {
|
|
23
23
|
RejectValue: () => RejectValue,
|
|
24
|
+
WithExpiration: () => WithExpiration,
|
|
24
25
|
cachedGetter: () => cachedGetter,
|
|
25
26
|
createCache: () => createCache
|
|
26
27
|
});
|
|
@@ -34,6 +35,22 @@ function isPromise(value) {
|
|
|
34
35
|
return isObject(value) && "then" in value;
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
// src/time.ts
|
|
39
|
+
var MINUTE_AS_MS = 60 * 1e3;
|
|
40
|
+
var HOUR_AS_MS = 60 * MINUTE_AS_MS;
|
|
41
|
+
var DAY_AS_MS = 24 * HOUR_AS_MS;
|
|
42
|
+
var WEEK_AS_MS = 7 * DAY_AS_MS;
|
|
43
|
+
var MONTH_AS_MS = 30 * DAY_AS_MS;
|
|
44
|
+
var YEAR_AS_MS = 365 * DAY_AS_MS;
|
|
45
|
+
var HOUR_AS_SECS = 60 * 60;
|
|
46
|
+
var DAY_AS_SECS = 24 * HOUR_AS_SECS;
|
|
47
|
+
var WEEK_AS_SECS = 7 * DAY_AS_SECS;
|
|
48
|
+
var MONTH_AS_SECS = 30 * DAY_AS_SECS;
|
|
49
|
+
var YEAR_AS_SECS = 365 * DAY_AS_SECS;
|
|
50
|
+
function durationObjToMs(durationObj) {
|
|
51
|
+
return (durationObj.hours ?? 0) * HOUR_AS_MS + (durationObj.minutes ?? 0) * MINUTE_AS_MS + (durationObj.seconds ?? 0) * 1e3 + (durationObj.ms ?? 0) + (durationObj.days ?? 0) * DAY_AS_MS;
|
|
52
|
+
}
|
|
53
|
+
|
|
37
54
|
// src/cache.ts
|
|
38
55
|
function cachedGetter(getter) {
|
|
39
56
|
return {
|
|
@@ -50,6 +67,18 @@ var RejectValue = class {
|
|
|
50
67
|
this.value = value;
|
|
51
68
|
}
|
|
52
69
|
};
|
|
70
|
+
var WithExpiration = class {
|
|
71
|
+
value;
|
|
72
|
+
expiration;
|
|
73
|
+
/**
|
|
74
|
+
* @param value - The value to store in the cache.
|
|
75
|
+
* @param expiration - The expiration time of the value in seconds or a duration object.
|
|
76
|
+
*/
|
|
77
|
+
constructor(value, expiration) {
|
|
78
|
+
this.value = value;
|
|
79
|
+
this.expiration = durationObjToMs(expiration);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
53
82
|
function createCache({
|
|
54
83
|
maxCacheSize = 1e3,
|
|
55
84
|
maxItemAge,
|
|
@@ -57,13 +86,14 @@ function createCache({
|
|
|
57
86
|
} = {}) {
|
|
58
87
|
const cache = /* @__PURE__ */ new Map();
|
|
59
88
|
let lastExpirationCheck = 0;
|
|
89
|
+
const defaultMaxItemAgeMs = maxItemAge && durationObjToMs(maxItemAge);
|
|
60
90
|
function cleanExpiredItems() {
|
|
61
91
|
const now = Date.now();
|
|
62
|
-
if (!
|
|
92
|
+
if (!defaultMaxItemAgeMs || now - lastExpirationCheck < expirationThrottle)
|
|
93
|
+
return;
|
|
63
94
|
lastExpirationCheck = now;
|
|
64
|
-
const maxAgeMs = maxItemAge * 1e3;
|
|
65
95
|
for (const [key, item] of cache.entries()) {
|
|
66
|
-
if (
|
|
96
|
+
if (isExpired(item, now)) {
|
|
67
97
|
cache.delete(key);
|
|
68
98
|
}
|
|
69
99
|
}
|
|
@@ -81,25 +111,43 @@ function createCache({
|
|
|
81
111
|
}
|
|
82
112
|
}
|
|
83
113
|
}
|
|
84
|
-
function isExpired(
|
|
85
|
-
|
|
114
|
+
function isExpired(entry, now) {
|
|
115
|
+
const maxItemAgeMs = entry.expiration ?? defaultMaxItemAgeMs;
|
|
116
|
+
return !!maxItemAgeMs && now - entry.timestamp > maxItemAgeMs;
|
|
117
|
+
}
|
|
118
|
+
function unwrapValue(value, now) {
|
|
119
|
+
if (value instanceof WithExpiration) {
|
|
120
|
+
return {
|
|
121
|
+
value: value.value,
|
|
122
|
+
timestamp: now,
|
|
123
|
+
expiration: value.expiration ? typeof value.expiration === "number" ? value.expiration : now + durationObjToMs(value.expiration) : void 0
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
return { value, timestamp: now, expiration: void 0 };
|
|
86
127
|
}
|
|
87
128
|
const utils = {
|
|
88
|
-
reject: (value) => new RejectValue(value)
|
|
129
|
+
reject: (value) => new RejectValue(value),
|
|
130
|
+
withExpiration: (value, expiration) => {
|
|
131
|
+
return new WithExpiration(value, expiration);
|
|
132
|
+
}
|
|
89
133
|
};
|
|
90
134
|
return {
|
|
91
|
-
getOrInsert(cacheKey, val) {
|
|
135
|
+
getOrInsert(cacheKey, val, options) {
|
|
92
136
|
const now = Date.now();
|
|
93
137
|
const entry = cache.get(cacheKey);
|
|
94
|
-
if (!entry || isExpired(entry
|
|
138
|
+
if (!entry || isExpired(entry, now)) {
|
|
95
139
|
const value = val(utils);
|
|
96
140
|
if (value instanceof RejectValue) {
|
|
97
141
|
return value.value;
|
|
98
142
|
}
|
|
99
|
-
|
|
143
|
+
if (options?.rejectWhen?.(value)) {
|
|
144
|
+
return value;
|
|
145
|
+
}
|
|
146
|
+
const unwrappedValue = unwrapValue(value, now);
|
|
147
|
+
cache.set(cacheKey, unwrappedValue);
|
|
100
148
|
trimToSize();
|
|
101
149
|
cleanExpiredItems();
|
|
102
|
-
return value;
|
|
150
|
+
return unwrappedValue.value;
|
|
103
151
|
}
|
|
104
152
|
if (isPromise(entry.value)) {
|
|
105
153
|
throw new Error(
|
|
@@ -108,13 +156,13 @@ function createCache({
|
|
|
108
156
|
}
|
|
109
157
|
return entry.value;
|
|
110
158
|
},
|
|
111
|
-
async getOrInsertAsync(cacheKey, val) {
|
|
159
|
+
async getOrInsertAsync(cacheKey, val, options) {
|
|
112
160
|
const entry = cache.get(cacheKey);
|
|
113
161
|
if (entry && isPromise(entry.value)) {
|
|
114
162
|
return entry.value;
|
|
115
163
|
}
|
|
116
164
|
const now = Date.now();
|
|
117
|
-
if (entry && !isExpired(entry
|
|
165
|
+
if (entry && !isExpired(entry, now)) {
|
|
118
166
|
return entry.value;
|
|
119
167
|
}
|
|
120
168
|
const promise = val(utils).then((result) => {
|
|
@@ -125,13 +173,25 @@ function createCache({
|
|
|
125
173
|
}
|
|
126
174
|
return result.value;
|
|
127
175
|
}
|
|
128
|
-
|
|
129
|
-
|
|
176
|
+
if (options?.rejectWhen?.(result)) {
|
|
177
|
+
const cacheValue = cache.get(cacheKey);
|
|
178
|
+
if (cacheValue?.value === promise) {
|
|
179
|
+
cache.delete(cacheKey);
|
|
180
|
+
}
|
|
181
|
+
return result;
|
|
182
|
+
}
|
|
183
|
+
const unwrappedValue = unwrapValue(result, Date.now());
|
|
184
|
+
cache.set(cacheKey, unwrappedValue);
|
|
185
|
+
return unwrappedValue.value;
|
|
130
186
|
}).catch((error) => {
|
|
131
187
|
cache.delete(cacheKey);
|
|
132
188
|
throw error;
|
|
133
189
|
});
|
|
134
|
-
cache.set(cacheKey, {
|
|
190
|
+
cache.set(cacheKey, {
|
|
191
|
+
value: promise,
|
|
192
|
+
timestamp: now,
|
|
193
|
+
expiration: void 0
|
|
194
|
+
});
|
|
135
195
|
trimToSize();
|
|
136
196
|
cleanExpiredItems();
|
|
137
197
|
return promise;
|
|
@@ -141,7 +201,7 @@ function createCache({
|
|
|
141
201
|
},
|
|
142
202
|
get(cacheKey) {
|
|
143
203
|
const entry = cache.get(cacheKey);
|
|
144
|
-
if (!entry || isExpired(entry
|
|
204
|
+
if (!entry || isExpired(entry, Date.now())) {
|
|
145
205
|
return void 0;
|
|
146
206
|
}
|
|
147
207
|
if (isPromise(entry.value)) {
|
|
@@ -150,28 +210,41 @@ function createCache({
|
|
|
150
210
|
return entry.value;
|
|
151
211
|
},
|
|
152
212
|
set(cacheKey, value) {
|
|
153
|
-
cache.set(cacheKey,
|
|
213
|
+
cache.set(cacheKey, unwrapValue(value, Date.now()));
|
|
154
214
|
trimToSize();
|
|
155
215
|
cleanExpiredItems();
|
|
156
216
|
},
|
|
157
217
|
async getAsync(cacheKey) {
|
|
158
218
|
const entry = cache.get(cacheKey);
|
|
159
|
-
if (!entry || isExpired(entry
|
|
219
|
+
if (!entry || isExpired(entry, Date.now())) {
|
|
160
220
|
return void 0;
|
|
161
221
|
}
|
|
162
|
-
return
|
|
222
|
+
return entry.value;
|
|
163
223
|
},
|
|
164
|
-
setAsync(cacheKey, value) {
|
|
165
|
-
const promise = value().then((result) => {
|
|
166
|
-
|
|
167
|
-
|
|
224
|
+
async setAsync(cacheKey, value) {
|
|
225
|
+
const promise = value(utils).then((result) => {
|
|
226
|
+
if (result instanceof RejectValue) {
|
|
227
|
+
const cacheValue = cache.get(cacheKey);
|
|
228
|
+
if (cacheValue?.value === promise) {
|
|
229
|
+
cache.delete(cacheKey);
|
|
230
|
+
}
|
|
231
|
+
return result.value;
|
|
232
|
+
}
|
|
233
|
+
const unwrappedValue = unwrapValue(result, Date.now());
|
|
234
|
+
cache.set(cacheKey, unwrappedValue);
|
|
235
|
+
return unwrappedValue.value;
|
|
168
236
|
}).catch((error) => {
|
|
169
237
|
cache.delete(cacheKey);
|
|
170
238
|
throw error;
|
|
171
239
|
});
|
|
172
|
-
cache.set(cacheKey, {
|
|
240
|
+
cache.set(cacheKey, {
|
|
241
|
+
value: promise,
|
|
242
|
+
timestamp: Date.now(),
|
|
243
|
+
expiration: void 0
|
|
244
|
+
});
|
|
173
245
|
trimToSize();
|
|
174
246
|
cleanExpiredItems();
|
|
247
|
+
return promise;
|
|
175
248
|
},
|
|
176
249
|
cleanExpiredItems,
|
|
177
250
|
/** @internal */
|
|
@@ -181,6 +254,7 @@ function createCache({
|
|
|
181
254
|
// Annotate the CommonJS export names for ESM import in node:
|
|
182
255
|
0 && (module.exports = {
|
|
183
256
|
RejectValue,
|
|
257
|
+
WithExpiration,
|
|
184
258
|
cachedGetter,
|
|
185
259
|
createCache
|
|
186
260
|
});
|
package/dist/cache.d.cts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { DurationObj } from './time.cjs';
|
|
2
|
+
|
|
1
3
|
declare function cachedGetter<T>(getter: () => T): {
|
|
2
4
|
value: T;
|
|
3
5
|
};
|
|
@@ -8,9 +10,9 @@ type Options = {
|
|
|
8
10
|
*/
|
|
9
11
|
maxCacheSize?: number;
|
|
10
12
|
/**
|
|
11
|
-
* The maximum age of items in the cache
|
|
13
|
+
* The maximum age of items in the cache.
|
|
12
14
|
*/
|
|
13
|
-
maxItemAge?:
|
|
15
|
+
maxItemAge?: DurationObj;
|
|
14
16
|
/**
|
|
15
17
|
* The throttle for checking expired items in milliseconds.
|
|
16
18
|
* @default
|
|
@@ -22,19 +24,42 @@ declare class RejectValue<T> {
|
|
|
22
24
|
value: T;
|
|
23
25
|
constructor(value: T);
|
|
24
26
|
}
|
|
27
|
+
declare class WithExpiration<T> {
|
|
28
|
+
value: T;
|
|
29
|
+
expiration: number;
|
|
30
|
+
/**
|
|
31
|
+
* @param value - The value to store in the cache.
|
|
32
|
+
* @param expiration - The expiration time of the value in seconds or a duration object.
|
|
33
|
+
*/
|
|
34
|
+
constructor(value: T, expiration: DurationObj);
|
|
35
|
+
}
|
|
36
|
+
type Utils<T> = {
|
|
37
|
+
reject: (value: T) => RejectValue<T>;
|
|
38
|
+
/**
|
|
39
|
+
* Create a new WithExpiration object with the given value and expiration time.
|
|
40
|
+
* @param value - The value to store in the cache.
|
|
41
|
+
* @param expiration - The expiration time of the value in seconds or a duration object.
|
|
42
|
+
*/
|
|
43
|
+
withExpiration: (value: T, expiration: DurationObj) => WithExpiration<T>;
|
|
44
|
+
};
|
|
45
|
+
type GetOptions<T> = {
|
|
46
|
+
/**
|
|
47
|
+
* A function that determines whether a value should be rejected from being cached.
|
|
48
|
+
* If the function returns true, the value will be returned but not cached.
|
|
49
|
+
* @param value The value to check
|
|
50
|
+
* @returns true if the value should be rejected, false otherwise
|
|
51
|
+
*/
|
|
52
|
+
rejectWhen?: (value: T) => boolean;
|
|
53
|
+
};
|
|
25
54
|
type Cache<T> = {
|
|
26
|
-
getOrInsert: (cacheKey: string, val: (utils:
|
|
27
|
-
|
|
28
|
-
}) => T | RejectValue<T>) => T;
|
|
29
|
-
getOrInsertAsync: (cacheKey: string, val: (utils: {
|
|
30
|
-
reject: (value: T) => RejectValue<T>;
|
|
31
|
-
}) => Promise<T | RejectValue<T>>) => Promise<T>;
|
|
55
|
+
getOrInsert: (cacheKey: string, val: (utils: Utils<T>) => T | RejectValue<T>, options?: GetOptions<T>) => T;
|
|
56
|
+
getOrInsertAsync: (cacheKey: string, val: (utils: Utils<T>) => Promise<T | RejectValue<T>>, options?: GetOptions<T>) => Promise<T>;
|
|
32
57
|
clear: () => void;
|
|
33
58
|
get: (cacheKey: string) => T | undefined;
|
|
34
|
-
set: (cacheKey: string, value: T) => void;
|
|
59
|
+
set: (cacheKey: string, value: T | WithExpiration<T>) => void;
|
|
35
60
|
cleanExpiredItems: () => void;
|
|
36
61
|
getAsync: (cacheKey: string) => Promise<T | undefined>;
|
|
37
|
-
setAsync: (cacheKey: string, value: () => Promise<T
|
|
62
|
+
setAsync: (cacheKey: string, value: (utils: Utils<T>) => Promise<T | WithExpiration<T>>) => Promise<T>;
|
|
38
63
|
[' cache']: {
|
|
39
64
|
map: Map<string, {
|
|
40
65
|
value: T | Promise<T>;
|
|
@@ -44,4 +69,4 @@ type Cache<T> = {
|
|
|
44
69
|
};
|
|
45
70
|
declare function createCache<T>({ maxCacheSize, maxItemAge, expirationThrottle, }?: Options): Cache<T>;
|
|
46
71
|
|
|
47
|
-
export { type Cache, RejectValue, cachedGetter, createCache };
|
|
72
|
+
export { type Cache, RejectValue, WithExpiration, cachedGetter, createCache };
|
package/dist/cache.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { DurationObj } from './time.js';
|
|
2
|
+
|
|
1
3
|
declare function cachedGetter<T>(getter: () => T): {
|
|
2
4
|
value: T;
|
|
3
5
|
};
|
|
@@ -8,9 +10,9 @@ type Options = {
|
|
|
8
10
|
*/
|
|
9
11
|
maxCacheSize?: number;
|
|
10
12
|
/**
|
|
11
|
-
* The maximum age of items in the cache
|
|
13
|
+
* The maximum age of items in the cache.
|
|
12
14
|
*/
|
|
13
|
-
maxItemAge?:
|
|
15
|
+
maxItemAge?: DurationObj;
|
|
14
16
|
/**
|
|
15
17
|
* The throttle for checking expired items in milliseconds.
|
|
16
18
|
* @default
|
|
@@ -22,19 +24,42 @@ declare class RejectValue<T> {
|
|
|
22
24
|
value: T;
|
|
23
25
|
constructor(value: T);
|
|
24
26
|
}
|
|
27
|
+
declare class WithExpiration<T> {
|
|
28
|
+
value: T;
|
|
29
|
+
expiration: number;
|
|
30
|
+
/**
|
|
31
|
+
* @param value - The value to store in the cache.
|
|
32
|
+
* @param expiration - The expiration time of the value in seconds or a duration object.
|
|
33
|
+
*/
|
|
34
|
+
constructor(value: T, expiration: DurationObj);
|
|
35
|
+
}
|
|
36
|
+
type Utils<T> = {
|
|
37
|
+
reject: (value: T) => RejectValue<T>;
|
|
38
|
+
/**
|
|
39
|
+
* Create a new WithExpiration object with the given value and expiration time.
|
|
40
|
+
* @param value - The value to store in the cache.
|
|
41
|
+
* @param expiration - The expiration time of the value in seconds or a duration object.
|
|
42
|
+
*/
|
|
43
|
+
withExpiration: (value: T, expiration: DurationObj) => WithExpiration<T>;
|
|
44
|
+
};
|
|
45
|
+
type GetOptions<T> = {
|
|
46
|
+
/**
|
|
47
|
+
* A function that determines whether a value should be rejected from being cached.
|
|
48
|
+
* If the function returns true, the value will be returned but not cached.
|
|
49
|
+
* @param value The value to check
|
|
50
|
+
* @returns true if the value should be rejected, false otherwise
|
|
51
|
+
*/
|
|
52
|
+
rejectWhen?: (value: T) => boolean;
|
|
53
|
+
};
|
|
25
54
|
type Cache<T> = {
|
|
26
|
-
getOrInsert: (cacheKey: string, val: (utils:
|
|
27
|
-
|
|
28
|
-
}) => T | RejectValue<T>) => T;
|
|
29
|
-
getOrInsertAsync: (cacheKey: string, val: (utils: {
|
|
30
|
-
reject: (value: T) => RejectValue<T>;
|
|
31
|
-
}) => Promise<T | RejectValue<T>>) => Promise<T>;
|
|
55
|
+
getOrInsert: (cacheKey: string, val: (utils: Utils<T>) => T | RejectValue<T>, options?: GetOptions<T>) => T;
|
|
56
|
+
getOrInsertAsync: (cacheKey: string, val: (utils: Utils<T>) => Promise<T | RejectValue<T>>, options?: GetOptions<T>) => Promise<T>;
|
|
32
57
|
clear: () => void;
|
|
33
58
|
get: (cacheKey: string) => T | undefined;
|
|
34
|
-
set: (cacheKey: string, value: T) => void;
|
|
59
|
+
set: (cacheKey: string, value: T | WithExpiration<T>) => void;
|
|
35
60
|
cleanExpiredItems: () => void;
|
|
36
61
|
getAsync: (cacheKey: string) => Promise<T | undefined>;
|
|
37
|
-
setAsync: (cacheKey: string, value: () => Promise<T
|
|
62
|
+
setAsync: (cacheKey: string, value: (utils: Utils<T>) => Promise<T | WithExpiration<T>>) => Promise<T>;
|
|
38
63
|
[' cache']: {
|
|
39
64
|
map: Map<string, {
|
|
40
65
|
value: T | Promise<T>;
|
|
@@ -44,4 +69,4 @@ type Cache<T> = {
|
|
|
44
69
|
};
|
|
45
70
|
declare function createCache<T>({ maxCacheSize, maxItemAge, expirationThrottle, }?: Options): Cache<T>;
|
|
46
71
|
|
|
47
|
-
export { type Cache, RejectValue, cachedGetter, createCache };
|
|
72
|
+
export { type Cache, RejectValue, WithExpiration, cachedGetter, createCache };
|
package/dist/cache.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
durationObjToMs
|
|
3
|
+
} from "./chunk-RK6PT7JY.js";
|
|
4
|
+
import "./chunk-HTCYUMDR.js";
|
|
1
5
|
import {
|
|
2
6
|
isPromise
|
|
3
7
|
} from "./chunk-4UGSP3L3.js";
|
|
8
|
+
import "./chunk-GBFS2I67.js";
|
|
4
9
|
|
|
5
10
|
// src/cache.ts
|
|
6
11
|
function cachedGetter(getter) {
|
|
@@ -18,6 +23,18 @@ var RejectValue = class {
|
|
|
18
23
|
this.value = value;
|
|
19
24
|
}
|
|
20
25
|
};
|
|
26
|
+
var WithExpiration = class {
|
|
27
|
+
value;
|
|
28
|
+
expiration;
|
|
29
|
+
/**
|
|
30
|
+
* @param value - The value to store in the cache.
|
|
31
|
+
* @param expiration - The expiration time of the value in seconds or a duration object.
|
|
32
|
+
*/
|
|
33
|
+
constructor(value, expiration) {
|
|
34
|
+
this.value = value;
|
|
35
|
+
this.expiration = durationObjToMs(expiration);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
21
38
|
function createCache({
|
|
22
39
|
maxCacheSize = 1e3,
|
|
23
40
|
maxItemAge,
|
|
@@ -25,13 +42,14 @@ function createCache({
|
|
|
25
42
|
} = {}) {
|
|
26
43
|
const cache = /* @__PURE__ */ new Map();
|
|
27
44
|
let lastExpirationCheck = 0;
|
|
45
|
+
const defaultMaxItemAgeMs = maxItemAge && durationObjToMs(maxItemAge);
|
|
28
46
|
function cleanExpiredItems() {
|
|
29
47
|
const now = Date.now();
|
|
30
|
-
if (!
|
|
48
|
+
if (!defaultMaxItemAgeMs || now - lastExpirationCheck < expirationThrottle)
|
|
49
|
+
return;
|
|
31
50
|
lastExpirationCheck = now;
|
|
32
|
-
const maxAgeMs = maxItemAge * 1e3;
|
|
33
51
|
for (const [key, item] of cache.entries()) {
|
|
34
|
-
if (
|
|
52
|
+
if (isExpired(item, now)) {
|
|
35
53
|
cache.delete(key);
|
|
36
54
|
}
|
|
37
55
|
}
|
|
@@ -49,25 +67,43 @@ function createCache({
|
|
|
49
67
|
}
|
|
50
68
|
}
|
|
51
69
|
}
|
|
52
|
-
function isExpired(
|
|
53
|
-
|
|
70
|
+
function isExpired(entry, now) {
|
|
71
|
+
const maxItemAgeMs = entry.expiration ?? defaultMaxItemAgeMs;
|
|
72
|
+
return !!maxItemAgeMs && now - entry.timestamp > maxItemAgeMs;
|
|
73
|
+
}
|
|
74
|
+
function unwrapValue(value, now) {
|
|
75
|
+
if (value instanceof WithExpiration) {
|
|
76
|
+
return {
|
|
77
|
+
value: value.value,
|
|
78
|
+
timestamp: now,
|
|
79
|
+
expiration: value.expiration ? typeof value.expiration === "number" ? value.expiration : now + durationObjToMs(value.expiration) : void 0
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return { value, timestamp: now, expiration: void 0 };
|
|
54
83
|
}
|
|
55
84
|
const utils = {
|
|
56
|
-
reject: (value) => new RejectValue(value)
|
|
85
|
+
reject: (value) => new RejectValue(value),
|
|
86
|
+
withExpiration: (value, expiration) => {
|
|
87
|
+
return new WithExpiration(value, expiration);
|
|
88
|
+
}
|
|
57
89
|
};
|
|
58
90
|
return {
|
|
59
|
-
getOrInsert(cacheKey, val) {
|
|
91
|
+
getOrInsert(cacheKey, val, options) {
|
|
60
92
|
const now = Date.now();
|
|
61
93
|
const entry = cache.get(cacheKey);
|
|
62
|
-
if (!entry || isExpired(entry
|
|
94
|
+
if (!entry || isExpired(entry, now)) {
|
|
63
95
|
const value = val(utils);
|
|
64
96
|
if (value instanceof RejectValue) {
|
|
65
97
|
return value.value;
|
|
66
98
|
}
|
|
67
|
-
|
|
99
|
+
if (options?.rejectWhen?.(value)) {
|
|
100
|
+
return value;
|
|
101
|
+
}
|
|
102
|
+
const unwrappedValue = unwrapValue(value, now);
|
|
103
|
+
cache.set(cacheKey, unwrappedValue);
|
|
68
104
|
trimToSize();
|
|
69
105
|
cleanExpiredItems();
|
|
70
|
-
return value;
|
|
106
|
+
return unwrappedValue.value;
|
|
71
107
|
}
|
|
72
108
|
if (isPromise(entry.value)) {
|
|
73
109
|
throw new Error(
|
|
@@ -76,13 +112,13 @@ function createCache({
|
|
|
76
112
|
}
|
|
77
113
|
return entry.value;
|
|
78
114
|
},
|
|
79
|
-
async getOrInsertAsync(cacheKey, val) {
|
|
115
|
+
async getOrInsertAsync(cacheKey, val, options) {
|
|
80
116
|
const entry = cache.get(cacheKey);
|
|
81
117
|
if (entry && isPromise(entry.value)) {
|
|
82
118
|
return entry.value;
|
|
83
119
|
}
|
|
84
120
|
const now = Date.now();
|
|
85
|
-
if (entry && !isExpired(entry
|
|
121
|
+
if (entry && !isExpired(entry, now)) {
|
|
86
122
|
return entry.value;
|
|
87
123
|
}
|
|
88
124
|
const promise = val(utils).then((result) => {
|
|
@@ -93,13 +129,25 @@ function createCache({
|
|
|
93
129
|
}
|
|
94
130
|
return result.value;
|
|
95
131
|
}
|
|
96
|
-
|
|
97
|
-
|
|
132
|
+
if (options?.rejectWhen?.(result)) {
|
|
133
|
+
const cacheValue = cache.get(cacheKey);
|
|
134
|
+
if (cacheValue?.value === promise) {
|
|
135
|
+
cache.delete(cacheKey);
|
|
136
|
+
}
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
const unwrappedValue = unwrapValue(result, Date.now());
|
|
140
|
+
cache.set(cacheKey, unwrappedValue);
|
|
141
|
+
return unwrappedValue.value;
|
|
98
142
|
}).catch((error) => {
|
|
99
143
|
cache.delete(cacheKey);
|
|
100
144
|
throw error;
|
|
101
145
|
});
|
|
102
|
-
cache.set(cacheKey, {
|
|
146
|
+
cache.set(cacheKey, {
|
|
147
|
+
value: promise,
|
|
148
|
+
timestamp: now,
|
|
149
|
+
expiration: void 0
|
|
150
|
+
});
|
|
103
151
|
trimToSize();
|
|
104
152
|
cleanExpiredItems();
|
|
105
153
|
return promise;
|
|
@@ -109,7 +157,7 @@ function createCache({
|
|
|
109
157
|
},
|
|
110
158
|
get(cacheKey) {
|
|
111
159
|
const entry = cache.get(cacheKey);
|
|
112
|
-
if (!entry || isExpired(entry
|
|
160
|
+
if (!entry || isExpired(entry, Date.now())) {
|
|
113
161
|
return void 0;
|
|
114
162
|
}
|
|
115
163
|
if (isPromise(entry.value)) {
|
|
@@ -118,28 +166,41 @@ function createCache({
|
|
|
118
166
|
return entry.value;
|
|
119
167
|
},
|
|
120
168
|
set(cacheKey, value) {
|
|
121
|
-
cache.set(cacheKey,
|
|
169
|
+
cache.set(cacheKey, unwrapValue(value, Date.now()));
|
|
122
170
|
trimToSize();
|
|
123
171
|
cleanExpiredItems();
|
|
124
172
|
},
|
|
125
173
|
async getAsync(cacheKey) {
|
|
126
174
|
const entry = cache.get(cacheKey);
|
|
127
|
-
if (!entry || isExpired(entry
|
|
175
|
+
if (!entry || isExpired(entry, Date.now())) {
|
|
128
176
|
return void 0;
|
|
129
177
|
}
|
|
130
|
-
return
|
|
178
|
+
return entry.value;
|
|
131
179
|
},
|
|
132
|
-
setAsync(cacheKey, value) {
|
|
133
|
-
const promise = value().then((result) => {
|
|
134
|
-
|
|
135
|
-
|
|
180
|
+
async setAsync(cacheKey, value) {
|
|
181
|
+
const promise = value(utils).then((result) => {
|
|
182
|
+
if (result instanceof RejectValue) {
|
|
183
|
+
const cacheValue = cache.get(cacheKey);
|
|
184
|
+
if (cacheValue?.value === promise) {
|
|
185
|
+
cache.delete(cacheKey);
|
|
186
|
+
}
|
|
187
|
+
return result.value;
|
|
188
|
+
}
|
|
189
|
+
const unwrappedValue = unwrapValue(result, Date.now());
|
|
190
|
+
cache.set(cacheKey, unwrappedValue);
|
|
191
|
+
return unwrappedValue.value;
|
|
136
192
|
}).catch((error) => {
|
|
137
193
|
cache.delete(cacheKey);
|
|
138
194
|
throw error;
|
|
139
195
|
});
|
|
140
|
-
cache.set(cacheKey, {
|
|
196
|
+
cache.set(cacheKey, {
|
|
197
|
+
value: promise,
|
|
198
|
+
timestamp: Date.now(),
|
|
199
|
+
expiration: void 0
|
|
200
|
+
});
|
|
141
201
|
trimToSize();
|
|
142
202
|
cleanExpiredItems();
|
|
203
|
+
return promise;
|
|
143
204
|
},
|
|
144
205
|
cleanExpiredItems,
|
|
145
206
|
/** @internal */
|
|
@@ -148,6 +209,7 @@ function createCache({
|
|
|
148
209
|
}
|
|
149
210
|
export {
|
|
150
211
|
RejectValue,
|
|
212
|
+
WithExpiration,
|
|
151
213
|
cachedGetter,
|
|
152
214
|
createCache
|
|
153
215
|
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import {
|
|
2
|
+
clampMax
|
|
3
|
+
} from "./chunk-HTCYUMDR.js";
|
|
4
|
+
import {
|
|
5
|
+
castToNumber
|
|
6
|
+
} from "./chunk-GBFS2I67.js";
|
|
7
|
+
|
|
8
|
+
// src/time.ts
|
|
9
|
+
var MINUTE_AS_MS = 60 * 1e3;
|
|
10
|
+
var HOUR_AS_MS = 60 * MINUTE_AS_MS;
|
|
11
|
+
var DAY_AS_MS = 24 * HOUR_AS_MS;
|
|
12
|
+
var WEEK_AS_MS = 7 * DAY_AS_MS;
|
|
13
|
+
var MONTH_AS_MS = 30 * DAY_AS_MS;
|
|
14
|
+
var YEAR_AS_MS = 365 * DAY_AS_MS;
|
|
15
|
+
var HOUR_AS_SECS = 60 * 60;
|
|
16
|
+
var DAY_AS_SECS = 24 * HOUR_AS_SECS;
|
|
17
|
+
var WEEK_AS_SECS = 7 * DAY_AS_SECS;
|
|
18
|
+
var MONTH_AS_SECS = 30 * DAY_AS_SECS;
|
|
19
|
+
var YEAR_AS_SECS = 365 * DAY_AS_SECS;
|
|
20
|
+
function dateStringOrNullToUnixMs(isoString) {
|
|
21
|
+
if (!isoString) return null;
|
|
22
|
+
const unixMs = new Date(isoString).getTime();
|
|
23
|
+
if (isNaN(unixMs)) return null;
|
|
24
|
+
return unixMs;
|
|
25
|
+
}
|
|
26
|
+
function msToTimeString(ms, format, hoursMinLength = 2) {
|
|
27
|
+
const { hours, minutes, seconds, milliseconds } = msToDurationObj(ms);
|
|
28
|
+
const hoursString = padTimeVal(hours, hoursMinLength);
|
|
29
|
+
const minutesString = padTimeVal(minutes);
|
|
30
|
+
if (format === "minutes") {
|
|
31
|
+
return `${hoursString}:${minutesString}`;
|
|
32
|
+
}
|
|
33
|
+
const secondsString = padTimeVal(seconds);
|
|
34
|
+
if (format === "seconds") {
|
|
35
|
+
return `${hoursString}:${minutesString}:${secondsString}`;
|
|
36
|
+
}
|
|
37
|
+
return `${hoursString}:${minutesString}:${secondsString}:${padTimeVal(
|
|
38
|
+
milliseconds,
|
|
39
|
+
3
|
|
40
|
+
)}`;
|
|
41
|
+
}
|
|
42
|
+
function padTimeVal(val, maxLength = 2) {
|
|
43
|
+
return val.toString().padStart(maxLength, "0");
|
|
44
|
+
}
|
|
45
|
+
function parseTimeStringToMs(timeString) {
|
|
46
|
+
if (!timeString.trim()) return 0;
|
|
47
|
+
const [hours, minutes, seconds, ms] = timeString.split(":");
|
|
48
|
+
return getTimeStringPartToInt(hours) * HOUR_AS_MS + clampMax(getTimeStringPartToInt(minutes), 59) * MINUTE_AS_MS + clampMax(getTimeStringPartToInt(seconds), 59) * 1e3 + getTimeStringPartToInt(ms, 3);
|
|
49
|
+
}
|
|
50
|
+
function getTimeStringPartToInt(timeStringPart, length) {
|
|
51
|
+
if (!timeStringPart?.trim()) return 0;
|
|
52
|
+
let string = timeStringPart.replaceAll("_", "0");
|
|
53
|
+
string = string.replaceAll("-", "");
|
|
54
|
+
if (length) {
|
|
55
|
+
string = string.padEnd(length, "0");
|
|
56
|
+
if (string.length > length) {
|
|
57
|
+
string = string.slice(0, length);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const num = castToNumber(string);
|
|
61
|
+
if (!num) return 0;
|
|
62
|
+
return Math.floor(num);
|
|
63
|
+
}
|
|
64
|
+
function msToDurationObj(ms) {
|
|
65
|
+
return {
|
|
66
|
+
milliseconds: ms % 1e3,
|
|
67
|
+
seconds: Math.floor(ms / 1e3) % 60,
|
|
68
|
+
minutes: Math.floor(ms / 1e3 / 60) % 60,
|
|
69
|
+
hours: Math.floor(ms / 1e3 / 60 / 60)
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function getUnixSeconds() {
|
|
73
|
+
return Math.floor(Date.now() / 1e3);
|
|
74
|
+
}
|
|
75
|
+
function durationObjToMs(durationObj) {
|
|
76
|
+
return (durationObj.hours ?? 0) * HOUR_AS_MS + (durationObj.minutes ?? 0) * MINUTE_AS_MS + (durationObj.seconds ?? 0) * 1e3 + (durationObj.ms ?? 0) + (durationObj.days ?? 0) * DAY_AS_MS;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export {
|
|
80
|
+
MINUTE_AS_MS,
|
|
81
|
+
HOUR_AS_MS,
|
|
82
|
+
DAY_AS_MS,
|
|
83
|
+
WEEK_AS_MS,
|
|
84
|
+
MONTH_AS_MS,
|
|
85
|
+
YEAR_AS_MS,
|
|
86
|
+
HOUR_AS_SECS,
|
|
87
|
+
DAY_AS_SECS,
|
|
88
|
+
WEEK_AS_SECS,
|
|
89
|
+
MONTH_AS_SECS,
|
|
90
|
+
YEAR_AS_SECS,
|
|
91
|
+
dateStringOrNullToUnixMs,
|
|
92
|
+
msToTimeString,
|
|
93
|
+
parseTimeStringToMs,
|
|
94
|
+
getUnixSeconds,
|
|
95
|
+
durationObjToMs
|
|
96
|
+
};
|
|
@@ -121,22 +121,29 @@ var EnhancedMap = class _EnhancedMap extends Map {
|
|
|
121
121
|
}
|
|
122
122
|
};
|
|
123
123
|
|
|
124
|
+
// src/time.ts
|
|
125
|
+
var MINUTE_AS_MS = 60 * 1e3;
|
|
126
|
+
var HOUR_AS_MS = 60 * MINUTE_AS_MS;
|
|
127
|
+
var DAY_AS_MS = 24 * HOUR_AS_MS;
|
|
128
|
+
var WEEK_AS_MS = 7 * DAY_AS_MS;
|
|
129
|
+
var MONTH_AS_MS = 30 * DAY_AS_MS;
|
|
130
|
+
var YEAR_AS_MS = 365 * DAY_AS_MS;
|
|
131
|
+
var HOUR_AS_SECS = 60 * 60;
|
|
132
|
+
var DAY_AS_SECS = 24 * HOUR_AS_SECS;
|
|
133
|
+
var WEEK_AS_SECS = 7 * DAY_AS_SECS;
|
|
134
|
+
var MONTH_AS_SECS = 30 * DAY_AS_SECS;
|
|
135
|
+
var YEAR_AS_SECS = 365 * DAY_AS_SECS;
|
|
136
|
+
function durationObjToMs(durationObj) {
|
|
137
|
+
return (durationObj.hours ?? 0) * HOUR_AS_MS + (durationObj.minutes ?? 0) * MINUTE_AS_MS + (durationObj.seconds ?? 0) * 1e3 + (durationObj.ms ?? 0) + (durationObj.days ?? 0) * DAY_AS_MS;
|
|
138
|
+
}
|
|
139
|
+
|
|
124
140
|
// src/createThrottleController.ts
|
|
125
141
|
function createThrottleController({
|
|
126
142
|
maxCalls,
|
|
127
143
|
per,
|
|
128
144
|
cleanupCheckSecsInterval = 60 * 30
|
|
129
145
|
}) {
|
|
130
|
-
|
|
131
|
-
if (per.ms) {
|
|
132
|
-
msInterval = per.ms;
|
|
133
|
-
} else if (per.seconds) {
|
|
134
|
-
msInterval = per.seconds * 1e3;
|
|
135
|
-
} else if (per.minutes) {
|
|
136
|
-
msInterval = per.minutes * 1e3 * 60;
|
|
137
|
-
} else if (per.hours) {
|
|
138
|
-
msInterval = per.hours * 1e3 * 60 * 60;
|
|
139
|
-
}
|
|
146
|
+
const msInterval = durationObjToMs(per);
|
|
140
147
|
if (msInterval === 0) {
|
|
141
148
|
throw new Error("Invalid interval");
|
|
142
149
|
}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
+
import { DurationObj } from './time.cjs';
|
|
2
|
+
|
|
1
3
|
type Options = {
|
|
2
4
|
maxCalls: number;
|
|
3
|
-
per:
|
|
4
|
-
ms?: number;
|
|
5
|
-
seconds?: number;
|
|
6
|
-
minutes?: number;
|
|
7
|
-
hours?: number;
|
|
8
|
-
};
|
|
5
|
+
per: DurationObj;
|
|
9
6
|
cleanupCheckSecsInterval?: number;
|
|
10
7
|
};
|
|
11
8
|
type ThrottleController = {
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
+
import { DurationObj } from './time.js';
|
|
2
|
+
|
|
1
3
|
type Options = {
|
|
2
4
|
maxCalls: number;
|
|
3
|
-
per:
|
|
4
|
-
ms?: number;
|
|
5
|
-
seconds?: number;
|
|
6
|
-
minutes?: number;
|
|
7
|
-
hours?: number;
|
|
8
|
-
};
|
|
5
|
+
per: DurationObj;
|
|
9
6
|
cleanupCheckSecsInterval?: number;
|
|
10
7
|
};
|
|
11
8
|
type ThrottleController = {
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
EnhancedMap
|
|
3
3
|
} from "./chunk-T5WDDPFI.js";
|
|
4
|
+
import {
|
|
5
|
+
durationObjToMs
|
|
6
|
+
} from "./chunk-RK6PT7JY.js";
|
|
7
|
+
import "./chunk-HTCYUMDR.js";
|
|
4
8
|
import "./chunk-4UGSP3L3.js";
|
|
9
|
+
import "./chunk-GBFS2I67.js";
|
|
5
10
|
|
|
6
11
|
// src/createThrottleController.ts
|
|
7
12
|
function createThrottleController({
|
|
@@ -9,16 +14,7 @@ function createThrottleController({
|
|
|
9
14
|
per,
|
|
10
15
|
cleanupCheckSecsInterval = 60 * 30
|
|
11
16
|
}) {
|
|
12
|
-
|
|
13
|
-
if (per.ms) {
|
|
14
|
-
msInterval = per.ms;
|
|
15
|
-
} else if (per.seconds) {
|
|
16
|
-
msInterval = per.seconds * 1e3;
|
|
17
|
-
} else if (per.minutes) {
|
|
18
|
-
msInterval = per.minutes * 1e3 * 60;
|
|
19
|
-
} else if (per.hours) {
|
|
20
|
-
msInterval = per.hours * 1e3 * 60 * 60;
|
|
21
|
-
}
|
|
17
|
+
const msInterval = durationObjToMs(per);
|
|
22
18
|
if (msInterval === 0) {
|
|
23
19
|
throw new Error("Invalid interval");
|
|
24
20
|
}
|
package/dist/testUtils.js
CHANGED
|
@@ -5,13 +5,13 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
deepEqual
|
|
7
7
|
} from "./chunk-JQFUKJU5.js";
|
|
8
|
-
import {
|
|
9
|
-
clampMin
|
|
10
|
-
} from "./chunk-HTCYUMDR.js";
|
|
11
8
|
import {
|
|
12
9
|
arrayWithPrevAndIndex,
|
|
13
10
|
filterAndMap
|
|
14
11
|
} from "./chunk-QMFZE2VO.js";
|
|
12
|
+
import {
|
|
13
|
+
clampMin
|
|
14
|
+
} from "./chunk-HTCYUMDR.js";
|
|
15
15
|
import {
|
|
16
16
|
isObject
|
|
17
17
|
} from "./chunk-4UGSP3L3.js";
|
package/dist/time.cjs
CHANGED
|
@@ -32,6 +32,7 @@ __export(time_exports, {
|
|
|
32
32
|
YEAR_AS_MS: () => YEAR_AS_MS,
|
|
33
33
|
YEAR_AS_SECS: () => YEAR_AS_SECS,
|
|
34
34
|
dateStringOrNullToUnixMs: () => dateStringOrNullToUnixMs,
|
|
35
|
+
durationObjToMs: () => durationObjToMs,
|
|
35
36
|
getUnixSeconds: () => getUnixSeconds,
|
|
36
37
|
msToTimeString: () => msToTimeString,
|
|
37
38
|
parseTimeStringToMs: () => parseTimeStringToMs
|
|
@@ -119,6 +120,9 @@ function msToDurationObj(ms) {
|
|
|
119
120
|
function getUnixSeconds() {
|
|
120
121
|
return Math.floor(Date.now() / 1e3);
|
|
121
122
|
}
|
|
123
|
+
function durationObjToMs(durationObj) {
|
|
124
|
+
return (durationObj.hours ?? 0) * HOUR_AS_MS + (durationObj.minutes ?? 0) * MINUTE_AS_MS + (durationObj.seconds ?? 0) * 1e3 + (durationObj.ms ?? 0) + (durationObj.days ?? 0) * DAY_AS_MS;
|
|
125
|
+
}
|
|
122
126
|
// Annotate the CommonJS export names for ESM import in node:
|
|
123
127
|
0 && (module.exports = {
|
|
124
128
|
DAY_AS_MS,
|
|
@@ -133,6 +137,7 @@ function getUnixSeconds() {
|
|
|
133
137
|
YEAR_AS_MS,
|
|
134
138
|
YEAR_AS_SECS,
|
|
135
139
|
dateStringOrNullToUnixMs,
|
|
140
|
+
durationObjToMs,
|
|
136
141
|
getUnixSeconds,
|
|
137
142
|
msToTimeString,
|
|
138
143
|
parseTimeStringToMs
|
package/dist/time.d.cts
CHANGED
|
@@ -13,5 +13,13 @@ declare function dateStringOrNullToUnixMs(isoString: string | null | undefined):
|
|
|
13
13
|
declare function msToTimeString(ms: number, format: 'minutes' | 'seconds' | 'milliseconds', hoursMinLength?: number): string;
|
|
14
14
|
declare function parseTimeStringToMs(timeString: string): number;
|
|
15
15
|
declare function getUnixSeconds(): number;
|
|
16
|
+
type DurationObj = {
|
|
17
|
+
ms?: number;
|
|
18
|
+
seconds?: number;
|
|
19
|
+
minutes?: number;
|
|
20
|
+
hours?: number;
|
|
21
|
+
days?: number;
|
|
22
|
+
};
|
|
23
|
+
declare function durationObjToMs(durationObj: DurationObj): number;
|
|
16
24
|
|
|
17
|
-
export { DAY_AS_MS, DAY_AS_SECS, HOUR_AS_MS, HOUR_AS_SECS, MINUTE_AS_MS, MONTH_AS_MS, MONTH_AS_SECS, WEEK_AS_MS, WEEK_AS_SECS, YEAR_AS_MS, YEAR_AS_SECS, dateStringOrNullToUnixMs, getUnixSeconds, msToTimeString, parseTimeStringToMs };
|
|
25
|
+
export { DAY_AS_MS, DAY_AS_SECS, type DurationObj, HOUR_AS_MS, HOUR_AS_SECS, MINUTE_AS_MS, MONTH_AS_MS, MONTH_AS_SECS, WEEK_AS_MS, WEEK_AS_SECS, YEAR_AS_MS, YEAR_AS_SECS, dateStringOrNullToUnixMs, durationObjToMs, getUnixSeconds, msToTimeString, parseTimeStringToMs };
|
package/dist/time.d.ts
CHANGED
|
@@ -13,5 +13,13 @@ declare function dateStringOrNullToUnixMs(isoString: string | null | undefined):
|
|
|
13
13
|
declare function msToTimeString(ms: number, format: 'minutes' | 'seconds' | 'milliseconds', hoursMinLength?: number): string;
|
|
14
14
|
declare function parseTimeStringToMs(timeString: string): number;
|
|
15
15
|
declare function getUnixSeconds(): number;
|
|
16
|
+
type DurationObj = {
|
|
17
|
+
ms?: number;
|
|
18
|
+
seconds?: number;
|
|
19
|
+
minutes?: number;
|
|
20
|
+
hours?: number;
|
|
21
|
+
days?: number;
|
|
22
|
+
};
|
|
23
|
+
declare function durationObjToMs(durationObj: DurationObj): number;
|
|
16
24
|
|
|
17
|
-
export { DAY_AS_MS, DAY_AS_SECS, HOUR_AS_MS, HOUR_AS_SECS, MINUTE_AS_MS, MONTH_AS_MS, MONTH_AS_SECS, WEEK_AS_MS, WEEK_AS_SECS, YEAR_AS_MS, YEAR_AS_SECS, dateStringOrNullToUnixMs, getUnixSeconds, msToTimeString, parseTimeStringToMs };
|
|
25
|
+
export { DAY_AS_MS, DAY_AS_SECS, type DurationObj, HOUR_AS_MS, HOUR_AS_SECS, MINUTE_AS_MS, MONTH_AS_MS, MONTH_AS_SECS, WEEK_AS_MS, WEEK_AS_SECS, YEAR_AS_MS, YEAR_AS_SECS, dateStringOrNullToUnixMs, durationObjToMs, getUnixSeconds, msToTimeString, parseTimeStringToMs };
|
package/dist/time.js
CHANGED
|
@@ -1,77 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (!isoString) return null;
|
|
22
|
-
const unixMs = new Date(isoString).getTime();
|
|
23
|
-
if (isNaN(unixMs)) return null;
|
|
24
|
-
return unixMs;
|
|
25
|
-
}
|
|
26
|
-
function msToTimeString(ms, format, hoursMinLength = 2) {
|
|
27
|
-
const { hours, minutes, seconds, milliseconds } = msToDurationObj(ms);
|
|
28
|
-
const hoursString = padTimeVal(hours, hoursMinLength);
|
|
29
|
-
const minutesString = padTimeVal(minutes);
|
|
30
|
-
if (format === "minutes") {
|
|
31
|
-
return `${hoursString}:${minutesString}`;
|
|
32
|
-
}
|
|
33
|
-
const secondsString = padTimeVal(seconds);
|
|
34
|
-
if (format === "seconds") {
|
|
35
|
-
return `${hoursString}:${minutesString}:${secondsString}`;
|
|
36
|
-
}
|
|
37
|
-
return `${hoursString}:${minutesString}:${secondsString}:${padTimeVal(
|
|
38
|
-
milliseconds,
|
|
39
|
-
3
|
|
40
|
-
)}`;
|
|
41
|
-
}
|
|
42
|
-
function padTimeVal(val, maxLength = 2) {
|
|
43
|
-
return val.toString().padStart(maxLength, "0");
|
|
44
|
-
}
|
|
45
|
-
function parseTimeStringToMs(timeString) {
|
|
46
|
-
if (!timeString.trim()) return 0;
|
|
47
|
-
const [hours, minutes, seconds, ms] = timeString.split(":");
|
|
48
|
-
return getTimeStringPartToInt(hours) * HOUR_AS_MS + clampMax(getTimeStringPartToInt(minutes), 59) * MINUTE_AS_MS + clampMax(getTimeStringPartToInt(seconds), 59) * 1e3 + getTimeStringPartToInt(ms, 3);
|
|
49
|
-
}
|
|
50
|
-
function getTimeStringPartToInt(timeStringPart, length) {
|
|
51
|
-
if (!timeStringPart?.trim()) return 0;
|
|
52
|
-
let string = timeStringPart.replaceAll("_", "0");
|
|
53
|
-
string = string.replaceAll("-", "");
|
|
54
|
-
if (length) {
|
|
55
|
-
string = string.padEnd(length, "0");
|
|
56
|
-
if (string.length > length) {
|
|
57
|
-
string = string.slice(0, length);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
const num = castToNumber(string);
|
|
61
|
-
if (!num) return 0;
|
|
62
|
-
return Math.floor(num);
|
|
63
|
-
}
|
|
64
|
-
function msToDurationObj(ms) {
|
|
65
|
-
return {
|
|
66
|
-
milliseconds: ms % 1e3,
|
|
67
|
-
seconds: Math.floor(ms / 1e3) % 60,
|
|
68
|
-
minutes: Math.floor(ms / 1e3 / 60) % 60,
|
|
69
|
-
hours: Math.floor(ms / 1e3 / 60 / 60)
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
function getUnixSeconds() {
|
|
73
|
-
return Math.floor(Date.now() / 1e3);
|
|
74
|
-
}
|
|
2
|
+
DAY_AS_MS,
|
|
3
|
+
DAY_AS_SECS,
|
|
4
|
+
HOUR_AS_MS,
|
|
5
|
+
HOUR_AS_SECS,
|
|
6
|
+
MINUTE_AS_MS,
|
|
7
|
+
MONTH_AS_MS,
|
|
8
|
+
MONTH_AS_SECS,
|
|
9
|
+
WEEK_AS_MS,
|
|
10
|
+
WEEK_AS_SECS,
|
|
11
|
+
YEAR_AS_MS,
|
|
12
|
+
YEAR_AS_SECS,
|
|
13
|
+
dateStringOrNullToUnixMs,
|
|
14
|
+
durationObjToMs,
|
|
15
|
+
getUnixSeconds,
|
|
16
|
+
msToTimeString,
|
|
17
|
+
parseTimeStringToMs
|
|
18
|
+
} from "./chunk-RK6PT7JY.js";
|
|
19
|
+
import "./chunk-HTCYUMDR.js";
|
|
20
|
+
import "./chunk-GBFS2I67.js";
|
|
75
21
|
export {
|
|
76
22
|
DAY_AS_MS,
|
|
77
23
|
DAY_AS_SECS,
|
|
@@ -85,6 +31,7 @@ export {
|
|
|
85
31
|
YEAR_AS_MS,
|
|
86
32
|
YEAR_AS_SECS,
|
|
87
33
|
dateStringOrNullToUnixMs,
|
|
34
|
+
durationObjToMs,
|
|
88
35
|
getUnixSeconds,
|
|
89
36
|
msToTimeString,
|
|
90
37
|
parseTimeStringToMs
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ls-stack/utils",
|
|
3
3
|
"description": "Typescript utils",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.14.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist"
|
|
@@ -322,13 +322,13 @@
|
|
|
322
322
|
}
|
|
323
323
|
},
|
|
324
324
|
"scripts": {
|
|
325
|
-
"test": "vitest --ui",
|
|
326
|
-
"test
|
|
325
|
+
"test:ui": "vitest --ui",
|
|
326
|
+
"test": "vitest run",
|
|
327
327
|
"lint": "pnpm tsc && pnpm eslint",
|
|
328
328
|
"tsc": "tsc -p tsconfig.prod.json",
|
|
329
329
|
"tsc:watch": "tsc -p tsconfig.prod.json --watch",
|
|
330
330
|
"eslint": "CI=true eslint src/ scripts/ --color --max-warnings=0",
|
|
331
|
-
"build": "pnpm test
|
|
331
|
+
"build": "pnpm test && pnpm lint && pnpm build:no-test && pnpm build:update-exports",
|
|
332
332
|
"build:no-test": "tsup",
|
|
333
333
|
"build:update-exports": "tsm --no-warnings scripts/updatePackageExports.ts",
|
|
334
334
|
"build-test": "tsup --config tsup.test.config.ts",
|