From c3ba0b13f848717691ab9727cacbc48f20e6c057 Mon Sep 17 00:00:00 2001 From: Lyon <88232613+pikasTech@users.noreply.github.com> Date: Tue, 23 Jun 2026 21:51:09 +0800 Subject: [PATCH] fix(web-probe): segment cross-page divergence windows (#756) Co-authored-by: Codex --- .../hwlab-node-web-observe-runner-source.ts | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/scripts/src/hwlab-node-web-observe-runner-source.ts b/scripts/src/hwlab-node-web-observe-runner-source.ts index b22137aa..b812c411 100644 --- a/scripts/src/hwlab-node-web-observe-runner-source.ts +++ b/scripts/src/hwlab-node-web-observe-runner-source.ts @@ -5974,14 +5974,35 @@ function annotateCrossPageDiffTiming(rows) { } const result = []; for (const group of groups.values()) { - const observedSpanMs = group.firstMs === null || group.lastMs === null ? null : group.lastMs - group.firstMs; - for (const row of group.rows) { + const sortedRows = group.rows.slice().sort((a, b) => Number(Date.parse(String(a.sampleStartAt || ""))) - Number(Date.parse(String(b.sampleStartAt || "")))); + const segments = []; + const splitGapMs = Math.max(1000, Number(alertThresholds.crossPageProjectionDivergenceRedMs || alertThresholds.visibleLoadingSlowMs || 10_000)); + for (const row of sortedRows) { + const startMs = Date.parse(String(row.sampleStartAt || "")); + const endMs = Date.parse(String(row.sampleEndAt || row.sampleStartAt || "")); + const last = segments.at(-1); + const lastEndMs = last && last.lastMs !== null ? last.lastMs : null; + if (!last || (Number.isFinite(startMs) && lastEndMs !== null && startMs - lastEndMs > splitGapMs)) { + segments.push({ rows: [row], firstMs: Number.isFinite(startMs) ? startMs : null, lastMs: Number.isFinite(endMs) ? endMs : Number.isFinite(startMs) ? startMs : null }); + continue; + } + last.rows.push(row); + if (Number.isFinite(startMs) && (last.firstMs === null || startMs < last.firstMs)) last.firstMs = startMs; + const effectiveEndMs = Number.isFinite(endMs) ? endMs : Number.isFinite(startMs) ? startMs : null; + if (effectiveEndMs !== null && (last.lastMs === null || effectiveEndMs > last.lastMs)) last.lastMs = effectiveEndMs; + } + for (let segmentIndex = 0; segmentIndex < segments.length; segmentIndex += 1) { + const segment = segments[segmentIndex]; + const observedSpanMs = segment.firstMs === null || segment.lastMs === null ? null : segment.lastMs - segment.firstMs; + for (const row of segment.rows) { result.push({ ...row, - observedFirstAt: group.firstMs === null ? null : new Date(group.firstMs).toISOString(), - observedLastAt: group.lastMs === null ? null : new Date(group.lastMs).toISOString(), + segmentIndex, + observedFirstAt: segment.firstMs === null ? null : new Date(segment.firstMs).toISOString(), + observedLastAt: segment.lastMs === null ? null : new Date(segment.lastMs).toISOString(), observedSpanMs, }); + } } } return result;