@naturalcycles/js-lib 15.101.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 (53) 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 +3 -3
  9. package/dist/browser/analytics.util.js +1 -1
  10. package/dist/browser/topbar.js +1 -1
  11. package/dist/datetime/localDate.js +10 -5
  12. package/dist/datetime/localTime.d.ts +2 -19
  13. package/dist/datetime/localTime.js +12 -30
  14. package/dist/datetime/time.util.d.ts +18 -1
  15. package/dist/datetime/time.util.js +28 -5
  16. package/dist/decorators/createPromiseDecorator.js +1 -1
  17. package/dist/decorators/debounce.js +1 -1
  18. package/dist/decorators/logMethod.decorator.js +1 -2
  19. package/dist/error/tryCatch.js +1 -2
  20. package/dist/http/fetcher.js +6 -8
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.js +0 -1
  23. package/dist/object/keySortedMap.js +1 -1
  24. package/dist/object/lazyKeySortedMap.js +1 -1
  25. package/dist/object/object.util.js +2 -2
  26. package/dist/promise/pGradualQueue.js +1 -1
  27. package/dist/promise/pRetry.js +1 -2
  28. package/dist/semver.js +10 -5
  29. package/dist/string/stringify.js +1 -2
  30. package/package.json +4 -2
  31. package/src/abort.ts +2 -21
  32. package/src/array/array.util.ts +1 -3
  33. package/src/array/sort.ts +1 -1
  34. package/src/array/sortedSet.ts +1 -1
  35. package/src/asyncManager.ts +3 -3
  36. package/src/browser/analytics.util.ts +1 -1
  37. package/src/browser/topbar.ts +1 -1
  38. package/src/datetime/localDate.ts +11 -7
  39. package/src/datetime/localTime.ts +12 -34
  40. package/src/datetime/time.util.ts +32 -5
  41. package/src/decorators/createPromiseDecorator.ts +1 -1
  42. package/src/decorators/debounce.ts +1 -1
  43. package/src/decorators/logMethod.decorator.ts +1 -2
  44. package/src/error/tryCatch.ts +1 -2
  45. package/src/http/fetcher.ts +7 -9
  46. package/src/index.ts +1 -1
  47. package/src/object/keySortedMap.ts +1 -1
  48. package/src/object/lazyKeySortedMap.ts +1 -1
  49. package/src/object/object.util.ts +2 -2
  50. package/src/promise/pGradualQueue.ts +1 -1
  51. package/src/promise/pRetry.ts +1 -2
  52. package/src/semver.ts +11 -7
  53. 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,4 +1,4 @@
1
- import { nowUnixMillis } from './datetime/localTime.js';
1
+ import { nowUnixMillis } from './datetime/time.util.js';
2
2
  import { consoleLogger } from './log/commonLogger.js';
3
3
  class AsyncManagerImpl {
4
4
  logger = consoleLogger;
@@ -82,6 +82,6 @@ class AsyncManagerImpl {
82
82
  *
83
83
  * @experimental
84
84
  */
85
- export const AsyncManager = new AsyncManagerImpl();
85
+ export const AsyncManager = /* @__PURE__ */ new AsyncManagerImpl();
86
86
  // Shorthand alias
87
- export const runInBackground = AsyncManager.runInBackground.bind(AsyncManager);
87
+ export const runInBackground = /* @__PURE__ */ AsyncManager.runInBackground.bind(AsyncManager);
@@ -1,4 +1,4 @@
1
- import { newDate, nowUnixMillis } from '../datetime/localTime.js';
1
+ import { newDate, nowUnixMillis } from '../datetime/time.util.js';
2
2
  import { isServerSide } from '../env.js';
3
3
  import { loadScript } from './script.util.js';
4
4
  /**
@@ -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
+ }
@@ -258,13 +258,13 @@ declare class LocalTimeFactory {
258
258
  Convenience function to return current Unix timestamp in seconds.
259
259
  Like Date.now(), but in seconds.
260
260
 
261
- Import nowUnix function individually in places where importing localTime is too heavy.
261
+ Import nowUnix from time.util.js in places where importing localTime is too heavy.
262
262
  */
263
263
  nowUnix(): UnixTimestamp;
264
264
  /**
265
265
  Convenience function that retuns the same as Date.now(), but with proper type of UnixTimestampMillis.
266
266
 
267
- Import nowUnixMillis function individually in places where importing localTime is too heavy.
267
+ Import nowUnixMillis from time.util.js in places where importing localTime is too heavy.
268
268
  */
269
269
  nowUnixMillis(): UnixTimestampMillis;
270
270
  /**
@@ -335,21 +335,4 @@ interface LocalTimeFn extends LocalTimeFactory {
335
335
  (d: LocalTimeInput): LocalTime;
336
336
  }
337
337
  export declare const localTime: LocalTimeFn;
338
- /**
339
- * Can be used instead of `oxlint-disable ...` in places where Date is intentionally needed
340
- */
341
- export declare function newDate(): Date;
342
- /**
343
- Convenience function to return current Unix timestamp in seconds.
344
- Like Date.now(), but in seconds.
345
-
346
- Import nowUnix function individually in places where importing localTime is too heavy.
347
- */
348
- export declare function nowUnix(): UnixTimestamp;
349
- /**
350
- Convenience function that retuns the same as Date.now(), but with proper type of UnixTimestampMillis.
351
-
352
- Import nowUnixMillis function individually in places where importing localTime is too heavy.
353
- */
354
- export declare function nowUnixMillis(): UnixTimestampMillis;
355
338
  export {};
@@ -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;
@@ -677,7 +677,7 @@ class LocalTimeFactory {
677
677
  Convenience function to return current Unix timestamp in seconds.
678
678
  Like Date.now(), but in seconds.
679
679
 
680
- Import nowUnix function individually in places where importing localTime is too heavy.
680
+ Import nowUnix from time.util.js in places where importing localTime is too heavy.
681
681
  */
682
682
  nowUnix() {
683
683
  return nowUnix();
@@ -685,7 +685,7 @@ class LocalTimeFactory {
685
685
  /**
686
686
  Convenience function that retuns the same as Date.now(), but with proper type of UnixTimestampMillis.
687
687
 
688
- Import nowUnixMillis function individually in places where importing localTime is too heavy.
688
+ Import nowUnixMillis from time.util.js in places where importing localTime is too heavy.
689
689
  */
690
690
  nowUnixMillis() {
691
691
  return nowUnixMillis();
@@ -1031,31 +1031,13 @@ function getWallComponentsInTimezone(date, tz) {
1031
1031
  }
1032
1032
  return dto;
1033
1033
  }
1034
- const localTimeFactory = new LocalTimeFactory();
1035
- export const localTime = localTimeFactory.fromInput.bind(localTimeFactory);
1036
- // The line below is the blackest of black magic I have ever written in 2024.
1037
- // And probably 2023 as well.
1038
- Object.setPrototypeOf(localTime, localTimeFactory);
1039
- /**
1040
- * Can be used instead of `oxlint-disable ...` in places where Date is intentionally needed
1041
- */
1042
- export function newDate() {
1043
- return new Date();
1044
- }
1045
- /**
1046
- Convenience function to return current Unix timestamp in seconds.
1047
- Like Date.now(), but in seconds.
1048
-
1049
- Import nowUnix function individually in places where importing localTime is too heavy.
1050
- */
1051
- export function nowUnix() {
1052
- return Math.floor(Date.now() / 1000);
1053
- }
1054
- /**
1055
- Convenience function that retuns the same as Date.now(), but with proper type of UnixTimestampMillis.
1056
-
1057
- Import nowUnixMillis function individually in places where importing localTime is too heavy.
1058
- */
1059
- export function nowUnixMillis() {
1060
- return Date.now();
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;
1061
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,8 +8,7 @@
8
8
  * @experimental
9
9
  */
10
10
  export function _blockTimer(name) {
11
- // oxlint-disable-next-line no-restricted-globals -- localTime imports this module, so it can't import localTime back
12
- const started = Date.now();
11
+ const started = nowUnixMillis();
13
12
  return {
14
13
  [Symbol.dispose]() {
15
14
  console.log(`${name ? name + ' ' : ''}took ${_since(started)}`);
@@ -19,9 +18,7 @@ export function _blockTimer(name) {
19
18
  /**
20
19
  * Returns time passed since `from` until `until` (default to Date.now())
21
20
  */
22
- export function _since(from,
23
- // oxlint-disable-next-line no-restricted-globals -- localTime imports this module, so it can't import localTime back
24
- until = Date.now()) {
21
+ export function _since(from, until = nowUnixMillis()) {
25
22
  return _ms(until - from);
26
23
  }
27
24
  /**
@@ -62,3 +59,29 @@ export function _ms(millis) {
62
59
  const days = Math.floor(hrs / 24);
63
60
  return `${days} days`;
64
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,4 +1,4 @@
1
- import { nowUnixMillis } from '../datetime/localTime.js';
1
+ import { nowUnixMillis } from '../datetime/time.util.js';
2
2
  import { _getTargetMethodSignature } from './decorator.util.js';
3
3
  /**
4
4
  * @example
@@ -1,4 +1,4 @@
1
- import { nowUnixMillis } from '../datetime/localTime.js';
1
+ import { nowUnixMillis } from '../datetime/time.util.js';
2
2
  import { _anyToError } from '../error/error.util.js';
3
3
  import { pDefer } from '../promise/pDefer.js';
4
4
  export function _debounce(func, wait, opt = {}) {
@@ -1,5 +1,4 @@
1
- import { nowUnixMillis } from '../datetime/localTime.js';
2
- import { _ms } from '../datetime/time.util.js';
1
+ import { _ms, nowUnixMillis } from '../datetime/time.util.js';
3
2
  import { _assert } from '../error/assert.js';
4
3
  import { consoleLogger } from '../log/commonLogger.js';
5
4
  import { SimpleMovingAverage } from '../math/sma.js';
@@ -1,5 +1,4 @@
1
- import { nowUnixMillis } from '../datetime/localTime.js';
2
- import { _since } from '../datetime/time.util.js';
1
+ import { _since, nowUnixMillis } from '../datetime/time.util.js';
3
2
  import { consoleLogger } from '../log/commonLogger.js';
4
3
  import { _anyToError } from './error.util.js';
5
4
  /**
@@ -2,8 +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 { nowUnixMillis } from '../datetime/localTime.js';
6
- import { _ms, _since } from '../datetime/time.util.js';
5
+ import { _ms, _since, nowUnixMillis } from '../datetime/time.util.js';
7
6
  import { isServerSide } from '../env.js';
8
7
  import { _assert, _assertErrorClassOrRethrow, _assertIsError } from '../error/assert.js';
9
8
  import { _anyToError, _anyToErrorObject, _errorDataAppend, _errorLikeToErrorObject, HttpRequestError, UnexpectedPassError, } from '../error/error.util.js';
@@ -12,9 +11,10 @@ import { _clamp } from '../number/number.util.js';
12
11
  import { _filterFalsyValues, _filterNullishValues, _filterUndefinedValues, _mapKeys, _merge, _omit, _pick, } from '../object/object.util.js';
13
12
  import { pDelaySignal } from '../promise/pDelay.js';
14
13
  import { pTimeout } from '../promise/pTimeout.js';
15
- import { _toUrlOrNull } from '../string/index.js';
16
14
  import { _jsonParse, _jsonParseIfPossible } from '../string/json.util.js';
15
+ import { _toUrlOrNull } from '../string/url.util.js';
17
16
  import { HTTP_METHODS } from './http.model.js';
17
+ const FETCHER_VERSION = 5;
18
18
  /**
19
19
  * Experimental wrapper around Fetch.
20
20
  * Works in both Browser and Node, using `globalThis.fetch`.
@@ -26,16 +26,14 @@ export class Fetcher {
26
26
  *
27
27
  * Version is to be incremented every time a difference in behaviour (or a bugfix) is done.
28
28
  */
29
- static VERSION = 5;
29
+ static VERSION = FETCHER_VERSION;
30
30
  /**
31
31
  * userAgent is statically exposed as Fetcher.userAgent.
32
32
  * It can be modified globally, and will be used (read) at the start of every request.
33
33
  */
34
- 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;
35
36
  constructor(cfg = {}) {
36
- if (typeof globalThis.fetch !== 'function') {
37
- throw new TypeError('globalThis.fetch is not available');
38
- }
39
37
  this.cfg = this.normalizeCfg(cfg);
40
38
  // Dynamically create all helper methods
41
39
  for (const method of HTTP_METHODS) {
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';
@@ -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,4 +1,4 @@
1
- import { nowUnixMillis } from '../datetime/localTime.js';
1
+ import { nowUnixMillis } from '../datetime/time.util.js';
2
2
  import { ErrorMode } from '../error/errorMode.js';
3
3
  import { createCommonLoggerAtLevel } from '../log/commonLogger.js';
4
4
  import { pDefer } from './pDefer.js';
@@ -1,5 +1,4 @@
1
- import { nowUnixMillis } from '../datetime/localTime.js';
2
- import { _since } from '../datetime/time.util.js';
1
+ import { _since, nowUnixMillis } from '../datetime/time.util.js';
3
2
  import { _errorDataAppend } from '../error/error.util.js';
4
3
  import { consoleLogger } from '../log/commonLogger.js';
5
4
  import { pDelay } from './pDelay.js';
package/dist/semver.js CHANGED
@@ -126,11 +126,16 @@ class SemverFactory {
126
126
  return opt.mutate ? items.sort(cmp) : items.toSorted(cmp);
127
127
  }
128
128
  }
129
- const semverFactory = new SemverFactory();
130
- export const semver2 = semverFactory.fromInput.bind(semverFactory);
131
- // The line below is the blackest of black magic I have ever written in 2024.
132
- // And probably 2023 as well.
133
- Object.setPrototypeOf(semver2, semverFactory);
129
+ // Built inside a function, so the whole construct can be marked pure and tree-shaken (see treeshake.test.ts)
130
+ export const semver2 = /* @__PURE__ */ createSemverFn();
131
+ function createSemverFn() {
132
+ const semverFactory = new SemverFactory();
133
+ const fn = semverFactory.fromInput.bind(semverFactory);
134
+ // The line below is the blackest of black magic I have ever written in 2024.
135
+ // And probably 2023 as well.
136
+ Object.setPrototypeOf(fn, semverFactory);
137
+ return fn;
138
+ }
134
139
  /**
135
140
  * Returns 1 if a > b
136
141
  * returns 0 if they are equal
@@ -4,7 +4,6 @@ import { _isBackendErrorResponseObject, _isErrorLike, _isErrorObject } from '../
4
4
  import { _jsonParseIfPossible } from './json.util.js';
5
5
  import { _safeJsonStringify } from './safeJsonStringify.js';
6
6
  import { _truncateMiddle } from './string.util.js';
7
- const supportsAggregateError = typeof globalThis.AggregateError === 'function';
8
7
  let globalStringifyFunction = _safeJsonStringify;
9
8
  /**
10
9
  * Allows to set Global "stringifyFunction" that will be used to "pretty-print" objects
@@ -127,7 +126,7 @@ function stringifyErrorLike(obj, opt) {
127
126
  const sLines = s.split('\n').length;
128
127
  s = [s, ...obj.stack.split('\n').slice(sLines)].join('\n');
129
128
  }
130
- if (supportsAggregateError && obj instanceof AggregateError && obj.errors.length) {
129
+ if (obj instanceof AggregateError && obj.errors.length) {
131
130
  s = [
132
131
  s,
133
132
  `${obj.errors.length} error(s):`,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
3
  "type": "module",
4
- "version": "15.101.0",
4
+ "version": "15.102.0",
5
5
  "dependencies": {
6
6
  "tslib": "^2"
7
7
  },
@@ -14,9 +14,10 @@
14
14
  }
15
15
  },
16
16
  "devDependencies": {
17
- "@naturalcycles/dev-lib": "20.71.0",
17
+ "@naturalcycles/dev-lib": "20.72.0",
18
18
  "@types/node": "^26",
19
19
  "@types/semver": "^7",
20
+ "rolldown": "^1",
20
21
  "typescript": "^7",
21
22
  "dayjs": "^1"
22
23
  },
@@ -35,6 +36,7 @@
35
36
  "./decorators": "./dist/decorators/index.js",
36
37
  "./decorators/*.js": "./dist/decorators/*.js",
37
38
  "./deviceIdService": "./dist/deviceIdService.js",
39
+ "./env/*.js": "./dist/env/*.js",
38
40
  "./error": "./dist/error/index.js",
39
41
  "./error/*.js": "./dist/error/*.js",
40
42
  "./http": "./dist/http/index.js",
package/src/abort.ts CHANGED
@@ -39,27 +39,7 @@ export function createAbortableSignal(): AbortableSignal {
39
39
  export function abortSignalTimeoutOrUndefined(
40
40
  ms: NumberOfMilliseconds | undefined,
41
41
  ): AbortSignal | undefined {
42
- return ms ? abortSignalTimeout(ms) : undefined
43
- }
44
-
45
- /**
46
- * Returns an AbortSignal that aborts after the given number of milliseconds.
47
- * Uses native `AbortSignal.timeout()` when available, falls back to a polyfill.
48
- *
49
- * The abort reason is a DOMException with name "TimeoutError".
50
- */
51
- export function abortSignalTimeout(ms: NumberOfMilliseconds): AbortSignal {
52
- return typeof AbortSignal.timeout === 'function'
53
- ? AbortSignal.timeout(ms)
54
- : polyfilledAbortSignalTimeout(ms)
55
- }
56
-
57
- export function polyfilledAbortSignalTimeout(ms: NumberOfMilliseconds): AbortSignal {
58
- const ac = new AbortController()
59
- setTimeout(() => {
60
- ac.abort(new DOMException('The operation was aborted due to timeout', 'TimeoutError'))
61
- }, ms)
62
- return ac.signal
42
+ return ms ? AbortSignal.timeout(ms) : undefined
63
43
  }
64
44
 
65
45
  /**
@@ -87,6 +67,7 @@ export function abortSignalAny(signals: readonly AbortSignal[]): AbortSignal {
87
67
  return signals[0]!
88
68
  }
89
69
 
70
+ // AbortSignal.any needs Chrome 116+ / Safari 17.4+, above our browser floor (Chrome 110, iOS 16.7)
90
71
  return typeof AbortSignal.any === 'function'
91
72
  ? AbortSignal.any(signals as AbortSignal[]) // lib.dom types require a mutable array, but it is only read
92
73
  : polyfilledAbortSignalAny(signals)
@@ -195,9 +195,7 @@ export function _find<T>(items: readonly T[], predicate: AbortablePredicate<T>):
195
195
  /**
196
196
  * Similar to `Array.findLast`, but the `predicate` may return `END` to stop the iteration early.
197
197
  *
198
- * Use `Array.findLast` if you don't need to stop the iteration early, which is supported:
199
- * - in Node since 18+
200
- * - in iOS Safari since 15.4
198
+ * Use `Array.findLast` if you don't need to stop the iteration early.
201
199
  */
202
200
  export function _findLast<T>(items: readonly T[], predicate: AbortablePredicate<T>): T | undefined {
203
201
  return _find(items.toReversed(), predicate)
package/src/array/sort.ts CHANGED
@@ -55,7 +55,7 @@ class Comparators {
55
55
  }
56
56
  }
57
57
 
58
- export const comparators = new Comparators()
58
+ export const comparators = /* @__PURE__ */ new Comparators()
59
59
 
60
60
  interface ComparatorByOptions {
61
61
  /**
@@ -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
 
4
4
  export interface SortedSetOptions<T> {
@@ -1,4 +1,4 @@
1
- import { nowUnixMillis } from './datetime/localTime.js'
1
+ import { nowUnixMillis } from './datetime/time.util.js'
2
2
  import { consoleLogger } from './log/commonLogger.js'
3
3
  import type { CommonLogger } from './log/commonLogger.js'
4
4
  import type { NumberOfMilliseconds } from './types.js'
@@ -93,9 +93,9 @@ class AsyncManagerImpl {
93
93
  *
94
94
  * @experimental
95
95
  */
96
- export const AsyncManager = new AsyncManagerImpl()
96
+ export const AsyncManager = /* @__PURE__ */ new AsyncManagerImpl()
97
97
 
98
98
  // Shorthand alias
99
- export const runInBackground = AsyncManager.runInBackground.bind(AsyncManager)
99
+ export const runInBackground = /* @__PURE__ */ AsyncManager.runInBackground.bind(AsyncManager)
100
100
 
101
101
  export type OnErrorHook = (err: Error) => any
@@ -1,4 +1,4 @@
1
- import { newDate, nowUnixMillis } from '../datetime/localTime.js'
1
+ import { newDate, nowUnixMillis } from '../datetime/time.util.js'
2
2
  import { isServerSide } from '../env.js'
3
3
  import { loadScript } from './script.util.js'
4
4
 
@@ -82,7 +82,7 @@ const createCanvas = () => {
82
82
  export const topbar = {
83
83
  config(opts: TopBarOptions) {
84
84
  for (const key in opts) {
85
- if (options.hasOwnProperty(key)) {
85
+ if (Object.hasOwn(options, key)) {
86
86
  // @ts-expect-error
87
87
  options[key] = opts[key]
88
88
  }
@@ -853,10 +853,14 @@ interface LocalDateFn extends LocalDateFactory {
853
853
  (d: LocalDateInput): LocalDate
854
854
  }
855
855
 
856
- const localDateFactory = new LocalDateFactory()
857
-
858
- export const localDate = localDateFactory.fromInput.bind(localDateFactory) as LocalDateFn
859
-
860
- // The line below is the blackest of black magic I have ever written in 2024.
861
- // And probably 2023 as well.
862
- Object.setPrototypeOf(localDate, localDateFactory)
856
+ // Built inside a function, so the whole construct can be marked pure and tree-shaken (see treeshake.test.ts)
857
+ export const localDate = /* @__PURE__ */ createLocalDateFn()
858
+
859
+ function createLocalDateFn(): LocalDateFn {
860
+ const localDateFactory = new LocalDateFactory()
861
+ const fn = localDateFactory.fromInput.bind(localDateFactory) as LocalDateFn
862
+ // The line below is the blackest of black magic I have ever written in 2024.
863
+ // And probably 2023 as well.
864
+ Object.setPrototypeOf(fn, localDateFactory)
865
+ return fn
866
+ }
@@ -17,7 +17,7 @@ import type {
17
17
  // oxlint-disable-next-line import/no-cycle -- intentional cycle
18
18
  import type { LocalDate } from './localDate.js'
19
19
  import { localDate } from './localDate.js'
20
- import { _ms } from './time.util.js'
20
+ import { _ms, nowUnix, nowUnixMillis } from './time.util.js'
21
21
  // oxlint-disable-next-line import/no-cycle -- intentional cycle
22
22
  import { WallTime } from './wallTime.js'
23
23
 
@@ -817,7 +817,7 @@ class LocalTimeFactory {
817
817
  Convenience function to return current Unix timestamp in seconds.
818
818
  Like Date.now(), but in seconds.
819
819
 
820
- Import nowUnix function individually in places where importing localTime is too heavy.
820
+ Import nowUnix from time.util.js in places where importing localTime is too heavy.
821
821
  */
822
822
  nowUnix(): UnixTimestamp {
823
823
  return nowUnix()
@@ -826,7 +826,7 @@ class LocalTimeFactory {
826
826
  /**
827
827
  Convenience function that retuns the same as Date.now(), but with proper type of UnixTimestampMillis.
828
828
 
829
- Import nowUnixMillis function individually in places where importing localTime is too heavy.
829
+ Import nowUnixMillis from time.util.js in places where importing localTime is too heavy.
830
830
  */
831
831
  nowUnixMillis(): UnixTimestampMillis {
832
832
  return nowUnixMillis()
@@ -1212,36 +1212,14 @@ interface LocalTimeFn extends LocalTimeFactory {
1212
1212
  (d: LocalTimeInput): LocalTime
1213
1213
  }
1214
1214
 
1215
- const localTimeFactory = new LocalTimeFactory()
1215
+ // Built inside a function, so the whole construct can be marked pure and tree-shaken (see treeshake.test.ts)
1216
+ export const localTime = /* @__PURE__ */ createLocalTimeFn()
1216
1217
 
1217
- export const localTime = localTimeFactory.fromInput.bind(localTimeFactory) as LocalTimeFn
1218
-
1219
- // The line below is the blackest of black magic I have ever written in 2024.
1220
- // And probably 2023 as well.
1221
- Object.setPrototypeOf(localTime, localTimeFactory)
1222
-
1223
- /**
1224
- * Can be used instead of `oxlint-disable ...` in places where Date is intentionally needed
1225
- */
1226
- export function newDate(): Date {
1227
- return new Date()
1228
- }
1229
-
1230
- /**
1231
- Convenience function to return current Unix timestamp in seconds.
1232
- Like Date.now(), but in seconds.
1233
-
1234
- Import nowUnix function individually in places where importing localTime is too heavy.
1235
- */
1236
- export function nowUnix(): UnixTimestamp {
1237
- return Math.floor(Date.now() / 1000) as UnixTimestamp
1238
- }
1239
-
1240
- /**
1241
- Convenience function that retuns the same as Date.now(), but with proper type of UnixTimestampMillis.
1242
-
1243
- Import nowUnixMillis function individually in places where importing localTime is too heavy.
1244
- */
1245
- export function nowUnixMillis(): UnixTimestampMillis {
1246
- return Date.now() as UnixTimestampMillis
1218
+ function createLocalTimeFn(): LocalTimeFn {
1219
+ const localTimeFactory = new LocalTimeFactory()
1220
+ const fn = localTimeFactory.fromInput.bind(localTimeFactory) as LocalTimeFn
1221
+ // The line below is the blackest of black magic I have ever written in 2024.
1222
+ // And probably 2023 as well.
1223
+ Object.setPrototypeOf(fn, localTimeFactory)
1224
+ return fn
1247
1225
  }
@@ -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
  /**
4
4
  * using _ = blockTimer()
@@ -10,8 +10,7 @@ import type { NumberOfMilliseconds, UnixTimestampMillis } from '../types.js'
10
10
  * @experimental
11
11
  */
12
12
  export function _blockTimer(name?: string): Disposable {
13
- // oxlint-disable-next-line no-restricted-globals -- localTime imports this module, so it can't import localTime back
14
- const started = Date.now() as UnixTimestampMillis
13
+ const started = nowUnixMillis()
15
14
  return {
16
15
  [Symbol.dispose](): void {
17
16
  console.log(`${name ? name + ' ' : ''}took ${_since(started)}`)
@@ -24,8 +23,7 @@ export function _blockTimer(name?: string): Disposable {
24
23
  */
25
24
  export function _since(
26
25
  from: UnixTimestampMillis,
27
- // oxlint-disable-next-line no-restricted-globals -- localTime imports this module, so it can't import localTime back
28
- until: UnixTimestampMillis = Date.now() as UnixTimestampMillis,
26
+ until: UnixTimestampMillis = nowUnixMillis(),
29
27
  ): string {
30
28
  return _ms(until - from)
31
29
  }
@@ -74,3 +72,32 @@ export function _ms(millis: NumberOfMilliseconds): string {
74
72
  const days = Math.floor(hrs / 24)
75
73
  return `${days} days`
76
74
  }
75
+
76
+ /**
77
+ * Can be used instead of `oxlint-disable ...` in places where Date is intentionally needed
78
+ */
79
+ export function newDate(): Date {
80
+ // oxlint-disable-next-line no-restricted-globals -- the one sanctioned way to get a native Date
81
+ return new Date()
82
+ }
83
+
84
+ /**
85
+ Convenience function to return current Unix timestamp in seconds.
86
+ Like Date.now(), but in seconds.
87
+
88
+ Lives here rather than in localTime.ts, so importing it doesn't pull LocalTime into browser bundles.
89
+ */
90
+ export function nowUnix(): UnixTimestamp {
91
+ // oxlint-disable-next-line no-restricted-globals -- the one sanctioned way to read the clock
92
+ return Math.floor(Date.now() / 1000) as UnixTimestamp
93
+ }
94
+
95
+ /**
96
+ Convenience function that retuns the same as Date.now(), but with proper type of UnixTimestampMillis.
97
+
98
+ Lives here rather than in localTime.ts, so importing it doesn't pull LocalTime into browser bundles.
99
+ */
100
+ export function nowUnixMillis(): UnixTimestampMillis {
101
+ // oxlint-disable-next-line no-restricted-globals -- the one sanctioned way to read the clock
102
+ return Date.now() as UnixTimestampMillis
103
+ }
@@ -1,4 +1,4 @@
1
- import { nowUnixMillis } from '../datetime/localTime.js'
1
+ import { nowUnixMillis } from '../datetime/time.util.js'
2
2
  import { _getTargetMethodSignature } from './decorator.util.js'
3
3
 
4
4
  export interface PromiseDecoratorCfg<RES = any, PARAMS = any> {
@@ -1,4 +1,4 @@
1
- import { nowUnixMillis } from '../datetime/localTime.js'
1
+ import { nowUnixMillis } from '../datetime/time.util.js'
2
2
  import { _anyToError } from '../error/error.util.js'
3
3
  import { pDefer } from '../promise/pDefer.js'
4
4
  import type { DeferredPromise } from '../promise/pDefer.js'
@@ -1,5 +1,4 @@
1
- import { nowUnixMillis } from '../datetime/localTime.js'
2
- import { _ms } from '../datetime/time.util.js'
1
+ import { _ms, nowUnixMillis } from '../datetime/time.util.js'
3
2
  import { _assert } from '../error/assert.js'
4
3
  import { consoleLogger } from '../log/commonLogger.js'
5
4
  import type { CommonLogger } from '../log/commonLogger.js'
@@ -1,5 +1,4 @@
1
- import { nowUnixMillis } from '../datetime/localTime.js'
2
- import { _since } from '../datetime/time.util.js'
1
+ import { _since, nowUnixMillis } from '../datetime/time.util.js'
3
2
  import { consoleLogger } from '../log/commonLogger.js'
4
3
  import type { CommonLogger } from '../log/commonLogger.js'
5
4
  import type { AnyFunction } from '../types.js'
@@ -4,8 +4,7 @@
4
4
 
5
5
  import type { ReadableStream as WebReadableStream } from 'node:stream/web'
6
6
  import { abortSignalAnyOrUndefined, abortSignalTimeoutOrUndefined } from '../abort.js'
7
- import { nowUnixMillis } from '../datetime/localTime.js'
8
- import { _ms, _since } from '../datetime/time.util.js'
7
+ import { _ms, _since, nowUnixMillis } from '../datetime/time.util.js'
9
8
  import { isServerSide } from '../env.js'
10
9
  import { _assert, _assertErrorClassOrRethrow, _assertIsError } from '../error/assert.js'
11
10
  import type { ErrorLike, ErrorObject } from '../error/error.model.js'
@@ -30,8 +29,8 @@ import {
30
29
  } from '../object/object.util.js'
31
30
  import { pDelaySignal } from '../promise/pDelay.js'
32
31
  import { pTimeout } from '../promise/pTimeout.js'
33
- import { _toUrlOrNull } from '../string/index.js'
34
32
  import { _jsonParse, _jsonParseIfPossible } from '../string/json.util.js'
33
+ import { _toUrlOrNull } from '../string/url.util.js'
35
34
  import type { AnyObject, ErrorDataTuple, NumberOfMilliseconds } from '../types.js'
36
35
  import type {
37
36
  FetcherAfterResponseHook,
@@ -56,6 +55,8 @@ import type {
56
55
  import type { HttpStatusFamily } from './http.model.js'
57
56
  import { HTTP_METHODS } from './http.model.js'
58
57
 
58
+ const FETCHER_VERSION = 5
59
+
59
60
  /**
60
61
  * Experimental wrapper around Fetch.
61
62
  * Works in both Browser and Node, using `globalThis.fetch`.
@@ -67,18 +68,15 @@ export class Fetcher {
67
68
  *
68
69
  * Version is to be incremented every time a difference in behaviour (or a bugfix) is done.
69
70
  */
70
- static readonly VERSION = 5
71
+ static readonly VERSION = FETCHER_VERSION
71
72
  /**
72
73
  * userAgent is statically exposed as Fetcher.userAgent.
73
74
  * It can be modified globally, and will be used (read) at the start of every request.
74
75
  */
75
- static userAgent = isServerSide() ? `fetcher/${this.VERSION}` : undefined
76
+ // Pure, and not reading `this.VERSION`, so bundlers can drop Fetcher when unused (see treeshake.test.ts)
77
+ static userAgent = /* @__PURE__ */ isServerSide() ? `fetcher/${FETCHER_VERSION}` : undefined
76
78
 
77
79
  private constructor(cfg: FetcherCfg & FetcherOptions = {}) {
78
- if (typeof globalThis.fetch !== 'function') {
79
- throw new TypeError('globalThis.fetch is not available')
80
- }
81
-
82
80
  this.cfg = this.normalizeCfg(cfg)
83
81
 
84
82
  // Dynamically create all helper methods
package/src/index.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'
@@ -1,4 +1,4 @@
1
- import { _assert } from '../error/index.js'
1
+ import { _assert } from '../error/assert.js'
2
2
  import type { Comparator } from '../types.js'
3
3
 
4
4
  export interface KeySortedMapOptions<K> {
@@ -1,4 +1,4 @@
1
- import { _assert } from '../error/index.js'
1
+ import { _assert } from '../error/assert.js'
2
2
  import type { Comparator } from '../types.js'
3
3
 
4
4
  export interface LazyKeySortedMapOptions<K> {
@@ -452,7 +452,7 @@ export function _unset<T extends AnyObject>(obj: T, prop: string): void {
452
452
  return
453
453
  }
454
454
 
455
- if (obj.hasOwnProperty(prop)) {
455
+ if (Object.hasOwn(obj, prop)) {
456
456
  delete obj[prop]
457
457
  return
458
458
  }
@@ -599,7 +599,7 @@ export function _deepFreeze(o: any): void {
599
599
 
600
600
  Object.getOwnPropertyNames(o).forEach(prop => {
601
601
  if (
602
- o.hasOwnProperty(prop) &&
602
+ Object.hasOwn(o, prop) &&
603
603
  o[prop] !== null &&
604
604
  (typeof o[prop] === 'object' || typeof o[prop] === 'function') &&
605
605
  !Object.isFrozen(o[prop])
@@ -1,4 +1,4 @@
1
- import { nowUnixMillis } from '../datetime/localTime.js'
1
+ import { nowUnixMillis } from '../datetime/time.util.js'
2
2
  import { ErrorMode } from '../error/errorMode.js'
3
3
  import { createCommonLoggerAtLevel } from '../log/commonLogger.js'
4
4
  import type { CommonLogger, CommonLogLevel } from '../log/commonLogger.js'
@@ -1,5 +1,4 @@
1
- import { nowUnixMillis } from '../datetime/localTime.js'
2
- import { _since } from '../datetime/time.util.js'
1
+ import { _since, nowUnixMillis } from '../datetime/time.util.js'
3
2
  import type { ErrorData } from '../error/error.model.js'
4
3
  import { _errorDataAppend } from '../error/error.util.js'
5
4
  import { consoleLogger } from '../log/commonLogger.js'
package/src/semver.ts CHANGED
@@ -147,13 +147,17 @@ interface SemverFn extends SemverFactory {
147
147
  (input: SemverInput): Semver
148
148
  }
149
149
 
150
- const semverFactory = new SemverFactory()
151
-
152
- export const semver2 = semverFactory.fromInput.bind(semverFactory) as SemverFn
153
-
154
- // The line below is the blackest of black magic I have ever written in 2024.
155
- // And probably 2023 as well.
156
- Object.setPrototypeOf(semver2, semverFactory)
150
+ // Built inside a function, so the whole construct can be marked pure and tree-shaken (see treeshake.test.ts)
151
+ export const semver2 = /* @__PURE__ */ createSemverFn()
152
+
153
+ function createSemverFn(): SemverFn {
154
+ const semverFactory = new SemverFactory()
155
+ const fn = semverFactory.fromInput.bind(semverFactory) as SemverFn
156
+ // The line below is the blackest of black magic I have ever written in 2024.
157
+ // And probably 2023 as well.
158
+ Object.setPrototypeOf(fn, semverFactory)
159
+ return fn
160
+ }
157
161
 
158
162
  /**
159
163
  * Returns 1 if a > b
@@ -1,14 +1,12 @@
1
+ import type { ErrorLike } from '../error/error.model.js'
1
2
  // oxlint-disable-next-line import/no-cycle -- intentional cycle
2
3
  import { _isBackendErrorResponseObject, _isErrorLike, _isErrorObject } from '../error/error.util.js'
3
- import type { ErrorLike } from '../error/index.js'
4
4
  import type { Reviver } from '../types.js'
5
5
  // oxlint-disable-next-line import/no-cycle -- intentional cycle
6
6
  import { _jsonParseIfPossible } from './json.util.js'
7
7
  import { _safeJsonStringify } from './safeJsonStringify.js'
8
8
  import { _truncateMiddle } from './string.util.js'
9
9
 
10
- const supportsAggregateError = typeof globalThis.AggregateError === 'function'
11
-
12
10
  let globalStringifyFunction: JsonStringifyFunction = _safeJsonStringify
13
11
 
14
12
  /**
@@ -184,7 +182,7 @@ function stringifyErrorLike(obj: Error | ErrorLike, opt: StringifyOptions): stri
184
182
  s = [s, ...obj.stack.split('\n').slice(sLines)].join('\n')
185
183
  }
186
184
 
187
- if (supportsAggregateError && obj instanceof AggregateError && obj.errors.length) {
185
+ if (obj instanceof AggregateError && obj.errors.length) {
188
186
  s = [
189
187
  s,
190
188
  `${obj.errors.length} error(s):`,