The condition checked when reporting whether there were `moreChildrenAvailable`
when constructing the initial DominatorTreeNode tree from a DominatorTree was
backwards. This commit fixes the condition and adds a test that fails without
the condition fix.
This commit adds the `DominatorTreeNode.insert` method to insert new
DominatorTreeNode children that have just been loaded from the
HeapAnalysesWorker into an existing partially complete DominatorTreeNode
tree. This is done in a persistent and immutable fashion so that we can use
=== to differentiate different generations of `DominatorTreeNode` trees but
still share the vast majority of the underlying structure.
As infrastructure for the insertion, HeapAnalysesWorker's
`getImmediatelyDominated` response also returns the path from the root to the
node whose immediately dominated children are being fetched. This makes it much
easier to know where to insert the newly loaded children.
This commit defines `DominatorTreeNode`, a JS class representing a node in a
heap snapshot's dominator tree. Three heap analysis client/worker
request/responses request and create these `DominatorTreeNode`s. Unlike
censuses, dominator trees are too big to practically mirror in memory as JS
object structures. Instead, we have one request to get a partial/shallow
representation of the tree starting from the root, and another to get subsequent
children and siblings in the tree. This allows for incremental, lazy, and
bounded mirroring of the dominator tree as `DominatorTreeNode`s.