I thought of a simple to explain algorithm which answers the original question without requiring "transitive closure". First, let me show 3 possible dependency graphs, then explain the algorithm. It is absolutely necessary that the dependency graphs contain no cycles - the algorithm detects cycles and just throws an exception if there is one. The graphs (displayed graphically ;-)

The first example is from the original question. You could also add an arrow directly from A to C, but it's not necessary.
The second example shows that dependencies don't have to form a true tree as long as there are no cycles.
The third example is a bit more complex. You should try the algorithm on it. Note that there are multiple possible different results, but all will fulfill the requirement that processing nodes in the resulting order means that when a node is processed, all of its dependencies have already been processed.
The algorithm in pseudo code is:
list = []
while there are still nodes in the graph:
find a leaf node (i.e. one with no children)
add the leaf node to the list
remove the leaf node and arrows leading to it from the graph
return list
In the step "find a leaf node", if there are nodes, but no leaf node, it just means that there's a cycle so we just throw an exception in that case. If there are multiple leaf nodes to choose from, it doesn't matter which you pick, though depending on the node picked, you'll get a different (but valid) ordering in the list.
Also, though I believe that the correctness of the algorithm is pretty clear from the way I've written it, it does modify the graph as it runs which isn't ideal. I'd recommend a variation where instead of "find a leaf node", you could substitute "find a node whose children all appear in list. Note that initially, since list is empty, only leaf nodes would satisfy that criteria.
Here is a JavaScript implementation with a simple test. I've changed the data structure used to make it simpler, plus it creates Sets, which make more sense in this context. I'm sure you could write an algorithm to convert the original data structure to the one I use here:
function getDependencies (hDep) {
let setDependencies = new Set();
let setKeys = new Set(Object.keys(hDep));
while (setDependencies.size < setKeys.size) {
// --- get a new key whose dependencies
// have all been added
let ok = undefined;
for (let item of setKeys.values()) {
if (!setDependencies.has(item)
&& hDep[item].isSubsetOf(setDependencies)) {
setDependencies.add(item);
ok = true;
break;
}
}
if (!ok) throw new Error("Circular dependencies");
}
return Array.from(setDependencies.values());
}
// --------------------------------------------
let hDep = {
a: new Set(['b','c']),
b: new Set(['f','d']),
c: new Set(['d','e']),
d: new Set([]),
e: new Set([]),
f: new Set(['g']),
g: new Set([]),
}
let lResults = getDependencies(hDep, 'debug');
console.log(lResults.join(' '));
The result of running this code is:
d e c g f b a
In case you're wondering, a Set remembers the order that you insert things into it, so Array.from(setDependencies.values()) returns an array of names in the order that they were inserted into the Set.
Array.sortbut it doesn't fit the job.