///|
pub fn order_init_order(g : Graph) -> Array[Array[String]] {
  let visited : Set[String] = Set::new()
  let simple_nodes = g.nodes().filter(v => g.children(v~).is_empty())
  if simple_nodes.is_empty() {
    return []
  }
  let simple_ranks = simple_nodes.map(v => g.node(v).get_int_or("rank", 0))
  let max_rank = apply_with_chunking_max(simple_ranks)
  let layers = range(max_rank + 1).map(_ => [])
  fn dfs(
    g : Graph,
    v : String,
    visited : Set[String],
    layers : Array[Array[String]],
  ) -> Unit {
    if visited.contains(v) {
      return
    }
    visited.add(v)
    let node = g.node(v)
    let rank = node.get_int_or("rank", 0)
    layers[rank].push(v)
    for w in g.successors(v) {
      dfs(g, w, visited, layers)
    }
  }

  // JS uses a stable sort when ordering by rank only. Preserve the original
  // `simple_nodes` order as a tiebreaker to match upstream behavior.
  let index_by_node : Map[String, Int] = Map::new()
  for i = 0; i < simple_nodes.length(); i = i + 1 {
    index_by_node.set(simple_nodes[i], i)
  }

  let ordered_vs = simple_nodes.copy()
  ordered_vs.sort_by((a, b) => {
    let ra = g.node(a).get_int_or("rank", 0)
    let rb = g.node(b).get_int_or("rank", 0)
    let d = ra - rb
    if d != 0 {
      d
    } else {
      index_by_node.get_or_default(a, 0) - index_by_node.get_or_default(b, 0)
    }
  })
  for v in ordered_vs {
    dfs(g, v, visited, layers)
  }
  layers
}