code: function topologicalSort(list, getDeps) {
    var sorted = [];
    const NOT_VISITED = 0;
    const MID_VISIT = 1;
    const COMPLETELY_VISITED = 2;
  
    // Mark all objects as not visited.
    list.forEach(function(object) {
      object.__mark = NOT_VISITED;
    });
  
    // Visit each object.
    list.forEach(function(object) {
      visit(object);
    });
  
    // Return the sorted list.
    return sorted;
  
    /**
     * @param {T} object
     * @template T
     */
    function visit(object) {
      if (object.__mark == MID_VISIT) {
        console.assert(false, 'Dependency cycle detected!');
      } else if (object.__mark == NOT_VISITED) {
        object.__mark = MID_VISIT;
  
        // Visit all dependencies.
        getDeps(object).forEach(visit);
  
        object.__mark = COMPLETELY_VISITED;
  
        // Push this object onto the list.  All transitive dependencies have
        // already been added to the list.
        sorted.push(object);
      }
    }
  }
docs: Topological sort of general objects using a DFS approach.
  Will add a __mark field to each object as part of the sorting process.
  @param {!Array.<T>} list
  @param {function(T):!Array.<T>} getDeps
  @return {!Array.<T>}
  @template T
  @see https://en.wikipedia.org/wiki/Topological_sorting#Depth-first_search