import { NodeHttpServer } from "@effect/platform-node" import { Effect, Layer } from "effect" import { createServer } from "node:http" import { Service } from "./httpapi-server" export { Service } export const name = "node-http-server" export type Opts = { port: number; hostname: string } export const layer = (opts: Opts) => { const server = createServer() const serverRef = { closeStarted: false, forceStop: false } const close = server.close.bind(server) // Keep shutdown owned by NodeHttpServer, but honor listener.stop(true) by // force-closing active HTTP sockets when its finalizer calls server.close(). server.close = ((callback?: Parameters[0]) => { serverRef.closeStarted = true const result = close(callback) if (serverRef.forceStop) server.closeAllConnections() return result }) as typeof server.close return Layer.mergeAll( NodeHttpServer.layer(() => server, { port: opts.port, host: opts.hostname, gracefulShutdownTimeout: "1 second" }), Layer.succeed(Service)( Service.of({ closeAll: Effect.sync(() => { serverRef.forceStop = true if (serverRef.closeStarted) server.closeAllConnections() }), }), ), ) }