import { DisposableStack } from "./Disposable.js";
export class ResourceScope {
    name;
    stack = new DisposableStack();
    children = new Set();
    disposed = false;
    constructor(name) {
        this.name = name;
    }
    use(resource) {
        if (this.disposed)
            throw new Error(`Resource scope ${this.name} is disposed.`);
        return this.stack.use(resource);
    }
    createChild(name) {
        if (this.disposed)
            throw new Error(`Resource scope ${this.name} is disposed.`);
        const child = new ResourceScope(name);
        this.children.add(child);
        return child;
    }
    leakSnapshot() {
        return {
            name: this.name,
            resourceCount: this.stack.size,
            childScopes: [...this.children].map((child) => child.leakSnapshot())
        };
    }
    async dispose() {
        if (this.disposed)
            return;
        this.disposed = true;
        const errors = [];
        for (const child of [...this.children].reverse()) {
            try {
                await child.dispose();
            }
            catch (error) {
                errors.push(error);
            }
        }
        this.children.clear();
        try {
            await this.stack.dispose();
        }
        catch (error) {
            errors.push(error);
        }
        if (errors.length > 0)
            throw new AggregateError(errors, `Resource scope ${this.name} failed to dispose.`);
    }
}
//# sourceMappingURL=ResourceScope.js.map