MCPcopy Create free account
hub / github.com/Effect-TS/effect / readableToPullUnsafe

Function readableToPullUnsafe

packages/platform/node-shared/src/NodeStream.ts:335–398  ·  view source on GitHub ↗
(options: {
  readonly scope: Scope.Scope
  readonly exit?: MutableRef.MutableRef<Exit.Exit<never, E | Cause.Done> | undefined> | undefined
  readonly readable: Readable | NodeJS.ReadableStream
  readonly onError: (error: unknown) => E
  readonly chunkSize: number | undefined
  readonly closeOnDone?: boolean | undefined
})

Source from the content-addressed store, hash-verified

333// ----------------------------------------------------------------------------
334
335const readableToPullUnsafe = <A, E>(options: {
336 readonly scope: Scope.Scope
337 readonly exit?: MutableRef.MutableRef<Exit.Exit<never, E | Cause.Done> | undefined> | undefined
338 readonly readable: Readable | NodeJS.ReadableStream
339 readonly onError: (error: unknown) => E
340 readonly chunkSize: number | undefined
341 readonly closeOnDone?: boolean | undefined
342}) => {
343 const readable = options.readable as Readable
344
345 const closeOnDone = options.closeOnDone ?? true
346 const exit = options.exit ?? MutableRef.make(undefined)
347 const latch = Latch.makeUnsafe(false)
348 function onReadable() {
349 latch.openUnsafe()
350 }
351 function onError(error: unknown) {
352 exit.current = Exit.fail(options.onError(error))
353 latch.openUnsafe()
354 }
355 function onEnd() {
356 exit.current = Exit.fail(Cause.Done())
357 latch.openUnsafe()
358 }
359 readable.on("readable", onReadable)
360 readable.once("error", onError)
361 readable.once("end", onEnd)
362
363 const pull = Effect.suspend(function loop(): Pull.Pull<Arr.NonEmptyReadonlyArray<A>, E> {
364 let item = options.readable.read(options.chunkSize) as A | null
365 if (item === null) {
366 if (exit.current) {
367 return exit.current
368 }
369 if (readable.readableEnded) {
370 return Effect.fail(Cause.Done())
371 }
372 latch.closeUnsafe()
373 return Effect.flatMap(latch.await, loop)
374 }
375 const chunk = Arr.of(item as A)
376 while (true) {
377 item = options.readable.read(options.chunkSize)
378 if (item === null) break
379 chunk.push(item)
380 }
381 return Effect.succeed(chunk)
382 })
383
384 return Effect.as(
385 Scope.addFinalizer(
386 options.scope,
387 Effect.sync(() => {
388 readable.off("readable", onReadable)
389 readable.off("error", onError)
390 readable.off("end", onEnd)
391 if (closeOnDone && "closed" in options.readable && !options.readable.closed) {
392 options.readable.destroy()

Callers 2

fromReadableChannelFunction · 0.85
fromDuplexFunction · 0.85

Calls 11

onceMethod · 0.80
pushMethod · 0.80
addFinalizerMethod · 0.80
makeMethod · 0.65
onMethod · 0.65
readMethod · 0.65
closeUnsafeMethod · 0.65
ofMethod · 0.65
failMethod · 0.45
succeedMethod · 0.45
syncMethod · 0.45

Tested by

no test coverage detected