import { invoke, Invokeable, NOOP_SUBSCRIBER, sendEndInTx, Subscriber, Subscription } from "./_core" import { Dispatcher } from "./_dispatcher" import { Subscribe } from "./_interfaces" import * as Sym from "./_symbols" import { Transaction } from "./_tx" import { is } from "./_util" import { HKT, Observable } from "./Observable" import { scheduleActivationTask } from "./scheduler/index" import { FromBinder } from "./sources/_binder" export class EventStream extends Observable implements HKT> { public [Sym.HKT]!: EventStream protected __isEventStream!: true constructor(dispatcherOrSubscribe: EventStreamDispatcher | Subscribe) { super( dispatcherOrSubscribe instanceof EventStreamDispatcher ? dispatcherOrSubscribe : dispatcherFromSubscribe(dispatcherOrSubscribe), ) } } export function isEventStream(x: any): x is EventStream { return is(x, EventStream) } export class EventStreamDispatcher extends Dispatcher { private ended: boolean = false public subscribe(subscriber: Subscriber, order: number): Subscription { return this.ended ? new StreamEndedSubscription(subscriber) : super.subscribe(subscriber, order) } public end(tx: Transaction): void { this.ended = true this.sink.end(tx) } } function dispatcherFromSubscribe(subscribe: Subscribe): EventStreamDispatcher { return new EventStreamDispatcher(new FromBinder(subscribe)) } class StreamEndedSubscription implements Subscription, Invokeable { constructor(private s: Subscriber) {} public activate(initialNeeded: boolean): void { scheduleActivationTask(invoke(this)) } public dispose(): void { this.s = NOOP_SUBSCRIBER } public reorder(order: number): void { // noop } public invoke(): void { sendEndInTx(this.s) } }