footprint-explainable-ui 0.26.2 → 0.27.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.
- package/dist/index.cjs +84 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -9
- package/dist/index.d.ts +20 -9
- package/dist/index.js +84 -36
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2300,6 +2300,67 @@ function TimeTravelControls({
|
|
|
2300
2300
|
// src/components/ExplainableShell/ExplainableShell.tsx
|
|
2301
2301
|
var import_react31 = require("react");
|
|
2302
2302
|
|
|
2303
|
+
// src/components/ExplainableShell/_internal/dataTrace.ts
|
|
2304
|
+
function readsByStep(tree) {
|
|
2305
|
+
const byStep = /* @__PURE__ */ new Map();
|
|
2306
|
+
if (!tree) return byStep;
|
|
2307
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2308
|
+
const stack = [tree];
|
|
2309
|
+
while (stack.length > 0) {
|
|
2310
|
+
const node = stack.pop();
|
|
2311
|
+
if (visited.has(node)) continue;
|
|
2312
|
+
visited.add(node);
|
|
2313
|
+
if (node.runtimeStageId && node.stageReads) {
|
|
2314
|
+
const keys = Object.keys(node.stageReads);
|
|
2315
|
+
if (keys.length > 0) byStep.set(node.runtimeStageId, keys);
|
|
2316
|
+
}
|
|
2317
|
+
if (node.next) stack.push(node.next);
|
|
2318
|
+
if (node.children) for (const c of node.children) stack.push(c);
|
|
2319
|
+
}
|
|
2320
|
+
return byStep;
|
|
2321
|
+
}
|
|
2322
|
+
function buildDataTrace(commitLog, executionTree, targetRuntimeStageId, maxDepth = 10, maxFrames = 50) {
|
|
2323
|
+
const log = commitLog ?? [];
|
|
2324
|
+
const reads = readsByStep(executionTree);
|
|
2325
|
+
const readsAvailable = reads.size > 0;
|
|
2326
|
+
if (!log.length) return { frames: [], readsAvailable };
|
|
2327
|
+
const idxOf = /* @__PURE__ */ new Map();
|
|
2328
|
+
for (let i = 0; i < log.length; i++) idxOf.set(log[i].runtimeStageId, i);
|
|
2329
|
+
const startIdx = idxOf.get(targetRuntimeStageId);
|
|
2330
|
+
if (startIdx === void 0) return { frames: [], readsAvailable };
|
|
2331
|
+
const findLastWriter = (key, beforeIdx) => {
|
|
2332
|
+
for (let i = beforeIdx - 1; i >= 0; i--) {
|
|
2333
|
+
if (log[i].trace.some((t) => t.path === key)) return i;
|
|
2334
|
+
}
|
|
2335
|
+
return -1;
|
|
2336
|
+
};
|
|
2337
|
+
const frames = [];
|
|
2338
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2339
|
+
const queue = [[startIdx, 0, ""]];
|
|
2340
|
+
while (queue.length > 0 && frames.length < maxFrames) {
|
|
2341
|
+
const [idx, depth, linkedBy] = queue.shift();
|
|
2342
|
+
const commit = log[idx];
|
|
2343
|
+
if (visited.has(commit.runtimeStageId)) continue;
|
|
2344
|
+
visited.add(commit.runtimeStageId);
|
|
2345
|
+
frames.push({
|
|
2346
|
+
runtimeStageId: commit.runtimeStageId,
|
|
2347
|
+
stageId: commit.stageId,
|
|
2348
|
+
stageName: commit.stage,
|
|
2349
|
+
keysWritten: commit.trace.map((t) => t.path),
|
|
2350
|
+
linkedBy,
|
|
2351
|
+
depth
|
|
2352
|
+
});
|
|
2353
|
+
if (depth >= maxDepth) continue;
|
|
2354
|
+
for (const key of reads.get(commit.runtimeStageId) ?? []) {
|
|
2355
|
+
const writerIdx = findLastWriter(key, idx);
|
|
2356
|
+
if (writerIdx >= 0 && !visited.has(log[writerIdx].runtimeStageId)) {
|
|
2357
|
+
queue.push([writerIdx, depth + 1, key]);
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2360
|
+
}
|
|
2361
|
+
return { frames, readsAvailable };
|
|
2362
|
+
}
|
|
2363
|
+
|
|
2303
2364
|
// src/utils/narrativeSync.ts
|
|
2304
2365
|
function buildEntryRangeIndex(entries) {
|
|
2305
2366
|
const ranges = /* @__PURE__ */ new Map();
|
|
@@ -5205,8 +5266,10 @@ var DataTracePanel = (0, import_react27.memo)(function DataTracePanel2({
|
|
|
5205
5266
|
frames,
|
|
5206
5267
|
selectedStageId,
|
|
5207
5268
|
onFrameClick,
|
|
5208
|
-
fromStageName
|
|
5269
|
+
fromStageName,
|
|
5270
|
+
note
|
|
5209
5271
|
}) {
|
|
5272
|
+
const noteLine = note ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { color: theme.textMuted, fontSize: 11, fontStyle: "italic", marginBottom: 8 }, children: note }) : null;
|
|
5210
5273
|
if (frames.length === 0) {
|
|
5211
5274
|
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { padding: "14px 14px 12px", fontSize: 13, lineHeight: 1.55 }, children: [
|
|
5212
5275
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
@@ -5224,10 +5287,12 @@ var DataTracePanel = (0, import_react27.memo)(function DataTracePanel2({
|
|
|
5224
5287
|
}
|
|
5225
5288
|
),
|
|
5226
5289
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { color: theme.textSecondary, marginBottom: 10 }, children: "Trace any value back to the stage that created it \u2014 and everything upstream that influenced it." }),
|
|
5290
|
+
noteLine,
|
|
5227
5291
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { color: theme.textMuted, fontSize: 12 }, children: "Select a stage above to see its dependency chain." })
|
|
5228
5292
|
] });
|
|
5229
5293
|
}
|
|
5230
5294
|
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { padding: "8px 0", fontSize: 13 }, children: [
|
|
5295
|
+
note && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { padding: "4px 12px 0", fontSize: 11, color: theme.textMuted, fontStyle: "italic" }, children: note }),
|
|
5231
5296
|
fromStageName && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { padding: "4px 12px 8px" }, children: [
|
|
5232
5297
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
5233
5298
|
"div",
|
|
@@ -5361,6 +5426,7 @@ var InspectorPanel = (0, import_react28.memo)(function InspectorPanel2({
|
|
|
5361
5426
|
snapshots,
|
|
5362
5427
|
selectedIndex,
|
|
5363
5428
|
dataTraceFrames,
|
|
5429
|
+
dataTraceNote,
|
|
5364
5430
|
selectedStageId,
|
|
5365
5431
|
onNavigateToStage
|
|
5366
5432
|
}) {
|
|
@@ -5417,6 +5483,7 @@ var InspectorPanel = (0, import_react28.memo)(function InspectorPanel2({
|
|
|
5417
5483
|
DataTracePanel,
|
|
5418
5484
|
{
|
|
5419
5485
|
frames: dataTraceFrames,
|
|
5486
|
+
note: dataTraceNote,
|
|
5420
5487
|
selectedStageId,
|
|
5421
5488
|
onFrameClick: onNavigateToStage,
|
|
5422
5489
|
fromStageName: currentSnapshot?.stageName
|
|
@@ -6008,40 +6075,6 @@ function resolveSubflowFromRuntime(parentSnapshots, subflowId, narrativeEntries)
|
|
|
6008
6075
|
if (sfSnapshots.length === 0) return null;
|
|
6009
6076
|
return { subflowId, label, spec: null, snapshots: sfSnapshots, narrative: sfNarrative };
|
|
6010
6077
|
}
|
|
6011
|
-
function buildDataTrace(commitLog, targetRuntimeStageId, maxDepth = 10) {
|
|
6012
|
-
const log = commitLog;
|
|
6013
|
-
if (!log?.length) return [];
|
|
6014
|
-
const idxMap = /* @__PURE__ */ new Map();
|
|
6015
|
-
for (let i = 0; i < log.length; i++) idxMap.set(log[i].runtimeStageId, i);
|
|
6016
|
-
const startIdx = idxMap.get(targetRuntimeStageId);
|
|
6017
|
-
if (startIdx === void 0) return [];
|
|
6018
|
-
const startCommit = log[startIdx];
|
|
6019
|
-
const frames = [];
|
|
6020
|
-
const visited = /* @__PURE__ */ new Set();
|
|
6021
|
-
let current = startCommit;
|
|
6022
|
-
let currentIdx = startIdx;
|
|
6023
|
-
let depth = 0;
|
|
6024
|
-
while (current && depth <= maxDepth) {
|
|
6025
|
-
if (visited.has(current.runtimeStageId)) break;
|
|
6026
|
-
visited.add(current.runtimeStageId);
|
|
6027
|
-
frames.push({
|
|
6028
|
-
runtimeStageId: current.runtimeStageId,
|
|
6029
|
-
stageId: current.stageId,
|
|
6030
|
-
stageName: current.stage,
|
|
6031
|
-
keysWritten: current.trace.map((t) => t.path),
|
|
6032
|
-
linkedBy: depth === 0 ? "" : current.trace[0]?.path ?? "",
|
|
6033
|
-
depth
|
|
6034
|
-
});
|
|
6035
|
-
if (currentIdx > 0) {
|
|
6036
|
-
currentIdx--;
|
|
6037
|
-
current = log[currentIdx];
|
|
6038
|
-
depth++;
|
|
6039
|
-
} else {
|
|
6040
|
-
break;
|
|
6041
|
-
}
|
|
6042
|
-
}
|
|
6043
|
-
return frames;
|
|
6044
|
-
}
|
|
6045
6078
|
var RightPanel = (0, import_react31.memo)(function RightPanel2({
|
|
6046
6079
|
mode,
|
|
6047
6080
|
onModeChange,
|
|
@@ -6056,6 +6089,10 @@ var RightPanel = (0, import_react31.memo)(function RightPanel2({
|
|
|
6056
6089
|
size,
|
|
6057
6090
|
onNavigateToStage
|
|
6058
6091
|
}) {
|
|
6092
|
+
const dataTrace = (0, import_react31.useMemo)(
|
|
6093
|
+
() => runtimeSnapshot?.commitLog ? buildDataTrace(runtimeSnapshot.commitLog, runtimeSnapshot.executionTree, snapshots[selectedIndex]?.runtimeStageId ?? "") : { frames: [], readsAvailable: true },
|
|
6094
|
+
[runtimeSnapshot, snapshots, selectedIndex]
|
|
6095
|
+
);
|
|
6059
6096
|
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
6060
6097
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { style: {
|
|
6061
6098
|
display: "flex",
|
|
@@ -6107,7 +6144,8 @@ var RightPanel = (0, import_react31.memo)(function RightPanel2({
|
|
|
6107
6144
|
{
|
|
6108
6145
|
snapshots,
|
|
6109
6146
|
selectedIndex,
|
|
6110
|
-
dataTraceFrames:
|
|
6147
|
+
dataTraceFrames: dataTrace.frames,
|
|
6148
|
+
dataTraceNote: dataTrace.readsAvailable ? void 0 : "\u26A0 reads were not recorded (readTracking off) \u2014 dependencies are unknowable, not absent.",
|
|
6111
6149
|
selectedStageId: snapshots[selectedIndex]?.runtimeStageId,
|
|
6112
6150
|
onNavigateToStage
|
|
6113
6151
|
}
|
|
@@ -6436,12 +6474,22 @@ function ExplainableShell({
|
|
|
6436
6474
|
}) }),
|
|
6437
6475
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { style: { flex: 1, overflow: "auto" }, children: detailsContent })
|
|
6438
6476
|
] });
|
|
6477
|
+
const shellThemeVars = (0, import_react31.useMemo)(() => {
|
|
6478
|
+
if (!traceTheme) return {};
|
|
6479
|
+
const base = traceTheme.mode ? tokensToCSSVars(traceTheme.mode === "light" ? coolLight : coolDark) : {};
|
|
6480
|
+
return {
|
|
6481
|
+
...base,
|
|
6482
|
+
...traceTheme.visited !== void 0 && { ["--fp-node-visited"]: traceTheme.visited },
|
|
6483
|
+
...traceTheme.current !== void 0 && { ["--fp-node-cursor"]: traceTheme.current }
|
|
6484
|
+
};
|
|
6485
|
+
}, [traceTheme]);
|
|
6439
6486
|
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
6440
6487
|
"div",
|
|
6441
6488
|
{
|
|
6442
6489
|
ref: shellRef,
|
|
6443
6490
|
className,
|
|
6444
6491
|
style: {
|
|
6492
|
+
...shellThemeVars,
|
|
6445
6493
|
height: "100%",
|
|
6446
6494
|
display: "flex",
|
|
6447
6495
|
flexDirection: "column",
|