(opts: { port: number; hostname: string })
| 197 | } |
| 198 | |
| 199 | function serverLayer(opts: { port: number; hostname: string }) { |
| 200 | const server = createServer() |
| 201 | const serverRef = { closeStarted: false, forceStop: false } |
| 202 | const close = server.close.bind(server) |
| 203 | // Keep shutdown owned by NodeHttpServer, but honor listener.stop(true) by |
| 204 | // force-closing active HTTP sockets when its finalizer calls server.close(). |
| 205 | // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- Node's overloads don't preserve a monkey-patched method assignment. |
| 206 | server.close = ((callback?: Parameters<typeof server.close>[0]) => { |
| 207 | serverRef.closeStarted = true |
| 208 | const result = close(callback) |
| 209 | if (serverRef.forceStop) server.closeAllConnections() |
| 210 | return result |
| 211 | }) as typeof server.close |
| 212 | |
| 213 | return Layer.mergeAll( |
| 214 | NodeHttpServer.layer(() => server, { port: opts.port, host: opts.hostname, gracefulShutdownTimeout: "1 second" }), |
| 215 | Layer.succeed(ListenerServerService)( |
| 216 | ListenerServerService.of({ |
| 217 | closeAll: Effect.sync(() => { |
| 218 | serverRef.forceStop = true |
| 219 | if (serverRef.closeStarted) server.closeAllConnections() |
| 220 | }), |
| 221 | }), |
| 222 | ), |
| 223 | ) |
| 224 | } |
| 225 | |
| 226 | export * as Server from "./server" |
no test coverage detected