import type { Task } from '../task' ; import type { RunLoop } from '../run-loop' ; import type { Operation } from '../operation' ; import { isResource , isFuture , isPromise , isGenerator } from '../predicates' ; import { createFunctionController } from './function-controller' ; import { createSuspendController } from './suspend-controller' ; import { createPromiseController } from './promise-controller' ; import { createIteratorController } from './iterator-controller' ; import { createFutureController } from './future-controller' ; import { createResourceController } from './resource-controller' ; import { Future } from '../future' ; export interface Controller < TOut > { type : string ; operation : Operation < TOut > ; resourceTask ? : Task ; start ( ) : void ; halt ( ) : void ; future : Future < TOut > ; } export type Options = { runLoop : RunLoop ; onYieldingToChange ? : ( task : Task | undefined ) => void ; } ; export function createController < T > ( task , operation , options ) { if ( typeof ( operation ) === 'function' ) { return createFunctionController ( task , operation , ( ) => createController ( task , operation ( task ) , options ) ) ; } else if ( ! operation ) { return createSuspendController ( ) ; } else if ( isResource ( operation ) ) { return createResourceController ( task , operation ) ; } else if ( isFuture < T > ( operation ) ) { return createFutureController ( task , operation ) ; } else if ( isPromise ( operation ) ) { return createPromiseController ( task , operation ) ; } else if ( isGenerator ( operation ) ) { return createIteratorController ( task , operation , options ) ; } else { return createFutureController ( task , Future . reject ( new Error ( `unkown type of operation: ${ operation }` ) ) ) ; } }