import type { MultiSet, MultiSetArray } from './multiset.js' import type { BinaryOperator, DifferenceStreamReader, DifferenceStreamWriter, UnaryOperator, } from './graph.js' export type KeyValue = [K, V] export interface IOperator<_T> { run: () => void hasPendingWork: () => boolean } export interface IDifferenceStreamReader { drain: () => Array> isEmpty: () => boolean } export interface IDifferenceStreamWriter { sendData: (collection: MultiSet | MultiSetArray) => void newReader: () => IDifferenceStreamReader } export interface ID2 { getNextOperatorId: () => number newInput: () => IStreamBuilder addOperator: (operator: UnaryOperator | BinaryOperator) => void finalize: () => void step: () => void } export interface IStreamBuilder { writer: DifferenceStreamWriter connectReader: () => DifferenceStreamReader graph: ID2 // Don't judge, this is the only way to type this function. // rxjs has very similar code to type its pipe function // https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/internal/util/pipe.ts // We go to 20 operators deep, because surly that's enough for anyone... // A user can always split the pipe into multiple pipes to get around this. pipe: ((o1: PipedOperator) => IStreamBuilder) & (( o1: PipedOperator, o2: PipedOperator, ) => IStreamBuilder) & (( o1: PipedOperator, o2: PipedOperator, o3: PipedOperator, ) => IStreamBuilder) & (( o1: PipedOperator, o2: PipedOperator, o3: PipedOperator, o4: PipedOperator, ) => IStreamBuilder) & (( o1: PipedOperator, o2: PipedOperator, o3: PipedOperator, o4: PipedOperator, o5: PipedOperator, ) => IStreamBuilder) & (( o1: PipedOperator, o2: PipedOperator, o3: PipedOperator, o4: PipedOperator, o5: PipedOperator, o6: PipedOperator, ) => IStreamBuilder) & (( o1: PipedOperator, o2: PipedOperator, o3: PipedOperator, o4: PipedOperator, o5: PipedOperator, o6: PipedOperator, o7: PipedOperator, ) => IStreamBuilder) & (( o1: PipedOperator, o2: PipedOperator, o3: PipedOperator, o4: PipedOperator, o5: PipedOperator, o6: PipedOperator, o7: PipedOperator, o8: PipedOperator, ) => IStreamBuilder) & (( o1: PipedOperator, o2: PipedOperator, o3: PipedOperator, o4: PipedOperator, o5: PipedOperator, o6: PipedOperator, o7: PipedOperator, o8: PipedOperator, o9: PipedOperator, ) => IStreamBuilder) & (( o1: PipedOperator, o2: PipedOperator, o3: PipedOperator, o4: PipedOperator, o5: PipedOperator, o6: PipedOperator, o7: PipedOperator, o8: PipedOperator, o9: PipedOperator, o10: PipedOperator, ) => IStreamBuilder) & (( o1: PipedOperator, o2: PipedOperator, o3: PipedOperator, o4: PipedOperator, o5: PipedOperator, o6: PipedOperator, o7: PipedOperator, o8: PipedOperator, o9: PipedOperator, o10: PipedOperator, o11: PipedOperator, ) => IStreamBuilder) & (( o1: PipedOperator, o2: PipedOperator, o3: PipedOperator, o4: PipedOperator, o5: PipedOperator, o6: PipedOperator, o7: PipedOperator, o8: PipedOperator, o9: PipedOperator, o10: PipedOperator, o11: PipedOperator, o12: PipedOperator, ) => IStreamBuilder) & (( o1: PipedOperator, o2: PipedOperator, o3: PipedOperator, o4: PipedOperator, o5: PipedOperator, o6: PipedOperator, o7: PipedOperator, o8: PipedOperator, o9: PipedOperator, o10: PipedOperator, o11: PipedOperator, o12: PipedOperator, o13: PipedOperator, ) => IStreamBuilder) & (( o1: PipedOperator, o2: PipedOperator, o3: PipedOperator, o4: PipedOperator, o5: PipedOperator, o6: PipedOperator, o7: PipedOperator, o8: PipedOperator, o9: PipedOperator, o10: PipedOperator, o11: PipedOperator, o12: PipedOperator, o13: PipedOperator, o14: PipedOperator, ) => IStreamBuilder) & (( o1: PipedOperator, o2: PipedOperator, o3: PipedOperator, o4: PipedOperator, o5: PipedOperator, o6: PipedOperator, o7: PipedOperator, o8: PipedOperator, o9: PipedOperator, o10: PipedOperator, o11: PipedOperator, o12: PipedOperator, o13: PipedOperator, o14: PipedOperator, o15: PipedOperator, ) => IStreamBuilder) & (( o1: PipedOperator, o2: PipedOperator, o3: PipedOperator, o4: PipedOperator, o5: PipedOperator, o6: PipedOperator, o7: PipedOperator, o8: PipedOperator, o9: PipedOperator, o10: PipedOperator, o11: PipedOperator, o12: PipedOperator, o13: PipedOperator, o14: PipedOperator, o15: PipedOperator, o16: PipedOperator, ) => IStreamBuilder) & (< T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, O, >( o1: PipedOperator, o2: PipedOperator, o3: PipedOperator, o4: PipedOperator, o5: PipedOperator, o6: PipedOperator, o7: PipedOperator, o8: PipedOperator, o9: PipedOperator, o10: PipedOperator, o11: PipedOperator, o12: PipedOperator, o13: PipedOperator, o14: PipedOperator, o15: PipedOperator, o16: PipedOperator, o17: PipedOperator, ) => IStreamBuilder) & (< T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, O, >( o1: PipedOperator, o2: PipedOperator, o3: PipedOperator, o4: PipedOperator, o5: PipedOperator, o6: PipedOperator, o7: PipedOperator, o8: PipedOperator, o9: PipedOperator, o10: PipedOperator, o11: PipedOperator, o12: PipedOperator, o13: PipedOperator, o14: PipedOperator, o15: PipedOperator, o16: PipedOperator, o17: PipedOperator, o18: PipedOperator, ) => IStreamBuilder) & (< T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, O, >( o1: PipedOperator, o2: PipedOperator, o3: PipedOperator, o4: PipedOperator, o5: PipedOperator, o6: PipedOperator, o7: PipedOperator, o8: PipedOperator, o9: PipedOperator, o10: PipedOperator, o11: PipedOperator, o12: PipedOperator, o13: PipedOperator, o14: PipedOperator, o15: PipedOperator, o16: PipedOperator, o17: PipedOperator, o18: PipedOperator, o19: PipedOperator, ) => IStreamBuilder) & (< T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, O, >( o1: PipedOperator, o2: PipedOperator, o3: PipedOperator, o4: PipedOperator, o5: PipedOperator, o6: PipedOperator, o7: PipedOperator, o8: PipedOperator, o9: PipedOperator, o10: PipedOperator, o11: PipedOperator, o12: PipedOperator, o13: PipedOperator, o14: PipedOperator, o15: PipedOperator, o16: PipedOperator, o17: PipedOperator, o18: PipedOperator, o19: PipedOperator, o20: PipedOperator, ) => IStreamBuilder) & ((...operators: Array>) => IStreamBuilder) } export type PipedOperator = ( stream: IStreamBuilder, ) => IStreamBuilder