Skip to content

Commit

Permalink
Merge pull request #90 from montymi/i/88/fastify
Browse files Browse the repository at this point in the history
Replace Express with Fastify #88
  • Loading branch information
bludnic authored Jan 5, 2025
2 parents 7a82f36 + 575e50e commit 8ab088f
Show file tree
Hide file tree
Showing 7 changed files with 332 additions and 148 deletions.
2 changes: 2 additions & 0 deletions packages/daemon/moon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ tasks:
command: eslint . --fix
typecheck:
command: tsc --noEmit
test:
command: vitest
12 changes: 5 additions & 7 deletions packages/daemon/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,22 @@
"@opentrader/eslint": "workspace:*",
"@opentrader/tsconfig": "workspace:*",
"@opentrader/types": "workspace:*",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/node": "^22.10.2",
"@types/serve-handler": "^6.1.4",
"eslint": "8.57.0",
"ts-node": "10.9.2",
"typescript": "5.7.2"
"typescript": "5.7.2",
"vitest": "^2.1.8"
},
"dependencies": {
"@fastify/cors": "^10.0.2",
"@fastify/static": "^8.0.3",
"@opentrader/bot": "workspace:*",
"@opentrader/db": "workspace:*",
"@opentrader/logger": "workspace:*",
"@opentrader/trpc": "workspace:*",
"@trpc/client": "^10.45.2",
"@trpc/server": "^10.45.2",
"cors": "^2.8.5",
"express": "^4.21.2",
"serve-handler": "^6.1.6",
"fastify": "^5.2.0",
"zod": "3.24.1"
}
}
30 changes: 24 additions & 6 deletions packages/daemon/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*
* Repository URL: https://github.com/bludnic/opentrader
*/
import { Server } from "node:http";
import { Platform } from "@opentrader/bot";
import { logger } from "@opentrader/logger";
import { createServer, CreateServerOptions } from "./server.js";
Expand All @@ -26,33 +25,52 @@ type DaemonParams = {
};

export class Daemon {
/**
* Constructs an instance of the class Daemon, called from the create class method.
*
* @param platform - The platform instance used by the class.
* @param server - The server instance created by the `createServer` function.
*/
constructor(
private platform: Platform,
private server: Server,
private server: ReturnType<typeof createServer>,
) {}

static async create(params: DaemonParams) {
/**
* Creates a new Daemon instance.
* @param params - The parameters required to create the Daemon.
* @returns A promise that resolves to a Daemon instance.
*/
static async create(params: DaemonParams): Promise<Daemon> {
const platform = await bootstrapPlatform();
logger.info("✅ Platform bootstrapped successfully");

const server = createServer(params.server).listen();
const server = createServer(params.server);
await server.listen();

logger.info(`RPC Server listening on port ${params.server.port}`);
logger.info(`OpenTrader UI: http://localhost:${params.server.port}`);

return new Daemon(platform, server);
}

/**
* Restarts the Daemon by shutting down the platform and bootstrapping it again.
*/
async restart() {
await this.platform.shutdown();

this.platform = await bootstrapPlatform();
}

/**
* Shuts down the Daemon by closing the server and shutting down the platform.
*/
async shutdown() {
logger.info("Shutting down Daemon...");

this.server.close();
logger.info("Express Server shutted down gracefully.");
await this.server.close();
logger.info("Fastify Server shutted down gracefully.");

await this.platform.shutdown();
logger.info("Processor shutted down gracefully.");
Expand Down
76 changes: 39 additions & 37 deletions packages/daemon/src/server.ts
Original file line number Diff line number Diff line change
@@ -1,56 +1,58 @@
import path from "node:path";
import { fileURLToPath } from "node:url";
import serveHandler from "serve-handler";
import { createExpressMiddleware } from "@trpc/server/adapters/express";
import express, { type Express } from "express";
import cors from "cors";

import Fastify from "fastify";
import fastifyCors from "@fastify/cors";
import fastifyStatic from "@fastify/static";
import { fastifyTRPCPlugin } from "@trpc/server/adapters/fastify";
import { appRouter } from "@opentrader/trpc";
import { createContext } from "./trpc.js";

// Path to the current file
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export type CreateServerOptions = {
/**
* Relative path to the Frontend dist directory, e.g. "../frontend" or "../../frontend/dist" for dev
*/
frontendDistPath: string;
/**
* Listen Express on port
*/
port: number;
};

export const createServer = ({ frontendDistPath, port }: CreateServerOptions) => {
const app: Express = express();
let server: ReturnType<typeof app.listen> | null = null;
/**
* Creates and configures a Fastify server instance with specified options.
*
* @param params - The options for creating the server.
*/
export const createServer = (params: CreateServerOptions) => {
const fastify = Fastify({
logger: false, // Set to true to enable logging
maxParamLength: 1000,
});
const staticDir = path.join(__dirname, params.frontendDistPath);

fastify.register(fastifyCors, {
origin: true,
});

fastify.register(fastifyStatic, {
root: staticDir,
prefix: "/", // optional: default '/'
});

fastify.register(fastifyTRPCPlugin, {
prefix: "/api/trpc",
trpcOptions: {
router: appRouter,
createContext,
},
});

return {
app,
server,
listen: (cb?: () => void) => {
app.use(cors());

// Configure tRPC
app.use(
"/api/trpc",
createExpressMiddleware({
router: appRouter,
createContext,
}),
);

// Serve Frontend app
const staticDir = path.resolve(__dirname, frontendDistPath);
app.get("*", (req, res) => serveHandler(req, res, { public: staticDir }));

server = app.listen(port, cb);

return server;
app: fastify,
server: fastify.server,
listen: async () => {
await fastify.listen({ port: params.port, host: "0.0.0.0" }); // Listen on all interfaces, remove host to listen only on localhost
},
close: () => {
server?.close();
close: async () => {
await fastify.close();
},
};
};
4 changes: 2 additions & 2 deletions packages/daemon/src/trpc.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type CreateExpressContextOptions } from "@trpc/server/adapters/express";
import { type CreateFastifyContextOptions } from "@trpc/server/adapters/fastify";

import { trpc, appRouter, type Context } from "@opentrader/trpc";

Expand All @@ -12,7 +12,7 @@ const ctx = {
};

// created for each request
export const createContext = ({ req }: CreateExpressContextOptions): Context => {
export const createContext = ({ req }: CreateFastifyContextOptions): Context => {
const password = req.headers.authorization;

if (password === process.env.ADMIN_PASSWORD) {
Expand Down
12 changes: 12 additions & 0 deletions packages/daemon/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineConfig } from "vitest/config";

export default defineConfig({
test: {
globals: true,
environment: "node",
coverage: {
reporter: ["text", "json", "html"],
},
include: ["src/**/*.test.ts"],
},
});
Loading

0 comments on commit 8ab088f

Please sign in to comment.