@ls-stack/utils 2.12.0 → 2.13.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
@@ -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 (!maxItemAge || now - lastExpirationCheck < expirationThrottle) return;
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 (now - item.timestamp > maxAgeMs) {
96
+ if (isExpired(item, now)) {
67
97
  cache.delete(key);
68
98
  }
69
99
  }
@@ -81,25 +111,40 @@ function createCache({
81
111
  }
82
112
  }
83
113
  }
84
- function isExpired(timestamp, now) {
85
- return maxItemAge !== void 0 && now - timestamp > maxItemAge * 1e3;
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
135
  getOrInsert(cacheKey, val) {
92
136
  const now = Date.now();
93
137
  const entry = cache.get(cacheKey);
94
- if (!entry || isExpired(entry.timestamp, now)) {
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
- cache.set(cacheKey, { value, timestamp: now });
143
+ const unwrappedValue = unwrapValue(value, now);
144
+ cache.set(cacheKey, unwrappedValue);
100
145
  trimToSize();
101
146
  cleanExpiredItems();
102
- return value;
147
+ return unwrappedValue.value;
103
148
  }
104
149
  if (isPromise(entry.value)) {
105
150
  throw new Error(
@@ -114,7 +159,7 @@ function createCache({
114
159
  return entry.value;
115
160
  }
116
161
  const now = Date.now();
117
- if (entry && !isExpired(entry.timestamp, now)) {
162
+ if (entry && !isExpired(entry, now)) {
118
163
  return entry.value;
119
164
  }
120
165
  const promise = val(utils).then((result) => {
@@ -125,13 +170,18 @@ function createCache({
125
170
  }
126
171
  return result.value;
127
172
  }
128
- cache.set(cacheKey, { value: result, timestamp: Date.now() });
129
- return result;
173
+ const unwrappedValue = unwrapValue(result, Date.now());
174
+ cache.set(cacheKey, unwrappedValue);
175
+ return unwrappedValue.value;
130
176
  }).catch((error) => {
131
177
  cache.delete(cacheKey);
132
178
  throw error;
133
179
  });
134
- cache.set(cacheKey, { value: promise, timestamp: now });
180
+ cache.set(cacheKey, {
181
+ value: promise,
182
+ timestamp: now,
183
+ expiration: void 0
184
+ });
135
185
  trimToSize();
136
186
  cleanExpiredItems();
137
187
  return promise;
@@ -141,7 +191,7 @@ function createCache({
141
191
  },
142
192
  get(cacheKey) {
143
193
  const entry = cache.get(cacheKey);
144
- if (!entry || isExpired(entry.timestamp, Date.now())) {
194
+ if (!entry || isExpired(entry, Date.now())) {
145
195
  return void 0;
146
196
  }
147
197
  if (isPromise(entry.value)) {
@@ -150,28 +200,41 @@ function createCache({
150
200
  return entry.value;
151
201
  },
152
202
  set(cacheKey, value) {
153
- cache.set(cacheKey, { value, timestamp: Date.now() });
203
+ cache.set(cacheKey, unwrapValue(value, Date.now()));
154
204
  trimToSize();
155
205
  cleanExpiredItems();
156
206
  },
157
207
  async getAsync(cacheKey) {
158
208
  const entry = cache.get(cacheKey);
159
- if (!entry || isExpired(entry.timestamp, Date.now())) {
209
+ if (!entry || isExpired(entry, Date.now())) {
160
210
  return void 0;
161
211
  }
162
- return await entry.value;
212
+ return entry.value;
163
213
  },
164
- setAsync(cacheKey, value) {
165
- const promise = value().then((result) => {
166
- cache.set(cacheKey, { value: result, timestamp: Date.now() });
167
- return result;
214
+ async setAsync(cacheKey, value) {
215
+ const promise = value(utils).then((result) => {
216
+ if (result instanceof RejectValue) {
217
+ const cacheValue = cache.get(cacheKey);
218
+ if (cacheValue?.value === promise) {
219
+ cache.delete(cacheKey);
220
+ }
221
+ return result.value;
222
+ }
223
+ const unwrappedValue = unwrapValue(result, Date.now());
224
+ cache.set(cacheKey, unwrappedValue);
225
+ return unwrappedValue.value;
168
226
  }).catch((error) => {
169
227
  cache.delete(cacheKey);
170
228
  throw error;
171
229
  });
172
- cache.set(cacheKey, { value: promise, timestamp: Date.now() });
230
+ cache.set(cacheKey, {
231
+ value: promise,
232
+ timestamp: Date.now(),
233
+ expiration: void 0
234
+ });
173
235
  trimToSize();
174
236
  cleanExpiredItems();
237
+ return promise;
175
238
  },
176
239
  cleanExpiredItems,
177
240
  /** @internal */
@@ -181,6 +244,7 @@ function createCache({
181
244
  // Annotate the CommonJS export names for ESM import in node:
182
245
  0 && (module.exports = {
183
246
  RejectValue,
247
+ WithExpiration,
184
248
  cachedGetter,
185
249
  createCache
186
250
  });
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 in seconds.
13
+ * The maximum age of items in the cache.
12
14
  */
13
- maxItemAge?: number;
15
+ maxItemAge?: DurationObj;
14
16
  /**
15
17
  * The throttle for checking expired items in milliseconds.
16
18
  * @default
@@ -22,19 +24,33 @@ 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
+ };
25
45
  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>;
46
+ getOrInsert: (cacheKey: string, val: (utils: Utils<T>) => T | RejectValue<T>) => T;
47
+ getOrInsertAsync: (cacheKey: string, val: (utils: Utils<T>) => Promise<T | RejectValue<T>>) => Promise<T>;
32
48
  clear: () => void;
33
49
  get: (cacheKey: string) => T | undefined;
34
- set: (cacheKey: string, value: T) => void;
50
+ set: (cacheKey: string, value: T | WithExpiration<T>) => void;
35
51
  cleanExpiredItems: () => void;
36
52
  getAsync: (cacheKey: string) => Promise<T | undefined>;
37
- setAsync: (cacheKey: string, value: () => Promise<T>) => void;
53
+ setAsync: (cacheKey: string, value: (utils: Utils<T>) => Promise<T | WithExpiration<T>>) => Promise<T>;
38
54
  [' cache']: {
39
55
  map: Map<string, {
40
56
  value: T | Promise<T>;
@@ -44,4 +60,4 @@ type Cache<T> = {
44
60
  };
45
61
  declare function createCache<T>({ maxCacheSize, maxItemAge, expirationThrottle, }?: Options): Cache<T>;
46
62
 
47
- export { type Cache, RejectValue, cachedGetter, createCache };
63
+ 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 in seconds.
13
+ * The maximum age of items in the cache.
12
14
  */
13
- maxItemAge?: number;
15
+ maxItemAge?: DurationObj;
14
16
  /**
15
17
  * The throttle for checking expired items in milliseconds.
16
18
  * @default
@@ -22,19 +24,33 @@ 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
+ };
25
45
  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>;
46
+ getOrInsert: (cacheKey: string, val: (utils: Utils<T>) => T | RejectValue<T>) => T;
47
+ getOrInsertAsync: (cacheKey: string, val: (utils: Utils<T>) => Promise<T | RejectValue<T>>) => Promise<T>;
32
48
  clear: () => void;
33
49
  get: (cacheKey: string) => T | undefined;
34
- set: (cacheKey: string, value: T) => void;
50
+ set: (cacheKey: string, value: T | WithExpiration<T>) => void;
35
51
  cleanExpiredItems: () => void;
36
52
  getAsync: (cacheKey: string) => Promise<T | undefined>;
37
- setAsync: (cacheKey: string, value: () => Promise<T>) => void;
53
+ setAsync: (cacheKey: string, value: (utils: Utils<T>) => Promise<T | WithExpiration<T>>) => Promise<T>;
38
54
  [' cache']: {
39
55
  map: Map<string, {
40
56
  value: T | Promise<T>;
@@ -44,4 +60,4 @@ type Cache<T> = {
44
60
  };
45
61
  declare function createCache<T>({ maxCacheSize, maxItemAge, expirationThrottle, }?: Options): Cache<T>;
46
62
 
47
- export { type Cache, RejectValue, cachedGetter, createCache };
63
+ 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 (!maxItemAge || now - lastExpirationCheck < expirationThrottle) return;
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 (now - item.timestamp > maxAgeMs) {
52
+ if (isExpired(item, now)) {
35
53
  cache.delete(key);
36
54
  }
37
55
  }
@@ -49,25 +67,40 @@ function createCache({
49
67
  }
50
68
  }
51
69
  }
52
- function isExpired(timestamp, now) {
53
- return maxItemAge !== void 0 && now - timestamp > maxItemAge * 1e3;
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
91
  getOrInsert(cacheKey, val) {
60
92
  const now = Date.now();
61
93
  const entry = cache.get(cacheKey);
62
- if (!entry || isExpired(entry.timestamp, now)) {
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
- cache.set(cacheKey, { value, timestamp: now });
99
+ const unwrappedValue = unwrapValue(value, now);
100
+ cache.set(cacheKey, unwrappedValue);
68
101
  trimToSize();
69
102
  cleanExpiredItems();
70
- return value;
103
+ return unwrappedValue.value;
71
104
  }
72
105
  if (isPromise(entry.value)) {
73
106
  throw new Error(
@@ -82,7 +115,7 @@ function createCache({
82
115
  return entry.value;
83
116
  }
84
117
  const now = Date.now();
85
- if (entry && !isExpired(entry.timestamp, now)) {
118
+ if (entry && !isExpired(entry, now)) {
86
119
  return entry.value;
87
120
  }
88
121
  const promise = val(utils).then((result) => {
@@ -93,13 +126,18 @@ function createCache({
93
126
  }
94
127
  return result.value;
95
128
  }
96
- cache.set(cacheKey, { value: result, timestamp: Date.now() });
97
- return result;
129
+ const unwrappedValue = unwrapValue(result, Date.now());
130
+ cache.set(cacheKey, unwrappedValue);
131
+ return unwrappedValue.value;
98
132
  }).catch((error) => {
99
133
  cache.delete(cacheKey);
100
134
  throw error;
101
135
  });
102
- cache.set(cacheKey, { value: promise, timestamp: now });
136
+ cache.set(cacheKey, {
137
+ value: promise,
138
+ timestamp: now,
139
+ expiration: void 0
140
+ });
103
141
  trimToSize();
104
142
  cleanExpiredItems();
105
143
  return promise;
@@ -109,7 +147,7 @@ function createCache({
109
147
  },
110
148
  get(cacheKey) {
111
149
  const entry = cache.get(cacheKey);
112
- if (!entry || isExpired(entry.timestamp, Date.now())) {
150
+ if (!entry || isExpired(entry, Date.now())) {
113
151
  return void 0;
114
152
  }
115
153
  if (isPromise(entry.value)) {
@@ -118,28 +156,41 @@ function createCache({
118
156
  return entry.value;
119
157
  },
120
158
  set(cacheKey, value) {
121
- cache.set(cacheKey, { value, timestamp: Date.now() });
159
+ cache.set(cacheKey, unwrapValue(value, Date.now()));
122
160
  trimToSize();
123
161
  cleanExpiredItems();
124
162
  },
125
163
  async getAsync(cacheKey) {
126
164
  const entry = cache.get(cacheKey);
127
- if (!entry || isExpired(entry.timestamp, Date.now())) {
165
+ if (!entry || isExpired(entry, Date.now())) {
128
166
  return void 0;
129
167
  }
130
- return await entry.value;
168
+ return entry.value;
131
169
  },
132
- setAsync(cacheKey, value) {
133
- const promise = value().then((result) => {
134
- cache.set(cacheKey, { value: result, timestamp: Date.now() });
135
- return result;
170
+ async setAsync(cacheKey, value) {
171
+ const promise = value(utils).then((result) => {
172
+ if (result instanceof RejectValue) {
173
+ const cacheValue = cache.get(cacheKey);
174
+ if (cacheValue?.value === promise) {
175
+ cache.delete(cacheKey);
176
+ }
177
+ return result.value;
178
+ }
179
+ const unwrappedValue = unwrapValue(result, Date.now());
180
+ cache.set(cacheKey, unwrappedValue);
181
+ return unwrappedValue.value;
136
182
  }).catch((error) => {
137
183
  cache.delete(cacheKey);
138
184
  throw error;
139
185
  });
140
- cache.set(cacheKey, { value: promise, timestamp: Date.now() });
186
+ cache.set(cacheKey, {
187
+ value: promise,
188
+ timestamp: Date.now(),
189
+ expiration: void 0
190
+ });
141
191
  trimToSize();
142
192
  cleanExpiredItems();
193
+ return promise;
143
194
  },
144
195
  cleanExpiredItems,
145
196
  /** @internal */
@@ -148,6 +199,7 @@ function createCache({
148
199
  }
149
200
  export {
150
201
  RejectValue,
202
+ WithExpiration,
151
203
  cachedGetter,
152
204
  createCache
153
205
  };
@@ -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
- let msInterval = 0;
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
- let msInterval = 0;
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
- 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
- }
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.12.0",
4
+ "version": "2.13.0",
5
5
  "license": "MIT",
6
6
  "files": [
7
7
  "dist"