Compare commits

...

1 Commits

Author SHA1 Message Date
a75373074a fix(canvas): sortParentsBeforeChildren stable ordering + TIER_CONFIG string keys
All checks were successful
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 11s
sop-tier-check / tier-check (pull_request) Successful in 12s
audit-force-merge / audit (pull_request) Has been skipped
sortParentsBeforeChildren: stable-order fix — visit true roots (parentId
undefined) before orphans (parentId references missing node). Previously
processed input order, so [orphan, root] produced [orphan, root] instead
of the expected [root, orphan].

TIER_CONFIG: use string keys ("1"…"4") in toHaveProperty calls.
Vitest's toHaveProperty is string-keyed; TypeScript strict mode with
noPropertyAccessFromIndexSignature rejects numeric literal keys on
Record<number, TIER_CONFIG_LEVEL>.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 03:37:57 +00:00
2 changed files with 20 additions and 5 deletions

View File

@ -55,10 +55,10 @@ describe("statusDotClass", () => {
describe("TIER_CONFIG", () => {
it("has entries for all four tier levels", () => {
expect(TIER_CONFIG).toHaveProperty(1);
expect(TIER_CONFIG).toHaveProperty(2);
expect(TIER_CONFIG).toHaveProperty(3);
expect(TIER_CONFIG).toHaveProperty(4);
expect(TIER_CONFIG).toHaveProperty("1");
expect(TIER_CONFIG).toHaveProperty("2");
expect(TIER_CONFIG).toHaveProperty("3");
expect(TIER_CONFIG).toHaveProperty("4");
});
it("each tier has label, color, and border fields", () => {

View File

@ -34,7 +34,22 @@ export function sortParentsBeforeChildren<T extends { id: string; parentId?: str
visited.add(n.id);
out.push(n);
};
for (const n of nodes) visit(n);
// Stable-sort: visit nodes without a valid parent first (true roots → orphans → non-roots).
// This ensures roots appear before their children and orphans appear after true roots.
const trueRoots: T[] = []; // parentId undefined
const orphans: T[] = []; // parentId defined but parent missing
const nonRoots: T[] = []; // parentId defined and parent exists in set
for (const n of nodes) {
if (!n.parentId) {
trueRoots.push(n);
} else {
const parent = byId.get(n.parentId);
if (parent) nonRoots.push(n);
else orphans.push(n);
}
}
for (const n of [...trueRoots, ...orphans]) visit(n);
for (const n of nonRoots) visit(n);
return out;
}