// ets_tracing: off import * as T from "@effect-ts/core/Effect" import * as S from "@effect-ts/core/Effect/Stream" import { pipe, tuple } from "@effect-ts/core/Function" import * as O from "@effect-ts/core/Option" import * as P from "process" import type { Byte } from "../Byte/index.js" import { chunk } from "../Byte/index.js" export class StdinError { readonly _tag = "StdinError" constructor(readonly error: Error) {} } /** * Creates a stream that reads from the standard input */ export const stdin: S.IO = pipe( T.succeedWith(() => tuple(P.stdin.resume(), new Array())), S.fromEffect, S.chain(([rs, cleanup]) => pipe( S.effectAsync((cb) => { const onData = (data: Buffer): void => { cb(T.succeed(chunk(data))) } const onError = (error: Error): void => { cb(T.fail(O.some(new StdinError(error)))) } cleanup.push( () => { rs.removeListener("error", onError) }, () => { rs.removeListener("data", onData) }, () => { rs.pause() } ) rs.on("data", onData) rs.on("error", onError) }), S.ensuring( T.succeedWith(() => { cleanup.forEach((h) => { h() }) }) ) ) ) )