import {Stream} from 'xstream'; export type FantasyObserver = { next(x: T): void; error(err: any): void; complete(c?: any): void; }; export type FantasySubscription = { unsubscribe(): void; }; export type FantasyObservable = { subscribe(observer: FantasyObserver): FantasySubscription; }; export type DevToolEnabledSource = { _isCycleSource: string; }; export type SinkProxies = {[P in keyof Si]: Stream}; export type Driver = Si extends void ? (() => So) : ((stream: Si) => So); export type DisposeFunction = () => void; export type Drivers = { [name: string]: Driver, any | void>; }; export type Main = (...args: Array) => any; export type Sources = {[k in keyof D]: ReturnType}; export type Sinks = ReturnType; export type MatchingMain = | Main & { (so: Sources): Sinks; } | Main & { (): Sinks; }; /** * For whatever reason, this does not work with RxJS observables, * this for this reason, `MatchingDrivers` has to be redefined * in @cycle/rxjs-run- */ export type ToStream = S extends FantasyObservable ? Stream : S; export type WidenStream = S extends Stream ? (T extends U ? U : never) : any; export type GetValidInputs> = D extends Driver< infer S, any > ? (S extends Stream ? T : never) : never; export type MatchingDrivers = Drivers & { [k in string & keyof Sinks]: | (() => Sources[k]) | (( si: Stream[k]>, GetValidInputs>> ) => Sources[k]) }; export interface CycleProgram< D extends MatchingDrivers, M extends MatchingMain > { sources: Sources; sinks: Sinks; run(): DisposeFunction; } export interface Engine { sources: Sources; run>(sinks: Sinks): DisposeFunction; dispose(): void; }