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)
}
}