Replace entire codebase with homarr-labs/homarr
This commit is contained in:
9
apps/websocket/eslint.config.js
Normal file
9
apps/websocket/eslint.config.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import baseConfig from "@homarr/eslint-config/base";
|
||||
|
||||
/** @type {import('typescript-eslint').Config} */
|
||||
export default [
|
||||
{
|
||||
ignores: ["wssServer.cjs"],
|
||||
},
|
||||
...baseConfig,
|
||||
];
|
||||
42
apps/websocket/package.json
Normal file
42
apps/websocket/package.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "@homarr/websocket",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"license": "Apache-2.0",
|
||||
"type": "module",
|
||||
"main": "./src/main.ts",
|
||||
"types": "./src/main.ts",
|
||||
"scripts": {
|
||||
"build": "esbuild src/main.ts --bundle --platform=node --outfile=wssServer.cjs --external:bcrypt --external:@opentelemetry/api --external:deasync --external:cpu-features --loader:.html=text --loader:.scss=text --loader:.node=text",
|
||||
"clean": "rm -rf .turbo node_modules",
|
||||
"dev": "pnpm with-env tsx ./src/main.ts",
|
||||
"format": "prettier --check . --ignore-path ../../.gitignore",
|
||||
"lint": "eslint",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"with-env": "dotenv -e ../../.env --"
|
||||
},
|
||||
"prettier": "@homarr/prettier-config",
|
||||
"dependencies": {
|
||||
"@homarr/api": "workspace:^0.1.0",
|
||||
"@homarr/auth": "workspace:^0.1.0",
|
||||
"@homarr/common": "workspace:^0.1.0",
|
||||
"@homarr/core": "workspace:^",
|
||||
"@homarr/db": "workspace:^0.1.0",
|
||||
"@homarr/definitions": "workspace:^0.1.0",
|
||||
"@homarr/redis": "workspace:^0.1.0",
|
||||
"@homarr/validation": "workspace:^0.1.0",
|
||||
"dotenv": "^17.2.3",
|
||||
"tsx": "4.20.4",
|
||||
"ws": "^8.18.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||
"@homarr/prettier-config": "workspace:^0.1.0",
|
||||
"@homarr/tsconfig": "workspace:^0.1.0",
|
||||
"@types/ws": "^8.18.1",
|
||||
"esbuild": "^0.27.2",
|
||||
"eslint": "^9.39.2",
|
||||
"prettier": "^3.7.4",
|
||||
"typescript": "^5.9.3"
|
||||
}
|
||||
}
|
||||
66
apps/websocket/src/main.ts
Normal file
66
apps/websocket/src/main.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { applyWSSHandler } from "@trpc/server/adapters/ws";
|
||||
import { WebSocketServer } from "ws";
|
||||
|
||||
import { appRouter, createTRPCContext } from "@homarr/api/websocket";
|
||||
import { getSessionFromToken, sessionTokenCookieName } from "@homarr/auth";
|
||||
import { parseCookies } from "@homarr/common";
|
||||
import { createLogger } from "@homarr/core/infrastructure/logs";
|
||||
import { db } from "@homarr/db";
|
||||
|
||||
const logger = createLogger({ module: "websocketMain" });
|
||||
|
||||
const wss = new WebSocketServer({
|
||||
port: 3001,
|
||||
});
|
||||
const handler = applyWSSHandler({
|
||||
wss,
|
||||
router: appRouter,
|
||||
// ignore error on next line because the createContext must be set with this name
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
createContext: async ({ req }) => {
|
||||
try {
|
||||
const headers = Object.entries(req.headers).map(
|
||||
([key, value]) => [key, typeof value === "string" ? value : value?.[0]] as [string, string],
|
||||
);
|
||||
const nextHeaders = new Headers(headers);
|
||||
|
||||
const store = parseCookies(nextHeaders.get("cookie") ?? "");
|
||||
const sessionToken = store[sessionTokenCookieName];
|
||||
|
||||
const session = await getSessionFromToken(db, sessionToken);
|
||||
|
||||
return createTRPCContext({
|
||||
headers: nextHeaders,
|
||||
session,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
return createTRPCContext({
|
||||
headers: new Headers(),
|
||||
session: null,
|
||||
});
|
||||
}
|
||||
},
|
||||
// Enable heartbeat messages to keep connection open (disabled by default)
|
||||
keepAlive: {
|
||||
enabled: true,
|
||||
// server ping message interval in milliseconds
|
||||
pingMs: 30000,
|
||||
// connection is terminated if pong message is not received in this many milliseconds
|
||||
pongWaitMs: 5000,
|
||||
},
|
||||
});
|
||||
|
||||
wss.on("connection", (websocket, incomingMessage) => {
|
||||
logger.info(`➕ Connection (${wss.clients.size}) ${incomingMessage.method} ${incomingMessage.url}`);
|
||||
websocket.once("close", (code, reason) => {
|
||||
logger.info(`➖ Connection (${wss.clients.size}) ${code} ${reason.toString()}`);
|
||||
});
|
||||
});
|
||||
logger.info("✅ WebSocket Server listening on ws://localhost:3001");
|
||||
|
||||
process.on("SIGTERM", () => {
|
||||
logger.info("SIGTERM");
|
||||
handler.broadcastReconnectNotification();
|
||||
wss.close();
|
||||
});
|
||||
13
apps/websocket/tsconfig.json
Normal file
13
apps/websocket/tsconfig.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": "@homarr/tsconfig/base.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"~/*": ["src/*"],
|
||||
"@homarr/node-unifi": ["../../node_modules/@types/node-unifi"]
|
||||
},
|
||||
"tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json"
|
||||
},
|
||||
"include": ["."],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
Reference in New Issue
Block a user