import { writeFileSync as writeFile, readFileSync as readFile, existsSync as exists } from 'fs' import { watch } from 'fs' import { join } from 'path' import { parseActions } from './actionParser' import { normalize } from './action' const srcDir = join(process.cwd(), 'src') generateActions() let timeout: Timer | null = null const watcher = watch(srcDir, (event, filename) => { if (filename === 'game.ts' && event === 'change') { if (timeout) clearTimeout(timeout) timeout = setTimeout(() => { generateActions() timeout = null }, 1000) } }) import.meta.hot?.dispose(() => { watcher.close() if (timeout) clearTimeout(timeout) }) export function generateActions() { const actions = parseActions(join(srcDir, 'game.ts')) const generated: string[] = [] generated.push(`// DO NOT MODIFY!\n`) generated.push(`// This file is generated by pyre.\n`) generated.push(`// Generated: ${new Date().toLocaleString('sv-SE')}.\n`) generated.push(`\n`) generated.push(`import { send } from 'pyre/client'\n`) for (const [name, params] of Object.entries(actions)) { generated.push(` export const ${normalize(name)} = (${paramsToString(params)}) => { send({ type: 'action', action: '${name}', args: [${argsToString(params)}] }) } `) } const generatedActions = generated.join('') const actionsPath = join(srcDir, 'client', 'actions.ts') if (exists(actionsPath)) { const existing = readFile(actionsPath, 'utf-8') if (stripTimestamp(existing) === stripTimestamp(generatedActions)) return } writeFile(actionsPath, generatedActions) console.log('Wrote', actionsPath) } function stripTimestamp(content: string): string { return content.replace(/^\/\/ Generated:.*\n/m, '') } function paramsToString(params: [string, string][]): string { const out: string[] = [] for (const [param, typeName] of params) out.push(`${param}: ${typeName}`) return out.join(', ') } function argsToString(params: [string, string][]): string { const out: string[] = [] for (const [param] of params) out.push(param) return out.join(', ') }