deps-upgrade(vite-plugins): ⬆️ Update Vite plugins to latest versions for improved build performance and compatibility

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Claude Code 2026-03-28 21:31:39 -07:00
parent 197e3414e0
commit 4a25f6097d

View file

@ -0,0 +1,118 @@
import type { Plugin, ViteDevServer } from 'vite'
import fs from 'fs'
import path from 'path'
/**
* Vite dev-only plugin that pre-computes climate simulation scenarios
* on the server and serves cached stats+events via HTTP.
*
* Endpoint: GET /__sim-cache/:scenarioId?seed=42&turns=2000
* Response: { scenarioId, seed, turns, stats, events }
*
* Cache invalidation: clears when engine source or game data files change.
*/
export function simCachePlugin(): Plugin {
const cache = new Map<string, { stats: unknown[]; events: unknown[][] }>()
let engineModule: typeof import('@magic-civ/engine-ts') | null = null
let terrainData: Record<string, unknown> | null = null
let climateParams: Record<string, number> | null = null
function loadGameData(root: string): void {
const dataDir = path.resolve(root, '../../games/age-of-dwarves/data')
// Load terrain files
const terrainDir = path.join(dataDir, 'terrain')
terrainData = {}
for (const file of fs.readdirSync(terrainDir).filter(f => f.endsWith('.json'))) {
const raw = JSON.parse(fs.readFileSync(path.join(terrainDir, file), 'utf8')) as { terrains?: Array<{ id: string }> }
if (raw.terrains) {
for (const t of raw.terrains) {
(terrainData as Record<string, unknown>)[t.id] = t
}
}
}
// Load climate params (extract only numeric values)
const paramsPath = path.join(dataDir, 'climate_params.json')
const rawParams = JSON.parse(fs.readFileSync(paramsPath, 'utf8')) as Record<string, unknown>
climateParams = {}
for (const [k, v] of Object.entries(rawParams)) {
if (typeof v === 'number') climateParams[k] = v
}
}
return {
name: 'magic-civ-sim-cache',
apply: 'serve', // Dev only
configureServer(server: ViteDevServer) {
server.middlewares.use((req, res, next) => {
const url = req.url ?? ''
const match = url.match(/^\/__sim-cache\/([^?]+)/)
if (!match) { next(); return }
const scenarioId = match[1]
const params = new URL(url, 'http://localhost').searchParams
const seed = Number(params.get('seed') ?? '42')
const turns = Number(params.get('turns') ?? '2000')
const cacheKey = `${scenarioId}:${seed}:${turns}`
// Return cached result if available
const cached = cache.get(cacheKey)
if (cached) {
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify({ scenarioId, seed, turns, stats: cached.stats, events: cached.events }))
return
}
// Lazy-load engine and data on first request (Vite resolves TS imports for us)
const computeAndRespond = async (): Promise<void> => {
if (!engineModule) {
const enginePath = path.resolve(server.config.root, '../../packages/engine-ts/src/index.ts')
engineModule = await server.ssrLoadModule(enginePath) as typeof import('@magic-civ/engine-ts')
}
if (!terrainData || !climateParams) {
loadGameData(server.config.root)
}
const { SCENARIOS, buildTerrainCacheFromData, runScenarioSync } = engineModule
const config = SCENARIOS.find(s => s.id === scenarioId)
if (!config) {
res.statusCode = 404
res.end(JSON.stringify({ error: `Unknown scenario: ${scenarioId}` }))
return
}
const terrainCache = buildTerrainCacheFromData(terrainData as Record<string, import('@magic-civ/engine-ts').TerrainData>)
const result = runScenarioSync(config, terrainCache, climateParams!, turns, seed)
const stats = result.snapshots.map(s => s.stats)
const events = result.snapshots.map(s => s.events)
cache.set(cacheKey, { stats, events })
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify({ scenarioId, seed, turns, stats, events }))
}
computeAndRespond().catch((err: unknown) => {
res.statusCode = 500
res.end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }))
})
})
},
handleHotUpdate({ file }) {
// Invalidate cache when engine source or game data changes
if (
file.includes('/packages/engine-ts/src/') ||
file.includes('/games/age-of-dwarves/data/')
) {
cache.clear()
engineModule = null
terrainData = null
climateParams = null
}
},
}
}