footprint-explainable-ui 0.25.1 → 0.25.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2208,7 +2208,7 @@ function TimeTravelControls({
2208
2208
  }
2209
2209
 
2210
2210
  // src/components/ExplainableShell/ExplainableShell.tsx
2211
- import { memo as memo8, useState as useState14, useCallback as useCallback8, useMemo as useMemo12, useRef as useRef9, useEffect as useEffect10 } from "react";
2211
+ import { memo as memo8, useState as useState14, useCallback as useCallback8, useMemo as useMemo12, useRef as useRef9, useEffect as useEffect11 } from "react";
2212
2212
 
2213
2213
  // src/utils/narrativeSync.ts
2214
2214
  function buildEntryRangeIndex(entries) {
@@ -3331,7 +3331,7 @@ var SubflowBreadcrumb = memo2(function SubflowBreadcrumb2({
3331
3331
  });
3332
3332
 
3333
3333
  // src/components/FlowchartView/TracedFlow.tsx
3334
- import { useCallback as useCallback7, useMemo as useMemo10, useRef as useRef8, useState as useState10 } from "react";
3334
+ import { useCallback as useCallback7, useEffect as useEffect10, useMemo as useMemo10, useRef as useRef8, useState as useState10 } from "react";
3335
3335
  import {
3336
3336
  ReactFlow,
3337
3337
  Background,
@@ -3453,6 +3453,16 @@ function createDagreTraceLayout(options = {}) {
3453
3453
  return (graph) => dagreTraceLayout(graph, options);
3454
3454
  }
3455
3455
 
3456
+ // src/components/FlowchartView/_internal/devWarn.ts
3457
+ function isDevModeEnv() {
3458
+ const proc = globalThis.process;
3459
+ return proc?.env?.NODE_ENV !== "production";
3460
+ }
3461
+ function devWarn(messageFn, ...extras) {
3462
+ if (!isDevModeEnv()) return;
3463
+ console.warn(messageFn(), ...extras);
3464
+ }
3465
+
3456
3466
  // src/components/FlowchartView/_internal/snapLinearSuccessors.ts
3457
3467
  function snapLinearSuccessors(graph, options = {}) {
3458
3468
  if (graph.nodes.length === 0) return graph;
@@ -3558,30 +3568,34 @@ function centerForkParents(graph, options = {}) {
3558
3568
  (a, b) => b.position.y - a.position.y || a.position.x - b.position.x || a.id.localeCompare(b.id)
3559
3569
  );
3560
3570
  for (const n of order) {
3561
- if ((outDegree.get(n.id) ?? 0) < 2) continue;
3562
- if ((inDegree.get(n.id) ?? 0) > 1) continue;
3563
- const kids = (childrenOf.get(n.id) ?? []).filter(
3571
+ const outD = outDegree.get(n.id) ?? 0;
3572
+ const inD = inDegree.get(n.id) ?? 0;
3573
+ const isFork = outD >= 2 && inD <= 1;
3574
+ const isMerge = inD >= 2 && outD <= 1;
3575
+ if (!isFork && !isMerge) continue;
3576
+ const kin = ((isFork ? childrenOf.get(n.id) : predsOf.get(n.id)) ?? []).filter(
3564
3577
  (k) => byId.get(k)?.parentId === n.parentId
3565
3578
  // same compound only
3566
3579
  );
3567
- if (kids.length < 2) continue;
3568
- const centers = kids.map(centerX);
3580
+ if (kin.length < 2) continue;
3581
+ const centers = kin.map(centerX);
3569
3582
  const wN = width.get(n.id);
3570
3583
  const span = (Math.min(...centers) + Math.max(...centers)) / 2;
3571
3584
  workingX.set(n.id, clampX(n.id, span - wN / 2));
3585
+ const stepOf = isFork ? predsOf : childrenOf;
3572
3586
  let curId = n.id;
3573
3587
  const walked = /* @__PURE__ */ new Set([curId]);
3574
3588
  for (; ; ) {
3575
- const ps = predsOf.get(curId);
3576
- if (!ps || ps.length !== 1) break;
3577
- const p = ps[0];
3578
- if (walked.has(p)) break;
3579
- if ((outDegree.get(p) ?? 0) !== 1) break;
3580
- if ((inDegree.get(p) ?? 0) > 1) break;
3581
- if (byId.get(p)?.parentId !== byId.get(curId)?.parentId) break;
3582
- workingX.set(p, clampX(p, centerX(curId) - width.get(p) / 2));
3583
- walked.add(p);
3584
- curId = p;
3589
+ const nexts = stepOf.get(curId);
3590
+ if (!nexts || nexts.length !== 1) break;
3591
+ const m = nexts[0];
3592
+ if (walked.has(m)) break;
3593
+ if ((outDegree.get(m) ?? 0) > 1) break;
3594
+ if ((inDegree.get(m) ?? 0) > 1) break;
3595
+ if (byId.get(m)?.parentId !== byId.get(curId)?.parentId) break;
3596
+ workingX.set(m, clampX(m, centerX(curId) - width.get(m) / 2));
3597
+ walked.add(m);
3598
+ curId = m;
3585
3599
  }
3586
3600
  }
3587
3601
  const nodes = graph.nodes.map(
@@ -4898,6 +4912,13 @@ function TracedFlow({
4898
4912
  style
4899
4913
  }) {
4900
4914
  const layout = layoutProp ?? dagreTraceLayout;
4915
+ useEffect10(() => {
4916
+ if (layoutProp === dagreTraceLayout) {
4917
+ devWarn(
4918
+ () => "[footprint-explainable-ui] <TracedFlow layout={dagreTraceLayout}> bypasses the built-in measure-then-layout pipeline (content-exact sizing, fork/merge centering, straight spines). OMIT the `layout` prop to use it \u2014 passing the raw dagreTraceLayout silently forfeits every layout improvement eui ships."
4919
+ );
4920
+ }
4921
+ }, [layoutProp]);
4901
4922
  const colors = useMemo10(
4902
4923
  () => ({ ...DEFAULT_COLORS, ...colorOverrides ?? {} }),
4903
4924
  [colorOverrides]
@@ -5813,7 +5834,7 @@ var DetailsContent = memo8(function DetailsContent2({
5813
5834
  const allViews = [...builtInViews, ...extraViews ?? []];
5814
5835
  const [activeViewId, setActiveViewId] = useState14(allViews[0]?.id ?? "memory");
5815
5836
  const viewIds = allViews.map((v2) => v2.id).join(",");
5816
- useEffect10(() => {
5837
+ useEffect11(() => {
5817
5838
  if (!allViews.find((v2) => v2.id === activeViewId)) {
5818
5839
  setActiveViewId(allViews[0]?.id ?? "memory");
5819
5840
  }
@@ -6070,7 +6091,7 @@ function ExplainableShell({
6070
6091
  const shellRef = useRef9(null);
6071
6092
  const [isNarrow, setIsNarrow] = useState14(false);
6072
6093
  const [isMedium, setIsMedium] = useState14(false);
6073
- useEffect10(() => {
6094
+ useEffect11(() => {
6074
6095
  const el = shellRef.current;
6075
6096
  if (!el) return;
6076
6097
  const ro = new ResizeObserver(([entry]) => {
@@ -6115,7 +6136,7 @@ function ExplainableShell({
6115
6136
  const [rightPanelMode, setRightPanelMode] = useState14("insights");
6116
6137
  const [leftExpanded, setLeftExpanded] = useState14(defaultExpanded?.topology ?? false);
6117
6138
  const [timelineExpanded, setTimelineExpanded] = useState14(defaultExpanded?.timeline ?? false);
6118
- useEffect10(() => {
6139
+ useEffect11(() => {
6119
6140
  if (isNarrow) {
6120
6141
  setLeftExpanded(false);
6121
6142
  setRightExpanded(false);