| 1816 | }) |
| 1817 | |
| 1818 | const readableStreamToPullUnsafe = <A, E, E2 = never>(options: { |
| 1819 | readonly scope: Scope.Scope |
| 1820 | readonly exit?: MutableRef.MutableRef<Exit.Exit<never, E | E2 | Cause.Done> | undefined> | undefined |
| 1821 | readonly readable: ReadableStream<A> |
| 1822 | readonly onError: (error: unknown) => E |
| 1823 | readonly releaseLockOnEnd?: boolean | undefined |
| 1824 | }): Effect.Effect<Pull.Pull<Arr.NonEmptyReadonlyArray<A>, E | E2>, never> => { |
| 1825 | const reader = options.readable.getReader() |
| 1826 | const exit = options.exit ?? MutableRef.make(undefined) |
| 1827 | const pull = Effect.suspend(() => { |
| 1828 | if (exit.current) return exit.current |
| 1829 | return Effect.matchCauseEffect( |
| 1830 | Effect.tryPromise({ |
| 1831 | try: () => reader.read(), |
| 1832 | catch: options.onError |
| 1833 | }), |
| 1834 | { |
| 1835 | onFailure: (cause) => exit.current ?? Effect.failCause(cause), |
| 1836 | onSuccess: ({ done, value }) => { |
| 1837 | if (exit.current) return exit.current |
| 1838 | return done ? Cause.done() : Effect.succeed(Arr.of(value)) |
| 1839 | } |
| 1840 | } |
| 1841 | ) |
| 1842 | }) |
| 1843 | return Effect.as( |
| 1844 | Scope.addFinalizer( |
| 1845 | options.scope, |
| 1846 | options.releaseLockOnEnd |
| 1847 | ? Effect.sync(() => reader.releaseLock()) |
| 1848 | : Effect.promise(() => reader.cancel().catch(constVoid)) |
| 1849 | ), |
| 1850 | pull |
| 1851 | ) |
| 1852 | } |
| 1853 | |
| 1854 | /** |
| 1855 | * Creates a channel that pulls values from an `AsyncIterable`. |