@spider-analyzer/timeline 5.0.2 → 5.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,27 @@
1
+ ## 5.0.4
2
+
3
+ - Fix: memoize the moment-typed props built by the outer TimeLine
4
+ wrapper. Previously `histo`, `quality`, `timeSpan`, `maxDomain`,
5
+ duration props, and the xAxis/margin defaults were rebuilt on every
6
+ wrapper render. The inner component's "did this reference change?"
7
+ effects (`histo !== prevHisto`, width/margin, etc.) fired on every
8
+ render, each calling `setState` and forcing another render — an
9
+ infinite loop that pegged CPU, kept the loader visible forever, and
10
+ left the x-axis ticks empty. Stabilizing the references with
11
+ `useMemo` (keyed on the raw consumer references) breaks the loop.
12
+
13
+ ## 5.0.3
14
+
15
+ - Fix: preserve `undefined` at the Date-→-Moment boundary. Optional
16
+ fields like `maxDomain.min`, `maxDomain.max`, or a partially-populated
17
+ `timeSpan` were silently turning into `moment()` (= now) because
18
+ `moment(undefined)` returns the current time. That turned
19
+ `maxDomain.min = undefined` (the common "no lower bound" case) into an
20
+ active minimum of *now*, which made every visible window appear to be
21
+ before the minimum — triggering `minTime`/`minDomainMsg` on zoom-out,
22
+ blocking pan, and causing constant cursor flicker from re-emitted
23
+ corrections.
24
+
1
25
  ## 5.0.2
2
26
 
3
27
  - Fix: apply the `xAxis` / `yAxis` / `margin` defaults inside the outer
package/dist/index.js CHANGED
@@ -1956,15 +1956,19 @@ function toMoment(x, zone) {
1956
1956
  const m = zone ? moment_shim_default.tz(x, zone) : moment_shim_default(x);
1957
1957
  return m;
1958
1958
  }
1959
+ function toMomentOpt(x, zone) {
1960
+ if (x == null) return void 0;
1961
+ return toMoment(x, zone);
1962
+ }
1959
1963
  function toDuration(x) {
1960
1964
  if (moment_shim_default.isDuration(x)) return x;
1961
1965
  return moment_shim_default.duration(x);
1962
1966
  }
1963
1967
  function domainToMoments(d, zone) {
1964
- return { min: toMoment(d.min, zone), max: toMoment(d.max, zone) };
1968
+ return { min: toMomentOpt(d.min, zone), max: toMomentOpt(d.max, zone) };
1965
1969
  }
1966
1970
  function timeSpanToMoments(t, zone) {
1967
- return { start: toMoment(t.start, zone), stop: toMoment(t.stop, zone) };
1971
+ return { start: toMomentOpt(t.start, zone), stop: toMomentOpt(t.stop, zone) };
1968
1972
  }
1969
1973
  var Cursor2 = Cursor;
1970
1974
  var Histogram2 = Histogram;
@@ -2758,8 +2762,9 @@ var TimeLine2 = react.forwardRef(function TimeLineWrapper(props, ref) {
2758
2762
  const handleLoadDefault = react.useCallback(() => {
2759
2763
  const ret = props.onLoadDefaultDomain?.();
2760
2764
  const apply = (d) => {
2761
- if (!d) return;
2765
+ if (!d || !d.min || !d.max) return;
2762
2766
  const m = domainToMoments(d, zone);
2767
+ if (!m.min || !m.max) return;
2763
2768
  setStack([m]);
2764
2769
  if (props.onDomainChange) {
2765
2770
  props.onDomainChange({ min: m.min.toDate(), max: m.max.toDate() });
@@ -2768,19 +2773,55 @@ var TimeLine2 = react.forwardRef(function TimeLineWrapper(props, ref) {
2768
2773
  if (ret && typeof ret.then === "function") ret.then(apply);
2769
2774
  else if (ret) apply(ret);
2770
2775
  }, [props.onLoadDefaultDomain, props.onDomainChange, zone]);
2776
+ const timeSpanMoments = react.useMemo(
2777
+ () => props.timeSpan ? timeSpanToMoments(props.timeSpan, zone) : void 0,
2778
+ [props.timeSpan, zone]
2779
+ );
2780
+ const maxDomainMoments = react.useMemo(
2781
+ () => props.maxDomain ? domainToMoments(props.maxDomain, zone) : void 0,
2782
+ [props.maxDomain, zone]
2783
+ );
2784
+ const histoMoments = react.useMemo(
2785
+ () => props.histo?.items ? { ...props.histo, items: props.histo.items.map((it) => ({ ...it, time: toMoment(it.time, zone) })) } : props.histo,
2786
+ [props.histo, zone]
2787
+ );
2788
+ const qualityMoments = react.useMemo(
2789
+ () => props.quality?.items ? { ...props.quality, items: props.quality.items.map((it) => ({ ...it, time: toMoment(it.time, zone) })) } : props.quality,
2790
+ [props.quality, zone]
2791
+ );
2792
+ const biggestVisibleDomainDur = react.useMemo(
2793
+ () => props.biggestVisibleDomain != null ? toDuration(props.biggestVisibleDomain) : void 0,
2794
+ [props.biggestVisibleDomain]
2795
+ );
2796
+ const biggestTimeSpanDur = react.useMemo(
2797
+ () => props.biggestTimeSpan != null ? toDuration(props.biggestTimeSpan) : void 0,
2798
+ [props.biggestTimeSpan]
2799
+ );
2800
+ const smallestResolutionDur = react.useMemo(
2801
+ () => props.smallestResolution != null ? toDuration(props.smallestResolution) : void 0,
2802
+ [props.smallestResolution]
2803
+ );
2804
+ const xAxisMerged = react.useMemo(
2805
+ () => ({ ...xAxisDefault, ...props.xAxis ?? {} }),
2806
+ [props.xAxis]
2807
+ );
2808
+ const marginMerged = react.useMemo(
2809
+ () => ({ ...marginDefault, ...props.margin ?? {} }),
2810
+ [props.margin]
2811
+ );
2771
2812
  const innerProps = {
2772
2813
  ...props,
2773
- xAxis: { ...xAxisDefault, ...props.xAxis ?? {} },
2814
+ xAxis: xAxisMerged,
2774
2815
  yAxis: props.yAxis ?? {},
2775
- margin: { ...marginDefault, ...props.margin ?? {} },
2816
+ margin: marginMerged,
2776
2817
  domains: stack,
2777
- timeSpan: props.timeSpan ? timeSpanToMoments(props.timeSpan, zone) : void 0,
2778
- maxDomain: props.maxDomain ? domainToMoments(props.maxDomain, zone) : void 0,
2779
- histo: props.histo?.items ? { ...props.histo, items: props.histo.items.map((it) => ({ ...it, time: toMoment(it.time, zone) })) } : props.histo,
2780
- quality: props.quality?.items ? { ...props.quality, items: props.quality.items.map((it) => ({ ...it, time: toMoment(it.time, zone) })) } : props.quality,
2781
- biggestVisibleDomain: props.biggestVisibleDomain != null ? toDuration(props.biggestVisibleDomain) : void 0,
2782
- biggestTimeSpan: props.biggestTimeSpan != null ? toDuration(props.biggestTimeSpan) : void 0,
2783
- smallestResolution: props.smallestResolution != null ? toDuration(props.smallestResolution) : void 0,
2818
+ timeSpan: timeSpanMoments,
2819
+ maxDomain: maxDomainMoments,
2820
+ histo: histoMoments,
2821
+ quality: qualityMoments,
2822
+ biggestVisibleDomain: biggestVisibleDomainDur,
2823
+ biggestTimeSpan: biggestTimeSpanDur,
2824
+ smallestResolution: smallestResolutionDur,
2784
2825
  onUpdateDomains: handleUpdateDomains,
2785
2826
  onLoadDefaultDomain: handleLoadDefault,
2786
2827
  // onLoadHisto: object shape + Date instants