// bankai start — the dev server: Vite middleware mode for the module // graph and HMR, per-request streaming SSR of the same entry through // vite.ssrLoadModule so server code shares Vite's transforms and cache. import { createServer } from 'node:http' import bankaiPlugin, { findCss, CLIENT_URL } from './plugin.js' import { resolveApp } from './app.js' import { documentHead, documentTail } from './document.js' export default async function dev ({ entry, port = 8080, title = 'choo' }) { const { createServer: createViteServer } = await import('vite') const css = await findCss(entry) // style.css convention; restart to add it const vite = await createViteServer({ appType: 'custom', server: { middlewareMode: true }, plugins: [bankaiPlugin(entry, { css })], css: { lightningcss: { errorRecovery: true } }, logLevel: 'warn' }) const server = createServer((req, res) => { vite.middlewares(req, res, async () => { // not an asset Vite knows: this is a page navigation — SSR it try { const mod = await vite.ssrLoadModule(entry) const app = resolveApp(mod, entry) const state = {} // Read the first chunk before writing the head: by then stores // have run and the view has rendered up to its first async hole, // so DOMTitleChange emits have landed in state.title. const reader = app.toStream(req.url, state).getReader() const first = await reader.read() res.writeHead(200, { 'content-type': 'text/html; charset=utf-8' }) res.write(documentHead({ title: state.title || title, scripts: ['/@vite/client', CLIENT_URL] })) if (!first.done) res.write(first.value) for (;;) { const { done, value } = await reader.read() if (done) break res.write(value) } res.end(documentTail(state)) } catch (err) { vite.ssrFixStacktrace(err) console.error(err) if (!res.headersSent) res.writeHead(500, { 'content-type': 'text/plain' }) res.end('bankai dev error:\n\n' + (err.stack || err.message)) } }) }) await new Promise((resolve) => server.listen(port, resolve)) return { server, vite, port: server.address().port, origin: `http://localhost:${server.address().port}`, close: async () => { await vite.close() await new Promise((resolve) => server.close(resolve)) } } }