import { Last } from 'ts-toolbelt/out/List/Last'; import { Length } from 'ts-toolbelt/out/List/Length'; import { Pop } from 'ts-toolbelt/out/List/Pop'; import { Merge } from 'ts-toolbelt/out/Object/Merge'; import { ListOf } from 'ts-toolbelt/out/Union/ListOf'; /** * Handling iteration as if it were events. * * Every element "yield'd" from an iterator must be a binary tuple, * where the 1st element is a symbol (representing the event) and the 2nd * is the value "emitted". * * You may only have 1 handler for each event and the handler can return * something to the iterator if neccessary. * * @example * const Foo = Symbol('foo') * const Bar = Symbol('bar') * * type MyGenerator = Generator< * | [typeof Foo, string] * | [typeof Bar, number], * any, * undefined * > * * function* myGenerator(): MyGenerator { * yield [Foo, 'foo'] * yield [Bar, 123] * } * * const handler = IteratorHandler * .create(myGenerator()) * .handle(Foo, (value) => console.info(value)) * .handle(Bar, (num) => console.info(num)) * .run() */ export default class IteratorHandler { #private; static create(iterator: Gen): IteratorHandler; constructor(iterator: Gen, handlers: Handlers); handle>(eventName: EventName, handler: Handler[EventName]>): IteratorHandler; run(): void; } type _Events> = Length extends 0 ? R : Last extends [infer K, infer V] ? K extends symbol ? _Events, Merge>> : never : never; type Events = _Events, {}>; type Handler = (value: T) => any; type Handlers = Partial<{ [K in keyof Events]: Handler[K]>; }>; type Gen = Generator; export {};