import { IDestroyable, IRemovable } from "@implab/core-amd/interfaces"; import { isDestroyable, isRemovable } from "@implab/core-amd/safe"; import { isUnsubscribable, Unsubscribable } from "../observable"; export interface IScope { own(target: (() => void) | IDestroyable | IRemovable | Unsubscribable): void; } export class Scope implements IDestroyable, IScope { private readonly _cleanup: (() => void)[] = []; static readonly dummy: IScope = { own() { } }; own(target: (() => void) | IDestroyable | IRemovable | Unsubscribable) { if (target instanceof Function) { this._cleanup.push(target); } else if (isDestroyable(target)) { this._cleanup.push(() => target.destroy()); } else if (isRemovable(target)) { this._cleanup.push(() => target.remove()); } else if (isUnsubscribable(target)) { this._cleanup.push(() => target.unsubscribe()); } } clean() { const guard = (cb: () => void) => { try { cb(); } catch { // guard } }; this._cleanup.forEach(guard); this._cleanup.length = 0; } destroy() { this.clean(); } }