( open: Effect.Effect<Deno.Conn, Socket.SocketError, RO> )
| 60 | * @since 4.0.0 |
| 61 | */ |
| 62 | export const fromConn = <RO>( |
| 63 | open: Effect.Effect<Deno.Conn, Socket.SocketError, RO> |
| 64 | ): Effect.Effect<Socket.Socket, never, Exclude<RO, Scope.Scope>> => |
| 65 | Effect.withFiber<Socket.Socket, never, Exclude<RO, Scope.Scope>>((fiber) => { |
| 66 | let current: { |
| 67 | readonly conn: Deno.Conn |
| 68 | readonly writer: WritableStreamDefaultWriter<Uint8Array> |
| 69 | } | undefined |
| 70 | let tearingDown = false |
| 71 | let writeClosed = false |
| 72 | const latch = Latch.makeUnsafe(false) |
| 73 | const openServices = fiber.context as Context.Context<RO> |
| 74 | |
| 75 | const run = <R, E, _>(handler: (_: Uint8Array) => Effect.Effect<_, E, R> | void, options?: { |
| 76 | readonly onOpen?: Effect.Effect<void> | undefined |
| 77 | }) => |
| 78 | Effect.scopedWith(Effect.fnUntraced(function*(scope) { |
| 79 | const fiberSet = yield* FiberSet.make<any, E | Socket.SocketError>().pipe( |
| 80 | Scope.provide(scope) |
| 81 | ) |
| 82 | let conn: Deno.Conn | undefined |
| 83 | yield* Scope.addFinalizer( |
| 84 | scope, |
| 85 | Effect.suspend(() => { |
| 86 | tearingDown = true |
| 87 | return conn === undefined ? Effect.void : close(conn) |
| 88 | }) |
| 89 | ) |
| 90 | conn = yield* Scope.provide(open, scope) |
| 91 | const reader = conn.readable.getReader() |
| 92 | const writer = conn.writable.getWriter() |
| 93 | const runFork = yield* Effect.provideService(FiberSet.runtime(fiberSet)<R>(), Conn, conn) |
| 94 | |
| 95 | current = { conn, writer } |
| 96 | tearingDown = false |
| 97 | if (writeClosed) { |
| 98 | writeClosed = false |
| 99 | writer.releaseLock() |
| 100 | yield* closeWrite(conn) |
| 101 | } |
| 102 | latch.openUnsafe() |
| 103 | |
| 104 | const read = Effect.tryPromise( |
| 105 | () => reader.read() |
| 106 | ).pipe( |
| 107 | Effect.catchIf( |
| 108 | (error) => tearingDown && isTeardownError(error.cause), |
| 109 | () => Effect.succeed({ done: true, value: undefined } as ReadableStreamReadDoneResult<Uint8Array>) |
| 110 | ), |
| 111 | Effect.mapError((error) => |
| 112 | new Socket.SocketError({ |
| 113 | reason: new Socket.SocketReadError({ cause: error.cause }) |
| 114 | }) |
| 115 | ) |
| 116 | ) |
| 117 | const readLoop: Effect.Effect<void, Socket.SocketError> = Effect.suspend(() => |
| 118 | Effect.flatMap(read, ({ done, value }) => { |
| 119 | if (done) { |
no test coverage detected