Stabilize tape virtualization and scoped live health

This commit is contained in:
dirtydishes 2026-05-07 01:52:20 -04:00
parent 034d24f8ac
commit e69bf295c8
11 changed files with 866 additions and 273 deletions

View file

@ -967,6 +967,11 @@ h3 {
min-width: 980px;
}
.data-table-body {
position: relative;
min-width: 100%;
}
.data-table-options {
min-width: 1280px;
}
@ -1024,10 +1029,16 @@ h3 {
text-align: left;
}
.data-table-row:nth-child(even) {
.data-table-row.is-even {
background: rgba(255, 255, 255, 0.022);
}
.data-table-virtual-row {
position: absolute;
left: 0;
width: 100%;
}
.data-table-row:hover,
.data-table-row:focus-visible {
outline: none;

View file

@ -5,12 +5,15 @@ import {
appendHistoryTail,
buildDefaultFlowFilters,
classifierToneForFamily,
composeTapeItems,
deriveAlertDirection,
countActiveFlowFilterGroups,
findAnchorRestoreIndex,
formatCompactUsd,
formatOptionContractLabel,
flushPausableTapeData,
getAlertWindowAnchorTs,
getHotChannelFeedStatus,
getScopedLiveAutoHydrationChannels,
getLiveHistoryRetentionCap,
getOptionTableSnapshot,
@ -246,6 +249,37 @@ describe("live tape pausable helpers", () => {
});
describe("live tape history helpers", () => {
it("composes tape items across seed, live, and history without seam duplicates", () => {
const seed = [makeItem("seed", 1, 100), makeItem("dup", 2, 200)];
const live = [makeItem("live", 5, 500), makeItem("dup", 2, 200)];
const history = [makeItem("old", 0, 50), makeItem("mid", 3, 300)];
expect(composeTapeItems(seed, live, history).map((item) => item.trace_id)).toEqual([
"live",
"mid",
"dup",
"seed",
"old"
]);
});
it("keeps a clicked seed row visible before scoped live and history arrive", () => {
const clicked = makeItem("clicked", 3, 300);
expect(composeTapeItems([clicked], [], []).map((item) => item.trace_id)).toEqual(["clicked"]);
});
it("drops focus seed duplicates once equivalent live or history rows arrive", () => {
const clicked = makeItem("clicked", 3, 300);
const live = [makeItem("new", 4, 400)];
const history = [makeItem("clicked", 3, 300)];
expect(composeTapeItems([clicked], live, history).map((item) => item.trace_id)).toEqual([
"new",
"clicked"
]);
});
it("promotes hot-window overflow into the history tail", () => {
const currentHot = [makeItem("hot-3", 3, 300), makeItem("hot-2", 2, 200), makeItem("hot-1", 1, 100)];
const incoming = [makeItem("hot-4", 4, 400)];
@ -362,6 +396,21 @@ describe("live tape history helpers", () => {
}, {})
).toEqual(["options"]);
});
it("restores the same anchor key after live insertions at the top", () => {
const nextKeys = ["new-1", "new-2", "anchor", "after-1", "after-2"];
expect(findAnchorRestoreIndex(nextKeys, "anchor", ["anchor", "after-1", "after-2"])).toBe(2);
});
it("falls forward to the nearest surviving key when the anchor is evicted", () => {
const nextKeys = ["new-1", "after-1", "after-2"];
expect(findAnchorRestoreIndex(nextKeys, "anchor", ["anchor", "after-1", "after-2"])).toBe(1);
});
it("keeps the same anchor when history is appended at the bottom", () => {
const nextKeys = ["anchor", "after-1", "after-2", "older-1", "older-2"];
expect(findAnchorRestoreIndex(nextKeys, "anchor", ["anchor", "after-1", "after-2"])).toBe(0);
});
});
describe("options display formatters", () => {
@ -533,4 +582,13 @@ describe("signals helpers", () => {
expect(statusLabel("connected", false, "live")).toBe("Connected");
expect(statusLabel("stale", false, "live")).toBe("Feed behind");
});
it("treats healthy scoped channels as connected even when no matching rows are visible", () => {
expect(getHotChannelFeedStatus("connected", { healthy: true })).toBe("connected");
});
it("surfaces feed behind only when the backend channel health is stale", () => {
expect(getHotChannelFeedStatus("connected", { healthy: false })).toBe("stale");
expect(getHotChannelFeedStatus("disconnected", { healthy: true })).toBe("disconnected");
});
});

File diff suppressed because it is too large Load diff

View file

@ -9,6 +9,7 @@
},
"dependencies": {
"@islandflow/types": "workspace:*",
"@tanstack/react-virtual": "^3.13.24",
"lightweight-charts": "^4.2.0",
"next": "^14.2.4",
"react": "^18.3.1",