import { createChannel, each, type Operation, race, resource, spawn, type Stream, until, } from "effection"; import process from "node:process"; export function useStdin(): Operation> { return resource(function* (provide) { let channel = createChannel(); let iterator = process.stdin.iterator() as AsyncIterator; yield* spawn(function* () { let next = yield* until(iterator.next()); while (!next.done) { yield* channel.send(next.value); next = yield* until(iterator.next()); } yield* channel.close(); }); yield* race([provide(channel), drain(channel)]); }); } function* drain(stream: Stream): Operation { for (let _ of yield* each(stream)) { yield* each.next(); } }