pyre/src/server/actionCodegen.ts
2026-01-20 21:16:52 -08:00

83 lines
2.1 KiB
TypeScript

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(', ')
}