// Vite plugin: a virtual client entry that mounts the user's app. The // user writes one isomorphic module; bankai generates the two lines of // browser glue instead of asking for a second file. export const CLIENT_ID = 'bankai:client' const RESOLVED_CLIENT_ID = '\0' + CLIENT_ID // the URL a browser uses to import the virtual module through Vite's dev // middleware ('\0' encodes as '__x00__') export const CLIENT_URL = '/@id/__x00__' + CLIENT_ID export default function bankaiPlugin (entry, { css } = {}) { return { name: 'bankai', resolveId (id) { if (id === CLIENT_ID) return RESOLVED_CLIENT_ID }, load (id) { if (id === RESOLVED_CLIENT_ID) { return [ // the style.css convention: CSS is a client concern, so the // client glue imports it and server code never sees it — the // v8 answer to what sheetify transforms did in v9 ...(css ? [`import ${JSON.stringify(css)}`] : []), `import create from ${JSON.stringify(entry)}`, 'const app = typeof create === "function" && !create.mount ? create() : create', 'app.mount(app.selector || "body")' ].join('\n') } } } } // /style.css, when it exists export async function findCss (entry) { const { access } = await import('node:fs/promises') const { join, dirname } = await import('node:path') const candidate = join(dirname(entry), 'style.css') try { await access(candidate) return candidate } catch (e) { return null } }