a very good jj gui
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: improve type safety by removing non-null assertions in revision-graph-utils

+33 -30
+33 -30
apps/desktop/src/components/revision-graph-utils.ts
··· 68 68 const queue = [...(parents.get(rev.commit_id) ?? [])]; 69 69 70 70 while (queue.length > 0) { 71 - const parentId = queue.shift()!; 72 - if (ancestorSet.has(parentId)) continue; 71 + const parentId = queue.shift(); 72 + if (!parentId || ancestorSet.has(parentId)) continue; 73 73 ancestorSet.add(parentId); 74 74 queue.push(...(parents.get(parentId) ?? [])); 75 75 } ··· 84 84 const queue = [...(children.get(rev.commit_id) ?? [])]; 85 85 86 86 while (queue.length > 0) { 87 - const childId = queue.shift()!; 88 - if (descendantSet.has(childId)) continue; 87 + const childId = queue.shift(); 88 + if (!childId || descendantSet.has(childId)) continue; 89 89 descendantSet.add(childId); 90 90 queue.push(...(children.get(childId) ?? [])); 91 91 } ··· 132 132 const queue = [rev.commit_id]; 133 133 134 134 while (queue.length > 0) { 135 - const commitId = queue.shift()!; 136 - if (commitToComponent.has(commitId)) continue; 135 + const commitId = queue.shift(); 136 + if (!commitId || commitToComponent.has(commitId)) continue; 137 137 138 138 commitToComponent.set(commitId, componentId); 139 139 componentMembers.push(commitId); ··· 371 371 } 372 372 373 373 // Identify trunk commits (is_trunk flag from backend) 374 - const trunkCommitIds = new Set( 375 - revisions.filter((r) => r.is_trunk).map((r) => r.commit_id), 376 - ); 374 + const trunkCommitIds = new Set(revisions.filter((r) => r.is_trunk).map((r) => r.commit_id)); 377 375 378 376 // Find the head that contains the working copy in its ancestry 379 377 const workingCopy = revisions.find((r) => r.is_working_copy); ··· 383 381 const visited = new Set<string>(); 384 382 const queue = [workingCopy.commit_id]; 385 383 while (queue.length > 0) { 386 - const id = queue.shift()!; 387 - if (visited.has(id)) continue; 384 + const id = queue.shift(); 385 + if (!id || visited.has(id)) continue; 388 386 visited.add(id); 389 387 const children = childrenMap.get(id) ?? []; 390 388 const validChildren = children.filter((c) => commitIds.has(c)); ··· 405 403 const visited = new Set<string>(); 406 404 const queue = [headCommitId]; 407 405 while (queue.length > 0) { 408 - const id = queue.shift()!; 409 - if (visited.has(id)) continue; 406 + const id = queue.shift(); 407 + if (!id || visited.has(id)) continue; 410 408 visited.add(id); 411 409 const ts = recency[id] ?? 0; 412 410 if (ts > maxRecency) maxRecency = ts; ··· 418 416 419 417 // Find all branch commits for a head (commits from head down to but not including trunk) 420 418 // Also returns the trunk merge-base (first trunk commit encountered) 421 - function getBranchCommitsAndMergeBase(headCommitId: string): { commits: string[]; mergeBase: string | null } { 419 + function getBranchCommitsAndMergeBase(headCommitId: string): { 420 + commits: string[]; 421 + mergeBase: string | null; 422 + } { 422 423 const branchCommits: string[] = []; 423 424 const visited = new Set<string>(); 424 425 const stack = [headCommitId]; 425 426 let mergeBase: string | null = null; 426 427 427 428 while (stack.length > 0) { 428 - const id = stack.pop()!; 429 - if (visited.has(id)) continue; 429 + const id = stack.pop(); 430 + if (!id || visited.has(id)) continue; 430 431 visited.add(id); 431 432 432 433 // Stop at trunk commits - record as merge base ··· 448 449 449 450 return { commits: branchCommits, mergeBase }; 450 451 } 451 - 452 + 452 453 // Wrapper for backward compatibility 453 454 function getBranchCommits(headCommitId: string): string[] { 454 455 return getBranchCommitsAndMergeBase(headCommitId).commits; ··· 469 470 { 470 471 const trunkCommits = revisions.filter((r) => trunkCommitIds.has(r.commit_id)); 471 472 const trunkChildCount = new Map<string, number>(); 472 - 473 + 473 474 for (const rev of trunkCommits) { 474 475 const parents = parentMap.get(rev.commit_id) ?? []; 475 476 for (const parentId of parents) { ··· 478 479 } 479 480 } 480 481 } 481 - 482 + 482 483 // Topological sort 483 484 const ready = trunkCommits.filter((r) => (trunkChildCount.get(r.commit_id) ?? 0) === 0); 484 485 let orderIdx = 0; 485 486 const visited = new Set<string>(); 486 - 487 + 487 488 while (ready.length > 0) { 488 - const rev = ready.shift()!; 489 - if (visited.has(rev.commit_id)) continue; 489 + const rev = ready.shift(); 490 + if (!rev || visited.has(rev.commit_id)) continue; 490 491 visited.add(rev.commit_id); 491 - 492 + 492 493 trunkOrder.set(rev.commit_id, orderIdx++); 493 - 494 + 494 495 const parents = parentMap.get(rev.commit_id) ?? []; 495 496 for (const parentId of parents) { 496 497 if (trunkCommitIds.has(parentId) && !visited.has(parentId)) { ··· 512 513 branchMergeBase.set(head.commit_id, mergeBase); 513 514 } 514 515 515 - // Sort branch heads by: 516 + // Sort branch heads by: 516 517 // 1. WC's branch first 517 518 // 2. Trunk merge-base position (branches connecting to same trunk area are grouped) 518 519 // 3. Recency as tiebreaker within same merge-base area ··· 578 579 const ready = branchCommits.filter((id) => (branchChildCount.get(id) ?? 0) === 0); 579 580 580 581 while (ready.length > 0) { 581 - const id = ready.shift()!; 582 - if (output.has(id)) continue; 582 + const id = ready.shift(); 583 + if (!id || output.has(id)) continue; 583 584 584 585 sorted.push(id); 585 586 output.add(id); ··· 605 606 606 607 // Phase 2: Output trunk commits (shared ancestors) 607 608 // Sort trunk commits topologically as well 608 - const trunkCommits = revisions.filter((r) => trunkCommitIds.has(r.commit_id) && !output.has(r.commit_id)); 609 + const trunkCommits = revisions.filter( 610 + (r) => trunkCommitIds.has(r.commit_id) && !output.has(r.commit_id), 611 + ); 609 612 610 613 // Build child counts for trunk commits 611 614 const trunkChildCount = new Map<string, number>(); ··· 622 625 const trunkReady = trunkCommits.filter((r) => (trunkChildCount.get(r.commit_id) ?? 0) === 0); 623 626 624 627 while (trunkReady.length > 0) { 625 - const rev = trunkReady.shift()!; 626 - if (output.has(rev.commit_id)) continue; 628 + const rev = trunkReady.shift(); 629 + if (!rev || output.has(rev.commit_id)) continue; 627 630 628 631 result.push(rev); 629 632 output.add(rev.commit_id);