export class AssetDependencyGraph {
    outgoing = new Map();
    incoming = new Map();
    addNode(id) {
        this.outgoing.get(id) ?? this.outgoing.set(id, new Set());
        this.incoming.get(id) ?? this.incoming.set(id, new Set());
    }
    addDependency(ownerId, dependencyId) {
        this.addNode(ownerId);
        this.addNode(dependencyId);
        if (ownerId === dependencyId || this.dependsOn(dependencyId, ownerId)) {
            throw new Error(`Asset dependency cycle detected: ${ownerId} -> ${dependencyId}`);
        }
        this.outgoing.get(ownerId)?.add(dependencyId);
        this.incoming.get(dependencyId)?.add(ownerId);
    }
    dependenciesOf(id) {
        return [...(this.outgoing.get(id) ?? [])];
    }
    dependentsOf(id) {
        return [...(this.incoming.get(id) ?? [])];
    }
    remove(id) {
        for (const dependency of this.dependenciesOf(id)) {
            this.incoming.get(dependency)?.delete(id);
        }
        for (const dependent of this.dependentsOf(id)) {
            this.outgoing.get(dependent)?.delete(id);
        }
        this.outgoing.delete(id);
        this.incoming.delete(id);
    }
    releaseOrder(rootId) {
        const visited = new Set();
        const order = [];
        const visit = (id) => {
            if (visited.has(id)) {
                return;
            }
            visited.add(id);
            for (const dependency of this.dependenciesOf(id)) {
                visit(dependency);
            }
            order.push(id);
        };
        visit(rootId);
        return order;
    }
    dependsOn(startId, targetId) {
        const seen = new Set();
        const stack = [startId];
        while (stack.length > 0) {
            const current = stack.pop();
            if (!current || seen.has(current)) {
                continue;
            }
            if (current === targetId) {
                return true;
            }
            seen.add(current);
            stack.push(...this.dependenciesOf(current));
        }
        return false;
    }
}
//# sourceMappingURL=AssetDependencyGraph.js.map