From 4f16a08b7f7022807f724c927912a4f852cce252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Thu, 5 Sep 2024 00:25:18 +0200 Subject: [PATCH] Express layers --- bun.lockb | Bin 104113 -> 120381 bytes package.json | 2 + src/Layers/express/ExpressApp.ts | 19 ++++++ src/Layers/express/ExpressNodeHTTPServer.ts | 67 ++++++++++++++++++++ src/Layers/express/index.ts | 2 + 5 files changed, 90 insertions(+) create mode 100644 src/Layers/express/ExpressApp.ts create mode 100644 src/Layers/express/ExpressNodeHTTPServer.ts create mode 100644 src/Layers/express/index.ts diff --git a/bun.lockb b/bun.lockb index 22706bc996ac2568b292fd7a9aaeffed48e21e27..a1e2534d1f7a58f3415692294337c72b8242c405 100755 GIT binary patch delta 24861 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 diff --git a/package.json b/package.json index 2545760..8550066 100644 --- a/package.json +++ b/package.json @@ -83,9 +83,11 @@ "@effect/schema": "^0.72.0", "@prisma/studio-server": "^0.502.0", "@tanstack/form-core": "^0.30.0", + "@types/express": "^4.17.21", "@types/jsonwebtoken": "^9.0.6", "bun-types": "^1.1.26", "effect": "^3.7.0", + "express": "^4.19.2", "jsonwebtoken": "^9.0.2", "mobx": "^6.13.1", "npm-check-updates": "^17.1.1", diff --git a/src/Layers/express/ExpressApp.ts b/src/Layers/express/ExpressApp.ts new file mode 100644 index 0000000..bcf72a6 --- /dev/null +++ b/src/Layers/express/ExpressApp.ts @@ -0,0 +1,19 @@ +import { Config, Context, Effect, Layer } from "effect" +import type { Express } from "express" + + +export class ExpressApp extends Context.Tag("ExpressApp")() {} + + +const importExpress = Effect.tryPromise({ + try: () => import("express"), + catch: cause => new Error("Could not import 'express'. Make sure it is installed.", { cause }), +}) + +export const ExpressAppLive = (config: { + readonly trustProxy?: Config.Config +}) => Layer.effect(ExpressApp, Effect.gen(function*() { + const app = (yield* importExpress).default() + app.set("trust proxy", yield* config.trustProxy || Config.succeed(false)) + return app +})) diff --git a/src/Layers/express/ExpressNodeHTTPServer.ts b/src/Layers/express/ExpressNodeHTTPServer.ts new file mode 100644 index 0000000..c634979 --- /dev/null +++ b/src/Layers/express/ExpressNodeHTTPServer.ts @@ -0,0 +1,67 @@ +import { Config, Context, Effect, Layer, Match } from "effect" +import type { Server } from "node:http" +import type { AddressInfo } from "node:net" +import { ExpressApp } from "./ExpressApp" + + +export class ExpressNodeHTTPServer extends Context.Tag("ExpressNodeHTTPServer")() {} + + +const importNodeHTTP = Effect.tryPromise({ + try: () => import("node:http"), + catch: cause => new Error("Could not import 'node:http'. Make sure you are using a runtime that implements Node APIs.", { cause }), +}) + +const serverListeningMessage = Match.type().pipe( + Match.when(Match.null, () => "HTTP server listening"), + Match.when(Match.string, v => `HTTP server listening on ${ v }`), + Match.orElse(v => `HTTP server listening on ${ v.address }:${ v.port }`), +) + +export const ExpressNodeHTTPServerLive = (config: { + readonly backlog?: Config.Config + readonly exclusive?: Config.Config + readonly host?: Config.Config + readonly ipv6Only?: Config.Config + readonly path?: Config.Config + readonly port?: Config.Config + readonly readableAll?: Config.Config + readonly signal?: AbortSignal + readonly writableAll?: Config.Config +}) => Layer.effect(ExpressNodeHTTPServer, Effect.acquireRelease( + Effect.gen(function*() { + const app = yield* ExpressApp + const http = yield* importNodeHTTP + + const options = { + backlog: yield* config.backlog || Config.succeed(undefined), + exclusive: yield* config.exclusive || Config.succeed(undefined), + host: yield* config.host || Config.succeed(undefined), + ipv6Only: yield* config.ipv6Only || Config.succeed(undefined), + path: yield* config.path || Config.succeed(undefined), + port: yield* config.port || Config.succeed(undefined), + readableAll: yield* config.readableAll || Config.succeed(undefined), + signal: config.signal, + writableAll: yield* config.writableAll || Config.succeed(undefined), + } as const + + return yield* Effect.async(resume => { + const server = http.createServer(app).listen(options, + () => resume( + Effect.succeed(server).pipe( + Effect.tap(Effect.logInfo( + serverListeningMessage(server.address()) + )) + ) + ) + ) + }) + }), + + server => Effect.gen(function*() { + yield* Effect.logInfo("HTTP server is stopping. Waiting for existing connections to end...") + yield* Effect.async(resume => { + server.close(() => resume(Effect.logInfo("HTTP server closed"))) + }) + }), +)) diff --git a/src/Layers/express/index.ts b/src/Layers/express/index.ts new file mode 100644 index 0000000..22f20a7 --- /dev/null +++ b/src/Layers/express/index.ts @@ -0,0 +1,2 @@ +export * from "./ExpressApp" +export * from "./ExpressNodeHTTPServer"