feat(analysis/parallel-groups): implement parallelGroups function with tests

This commit is contained in:
2026-04-27 12:31:43 +00:00
parent b0d943f4e6
commit 37179bc1de
4 changed files with 339 additions and 10 deletions

View File

@@ -5,4 +5,5 @@ export * from './bottleneck.js';
export * from './risk.js';
export * from './cost-benefit.js';
export * from './decompose.js';
export * from './defaults.js';
export * from './defaults.js';
export * from './parallel-groups.js';

View File

@@ -0,0 +1,32 @@
// parallelGroups — groups of tasks that can be executed concurrently
import { topologicalGenerations } from 'graphology-dag';
import type { TaskGraph } from '../graph/index.js';
import { CircularDependencyError } from '../error/index.js';
import { findCycles } from '../graph/queries.js';
/**
* Return groups of tasks that can be executed concurrently.
*
* Each inner array is a "generation" of tasks at the same topological depth
* from sources — tasks with zero prerequisites are in the first group.
*
* Uses `graphology-dag.topologicalGenerations()` for the generation
* computation. Works on disconnected graphs (each connected component is
* sorted independently, then merged by depth).
*
* @param graph - The TaskGraph to analyze
* @returns An array of arrays, where each inner array is a generation of
* tasks at the same depth from sources
* @throws {CircularDependencyError} If the graph contains cycles, with
* `cycles` populated from `findCycles()`
*/
export function parallelGroups(graph: TaskGraph): string[][] {
try {
return topologicalGenerations(graph.raw);
} catch {
// graphology-dag throws when the graph is cyclic — re-throw with
// our CircularDependencyError that carries cycle information
throw new CircularDependencyError(findCycles(graph.raw));
}
}