import { NOOP_SUBSCRIPTION, Source, Subscriber, Subscription } from "../_core" import { Transaction } from "../_tx" export interface Indexed { idx: number val: T } export interface IndexedEndSubscriber { iend(tx: Transaction, idx: number, source: IndexedSource): void } const NOOP_IES = new class NoopIES { public iend(tx: Transaction, idx: number) {} }() export class IndexedSource implements Source>, Subscription { public readonly weight: number private ies: IndexedEndSubscriber = NOOP_IES private subs: Subscription[] constructor(private sources: Array>) { let totalWeight = 0 let n = sources.length this.subs = Array(n) while (n--) { totalWeight += sources[n].weight this.subs[n] = NOOP_SUBSCRIPTION } this.weight = totalWeight this.subs = [] this.ies = NOOP_IES } public activate(initialNeeded: boolean): void { const { subs } = this let n = subs.length while (n--) { subs[n].activate(initialNeeded) } } public size(): number { return this.sources.length } public setEndSubscriber(ies: IndexedEndSubscriber): void { this.ies = ies } public subscribe(subscriber: Subscriber>, order: number): Subscription { let n = this.sources.length const srcs = this.sources const subs = this.subs while (n--) { subs[n] = srcs[n].subscribe(new IndexedPipe(n, this, subscriber, this.ies), order) } return this } public disposeIdx(idx: number): void { const subs = this.subs[idx] this.subs[idx] = NOOP_SUBSCRIPTION subs.dispose() } public dispose(): void { let n = this.subs.length while (n--) this.disposeIdx(n) } public reorder(order: number): void { const { subs } = this let n = subs.length while (n--) { subs[n].reorder(order) } } } class IndexedPipe implements Subscriber { constructor( private i: number, private is: IndexedSource, private s: Subscriber>, private ies: IndexedEndSubscriber, ) {} public next(tx: Transaction, val: T): void { this.s.next(tx, { val, idx: this.i }) } public error(tx: Transaction, err: Error): void { this.s.error(tx, err) } public end(tx: Transaction): void { this.ies.iend(tx, this.i, this.is) } }