import { ICancellation } from "@implab/core-amd/interfaces"; export interface Subscription { finalize(): boolean; isClosed(): boolean; teardown(cleanup: void | (() => void)): void; around(next: (item: T) => void): (item: T) => void; unsubscribe(): void; } const noop = () => {}; export class SubscriptionImpl implements Subscription { private _done = false; private _cleanup = noop; finalize() { return this._done ? false : ((0,this._cleanup)(), this._done = true); } isClosed() { return this._done; } teardown(cleanup: void | (() => void)) { if (cleanup) { if (this._done) { cleanup(); } else { const _prev = this._cleanup; this._cleanup = _prev === noop ? cleanup : () => (_prev(), cleanup()); } } } cancellable(ct: ICancellation, reject: (err: unknown) => void) { if (ct.isSupported()) { const h = ct.register(reason => this.finalize() && reject(reason)); this.teardown(() => h.destroy()); } } unsubscribe() { this.finalize(); } around(next: (item: T) => void): (item: T) => void { return (item) => this._done ? void(0) : next(item); } }