@naturalcycles/js-lib 15.100.0 → 15.102.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.
Files changed (57) hide show
  1. package/dist/abort.d.ts +0 -8
  2. package/dist/abort.js +2 -19
  3. package/dist/array/array.util.d.ts +1 -3
  4. package/dist/array/array.util.js +1 -3
  5. package/dist/array/sort.js +1 -1
  6. package/dist/array/sortedSet.d.ts +1 -1
  7. package/dist/array/sortedSet.js +1 -1
  8. package/dist/asyncManager.js +5 -4
  9. package/dist/browser/analytics.util.js +3 -2
  10. package/dist/browser/topbar.js +1 -1
  11. package/dist/datetime/localDate.js +10 -5
  12. package/dist/datetime/localTime.d.ts +4 -0
  13. package/dist/datetime/localTime.js +17 -8
  14. package/dist/datetime/time.util.d.ts +18 -1
  15. package/dist/datetime/time.util.js +28 -2
  16. package/dist/decorators/createPromiseDecorator.js +2 -1
  17. package/dist/decorators/debounce.js +7 -6
  18. package/dist/decorators/logMethod.decorator.js +3 -3
  19. package/dist/enum.util.js +1 -0
  20. package/dist/error/tryCatch.js +2 -2
  21. package/dist/http/fetcher.js +13 -13
  22. package/dist/index.d.ts +1 -1
  23. package/dist/index.js +0 -1
  24. package/dist/object/deepEquals.js +2 -0
  25. package/dist/object/keySortedMap.js +1 -1
  26. package/dist/object/lazyKeySortedMap.js +1 -1
  27. package/dist/object/object.util.js +2 -2
  28. package/dist/promise/pGradualQueue.js +3 -2
  29. package/dist/promise/pRetry.js +2 -2
  30. package/dist/semver.js +10 -5
  31. package/dist/string/stringify.js +1 -2
  32. package/package.json +4 -2
  33. package/src/abort.ts +2 -21
  34. package/src/array/array.util.ts +1 -3
  35. package/src/array/sort.ts +1 -1
  36. package/src/array/sortedSet.ts +1 -1
  37. package/src/asyncManager.ts +5 -4
  38. package/src/browser/analytics.util.ts +3 -2
  39. package/src/browser/topbar.ts +1 -1
  40. package/src/datetime/localDate.ts +12 -6
  41. package/src/datetime/localTime.ts +19 -9
  42. package/src/datetime/time.util.ts +32 -3
  43. package/src/decorators/createPromiseDecorator.ts +2 -1
  44. package/src/decorators/debounce.ts +7 -6
  45. package/src/decorators/logMethod.decorator.ts +3 -3
  46. package/src/enum.util.ts +1 -0
  47. package/src/error/tryCatch.ts +3 -3
  48. package/src/http/fetcher.ts +15 -20
  49. package/src/index.ts +1 -1
  50. package/src/object/deepEquals.ts +2 -0
  51. package/src/object/keySortedMap.ts +1 -1
  52. package/src/object/lazyKeySortedMap.ts +1 -1
  53. package/src/object/object.util.ts +2 -2
  54. package/src/promise/pGradualQueue.ts +3 -2
  55. package/src/promise/pRetry.ts +3 -3
  56. package/src/semver.ts +11 -7
  57. package/src/string/stringify.ts +2 -4
package/dist/abort.d.ts CHANGED
@@ -28,14 +28,6 @@ export declare function createAbortableSignal(): AbortableSignal;
28
28
  * Otherwise returns undefined.
29
29
  */
30
30
  export declare function abortSignalTimeoutOrUndefined(ms: NumberOfMilliseconds | undefined): AbortSignal | undefined;
31
- /**
32
- * Returns an AbortSignal that aborts after the given number of milliseconds.
33
- * Uses native `AbortSignal.timeout()` when available, falls back to a polyfill.
34
- *
35
- * The abort reason is a DOMException with name "TimeoutError".
36
- */
37
- export declare function abortSignalTimeout(ms: NumberOfMilliseconds): AbortSignal;
38
- export declare function polyfilledAbortSignalTimeout(ms: NumberOfMilliseconds): AbortSignal;
39
31
  /**
40
32
  * Returns AbortSignal.any(signals) is the array (after filtering undefined inputs) is not empty,
41
33
  * otherwise undefined.
package/dist/abort.js CHANGED
@@ -16,25 +16,7 @@ export function createAbortableSignal() {
16
16
  * Otherwise returns undefined.
17
17
  */
18
18
  export function abortSignalTimeoutOrUndefined(ms) {
19
- return ms ? abortSignalTimeout(ms) : undefined;
20
- }
21
- /**
22
- * Returns an AbortSignal that aborts after the given number of milliseconds.
23
- * Uses native `AbortSignal.timeout()` when available, falls back to a polyfill.
24
- *
25
- * The abort reason is a DOMException with name "TimeoutError".
26
- */
27
- export function abortSignalTimeout(ms) {
28
- return typeof AbortSignal.timeout === 'function'
29
- ? AbortSignal.timeout(ms)
30
- : polyfilledAbortSignalTimeout(ms);
31
- }
32
- export function polyfilledAbortSignalTimeout(ms) {
33
- const ac = new AbortController();
34
- setTimeout(() => {
35
- ac.abort(new DOMException('The operation was aborted due to timeout', 'TimeoutError'));
36
- }, ms);
37
- return ac.signal;
19
+ return ms ? AbortSignal.timeout(ms) : undefined;
38
20
  }
39
21
  /**
40
22
  * Returns AbortSignal.any(signals) is the array (after filtering undefined inputs) is not empty,
@@ -57,6 +39,7 @@ export function abortSignalAny(signals) {
57
39
  if (signals.length === 1) {
58
40
  return signals[0];
59
41
  }
42
+ // AbortSignal.any needs Chrome 116+ / Safari 17.4+, above our browser floor (Chrome 110, iOS 16.7)
60
43
  return typeof AbortSignal.any === 'function'
61
44
  ? AbortSignal.any(signals) // lib.dom types require a mutable array, but it is only read
62
45
  : polyfilledAbortSignalAny(signals);
@@ -99,9 +99,7 @@ export declare function _find<T>(items: readonly T[], predicate: AbortablePredic
99
99
  /**
100
100
  * Similar to `Array.findLast`, but the `predicate` may return `END` to stop the iteration early.
101
101
  *
102
- * Use `Array.findLast` if you don't need to stop the iteration early, which is supported:
103
- * - in Node since 18+
104
- * - in iOS Safari since 15.4
102
+ * Use `Array.findLast` if you don't need to stop the iteration early.
105
103
  */
106
104
  export declare function _findLast<T>(items: readonly T[], predicate: AbortablePredicate<T>): T | undefined;
107
105
  export declare function _takeWhile<T>(items: readonly T[], predicate: Predicate<T>): T[];
@@ -174,9 +174,7 @@ export function _find(items, predicate) {
174
174
  /**
175
175
  * Similar to `Array.findLast`, but the `predicate` may return `END` to stop the iteration early.
176
176
  *
177
- * Use `Array.findLast` if you don't need to stop the iteration early, which is supported:
178
- * - in Node since 18+
179
- * - in iOS Safari since 15.4
177
+ * Use `Array.findLast` if you don't need to stop the iteration early.
180
178
  */
181
179
  export function _findLast(items, predicate) {
182
180
  return _find(items.toReversed(), predicate);
@@ -42,7 +42,7 @@ class Comparators {
42
42
  return b.created - a.created;
43
43
  }
44
44
  }
45
- export const comparators = new Comparators();
45
+ export const comparators = /* @__PURE__ */ new Comparators();
46
46
  /**
47
47
  * _sortBy([{age: 20}, {age: 10}], 'age')
48
48
  * // => [{age: 10}, {age: 20}]
@@ -1,4 +1,4 @@
1
- import { Set2 } from '../object/index.js';
1
+ import { Set2 } from '../object/set2.js';
2
2
  import type { Comparator } from '../types.js';
3
3
  export interface SortedSetOptions<T> {
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { Set2 } from '../object/index.js';
1
+ import { Set2 } from '../object/set2.js';
2
2
  /**
3
3
  * Like Set, but keeps members sorted after every insertion.
4
4
  */
@@ -1,3 +1,4 @@
1
+ import { nowUnixMillis } from './datetime/time.util.js';
1
2
  import { consoleLogger } from './log/commonLogger.js';
2
3
  class AsyncManagerImpl {
3
4
  logger = consoleLogger;
@@ -24,7 +25,7 @@ class AsyncManagerImpl {
24
25
  if (!size)
25
26
  return;
26
27
  const { logger } = this;
27
- const started = Date.now();
28
+ const started = nowUnixMillis();
28
29
  if (timeout) {
29
30
  const result = await Promise.race([
30
31
  Promise.allSettled(this.pendingOps),
@@ -38,7 +39,7 @@ class AsyncManagerImpl {
38
39
  else {
39
40
  await Promise.allSettled(this.pendingOps);
40
41
  }
41
- logger.log(`AsyncManager.allDone for ${size} op(s) in ${Date.now() - started} ms`);
42
+ logger.log(`AsyncManager.allDone for ${size} op(s) in ${nowUnixMillis() - started} ms`);
42
43
  }
43
44
  reset() {
44
45
  this.pendingOps.clear();
@@ -81,6 +82,6 @@ class AsyncManagerImpl {
81
82
  *
82
83
  * @experimental
83
84
  */
84
- export const AsyncManager = new AsyncManagerImpl();
85
+ export const AsyncManager = /* @__PURE__ */ new AsyncManagerImpl();
85
86
  // Shorthand alias
86
- export const runInBackground = AsyncManager.runInBackground.bind(AsyncManager);
87
+ export const runInBackground = /* @__PURE__ */ AsyncManager.runInBackground.bind(AsyncManager);
@@ -1,3 +1,4 @@
1
+ import { newDate, nowUnixMillis } from '../datetime/time.util.js';
1
2
  import { isServerSide } from '../env.js';
2
3
  import { loadScript } from './script.util.js';
3
4
  /**
@@ -10,7 +11,7 @@ export async function loadGTag(gtagId, enabled = true) {
10
11
  globalThis.gtag ||= function gtag() {
11
12
  globalThis.dataLayer.push(arguments);
12
13
  };
13
- globalThis.gtag('js', new Date());
14
+ globalThis.gtag('js', newDate());
14
15
  globalThis.gtag('config', gtagId);
15
16
  if (!enabled)
16
17
  return;
@@ -21,7 +22,7 @@ export async function loadGTM(gtmId, enabled = true) {
21
22
  return;
22
23
  globalThis.dataLayer ||= [];
23
24
  globalThis.dataLayer.push({
24
- 'gtm.start': Date.now(),
25
+ 'gtm.start': nowUnixMillis(),
25
26
  event: 'gtm.js',
26
27
  });
27
28
  if (!enabled)
@@ -60,7 +60,7 @@ const createCanvas = () => {
60
60
  export const topbar = {
61
61
  config(opts) {
62
62
  for (const key in opts) {
63
- if (options.hasOwnProperty(key)) {
63
+ if (Object.hasOwn(options, key)) {
64
64
  // @ts-expect-error
65
65
  options[key] = opts[key];
66
66
  }
@@ -719,8 +719,13 @@ class LocalDateFactory {
719
719
  return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
720
720
  }
721
721
  }
722
- const localDateFactory = new LocalDateFactory();
723
- export const localDate = localDateFactory.fromInput.bind(localDateFactory);
724
- // The line below is the blackest of black magic I have ever written in 2024.
725
- // And probably 2023 as well.
726
- Object.setPrototypeOf(localDate, localDateFactory);
722
+ // Built inside a function, so the whole construct can be marked pure and tree-shaken (see treeshake.test.ts)
723
+ export const localDate = /* @__PURE__ */ createLocalDateFn();
724
+ function createLocalDateFn() {
725
+ const localDateFactory = new LocalDateFactory();
726
+ const fn = localDateFactory.fromInput.bind(localDateFactory);
727
+ // The line below is the blackest of black magic I have ever written in 2024.
728
+ // And probably 2023 as well.
729
+ Object.setPrototypeOf(fn, localDateFactory);
730
+ return fn;
731
+ }
@@ -257,10 +257,14 @@ declare class LocalTimeFactory {
257
257
  /**
258
258
  Convenience function to return current Unix timestamp in seconds.
259
259
  Like Date.now(), but in seconds.
260
+
261
+ Import nowUnix from time.util.js in places where importing localTime is too heavy.
260
262
  */
261
263
  nowUnix(): UnixTimestamp;
262
264
  /**
263
265
  Convenience function that retuns the same as Date.now(), but with proper type of UnixTimestampMillis.
266
+
267
+ Import nowUnixMillis from time.util.js in places where importing localTime is too heavy.
264
268
  */
265
269
  nowUnixMillis(): UnixTimestampMillis;
266
270
  /**
@@ -2,7 +2,7 @@ import { comparators } from '../array/sort.js';
2
2
  import { _assert } from '../error/assert.js';
3
3
  import { Intl2 } from '../intl/intl.js';
4
4
  import { localDate } from './localDate.js';
5
- import { _ms } from './time.util.js';
5
+ import { _ms, nowUnix, nowUnixMillis } from './time.util.js';
6
6
  // oxlint-disable-next-line import/no-cycle -- intentional cycle
7
7
  import { WallTime } from './wallTime.js';
8
8
  export var ISODayOfWeek;
@@ -676,15 +676,19 @@ class LocalTimeFactory {
676
676
  /**
677
677
  Convenience function to return current Unix timestamp in seconds.
678
678
  Like Date.now(), but in seconds.
679
+
680
+ Import nowUnix from time.util.js in places where importing localTime is too heavy.
679
681
  */
680
682
  nowUnix() {
681
- return Math.floor(Date.now() / 1000);
683
+ return nowUnix();
682
684
  }
683
685
  /**
684
686
  Convenience function that retuns the same as Date.now(), but with proper type of UnixTimestampMillis.
687
+
688
+ Import nowUnixMillis from time.util.js in places where importing localTime is too heavy.
685
689
  */
686
690
  nowUnixMillis() {
687
- return Date.now();
691
+ return nowUnixMillis();
688
692
  }
689
693
  /**
690
694
  * Create LocalTime from LocalTimeInput.
@@ -1027,8 +1031,13 @@ function getWallComponentsInTimezone(date, tz) {
1027
1031
  }
1028
1032
  return dto;
1029
1033
  }
1030
- const localTimeFactory = new LocalTimeFactory();
1031
- export const localTime = localTimeFactory.fromInput.bind(localTimeFactory);
1032
- // The line below is the blackest of black magic I have ever written in 2024.
1033
- // And probably 2023 as well.
1034
- Object.setPrototypeOf(localTime, localTimeFactory);
1034
+ // Built inside a function, so the whole construct can be marked pure and tree-shaken (see treeshake.test.ts)
1035
+ export const localTime = /* @__PURE__ */ createLocalTimeFn();
1036
+ function createLocalTimeFn() {
1037
+ const localTimeFactory = new LocalTimeFactory();
1038
+ const fn = localTimeFactory.fromInput.bind(localTimeFactory);
1039
+ // The line below is the blackest of black magic I have ever written in 2024.
1040
+ // And probably 2023 as well.
1041
+ Object.setPrototypeOf(fn, localTimeFactory);
1042
+ return fn;
1043
+ }
@@ -1,4 +1,4 @@
1
- import type { NumberOfMilliseconds, UnixTimestampMillis } from '../types.js';
1
+ import type { NumberOfMilliseconds, UnixTimestamp, UnixTimestampMillis } from '../types.js';
2
2
  /**
3
3
  * using _ = blockTimer()
4
4
  * // will log "took 1.234 sec" on dispose
@@ -23,3 +23,20 @@ export declare function _since(from: UnixTimestampMillis, until?: UnixTimestampM
23
23
  * 1h3m12s
24
24
  */
25
25
  export declare function _ms(millis: NumberOfMilliseconds): string;
26
+ /**
27
+ * Can be used instead of `oxlint-disable ...` in places where Date is intentionally needed
28
+ */
29
+ export declare function newDate(): Date;
30
+ /**
31
+ Convenience function to return current Unix timestamp in seconds.
32
+ Like Date.now(), but in seconds.
33
+
34
+ Lives here rather than in localTime.ts, so importing it doesn't pull LocalTime into browser bundles.
35
+ */
36
+ export declare function nowUnix(): UnixTimestamp;
37
+ /**
38
+ Convenience function that retuns the same as Date.now(), but with proper type of UnixTimestampMillis.
39
+
40
+ Lives here rather than in localTime.ts, so importing it doesn't pull LocalTime into browser bundles.
41
+ */
42
+ export declare function nowUnixMillis(): UnixTimestampMillis;
@@ -8,7 +8,7 @@
8
8
  * @experimental
9
9
  */
10
10
  export function _blockTimer(name) {
11
- const started = Date.now();
11
+ const started = nowUnixMillis();
12
12
  return {
13
13
  [Symbol.dispose]() {
14
14
  console.log(`${name ? name + ' ' : ''}took ${_since(started)}`);
@@ -18,7 +18,7 @@ export function _blockTimer(name) {
18
18
  /**
19
19
  * Returns time passed since `from` until `until` (default to Date.now())
20
20
  */
21
- export function _since(from, until = Date.now()) {
21
+ export function _since(from, until = nowUnixMillis()) {
22
22
  return _ms(until - from);
23
23
  }
24
24
  /**
@@ -59,3 +59,29 @@ export function _ms(millis) {
59
59
  const days = Math.floor(hrs / 24);
60
60
  return `${days} days`;
61
61
  }
62
+ /**
63
+ * Can be used instead of `oxlint-disable ...` in places where Date is intentionally needed
64
+ */
65
+ export function newDate() {
66
+ // oxlint-disable-next-line no-restricted-globals -- the one sanctioned way to get a native Date
67
+ return new Date();
68
+ }
69
+ /**
70
+ Convenience function to return current Unix timestamp in seconds.
71
+ Like Date.now(), but in seconds.
72
+
73
+ Lives here rather than in localTime.ts, so importing it doesn't pull LocalTime into browser bundles.
74
+ */
75
+ export function nowUnix() {
76
+ // oxlint-disable-next-line no-restricted-globals -- the one sanctioned way to read the clock
77
+ return Math.floor(Date.now() / 1000);
78
+ }
79
+ /**
80
+ Convenience function that retuns the same as Date.now(), but with proper type of UnixTimestampMillis.
81
+
82
+ Lives here rather than in localTime.ts, so importing it doesn't pull LocalTime into browser bundles.
83
+ */
84
+ export function nowUnixMillis() {
85
+ // oxlint-disable-next-line no-restricted-globals -- the one sanctioned way to read the clock
86
+ return Date.now();
87
+ }
@@ -1,3 +1,4 @@
1
+ import { nowUnixMillis } from '../datetime/time.util.js';
1
2
  import { _getTargetMethodSignature } from './decorator.util.js';
2
3
  /**
3
4
  * @example
@@ -19,7 +20,7 @@ export function _createPromiseDecorator(cfg, decoratorParams = {}) {
19
20
  const methodSignature = _getTargetMethodSignature(target, key);
20
21
  pd.value = async function (...args) {
21
22
  // console.log(`@${cfg.decoratorName} called inside function`)
22
- const started = Date.now();
23
+ const started = nowUnixMillis();
23
24
  try {
24
25
  // Before function
25
26
  // console.log(`@${cfg.decoratorName} Before`)
@@ -1,3 +1,4 @@
1
+ import { nowUnixMillis } from '../datetime/time.util.js';
1
2
  import { _anyToError } from '../error/error.util.js';
2
3
  import { pDefer } from '../promise/pDefer.js';
3
4
  export function _debounce(func, wait, opt = {}) {
@@ -31,7 +32,7 @@ export function _debounce(func, wait, opt = {}) {
31
32
  return leading ? invokeFunc(time) : result;
32
33
  }
33
34
  function timerExpired() {
34
- const time = Date.now();
35
+ const time = nowUnixMillis();
35
36
  if (shouldInvoke(time, state)) {
36
37
  trailingEdge(time);
37
38
  return;
@@ -58,13 +59,13 @@ export function _debounce(func, wait, opt = {}) {
58
59
  lastArgs = lastThis = timerId = undefined;
59
60
  }
60
61
  function flush() {
61
- return timerId === undefined ? result : trailingEdge(Date.now());
62
+ return timerId === undefined ? result : trailingEdge(nowUnixMillis());
62
63
  }
63
64
  function pending() {
64
65
  return timerId !== undefined;
65
66
  }
66
67
  function debounced(...args) {
67
- const time = Date.now();
68
+ const time = nowUnixMillis();
68
69
  const isInvoking = shouldInvoke(time, state);
69
70
  lastArgs = args;
70
71
  lastThis = this;
@@ -151,7 +152,7 @@ export function _asyncDebounce(func, wait, opt = {}) {
151
152
  return d;
152
153
  }
153
154
  function timerExpired() {
154
- const time = Date.now();
155
+ const time = nowUnixMillis();
155
156
  if (shouldInvoke(time, state)) {
156
157
  void trailingEdge(time);
157
158
  return;
@@ -195,14 +196,14 @@ export function _asyncDebounce(func, wait, opt = {}) {
195
196
  }
196
197
  const d = deferred;
197
198
  cancelTimer(timerId);
198
- await trailingEdge(Date.now());
199
+ await trailingEdge(nowUnixMillis());
199
200
  return d;
200
201
  }
201
202
  function pending() {
202
203
  return timerId !== undefined;
203
204
  }
204
205
  async function debounced(...args) {
205
- const time = Date.now();
206
+ const time = nowUnixMillis();
206
207
  const isInvoking = shouldInvoke(time, state);
207
208
  lastArgs = args;
208
209
  lastThis = this;
@@ -1,4 +1,4 @@
1
- import { _ms } from '../datetime/time.util.js';
1
+ import { _ms, nowUnixMillis } from '../datetime/time.util.js';
2
2
  import { _assert } from '../error/assert.js';
3
3
  import { consoleLogger } from '../log/commonLogger.js';
4
4
  import { SimpleMovingAverage } from '../math/sma.js';
@@ -35,7 +35,7 @@ export function _LogMethod(opt = {}) {
35
35
  const sma = avg ? new SimpleMovingAverage(avg) : undefined;
36
36
  let count = 0;
37
37
  descriptor.value = function (...args) {
38
- const started = Date.now();
38
+ const started = nowUnixMillis();
39
39
  const ctx = this;
40
40
  // e.g `NameOfYourClass.methodName`
41
41
  // or `NameOfYourClass(instanceId).methodName`
@@ -72,7 +72,7 @@ export function _LogMethod(opt = {}) {
72
72
  }
73
73
  // oxlint-disable-next-line max-params
74
74
  function logFinished(logger, callSignature, started, sma, logResultFn, res, err) {
75
- const millis = Date.now() - started;
75
+ const millis = nowUnixMillis() - started;
76
76
  const t = ['<<', callSignature, 'took', _ms(millis)];
77
77
  if (sma) {
78
78
  t.push(`(avg ${_ms(sma.pushGetAvg(millis))})`);
package/dist/enum.util.js CHANGED
@@ -234,6 +234,7 @@ export function _numberEnumKeyOrUndefined(en, v) {
234
234
  export function _numberEnumKey(en, v) {
235
235
  const key = en[v];
236
236
  // This prevents passing a Key (not a Value) of enum here, which returns unexpected result (number, not string)
237
+ // oxlint-disable-next-line unicorn/prefer-type-error
237
238
  if (typeof key !== 'string')
238
239
  throw new Error(`_numberEnumKey not found for: ${v}`);
239
240
  return key;
@@ -1,4 +1,4 @@
1
- import { _since } from '../datetime/time.util.js';
1
+ import { _since, nowUnixMillis } from '../datetime/time.util.js';
2
2
  import { consoleLogger } from '../log/commonLogger.js';
3
3
  import { _anyToError } from './error.util.js';
4
4
  /**
@@ -13,7 +13,7 @@ export function _tryCatch(fn, opt = {}) {
13
13
  const { onError, logError = true, logSuccess = false, logger = consoleLogger } = opt;
14
14
  const fname = fn.name || 'anonymous';
15
15
  return async function (...args) {
16
- const started = Date.now();
16
+ const started = nowUnixMillis();
17
17
  try {
18
18
  const r = await fn.apply(this, args);
19
19
  if (logSuccess) {
@@ -2,7 +2,7 @@
2
2
  /// <reference lib="dom" preserve="true" />
3
3
  /// <reference lib="dom.iterable" preserve="true" />
4
4
  import { abortSignalAnyOrUndefined, abortSignalTimeoutOrUndefined } from '../abort.js';
5
- import { _ms, _since } from '../datetime/time.util.js';
5
+ import { _ms, _since, nowUnixMillis } from '../datetime/time.util.js';
6
6
  import { isServerSide } from '../env.js';
7
7
  import { _assert, _assertErrorClassOrRethrow, _assertIsError } from '../error/assert.js';
8
8
  import { _anyToError, _anyToErrorObject, _errorDataAppend, _errorLikeToErrorObject, HttpRequestError, UnexpectedPassError, } from '../error/error.util.js';
@@ -11,9 +11,10 @@ import { _clamp } from '../number/number.util.js';
11
11
  import { _filterFalsyValues, _filterNullishValues, _filterUndefinedValues, _mapKeys, _merge, _omit, _pick, } from '../object/object.util.js';
12
12
  import { pDelaySignal } from '../promise/pDelay.js';
13
13
  import { pTimeout } from '../promise/pTimeout.js';
14
- import { _toUrlOrNull } from '../string/index.js';
15
14
  import { _jsonParse, _jsonParseIfPossible } from '../string/json.util.js';
15
+ import { _toUrlOrNull } from '../string/url.util.js';
16
16
  import { HTTP_METHODS } from './http.model.js';
17
+ const FETCHER_VERSION = 5;
17
18
  /**
18
19
  * Experimental wrapper around Fetch.
19
20
  * Works in both Browser and Node, using `globalThis.fetch`.
@@ -25,16 +26,14 @@ export class Fetcher {
25
26
  *
26
27
  * Version is to be incremented every time a difference in behaviour (or a bugfix) is done.
27
28
  */
28
- static VERSION = 5;
29
+ static VERSION = FETCHER_VERSION;
29
30
  /**
30
31
  * userAgent is statically exposed as Fetcher.userAgent.
31
32
  * It can be modified globally, and will be used (read) at the start of every request.
32
33
  */
33
- static userAgent = isServerSide() ? `fetcher/${this.VERSION}` : undefined;
34
+ // Pure, and not reading `this.VERSION`, so bundlers can drop Fetcher when unused (see treeshake.test.ts)
35
+ static userAgent = /* @__PURE__ */ isServerSide() ? `fetcher/${FETCHER_VERSION}` : undefined;
34
36
  constructor(cfg = {}) {
35
- if (typeof globalThis.fetch !== 'function') {
36
- throw new TypeError('globalThis.fetch is not available');
37
- }
38
37
  this.cfg = this.normalizeCfg(cfg);
39
38
  // Dynamically create all helper methods
40
39
  for (const method of HTTP_METHODS) {
@@ -184,7 +183,7 @@ export class Fetcher {
184
183
  requestSignature: res.signature,
185
184
  requestName: res.req.requestName,
186
185
  fetcherName: this.cfg.name,
187
- requestDuration: Date.now() - res.req.started,
186
+ requestDuration: nowUnixMillis() - res.req.started,
188
187
  });
189
188
  }
190
189
  const { data } = res.body;
@@ -314,7 +313,7 @@ export class Fetcher {
314
313
  signature,
315
314
  };
316
315
  while (!res.retryStatus.retryStopped) {
317
- req.started = Date.now();
316
+ req.started = nowUnixMillis();
318
317
  res.body = undefined;
319
318
  req.init.signal = abortSignalAnyOrUndefined([
320
319
  abortSignalTimeoutOrUndefined(timeoutMillis),
@@ -532,7 +531,7 @@ export class Fetcher {
532
531
  requestSignature: res.signature,
533
532
  requestName: res.req.requestName,
534
533
  fetcherName: this.cfg.name,
535
- requestDuration: Date.now() - res.req.started,
534
+ requestDuration: nowUnixMillis() - res.req.started,
536
535
  }), {
537
536
  cause,
538
537
  });
@@ -609,16 +608,17 @@ export class Fetcher {
609
608
  if (retryAfterNumber > 10 ** 9) {
610
609
  // Value is too large to be a "seconds from now" delay,
611
610
  // treat it as a UnixTimestamp instead (e.g GitHub sends `x-ratelimit-reset` like that)
612
- timeout = retryAfterNumber * 1000 - Date.now();
611
+ timeout = retryAfterNumber * 1000 - nowUnixMillis();
613
612
  }
614
613
  else {
615
614
  timeout = retryAfterNumber * 1000;
616
615
  }
617
616
  }
618
617
  else {
618
+ // oxlint-disable-next-line no-restricted-globals -- parses an HTTP-date, which localTime doesn't support
619
619
  const date = new Date(retryAfterStr);
620
620
  if (!Number.isNaN(date.getTime())) {
621
- timeout = date.getTime() - Date.now();
621
+ timeout = date.getTime() - nowUnixMillis();
622
622
  }
623
623
  }
624
624
  this.cfg.logger.log(`retry-after: ${retryAfterStr}`);
@@ -778,7 +778,7 @@ export class Fetcher {
778
778
  'fetchFn',
779
779
  'overrideFetchFn',
780
780
  ]),
781
- started: Date.now(),
781
+ started: nowUnixMillis(),
782
782
  ..._omit(opt, ['method', 'headers', 'credentials']),
783
783
  inputUrl: opt.url || '',
784
784
  fullUrl: opt.url || '',
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ export * from './bot.model.js';
4
4
  export * from './define.js';
5
5
  export * from './enum.util.js';
6
6
  export * from './env.js';
7
- export * from './env/buildInfo.js';
7
+ export type * from './env/buildInfo.js';
8
8
  export * from './form.util.js';
9
9
  export * from './is.util.js';
10
10
  export * from './iter/asyncIterable2.js';
package/dist/index.js CHANGED
@@ -4,7 +4,6 @@ export * from './bot.model.js';
4
4
  export * from './define.js';
5
5
  export * from './enum.util.js';
6
6
  export * from './env.js';
7
- export * from './env/buildInfo.js';
8
7
  export * from './form.util.js';
9
8
  export * from './is.util.js';
10
9
  export * from './iter/asyncIterable2.js';
@@ -115,6 +115,7 @@ export function _deepJsonEquals(a, b) {
115
115
  a = undefined;
116
116
  }
117
117
  else if (a && typeof a === 'object') {
118
+ // oxlint-disable-next-line no-restricted-globals -- Date instances are compared by value
118
119
  if (a instanceof Date) {
119
120
  ;
120
121
  a = a.valueOf();
@@ -132,6 +133,7 @@ export function _deepJsonEquals(a, b) {
132
133
  b = undefined;
133
134
  }
134
135
  else if (b && typeof b === 'object') {
136
+ // oxlint-disable-next-line no-restricted-globals -- Date instances are compared by value
135
137
  if (b instanceof Date) {
136
138
  ;
137
139
  b = b.valueOf();
@@ -1,4 +1,4 @@
1
- import { _assert } from '../error/index.js';
1
+ import { _assert } from '../error/assert.js';
2
2
  export class KeySortedMap {
3
3
  map;
4
4
  #sortedKeys;
@@ -1,4 +1,4 @@
1
- import { _assert } from '../error/index.js';
1
+ import { _assert } from '../error/assert.js';
2
2
  export class LazyKeySortedMap {
3
3
  map;
4
4
  maybeSortedKeys;
@@ -387,7 +387,7 @@ export function _unset(obj, prop) {
387
387
  if (!_isObject(obj)) {
388
388
  return;
389
389
  }
390
- if (obj.hasOwnProperty(prop)) {
390
+ if (Object.hasOwn(obj, prop)) {
391
391
  delete obj[prop];
392
392
  return;
393
393
  }
@@ -512,7 +512,7 @@ export function _deepFreeze(o) {
512
512
  // Object.freeze — never assigns properties from one object to another.
513
513
  Object.freeze(o);
514
514
  Object.getOwnPropertyNames(o).forEach(prop => {
515
- if (o.hasOwnProperty(prop) &&
515
+ if (Object.hasOwn(o, prop) &&
516
516
  o[prop] !== null &&
517
517
  (typeof o[prop] === 'object' || typeof o[prop] === 'function') &&
518
518
  !Object.isFrozen(o[prop])) {
@@ -1,3 +1,4 @@
1
+ import { nowUnixMillis } from '../datetime/time.util.js';
1
2
  import { ErrorMode } from '../error/errorMode.js';
2
3
  import { createCommonLoggerAtLevel } from '../log/commonLogger.js';
3
4
  import { pDefer } from './pDefer.js';
@@ -34,7 +35,7 @@ export class PGradualQueue {
34
35
  // Fast-path: warmup complete
35
36
  if (this.warmupComplete)
36
37
  return this.cfg.concurrency;
37
- const elapsed = Date.now() - this.startTime;
38
+ const elapsed = nowUnixMillis() - this.startTime;
38
39
  if (elapsed >= this.warmupMs) {
39
40
  this.warmupComplete = true;
40
41
  this.logger.debug('warmup complete');
@@ -51,7 +52,7 @@ export class PGradualQueue {
51
52
  async push(fn) {
52
53
  // Initialize start time on first push
53
54
  if (this.startTime === 0) {
54
- this.startTime = Date.now();
55
+ this.startTime = nowUnixMillis();
55
56
  }
56
57
  const job = { fn, defer: pDefer() };
57
58
  const concurrency = this.getCurrentConcurrency();
@@ -1,4 +1,4 @@
1
- import { _since } from '../datetime/time.util.js';
1
+ import { _since, nowUnixMillis } from '../datetime/time.util.js';
2
2
  import { _errorDataAppend } from '../error/error.util.js';
3
3
  import { consoleLogger } from '../log/commonLogger.js';
4
4
  import { pDelay } from './pDelay.js';
@@ -26,7 +26,7 @@ export async function pRetry(fn, opt = {}) {
26
26
  let delay = initialDelay;
27
27
  let attempt = 0;
28
28
  while (true) {
29
- const started = Date.now();
29
+ const started = nowUnixMillis();
30
30
  try {
31
31
  attempt++;
32
32
  if ((attempt === 1 && logFirstAttempt) || (attempt > 1 && logRetries)) {