UNPKG

@needle-tools/engine

Version:

Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.

104 lines (95 loc) 3.74 kB
// @ts-check import { existsSync, readFileSync } from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; import { captureLogMessage, patchConsoleLogs } from '../common/logger.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); /** * write logs to local file * @param {string} command * @param {unknown} _config * @param {import('../types/userconfig.js').userSettings} userSettings * @returns {import('vite').Plugin | null} */ export function needleLogger(command, _config, userSettings) { if (userSettings?.disableLogging === true) { return null; } patchConsoleLogs({ command }); captureLogMessage("server", "info", "Vite started with command \"" + command + "\" in " + __dirname, null); return { name: "needle:logger", enforce: 'pre', configureServer(server) { logRequests(server); }, configurePreviewServer(server) { logRequests(server); }, transformIndexHtml: { order: 'pre', handler(_html, _ctx) { // inject client logger script during development if (command === 'serve') { const file = path.join(__dirname, 'logger.client.js'); if (existsSync(file)) { const scriptContent = readFileSync(file, 'utf8'); return [ { tag: 'script', attrs: { type: 'module', }, children: scriptContent, injectTo: 'head-prepend', }, ]; } } return []; }, } } } /** * Logs HTTP requests to the console. * This function is used in the Vite server to log incoming HTTP requests. * @param {import('vite').PreviewServer | import('vite').ViteDevServer} server */ function logRequests(server, log_http_requests = false) { /** * Logs a message to the server console and captures it. * @type {Map<import("vite").WebSocket, {id:string}>} */ const connectedClients = new Map(); let index = 0; if ("ws" in server) { // Clent connections server.ws.on('connection', (socket, request) => { const clientId = String(index++); connectedClients.set(socket, { id: clientId }); const ip = request.socket.remoteAddress || 'unknown'; captureLogMessage("server", "connection", `New websocket connection established ${clientId} from ${ip}`, clientId); socket.on('close', () => { captureLogMessage("server", "connection", `Websocket connection closed ${clientId}`, clientId); }); }); // Client log messages via websocket server.ws.on('needle:client-log', async (/** @type {{level: string, message: unknown}} */ data, /** @type {import('vite').WebSocketClient} */ client) => { if (!data || !data.level || !data.message) { console.warn("Received empty log data, ignoring"); return; } const info = connectedClients.get(client.socket); captureLogMessage("client", data.level, data.message, info ? info.id : null); }); } // Log HTTP requests server.middlewares.use((req, _res, next) => { if (log_http_requests) { captureLogMessage("client-http", "info", [req.method, req.url], null); } next(); }); }