graph_explorer 1.2.0
graph_explorer: ^1.2.0 copied to clipboard
A versatile library for generating and analyzing graphs with support for JSON and ASCIIArtTree.
1.2.0 #
Behaviour changes (results differ from 1.1.x where they were wrong):
GraphScanner/Graph.scanPathsFrom/scanPathsFromMany/scanPathsMatching/shortestPathsFrom/shortestPathsFromMany/shortestPathsMatching:- Behaviour change: every returned path now starts at one of the
fromnodes and ends at a target. Before, paths were resolved backwards to the graph roots: scanning from a non-root node returned the path from the real root, and paths from other roots were included (e.g. withx -> danda -> d,scanPathsFrom('a', 'd')returned[x, d]). - Behaviour change:
findAll: truenow returns all the simple paths. The defaultmaxExpansionis nownull(no cap); before, the default (3) silently dropped paths when many of them went through the same node (3 chained diamonds: 6 of 8 paths).maxExpansionis still available as an explicit cap (the maximum number of times a node is expanded while enumerating paths; with a cap only a subset may be returned). Note that the number of paths can grow exponentially with the graph size. findAll: truepaths are grouped by target (inGraph.targetsorder) and sorted by length.Graph.shortestPathsFrom/shortestPathsFromMany/shortestPathsMatching/shortestPathswithfindAll: trueenumerate only the shortest paths (following the BFS layers fromfrom), not all the paths, so they stay fast when there are many longer paths.Graph.scanPathsFrom/scanPathsFromMany/scanPathsMatching: new optionalmaxExpansion(an explicit cap, forwarded toGraphScanner).- Behaviour change:
findAll: false(andshortestPathsFromwith the defaultfindAll: false) now returns a truly shortest path: the scan is a BFS fromfromthat stops at the 1st target, and the path is the one walked by the BFS. Before, it wasshortestPathToRootof the target (see below). - With an
outputsProviderand agraph, paths follow the provided outputs. - When populating a new graph with an
outputsProvider, the graph is now populated in BFS and each node's outputs are requested once (maxExpansionno longer applies to the walk).
- Behaviour change: every returned path now starts at one of the
Node:- Behaviour change:
shortestPathToRoot/depthare now truly the shortest (a BFS from the roots). Before, they followed each node's 1st input, which is only shortest when the inputs were added in BFS order (a -> b -> c -> dplusa -> dgavedepth4 instead of 2). Ties are resolved by the inputs order.- The distances are computed once per graph (a multi-source BFS,
O(nodes + edges)) and cached until the graph changes (a new node or edge anywhere invalidates the cache, not only an edge of the node itself, which also fixes stale cached paths). depthno longer builds the path.
- The distances are computed once per graph (a multi-source BFS,
- Behaviour change: a
Node.root(Graph.root) now reportsshortestPathToRoot[self]anddepth1, like any other root. Before, it reported an empty path (depth0) until it got an output, and thendepth1. - Behaviour change:
resolveAllPathsToRootnow returns all the simple paths from a root (sorted by length). ItsmaxExpansionis nowint?, defaultnull(no cap; was3).
- Behaviour change:
GraphWalker(walk,walkAsync,walkByNodes,walkByNodesAsync,walkOrder) and soNode.outputsInDepth/inputsInDepth/sideRoots/Graph.walk*From:- Behaviour change: the
maxDepthlimit is now exact in a DFS too. A DFS can reach a node first at a deeper level (where its outputs beyondmaxDepthare cut); it's now expanded again when reached at a shallower depth (without being processed again).a -> b -> c -> d,a -> c,outputsInDepth(maxDepth: 2)now returns[b, c, d](was[b, c]). The DFS visit order is otherwise kept; a BFS is unchanged.
- Behaviour change: the
sortByInputDependency(GraphWalker,Graph.toTree/toJson/walk*OrderFrom,sortedByInputDependency/sortedByOutputDependency):- Behaviour change: the sort is now stable: tied siblings keep their insertion order
(
[a, b, c], was[a, c, b]: an ascending sort was reversed). This can change the order oftoTree(sortByInputDependency: true)/ ASCII art trees. sortedByOutputsDepth,sortedByInputDepthandsortedPathsByLengthare now stable too.
- Behaviour change: the sort is now stable: tied siblings keep their insertion order
(
- Tests:
- The property tests now compare against brute force without special cases: arbitrary random
digraphs (any roots, rootless cycles, self-loops), every
(from, target)pair, graphs populated in BFS and DFS, the defaultmaxExpansion, DFS and BFS withmaxDepth,shortestPathToRoot/depth/resolveAllPathsToRoot. - The pinned quirks of 1.1.2 are now regression tests of the fixed behaviour.
- The property tests now compare against brute force without special cases: arbitrary random
digraphs (any roots, rootless cycles, self-loops), every
1.1.2 #
GraphWalker:- Fix
maxDepth: a step beyondmaxDepthwas counted as processed, so a DFS walk could skip a node reached first beyondmaxDepthand then again within it. Affectswalk,walkAsync,walkByNodes,walkByNodesAsyncandwalkOrder, and soNode.outputsInDepth/inputsInDepth/sideRootswithmaxDepth(e.g.outputsInDepth(maxDepth: 1)now returns every direct output). A DFS withmaxDepth >= 2can still miss a node whose ancestor was reached first at a deeper level; usebfs: truefor an exact depth limit.
- Fix
- New tests: coverage 98.4% -> 99.4%.
- Property tests over seeded random graphs (DAGs, cycles, self-loops, diamonds,
long chains, disconnected components): scanner paths vs. brute-force path
enumeration, shortest/longest path invariants, reachability, BFS/DFS walk
orders,
toJson/fromJsonround-trips (Stringandintnodes), sync vs. async APIs. - Integration test querying a package dependency graph loaded from JSON.
- Pins of current behaviour: tied siblings reversed with
sortByInputDependency,Node.rootdepth, scan paths resolved back to the graph roots,shortestPathToRootfollowing the 1st input, DFSmaxDepth >= 2.
- Property tests over seeded random graphs (DAGs, cycles, self-loops, diamonds,
long chains, disconnected components): scanner paths vs. brute-force path
enumeration, shortest/longest path invariants, reachability, BFS/DFS walk
orders,
1.1.1 #
Graph:- Fix
toTree/toTreeFrom: thekeyCastargument was silently ignored (it was not forwarded toGraphWalker.toTreeFrom). - Fix
Graph.fromJsonfor non-Stringnode types (e.g.Graph<int>.fromJsonwith anodeValueMapper): JSON nodes were looked up by node value instead of by theirStringkey, so only the roots were created. JSON keys are now tracked per parent. A string reference is also accepted when it maps to the same node value.
- Fix
- Tests for
keyCastand forfromJsonwithintnodes (merged definitions, references).
1.1.0 #
-
sdk: ^3.13.0
-
Node:- Fix
isAlwaysRoot: nowtrueonly for nodes created withNode.root(Graph.root), even after outputs are added, andfalsefor ordinary root nodes.
- Fix
-
IterableOfListNodeExtension.longestPaths:- Fix: was returning shorter paths too when more than one path was shorter than the longest.
-
Replaced deprecated
whereNotNullwithnonNulls. -
Dart 3 lints and formatting (initializing formals for private named parameters; public parameter names are unchanged).
-
New tests for the public API (
test/graph_explorer_api_test.dart): coverage 84% -> 98%. -
GitHub Actions:
actions/checkout@v7,codecov/codecov-action@v7. -
collection: ^1.19.1
-
lints: ^6.1.0
-
dependency_validator: ^5.1.0
-
test: ^1.33.0
-
coverage: ^1.16.0
1.0.2 #
GraphWalker:- Added
extractAllEntries.
- Added
Graph.fromJson:maxExpansioncomputed fromGraphWalker.extractAllEntries.
1.0.1 #
-
Added
AnyNodeandNoneNode. -
Graph:- Added
populateandpopulateAsync. - Added
walkOutputsFromandwalkInputsFrom. - Added
walkOutputsOrderFromandwalkInputsOrderFrom. - Added
rootValues,valuesToNodes. - Added
getNodesandgetNodesNullable.
- Added
-
Node:- Added field
attachment. - Added
roots,sideRoots,dependencies,missingDependencies.
- Added field
-
IterableNodeExtension:- Added
mergeandcomplement. - Added
inputsInDepthIntersection,sortedByOutputDependencyandsortedByInputDependency.
- Added
-
New
GraphWalker. -
Removed
ascii_art_treedependency:- Package
ascii_art_tree 1.0.6now usesgraph_explorerinternally (avoid dependency loop).- The
Graphintegration was moved to packageascii_art_treeas an extension.
- The
- Package
-
Improved tests coverage (80%+).
1.0.0 #
- Initial version.