@naturalcycles/js-lib 14.244.0 → 14.245.1

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 (40) hide show
  1. package/dist/datetime/dateInterval.d.ts +1 -1
  2. package/dist/datetime/localDate.d.ts +62 -43
  3. package/dist/datetime/localDate.js +153 -123
  4. package/dist/datetime/localTime.d.ts +57 -28
  5. package/dist/datetime/localTime.js +205 -138
  6. package/dist/datetime/timeInterval.d.ts +2 -2
  7. package/dist/datetime/timeInterval.js +2 -2
  8. package/dist/error/error.util.d.ts +1 -1
  9. package/dist/index.d.ts +37 -37
  10. package/dist/index.js +37 -37
  11. package/dist/json-schema/from-data/generateJsonSchemaFromData.d.ts +1 -1
  12. package/dist/json-schema/jsonSchemaBuilder.d.ts +1 -1
  13. package/dist/log/commonLogger.js +10 -9
  14. package/dist/object/object.util.d.ts +1 -1
  15. package/dist/time/time.util.js +4 -2
  16. package/dist/zod/zod.util.d.ts +1 -1
  17. package/dist-esm/datetime/localDate.js +153 -122
  18. package/dist-esm/datetime/localTime.js +205 -137
  19. package/dist-esm/datetime/timeInterval.js +2 -2
  20. package/dist-esm/decorators/logMethod.decorator.js +1 -1
  21. package/dist-esm/index.js +37 -37
  22. package/dist-esm/json-schema/jsonSchemaBuilder.js +1 -1
  23. package/dist-esm/log/commonLogger.js +2 -1
  24. package/dist-esm/time/time.util.js +4 -2
  25. package/package.json +1 -1
  26. package/src/datetime/dateInterval.ts +1 -1
  27. package/src/datetime/localDate.ts +157 -133
  28. package/src/datetime/localTime.ts +204 -149
  29. package/src/datetime/timeInterval.ts +4 -4
  30. package/src/decorators/logMethod.decorator.ts +1 -1
  31. package/src/define.ts +1 -1
  32. package/src/error/error.util.ts +3 -3
  33. package/src/http/fetcher.ts +1 -1
  34. package/src/index.ts +37 -37
  35. package/src/json-schema/from-data/generateJsonSchemaFromData.ts +1 -1
  36. package/src/json-schema/jsonSchemaBuilder.ts +2 -2
  37. package/src/log/commonLogger.ts +2 -1
  38. package/src/object/object.util.ts +1 -1
  39. package/src/time/time.util.ts +4 -1
  40. package/src/zod/zod.util.ts +1 -1
@@ -19,10 +19,22 @@ const SECONDS_IN_DAY = 86400;
19
19
  // const MILLISECONDS_IN_DAY = 86400000
20
20
  // const MILLISECONDS_IN_MINUTE = 60000
21
21
  const VALID_DAYS_OF_WEEK = new Set([1, 2, 3, 4, 5, 6, 7]);
22
- // It supports 2 forms:
23
- // 1. 2023-03-03
24
- // 2. 2023-03-03T05:10:02
25
- const DATE_TIME_REGEX = /^(\d{4})-(\d{2})-(\d{2})([T\s](\d{2}):(\d{2}):(\d{2}))?/;
22
+ /**
23
+ * It supports 2 forms:
24
+ * 1. 2023-03-03
25
+ * 2. 2023-03-03T05:10:02
26
+ * // todo: make it even looser, like Day.js
27
+ */
28
+ const DATE_TIME_REGEX_LOOSE = /^(\d{4})-(\d{2})-(\d{2})([Tt\s](\d{2}):?(\d{2})?:?(\d{2})?)?/;
29
+ /**
30
+ * Supports 2 forms:
31
+ * 1. 2023-03-03
32
+ * 2. 2023-03-03T05:10:02
33
+ * Ok, now it allows arbitrary stuff after `:ss`, to allow millis/timezone info,
34
+ * but it will not take it into account.
35
+ */
36
+ const DATE_TIME_REGEX_STRICT = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})/;
37
+ const DATE_REGEX_STRICT = /^(\d\d\d\d)-(\d\d)-(\d\d)$/;
26
38
  export class LocalTime {
27
39
  constructor($date) {
28
40
  this.$date = $date;
@@ -279,7 +291,7 @@ export class LocalTime {
279
291
  }
280
292
  if (unit === 'year' || unit === 'month') {
281
293
  const d = addMonths(this.$date, unit === 'month' ? num : num * 12, mutate);
282
- return mutate ? this : localTime.from(d);
294
+ return mutate ? this : localTime.fromInput(d);
283
295
  }
284
296
  return this.set(unit, this.get(unit) + num, mutate);
285
297
  }
@@ -290,7 +302,7 @@ export class LocalTime {
290
302
  return Math.abs(this.diff(other, unit));
291
303
  }
292
304
  diff(other, unit) {
293
- const date2 = localTime.from(other).$date;
305
+ const date2 = localTime.fromInput(other).$date;
294
306
  const secDiff = (this.$date.valueOf() - date2.valueOf()) / 1000;
295
307
  if (!secDiff)
296
308
  return 0;
@@ -418,13 +430,13 @@ export class LocalTime {
418
430
  * Third argument allows to override "now".
419
431
  */
420
432
  isOlderThan(n, unit, now) {
421
- return this.isBefore(localTime.from(now ?? new Date()).plus(-n, unit));
433
+ return this.isBefore(localTime.fromInput(now ?? new Date()).plus(-n, unit));
422
434
  }
423
435
  /**
424
436
  * Checks if this localTime is same or older (<=) than "now" by X units.
425
437
  */
426
438
  isSameOrOlderThan(n, unit, now) {
427
- return this.isSameOrBefore(localTime.from(now ?? new Date()).plus(-n, unit));
439
+ return this.isSameOrBefore(localTime.fromInput(now ?? new Date()).plus(-n, unit));
428
440
  }
429
441
  /**
430
442
  * Checks if this localTime is younger (>) than "now" by X units.
@@ -436,13 +448,13 @@ export class LocalTime {
436
448
  * Third argument allows to override "now".
437
449
  */
438
450
  isYoungerThan(n, unit, now) {
439
- return this.isAfter(localTime.from(now ?? new Date()).plus(-n, unit));
451
+ return this.isAfter(localTime.fromInput(now ?? new Date()).plus(-n, unit));
440
452
  }
441
453
  /**
442
454
  * Checks if this localTime is same or younger (>=) than "now" by X units.
443
455
  */
444
456
  isSameOrYoungerThan(n, unit, now) {
445
- return this.isSameOrAfter(localTime.from(now ?? new Date()).plus(-n, unit));
457
+ return this.isSameOrAfter(localTime.fromInput(now ?? new Date()).plus(-n, unit));
446
458
  }
447
459
  getAgeInYears(now) {
448
460
  return this.getAgeIn('year', now);
@@ -463,7 +475,7 @@ export class LocalTime {
463
475
  return this.getAgeIn('second', now);
464
476
  }
465
477
  getAgeIn(unit, now) {
466
- return localTime.from(now ?? new Date()).diff(this, unit);
478
+ return localTime.fromInput(now ?? new Date()).diff(this, unit);
467
479
  }
468
480
  /**
469
481
  * Returns 1 if this > d
@@ -472,7 +484,7 @@ export class LocalTime {
472
484
  */
473
485
  compare(d) {
474
486
  const t1 = this.$date.valueOf();
475
- const t2 = localTime.from(d).$date.valueOf();
487
+ const t2 = localTime.fromInput(d).$date.valueOf();
476
488
  if (t1 === t2)
477
489
  return 0;
478
490
  return t1 < t2 ? -1 : 1;
@@ -498,7 +510,7 @@ export class LocalTime {
498
510
  };
499
511
  }
500
512
  toFromNowString(now = new Date()) {
501
- const msDiff = localTime.from(now).$date.valueOf() - this.$date.valueOf();
513
+ const msDiff = localTime.fromInput(now).$date.valueOf() - this.$date.valueOf();
502
514
  if (msDiff === 0)
503
515
  return 'now';
504
516
  if (msDiff >= 0) {
@@ -604,118 +616,198 @@ export class LocalTime {
604
616
  }
605
617
  class LocalTimeFactory {
606
618
  /**
607
- * Parses input String into LocalTime.
608
- * Input can already be a LocalTime - it is returned as-is in that case.
619
+ * Creates a LocalTime from the input, unless it's falsy - then returns undefined.
620
+ *
621
+ * `localTime` function will instead return LocalTime of `now` for falsy input.
609
622
  */
610
- from(input) {
611
- const lt = this.fromOrNull(input);
612
- this.assertNotNull(lt, input);
613
- return lt;
623
+ orUndefined(input) {
624
+ return input || input === 0 ? this.fromInput(input) : undefined;
614
625
  }
615
- fromDate(date) {
616
- return new LocalTime(date);
626
+ /**
627
+ * Creates a LocalTime from the input, unless it's falsy - then returns LocalTime.now
628
+ */
629
+ orNow(input) {
630
+ return input || input === 0 ? this.fromInput(input) : this.now();
617
631
  }
618
- fromUnix(ts) {
619
- return new LocalTime(new Date(ts * 1000));
632
+ now() {
633
+ return new LocalTime(new Date());
620
634
  }
621
635
  /**
622
- * Create LocalTime from unixTimestamp in milliseconds (not in seconds).
636
+ Convenience function to return current Unix timestamp in seconds.
637
+ Like Date.now(), but in seconds.
623
638
  */
624
- fromMillis(millis) {
625
- return new LocalTime(new Date(millis));
639
+ nowUnix() {
640
+ return Math.floor(Date.now() / 1000);
626
641
  }
627
642
  /**
628
- * Returns null if invalid
643
+ * Create LocalTime from LocalTimeInput.
644
+ * Input can already be a LocalTime - it is returned as-is in that case.
645
+ * Date - will be used as-is.
646
+ * String - will be parsed as strict `yyyy-mm-ddThh:mm:ss`.
647
+ * Number - will be treated as unix timestamp in seconds.
629
648
  */
630
- fromOrNull(d) {
631
- if (d instanceof LocalTime)
632
- return d;
633
- if (d instanceof Date) {
634
- return new LocalTime(d);
635
- }
636
- if (typeof d === 'number') {
637
- return new LocalTime(new Date(d * 1000));
638
- }
639
- if (typeof d === 'string') {
640
- return this.fromStringOrNull(d);
641
- }
642
- // This check is after checking the number, to support `0`
643
- // unexpected type, e.g Function or something
644
- return null;
645
- }
646
- fromStringOrNull(s) {
647
- const date = this.parseStringToDateOrNull(s);
648
- return date ? new LocalTime(date) : null;
649
- }
650
- fromDateTimeObject(input) {
651
- const { year, month, day = 1, hour = 0, minute = 0, second = 0 } = input;
652
- return new LocalTime(new Date(year, month - 1, day, hour, minute, second));
653
- }
654
- parseStringToDateOrNull(s) {
655
- if (!s)
656
- return null;
657
- // Slicing removes the "timezone component", and makes the date "local"
658
- // e.g 2022-04-06T23:15:00+09:00
659
- // becomes 2022-04-06T23:15:00
660
- // date = new Date(d.slice(0, 19))
661
- // Parsing is inspired by how Day.js does it
662
- // Specifically, it ensures that `localTime('2023-03-03')` returns the expected Date, and not a day before
663
- // Because `new Date('2023-03-03')` in NewYork gives you '2023-03-02 19:00:00 GMT-0500'
664
- const m = s.match(DATE_TIME_REGEX);
665
- // Validate in 3 ways:
666
- // 1. Should match Regex.
667
- // In some ways it's stricter than Date constructor, e.g it doesn't allow 2023/05/05
668
- // In other ways it's looser, e.g it allows `2023-05-05T`, while Date constructor doesn't.
669
- // 2. Date constructor (of Node/v8 implementation, which we know is different from e.g WebKit/Safari)
670
- // should not return `Invalid Date`.
671
- // 3. Year, month and day should be valid, e.g 2023-01-32 should not be allowed.
672
- // UPD: Actually, 3 can be skipped, because 2 is catching it already
673
- // UPD: 2 is skipped, 1 and 3 are kept
674
- // if (!m || isNaN(new Date(s).getDate())) return null
675
- if (!m)
676
- return null;
677
- const year = Number(m[1]);
678
- const month = Number(m[2]);
679
- const day = Number(m[3]);
680
- const hour = Number(m[5]);
681
- const minute = Number(m[6]);
682
- const second = Number(m[7]);
683
- // Validation for just the Date part
684
- if (!year ||
685
- !month ||
686
- month < 1 ||
687
- month > 12 ||
688
- !day ||
689
- day < 1 ||
690
- day > localDate.getMonthLength(year, month)) {
691
- return null;
692
- }
693
- // Validation for Date+Time string, since the string is longer than YYYY-MM-DD
694
- if (s.length > 10 &&
695
- (isNaN(hour) ||
696
- isNaN(minute) ||
697
- isNaN(second) ||
698
- hour < 0 ||
699
- hour > 23 ||
700
- minute < 0 ||
701
- minute > 59 ||
702
- second < 0 ||
703
- second > 59)) {
704
- return null;
705
- }
706
- return new Date(year, month - 1, day, hour || 0, minute || 0, second || 0, 0);
649
+ fromInput(input) {
650
+ if (input instanceof LocalTime)
651
+ return input;
652
+ if (input instanceof Date) {
653
+ return this.fromDate(input);
654
+ }
655
+ if (typeof input === 'number') {
656
+ return this.fromUnix(input);
657
+ }
658
+ // It means it's a string
659
+ // Will parse it STRICTLY
660
+ return this.fromIsoDateTimeString(input);
707
661
  }
662
+ /**
663
+ * Returns true if input is valid to create LocalTime.
664
+ */
708
665
  isValid(input) {
709
- return this.fromOrNull(input) !== null;
666
+ if (!input)
667
+ return false;
668
+ if (input instanceof LocalTime)
669
+ return true;
670
+ if (input instanceof Date)
671
+ return !isNaN(input.getDate());
672
+ // We currently don't validate Unixtimestamp input, treat it as always valid
673
+ if (typeof input === 'number')
674
+ return true;
675
+ return this.isValidString(input);
710
676
  }
677
+ /**
678
+ * Returns true if isoString is a valid iso8601 string like `yyyy-mm-ddThh:mm:dd`.
679
+ */
711
680
  isValidString(isoString) {
712
- return this.fromStringOrNull(isoString) !== null;
681
+ return !!this.parseStrictlyOrUndefined(isoString);
713
682
  }
714
- assertNotNull(lt, input) {
715
- _assert(lt !== null, `Cannot parse "${input}" into LocalTime`, {
716
- input,
717
- });
683
+ /**
684
+ * Tries to convert/parse the input into LocalTime.
685
+ * Uses LOOSE parsing.
686
+ * If invalid - doesn't throw, but returns undefined instead.
687
+ */
688
+ try(input) {
689
+ if (input instanceof LocalTime)
690
+ return input;
691
+ if (input instanceof Date) {
692
+ if (isNaN(input.getDate()))
693
+ return;
694
+ return new LocalTime(input);
695
+ }
696
+ if (typeof input === 'number') {
697
+ return this.fromUnix(input);
698
+ }
699
+ if (!input)
700
+ return;
701
+ const date = this.parseLooselyOrUndefined(input);
702
+ return date ? new LocalTime(date) : undefined;
703
+ }
704
+ /**
705
+ * Performs STRICT parsing.
706
+ * Only allows IsoDateTimeString or IsoDateString input, nothing else.
707
+ */
708
+ // eslint-disable-next-line @typescript-eslint/no-duplicate-type-constituents
709
+ fromIsoDateTimeString(s) {
710
+ const d = this.parseStrictlyOrUndefined(s);
711
+ _assert(d, `Cannot parse "${s}" into LocalTime`);
712
+ return new LocalTime(d);
713
+ }
714
+ /**
715
+ * Performs LOOSE parsing.
716
+ * Tries to coerce imprefect/incorrect string input into IsoDateTimeString.
717
+ * Use with caution.
718
+ * Allows to input IsoDateString, will set h:m:s to zeros.
719
+ */
720
+ parse(s) {
721
+ const d = this.parseLooselyOrUndefined(String(s));
722
+ _assert(d, `Cannot parse "${s}" into LocalTime`);
723
+ return new LocalTime(d);
724
+ }
725
+ parseStrictlyOrUndefined(s) {
726
+ if (!s || typeof s !== 'string')
727
+ return;
728
+ let m = DATE_TIME_REGEX_STRICT.exec(s);
729
+ if (!m) {
730
+ // DateTime regex didn't match, try just-Date regex
731
+ m = DATE_REGEX_STRICT.exec(s);
732
+ if (!m)
733
+ return;
734
+ }
735
+ const o = {
736
+ year: Number(m[1]),
737
+ month: Number(m[2]),
738
+ day: Number(m[3]),
739
+ hour: Number(m[4]) || 0,
740
+ minute: Number(m[5]) || 0,
741
+ second: Number(m[6]) || 0,
742
+ };
743
+ if (!this.isDateTimeObjectValid(o))
744
+ return;
745
+ return this.createDateFromDateTimeObject(o);
746
+ }
747
+ parseLooselyOrUndefined(s) {
748
+ if (!s || typeof s !== 'string')
749
+ return;
750
+ const m = DATE_TIME_REGEX_LOOSE.exec(s);
751
+ if (!m) {
752
+ if (s.length < 8)
753
+ return;
754
+ // Attempt to parse with Date constructor
755
+ const d = new Date(s);
756
+ return isNaN(d.getDate()) ? undefined : d;
757
+ }
758
+ const o = {
759
+ year: Number(m[1]),
760
+ month: Number(m[2]),
761
+ day: Number(m[3]) || 1,
762
+ // [4] is skipped due to extra regex parentheses group
763
+ hour: Number(m[5]) || 0,
764
+ minute: Number(m[6]) || 0,
765
+ second: Number(m[7]) || 0,
766
+ };
767
+ if (!this.isDateTimeObjectValid(o))
768
+ return;
769
+ return this.createDateFromDateTimeObject(o);
770
+ }
771
+ /**
772
+ * Throws on invalid value.
773
+ */
774
+ validateDateTimeObject(o) {
775
+ _assert(this.isDateTimeObjectValid(o), `Cannot construct LocalTime from: ${o.year}-${o.month}-${o.day} ${o.hour}:${o.minute}:${o.second}`);
776
+ }
777
+ isDateTimeObjectValid(o) {
778
+ return localDate.isDateObjectValid(o) && this.isTimeObjectValid(o);
779
+ }
780
+ isTimeObjectValid({ hour, minute, second }) {
781
+ return hour >= 0 && hour <= 23 && minute >= 0 && minute <= 59 && second >= 0 && second <= 59;
782
+ }
783
+ fromDate(date) {
784
+ _assert(!isNaN(date.getDate()), `localTime.fromDate is called on Date object that is invalid`);
785
+ return new LocalTime(date);
786
+ }
787
+ fromUnix(ts) {
788
+ return new LocalTime(new Date(ts * 1000));
789
+ }
790
+ /**
791
+ * Create LocalTime from unixTimestamp in milliseconds (not in seconds).
792
+ */
793
+ fromMillis(millis) {
794
+ return new LocalTime(new Date(millis));
718
795
  }
796
+ fromDateTimeObject(o) {
797
+ // todo: validate?
798
+ return new LocalTime(this.createDateFromDateTimeObject(o));
799
+ }
800
+ createDateFromDateTimeObject(o) {
801
+ return new Date(o.year, o.month - 1, o.day || 1, o.hour || 0, o.minute || 0, o.second || 0);
802
+ }
803
+ // private assertNotNull(
804
+ // lt: LocalTime | null,
805
+ // input: LocalTimeInputNullable,
806
+ // ): asserts lt is LocalTime {
807
+ // _assert(lt !== null, `Cannot parse "${input}" into LocalTime`, {
808
+ // input,
809
+ // })
810
+ // }
719
811
  /**
720
812
  * Returns the IANA timezone e.g `Europe/Stockholm`.
721
813
  * https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
@@ -733,23 +825,6 @@ class LocalTimeFactory {
733
825
  isTimezoneValid(tz) {
734
826
  return Intl.supportedValuesOf('timeZone').includes(tz);
735
827
  }
736
- now() {
737
- return new LocalTime(new Date());
738
- }
739
- /**
740
- * Creates a LocalTime from the input, unless it's falsy - then returns undefined.
741
- *
742
- * `localTime` function will instead return LocalTime of `now` for falsy input.
743
- */
744
- orUndefined(input) {
745
- return input || input === 0 ? this.from(input) : undefined;
746
- }
747
- /**
748
- * Creates a LocalTime from the input, unless it's falsy - then returns LocalTime.now
749
- */
750
- orNow(input) {
751
- return input || input === 0 ? this.from(input) : this.now();
752
- }
753
828
  sort(items, dir = 'asc', mutate = false) {
754
829
  const mod = dir === 'desc' ? -1 : 1;
755
830
  return (mutate ? items : [...items]).sort((a, b) => {
@@ -767,7 +842,7 @@ class LocalTimeFactory {
767
842
  const items2 = items.filter(_isTruthy);
768
843
  _assert(items2.length, 'localTime.min called on empty array');
769
844
  return items2
770
- .map(i => this.from(i))
845
+ .map(i => this.fromInput(i))
771
846
  .reduce((min, item) => (min.$date.valueOf() <= item.$date.valueOf() ? min : item));
772
847
  }
773
848
  maxOrUndefined(items) {
@@ -777,7 +852,7 @@ class LocalTimeFactory {
777
852
  const items2 = items.filter(_isTruthy);
778
853
  _assert(items2.length, 'localTime.max called on empty array');
779
854
  return items2
780
- .map(i => this.from(i))
855
+ .map(i => this.fromInput(i))
781
856
  .reduce((max, item) => (max.$date.valueOf() >= item.$date.valueOf() ? max : item));
782
857
  }
783
858
  }
@@ -870,14 +945,7 @@ function differenceInMonths(a, b) {
870
945
  return -(wholeMonthDiff + ((b.getTime() - anchor) / (anchor2 - anchor)) * sign);
871
946
  }
872
947
  const localTimeFactory = new LocalTimeFactory();
873
- export const localTime = localTimeFactory.from.bind(localTimeFactory);
948
+ export const localTime = localTimeFactory.fromInput.bind(localTimeFactory);
874
949
  // The line below is the blackest of black magic I have ever written in 2024.
875
950
  // And probably 2023 as well.
876
951
  Object.setPrototypeOf(localTime, localTimeFactory);
877
- /**
878
- Convenience function to return current Unix timestamp in seconds.
879
- Like Date.now(), but in seconds.
880
- */
881
- export function nowUnix() {
882
- return Math.floor(Date.now() / 1000);
883
- }
@@ -11,7 +11,7 @@ export class TimeInterval {
11
11
  this.$end = $end;
12
12
  }
13
13
  static of(start, end) {
14
- return new TimeInterval(localTime.from(start).unix, localTime.from(end).unix);
14
+ return new TimeInterval(localTime.fromInput(start).unix, localTime.fromInput(end).unix);
15
15
  }
16
16
  get start() {
17
17
  return this.$start;
@@ -55,7 +55,7 @@ export class TimeInterval {
55
55
  return this.cmp(d) >= 0;
56
56
  }
57
57
  includes(d, incl = '[)') {
58
- d = localTime.from(d).unix;
58
+ d = localTime.fromInput(d).unix;
59
59
  // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
60
60
  if (d < this.$start || (d === this.$start && incl[0] === '('))
61
61
  return false;
@@ -1,4 +1,4 @@
1
- import { SimpleMovingAverage, _stringify, _assert } from '..';
1
+ import { _assert, _stringify, SimpleMovingAverage } from '..';
2
2
  import { _ms } from '../time/time.util';
3
3
  import { _getArgsSignature, _getMethodSignature } from './decorator.util';
4
4
  /**
package/dist-esm/index.js CHANGED
@@ -1,88 +1,88 @@
1
+ export * from './abort';
1
2
  export * from './array/array.util';
2
- export * from './define';
3
- export * from './string/url.util';
4
3
  export * from './array/range';
4
+ export * from './datetime/dateInterval';
5
+ export * from './datetime/localDate';
6
+ export * from './datetime/localTime';
7
+ export * from './datetime/timeInterval';
8
+ export * from './datetime/wallTime';
9
+ export * from './decorators/asyncMemo.decorator';
5
10
  export * from './decorators/createPromiseDecorator';
6
11
  export * from './decorators/debounce';
7
12
  export * from './decorators/debounce.decorator';
8
13
  export * from './decorators/decorator.util';
9
14
  export * from './decorators/logMethod.decorator';
10
15
  export * from './decorators/memo.decorator';
11
- export * from './decorators/asyncMemo.decorator';
12
16
  export * from './decorators/memo.util';
13
17
  export * from './decorators/memoFn';
14
18
  export * from './decorators/memoFnAsync';
15
19
  export * from './decorators/retry.decorator';
16
20
  export * from './decorators/timeout.decorator';
17
- export * from './error/assert';
21
+ export * from './define';
18
22
  export * from './enum.util';
23
+ export * from './env';
24
+ export * from './env/buildInfo';
25
+ export * from './error/assert';
19
26
  export * from './error/error.model';
20
27
  export * from './error/error.util';
21
28
  export * from './error/errorMode';
22
29
  export * from './error/try';
23
30
  export * from './error/tryCatch';
31
+ export * from './form.util';
32
+ export * from './http/fetcher';
33
+ export * from './http/fetcher.model';
34
+ export * from './http/http.model';
35
+ export * from './is.util';
36
+ export * from './iter/asyncIterable2';
37
+ export * from './iter/iterable2';
24
38
  export * from './json-schema/from-data/generateJsonSchemaFromData';
25
39
  export * from './json-schema/jsonSchema.cnst';
26
40
  export * from './json-schema/jsonSchema.model';
27
41
  export * from './json-schema/jsonSchema.util';
28
42
  export * from './json-schema/jsonSchemaBuilder';
43
+ export * from './log/commonLogger';
29
44
  export * from './math/math.util';
30
45
  export * from './math/sma';
46
+ export * from './math/stack.util';
31
47
  export * from './number/createDeterministicRandom';
32
48
  export * from './number/number.util';
33
49
  export * from './object/deepEquals';
50
+ export * from './object/map2';
34
51
  export * from './object/object.util';
52
+ export * from './object/set2';
35
53
  export * from './object/sortObject';
36
54
  export * from './object/sortObjectDeep';
37
- export * from './object/map2';
38
- export * from './object/set2';
55
+ export * from './polyfill';
56
+ export * from './promise/abortable';
39
57
  export * from './promise/pDefer';
40
58
  export * from './promise/pDelay';
41
59
  export * from './promise/pFilter';
42
60
  export * from './promise/pHang';
43
61
  export * from './promise/pMap';
44
62
  export * from './promise/pProps';
63
+ export * from './promise/pQueue';
45
64
  export * from './promise/pRetry';
46
65
  export * from './promise/pState';
47
66
  export * from './promise/pTimeout';
67
+ export * from './semver';
48
68
  export * from './string/case';
49
- export * from './string/json.util';
50
- export * from './string/string.util';
51
- export * from './string/readingTime';
52
69
  export * from './string/escape';
70
+ export * from './string/hash.util';
71
+ export * from './string/json.util';
72
+ export * from './string/leven';
53
73
  export * from './string/pupa';
74
+ export * from './string/readingTime';
75
+ export * from './string/regex';
76
+ export * from './string/safeJsonStringify';
77
+ export * from './string/string.util';
54
78
  export * from './string/stringify';
79
+ export * from './string/url.util';
55
80
  export * from './time/time.util';
56
- export * from './is.util';
57
81
  export * from './typeFest';
58
82
  export * from './types';
59
83
  export * from './unit/size.util';
60
- export * from './log/commonLogger';
61
- export * from './string/safeJsonStringify';
62
- export * from './promise/pQueue';
63
- export * from './promise/abortable';
64
- export * from './iter/iterable2';
65
- export * from './iter/asyncIterable2';
66
- export * from './math/stack.util';
67
- export * from './string/leven';
68
- export * from './datetime/localDate';
69
- export * from './datetime/localTime';
70
- export * from './datetime/wallTime';
71
- export * from './datetime/dateInterval';
72
- export * from './datetime/timeInterval';
73
- export * from './env';
74
- export * from './http/http.model';
75
- export * from './http/fetcher';
76
- export * from './http/fetcher.model';
77
- export * from './string/hash.util';
78
- export * from './env/buildInfo';
79
- export * from './form.util';
80
- export * from './semver';
81
84
  export * from './web';
82
- export * from './abort';
83
- export * from './polyfill';
84
- export * from './string/regex';
85
- export * from './zod/zod.util';
86
85
  export * from './zod/zod.shared.schemas';
87
- import { z, ZodSchema, ZodError } from 'zod';
88
- export { z, ZodSchema, ZodError };
86
+ export * from './zod/zod.util';
87
+ import { z, ZodError, ZodSchema } from 'zod';
88
+ export { z, ZodError, ZodSchema };
@@ -1,5 +1,5 @@
1
1
  import { _uniq } from '../array/array.util';
2
- import { mergeJsonSchemaObjects, _deepCopy, _sortObject } from '../index';
2
+ import { _deepCopy, _sortObject, mergeJsonSchemaObjects } from '../index';
3
3
  import { JSON_SCHEMA_ORDER } from './jsonSchema.cnst';
4
4
  /**
5
5
  * Fluent (chainable) API to manually create Json Schemas.
@@ -1,4 +1,5 @@
1
- import { _noop } from '../index';
1
+ // copy-pasted to avoid weird circular dependency
2
+ const _noop = (..._args) => undefined;
2
3
  export const commonLogLevelNumber = {
3
4
  log: 10,
4
5
  warn: 20,
@@ -35,8 +35,10 @@ export function _ms(millis) {
35
35
  if (millis < 1000)
36
36
  return `${Math.round(millis)} ms`;
37
37
  // < 5 sec
38
- if (millis < 5000)
39
- return `${(millis / 1000).toFixed(3)} sec`;
38
+ if (millis < 5000) {
39
+ const s = millis / 1000;
40
+ return `${Math.trunc(s) === s ? s : s.toFixed(3)} sec`;
41
+ }
40
42
  const sec = Math.floor(millis / 1000) % 60;
41
43
  const min = Math.floor(millis / (60 * 1000)) % 60;
42
44
  const hrs = Math.floor(millis / (3600 * 1000));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
- "version": "14.244.0",
3
+ "version": "14.245.1",
4
4
  "scripts": {
5
5
  "prepare": "husky",
6
6
  "build-prod": "build-prod-esm-cjs",
@@ -1,5 +1,5 @@
1
1
  import { Inclusiveness } from '../types'
2
- import { localDate, LocalDateInput, LocalDateUnit, LocalDate } from './localDate'
2
+ import { LocalDate, localDate, LocalDateInput, LocalDateUnit } from './localDate'
3
3
 
4
4
  export type DateIntervalConfig = DateInterval | DateIntervalString
5
5
  export type DateIntervalString = string