getMissingDeps(heads = []) {
    if (!this.haveHashGraph) this.computeHashGraph()

    let allDeps = new Set(heads), inQueue = new Set()
    for (let change of this.queue) {
      inQueue.add(change.hash)
      for (let dep of change.deps) allDeps.add(dep)
    }

    let missing = []
    for (let hash of allDeps) {
      if (this.changeIndexByHash[hash] === undefined && !inQueue.has(hash)) missing.push(hash)
    }
    return missing.sort()
  }
Returns the hashes of any missing dependencies, i.e. where we have tried to apply a change that
has a dependency on a change we have not seen.

If the argument `heads` is given (an array of hexadecimal strings representing hashes as
returned by `getHeads()`), this function also ensures that all of those hashes resolve to
either a change that has been applied to the document, or that has been enqueued for later
application once missing dependencies have arrived. Any missing heads hashes are included in
the returned array.