UNPKG

seia.js

Version:

Lightweight SSR framework for React Server Components

78 lines (77 loc) 3.24 kB
/** @jsxImportSource hono/jsx */ import { jsx as _jsx, jsxs as _jsxs } from "hono/jsx/jsx-runtime"; import { serve as nodeServe } from '@hono/node-server'; import { serveStatic } from '@hono/node-server/serve-static'; import { Hono } from 'hono'; import { logger } from 'hono/logger'; import { renderToReadableStream } from 'react-dom/server.edge'; import { makeBanner } from './banner.js'; import { renderRscPayloadStream, renderRscPayloadStreamToDom } from './renderer.js'; import { changeExtension } from './utils-path.js'; import { trimPrefix } from './utils.js'; const injectGlobal = (rscPayload)=>`globalThis.__SEIA_RSC_PAYLOAD = \`${rscPayload}\``; /** * Start Seia SSR server. */ export const serve = async (config)=>{ const { paths: { entry, dist, anchor }, serve: { port } } = config; const app = new Hono(); app.use(logger()); app.use('/@seia/*', serveStatic({ root: dist, rewriteRequestPath: (path)=>trimPrefix(path, '/@seia') })); app.get('/', async (c)=>{ const entryFile = changeExtension(entry, '.js') + '#' + anchor; const [worker, stream] = await renderRscPayloadStream(entryFile, config); const [rscPayloadStream, domStream] = stream.tee(); const rscPayload = await new Response(rscPayloadStream).text(); const dom = await renderRscPayloadStreamToDom(domStream, config); const __html = await new Response(await renderToReadableStream(dom)).text(); await worker.terminate(); return c.html(/*#__PURE__*/ _jsxs("html", { children: [ /*#__PURE__*/ _jsxs("head", { children: [ /*#__PURE__*/ _jsx("meta", { charSet: "utf-8" }), /*#__PURE__*/ _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1.0" }), /*#__PURE__*/ _jsx("title", { children: "Seia SSR" }), /*#__PURE__*/ _jsx("link", { rel: "stylesheet", href: "/@seia/style.css" }), /*#__PURE__*/ _jsx("script", { type: "module", src: "/@seia/client.js" }) ] }), /*#__PURE__*/ _jsxs("body", { children: [ /*#__PURE__*/ _jsx("div", { id: "root", dangerouslySetInnerHTML: { __html } }), /*#__PURE__*/ _jsx("script", { dangerouslySetInnerHTML: { __html: injectGlobal(rscPayload) } }) ] }) ] })); }); console.log(makeBanner(config)); nodeServe({ fetch: app.fetch, port }); };