import { copyFileSync, createReadStream, existsSync, mkdirSync } from 'node:fs' import { dirname, resolve } from 'node:path' import type { Connect, Plugin, ResolvedConfig } from 'vite' function syncWasmFromNodeModules(root: string, source: string, destination: string) { const sourcePath = resolve(root, source) const destinationPath = resolve(root, destination) if (!existsSync(sourcePath)) { console.warn(`[copy-canvaskit-wasm] Missing source (run \`bun install\`): ${sourcePath}`) return } mkdirSync(dirname(destinationPath), { recursive: true }) copyFileSync(sourcePath, destinationPath) } function serveCanvasKitWasm(root: string): Connect.NextHandleFunction { return (req, res, next) => { const pathname = req.url?.split('?')[0] ?? '' if (pathname !== '/canvaskit.wasm' && pathname !== '/canvaskit-webgpu/canvaskit.wasm') { next() return } const publicPath = resolve(root, pathname.slice(1)) const fallbackPath = pathname === '/canvaskit.wasm' ? resolve(root, 'node_modules/canvaskit-wasm/bin/canvaskit.wasm') : resolve(root, 'packages/core/vendor/canvaskit-webgpu/canvaskit.wasm') const file = existsSync(publicPath) ? publicPath : fallbackPath if (!existsSync(file)) { next() return } res.setHeader('Content-Type', 'application/wasm') res.setHeader('Cache-Control', 'no-cache') createReadStream(file).on('error', next).pipe(res) } } export function copyCanvasKitAssetsPlugin(): Plugin { let root = process.cwd() return { name: 'copy-canvaskit-wasm', enforce: 'pre', configResolved(config: ResolvedConfig) { root = config.root }, buildStart() { syncWasmFromNodeModules( root, 'node_modules/canvaskit-wasm/bin/canvaskit.wasm', 'public/canvaskit.wasm' ) syncWasmFromNodeModules( root, 'packages/core/vendor/canvaskit-webgpu/canvaskit.wasm', 'public/canvaskit-webgpu/canvaskit.wasm' ) syncWasmFromNodeModules( root, 'packages/core/vendor/canvaskit-webgpu/canvaskit.js', 'public/canvaskit-webgpu/canvaskit.js' ) }, configureServer(server) { server.middlewares.use(serveCanvasKitWasm(server.config.root)) }, configurePreviewServer(server) { server.middlewares.use(serveCanvasKitWasm(server.config.root)) } } }