| 8 | import type { ID2, IStreamBuilder, PipedOperator } from './types.js' |
| 9 | |
| 10 | export class D2 implements ID2 { |
| 11 | #operators: Array<UnaryOperator<any> | BinaryOperator<any>> = [] |
| 12 | #nextOperatorId = 0 |
| 13 | #finalized = false |
| 14 | |
| 15 | constructor() {} |
| 16 | |
| 17 | #checkNotFinalized(): void { |
| 18 | if (this.#finalized) { |
| 19 | throw new Error(`Graph already finalized`) |
| 20 | } |
| 21 | } |
| 22 | |
| 23 | getNextOperatorId(): number { |
| 24 | this.#checkNotFinalized() |
| 25 | return this.#nextOperatorId++ |
| 26 | } |
| 27 | |
| 28 | newInput<T>(): RootStreamBuilder<T> { |
| 29 | this.#checkNotFinalized() |
| 30 | const writer = new DifferenceStreamWriter<T>() |
| 31 | // Use the root stream builder that exposes the sendData and sendFrontier methods |
| 32 | const streamBuilder = new RootStreamBuilder<T>(this, writer) |
| 33 | return streamBuilder |
| 34 | } |
| 35 | |
| 36 | addOperator(operator: UnaryOperator<any> | BinaryOperator<any>): void { |
| 37 | this.#checkNotFinalized() |
| 38 | this.#operators.push(operator) |
| 39 | } |
| 40 | |
| 41 | finalize() { |
| 42 | this.#checkNotFinalized() |
| 43 | this.#finalized = true |
| 44 | } |
| 45 | |
| 46 | step(): void { |
| 47 | if (!this.#finalized) { |
| 48 | throw new Error(`Graph not finalized`) |
| 49 | } |
| 50 | for (const op of this.#operators) { |
| 51 | op.run() |
| 52 | } |
| 53 | } |
| 54 | |
| 55 | pendingWork(): boolean { |
| 56 | return this.#operators.some((op) => op.hasPendingWork()) |
| 57 | } |
| 58 | |
| 59 | run(): void { |
| 60 | while (this.pendingWork()) { |
| 61 | this.step() |
| 62 | } |
| 63 | } |
| 64 | } |
| 65 | |
| 66 | export class StreamBuilder<T> implements IStreamBuilder<T> { |
| 67 | #graph: ID2 |
nothing calls this directly
no outgoing calls
no test coverage detected