diff --git a/bun.lockb b/bun.lockb index 23fdc55..87eb5c2 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/packages/server/package.json b/packages/server/package.json index 3c381d7..bfdf540 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -14,7 +14,8 @@ "@trpc/server": "^10.45.2", "effect": "^3.4.7", "express": "^4.19.2", - "trpc-playground": "^1.0.4" + "trpc-playground": "^1.0.4", + "ws": "^8.18.0" }, "devDependencies": { "@types/express": "^4.17.21", diff --git a/packages/server/src/config.ts b/packages/server/src/config.ts new file mode 100644 index 0000000..0e78978 --- /dev/null +++ b/packages/server/src/config.ts @@ -0,0 +1,8 @@ +import { Config } from "effect" + + +export const httpPort = Config.number("HTTP_PORT").pipe(Config.withDefault(8080)) +export const websocketPort = Config.number("WEBSOCKET_PORT").pipe(Config.withDefault(3001)) + +export const rpcHTTPRoot = Config.string("RPC_HTTP_ROOT").pipe(Config.withDefault("/rpc")) +export const rpcHTTPPlaygroundRoot = Config.string("RPC_HTTP_PLAYGROUND_ROOT").pipe(Config.withDefault("/rpc/playground")) diff --git a/packages/server/src/express/ExpressHTTPServer.ts b/packages/server/src/express/ExpressHTTPServer.ts index 9080588..e17efd5 100644 --- a/packages/server/src/express/ExpressHTTPServer.ts +++ b/packages/server/src/express/ExpressHTTPServer.ts @@ -1,20 +1,19 @@ -import { Config, Effect, Layer } from "effect" +import { Effect, Layer } from "effect" +import { httpPort } from "../config" import { ExpressApp } from "./ExpressApp" export module ExpressHTTPServer { - export const Live = Layer.scopedDiscard(Effect.gen(function*() { - const app = yield* ExpressApp - const port = yield* Config.number("PORT").pipe(Config.withDefault(8080)) + export const Live = Layer.scopedDiscard(Effect.acquireRelease( + Effect.gen(function*() { + const app = yield* ExpressApp + const port = yield* httpPort - yield* Effect.acquireRelease( - Effect.sync(() => - app.listen(port, () => console.log(`HTTP server listening on ${ port }.`)) - ), + return app.listen(port, () => console.log(`HTTP server listening on ${ port }.`)) + }), - server => Effect.sync(() => - server.close() - ), - ) - })) + server => Effect.sync(() => + server.close() + ), + )) } diff --git a/packages/server/src/rpc/RPCPlaygroundRoute.ts b/packages/server/src/rpc/RPCPlaygroundRoute.ts index a3e7ca8..aae1a3c 100644 --- a/packages/server/src/rpc/RPCPlaygroundRoute.ts +++ b/packages/server/src/rpc/RPCPlaygroundRoute.ts @@ -1,8 +1,8 @@ import { Effect, Layer } from "effect" import { expressHandler } from "trpc-playground/handlers/express" +import { rpcHTTPPlaygroundRoot, rpcHTTPRoot } from "../config" import { ExpressApp } from "../express/ExpressApp" import { RPCRouter } from "./RPCRouter" -import { rpcPlaygroundRoot, rpcRoot } from "./config" export module RPCPlaygroundRoute { @@ -10,10 +10,10 @@ export module RPCPlaygroundRoute { export const Dev = Layer.effectDiscard(Effect.gen(function*() { const app = yield* ExpressApp - const playgroundEndpoint = yield* rpcPlaygroundRoot + const playgroundEndpoint = yield* rpcHTTPPlaygroundRoot const handler = expressHandler({ - trpcApiEndpoint: yield* rpcRoot, + trpcApiEndpoint: yield* rpcHTTPRoot, playgroundEndpoint, router: yield* RPCRouter, }) diff --git a/packages/server/src/rpc/RPCServerRoute.ts b/packages/server/src/rpc/RPCServerRoute.ts index f015200..950e1ff 100644 --- a/packages/server/src/rpc/RPCServerRoute.ts +++ b/packages/server/src/rpc/RPCServerRoute.ts @@ -1,16 +1,16 @@ import { createExpressMiddleware } from "@trpc/server/adapters/express" import { Effect, Layer } from "effect" +import { rpcHTTPRoot } from "../config" import { ExpressApp } from "../express/ExpressApp" import { TRPCContextCreator } from "../trpc/TRPCContextCreator" import { RPCRouter } from "./RPCRouter" -import { rpcRoot } from "./config" export module RPCServerRoute { export const Live = Layer.effectDiscard(Effect.gen(function*() { const app = yield* ExpressApp - app.use(yield* rpcRoot, + app.use(yield* rpcHTTPRoot, createExpressMiddleware({ router: yield* RPCRouter, createContext: yield* TRPCContextCreator, diff --git a/packages/server/src/rpc/RPCWebSocketServer.ts b/packages/server/src/rpc/RPCWebSocketServer.ts new file mode 100644 index 0000000..303b3f4 --- /dev/null +++ b/packages/server/src/rpc/RPCWebSocketServer.ts @@ -0,0 +1,28 @@ +import { applyWSSHandler } from "@trpc/server/adapters/ws" +import { Effect, Layer } from "effect" +import ws from "ws" +import { websocketPort } from "../config" +import { TRPCContextCreator } from "../trpc/TRPCContextCreator" +import { RPCRouter } from "./RPCRouter" + + +export module RPCWebSocketServer { + export const Live = Layer.scopedDiscard(Effect.acquireRelease( + Effect.gen(function*() { + const wss = new ws.Server({ port: yield* websocketPort }) + + const handler = applyWSSHandler({ + wss, + router: yield* RPCRouter, + createContext: yield* TRPCContextCreator, + }) + + return { wss, handler } + }), + + ({ wss, handler }) => Effect.sync(() => { + handler.broadcastReconnectNotification() + wss.close() + }), + )) +} diff --git a/packages/server/src/rpc/config.ts b/packages/server/src/rpc/config.ts deleted file mode 100644 index 9a0077b..0000000 --- a/packages/server/src/rpc/config.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Config } from "effect" - - -export const rpcRoot = Config.string("RPC_ROOT").pipe(Config.withDefault("/rpc")) -export const rpcPlaygroundRoot = Config.string("RPC_PLAYGROUND_ROOT").pipe(Config.withDefault("/rpc/playground"))