/* ! /server/actions.js ? Dynamic action loader for Socket.IO events using a recursive file system scan. */ // % imports import fs from 'fs'; import path from 'path'; import { fileURLToPath, pathToFileURL } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // % Target directory where the actual action files reside const actionsDir = path.join(__dirname, '..', 'actions'); // $ debug-output console.info('[Paths] Actions:', actionsDir); /* $ Recursive function to load action files and build a flat map for direct dot-notation access = Maps all JavaScript files inside the actions directory into a flat key-value structure (e.g. 'chat.message'). ^ Usage in WebSocket (Socket.io) Handlers: ?? import actions from './actions/index.js'; ? Example: "socket.on('chat.message', (data) => actions['chat.message'](socket, data));" ? Example: "socket.on('system.ping', () => actions['system.ping'](socket));" */ async function loadActions(dir = actionsDir, baseDir = actionsDir, actionsObj = {}) { const entries = fs.readdirSync(dir, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(dir, entry.name); if (entry.isDirectory()) { // ~ Pass the main object (actionsObj) further down recursively await loadActions(fullPath, baseDir, actionsObj); } else if (entry.isFile() && entry.name !== 'index.js' && !entry.name.startsWith('.') && entry.name.endsWith('.js')) { // ~ Calculate the relative path from the root directory const relativePath = path.relative(baseDir, fullPath); const parts = relativePath.split(path.sep).map(p => p.replace(/\.js$/, '')); // ~ Import the module const fileUrl = pathToFileURL(fullPath).href; const module = await import(fileUrl); // ~ Map the module directly as a flat string key (e.g. "chat.message") into the main object const eventName = parts.join('.'); actionsObj[eventName] = module.default || module; } } return actionsObj; } // $ Initialize asynchronously and export the loaded actions object const actions = await loadActions(); export default actions;