@rshono/core 1.0.0-rc.12 → 1.0.0-rc.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +29 -8
- package/bin/rshono.mjs +3 -4
- package/dist/builder/env-shadow-loader.cjs +25 -6
- package/dist/builder/page-files.js +5 -5
- package/dist/builder/page-files.js.map +1 -1
- package/dist/builder/public-env.d.ts +5 -4
- package/dist/builder/public-env.d.ts.map +1 -1
- package/dist/builder/public-env.js +5 -4
- package/dist/builder/public-env.js.map +1 -1
- package/dist/builder/react-versions.d.ts +13 -0
- package/dist/builder/react-versions.d.ts.map +1 -0
- package/dist/builder/react-versions.js +74 -0
- package/dist/builder/react-versions.js.map +1 -0
- package/dist/builder/rspack-config.d.ts +5 -11
- package/dist/builder/rspack-config.d.ts.map +1 -1
- package/dist/builder/rspack-config.js +73 -55
- package/dist/builder/rspack-config.js.map +1 -1
- package/dist/cli/build.d.ts.map +1 -1
- package/dist/cli/build.js +6 -2
- package/dist/cli/build.js.map +1 -1
- package/dist/cli/dev.d.ts.map +1 -1
- package/dist/cli/dev.js +30 -40
- package/dist/cli/dev.js.map +1 -1
- package/dist/cli/index.js +5 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/start.d.ts.map +1 -1
- package/dist/cli/start.js +12 -16
- package/dist/cli/start.js.map +1 -1
- package/dist/config.d.ts +28 -31
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/deploy/aws-lambda/runtime.d.ts +4 -6
- package/dist/deploy/aws-lambda/runtime.d.ts.map +1 -1
- package/dist/deploy/aws-lambda/runtime.js +5 -8
- package/dist/deploy/aws-lambda/runtime.js.map +1 -1
- package/dist/deploy/build-marker.d.ts +3 -5
- package/dist/deploy/build-marker.d.ts.map +1 -1
- package/dist/deploy/build-marker.js +3 -5
- package/dist/deploy/build-marker.js.map +1 -1
- package/dist/deploy/cloudflare/build.d.ts.map +1 -1
- package/dist/deploy/cloudflare/build.js +6 -10
- package/dist/deploy/cloudflare/build.js.map +1 -1
- package/dist/deploy/cloudflare/runtime.d.ts +2 -5
- package/dist/deploy/cloudflare/runtime.d.ts.map +1 -1
- package/dist/deploy/cloudflare/runtime.js +19 -32
- package/dist/deploy/cloudflare/runtime.js.map +1 -1
- package/dist/deploy/contract.d.ts +25 -42
- package/dist/deploy/contract.d.ts.map +1 -1
- package/dist/deploy/contract.js.map +1 -1
- package/dist/deploy/filesystem.d.ts +3 -5
- package/dist/deploy/filesystem.d.ts.map +1 -1
- package/dist/deploy/filesystem.js +15 -11
- package/dist/deploy/filesystem.js.map +1 -1
- package/dist/deploy/node/runtime.d.ts +4 -5
- package/dist/deploy/node/runtime.d.ts.map +1 -1
- package/dist/deploy/node/runtime.js +9 -15
- package/dist/deploy/node/runtime.js.map +1 -1
- package/dist/deploy/presets.d.ts +19 -29
- package/dist/deploy/presets.d.ts.map +1 -1
- package/dist/deploy/presets.js +41 -24
- package/dist/deploy/presets.js.map +1 -1
- package/dist/deploy/vercel/build.d.ts.map +1 -1
- package/dist/deploy/vercel/build.js +19 -16
- package/dist/deploy/vercel/build.js.map +1 -1
- package/dist/deploy/vercel/runtime.d.ts +4 -7
- package/dist/deploy/vercel/runtime.d.ts.map +1 -1
- package/dist/deploy/vercel/runtime.js +13 -7
- package/dist/deploy/vercel/runtime.js.map +1 -1
- package/dist/index.d.ts +13 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -12
- package/dist/index.js.map +1 -1
- package/dist/router.d.ts +65 -93
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +2 -5
- package/dist/router.js.map +1 -1
- package/dist/runtime/boundaries.d.ts +24 -30
- package/dist/runtime/boundaries.d.ts.map +1 -1
- package/dist/runtime/boundaries.js +15 -22
- package/dist/runtime/boundaries.js.map +1 -1
- package/dist/runtime/client.d.ts +16 -7
- package/dist/runtime/client.d.ts.map +1 -1
- package/dist/runtime/client.js +16 -7
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/context.d.ts +89 -118
- package/dist/runtime/context.d.ts.map +1 -1
- package/dist/runtime/context.js +122 -167
- package/dist/runtime/context.js.map +1 -1
- package/dist/runtime/control.js +3 -3
- package/dist/runtime/control.js.map +1 -1
- package/dist/runtime/dev-protocol.d.ts +4 -8
- package/dist/runtime/dev-protocol.d.ts.map +1 -1
- package/dist/runtime/dev-protocol.js.map +1 -1
- package/dist/runtime/entry.client.js +121 -113
- package/dist/runtime/entry.client.js.map +1 -1
- package/dist/runtime/entry.rsc.d.ts +5 -6
- package/dist/runtime/entry.rsc.d.ts.map +1 -1
- package/dist/runtime/entry.rsc.js +140 -129
- package/dist/runtime/entry.rsc.js.map +1 -1
- package/dist/runtime/entry.ssr.d.ts +7 -12
- package/dist/runtime/entry.ssr.d.ts.map +1 -1
- package/dist/runtime/entry.ssr.js +13 -24
- package/dist/runtime/entry.ssr.js.map +1 -1
- package/dist/runtime/flight-inject.d.ts +10 -17
- package/dist/runtime/flight-inject.d.ts.map +1 -1
- package/dist/runtime/flight-inject.js +63 -54
- package/dist/runtime/flight-inject.js.map +1 -1
- package/dist/runtime/hot-update.d.ts +20 -27
- package/dist/runtime/hot-update.d.ts.map +1 -1
- package/dist/runtime/hot-update.js +17 -23
- package/dist/runtime/hot-update.js.map +1 -1
- package/dist/runtime/navigation.d.ts +14 -19
- package/dist/runtime/navigation.d.ts.map +1 -1
- package/dist/runtime/navigation.js +9 -13
- package/dist/runtime/navigation.js.map +1 -1
- package/dist/runtime/request.d.ts +16 -10
- package/dist/runtime/request.d.ts.map +1 -1
- package/dist/runtime/request.js +30 -10
- package/dist/runtime/request.js.map +1 -1
- package/dist/runtime/server.d.ts +18 -10
- package/dist/runtime/server.d.ts.map +1 -1
- package/dist/runtime/server.js +21 -19
- package/dist/runtime/server.js.map +1 -1
- package/dist/server/headers.d.ts +8 -15
- package/dist/server/headers.d.ts.map +1 -1
- package/dist/server/headers.js +8 -15
- package/dist/server/headers.js.map +1 -1
- package/dist/server/load-config.d.ts +2 -2
- package/dist/server/load-config.d.ts.map +1 -1
- package/dist/server/load-config.js +6 -9
- package/dist/server/load-config.js.map +1 -1
- package/dist/server/prerendered.d.ts +40 -45
- package/dist/server/prerendered.d.ts.map +1 -1
- package/dist/server/prerendered.js +50 -33
- package/dist/server/prerendered.js.map +1 -1
- package/dist/server/server-config.d.ts +13 -28
- package/dist/server/server-config.d.ts.map +1 -1
- package/dist/server/server-config.js +5 -10
- package/dist/server/server-config.js.map +1 -1
- package/dist/server/shutdown.d.ts +5 -3
- package/dist/server/shutdown.d.ts.map +1 -1
- package/dist/server/shutdown.js +5 -3
- package/dist/server/shutdown.js.map +1 -1
- package/dist/server/ssg.d.ts +3 -6
- package/dist/server/ssg.d.ts.map +1 -1
- package/dist/server/ssg.js +12 -21
- package/dist/server/ssg.js.map +1 -1
- package/package.json +2 -2
package/dist/cli/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"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","sourcesContent":["import { serve } from '@hono/node-server';\nimport { rspack, type Stats } from '@rspack/core';\nimport { Hono } from 'hono';\nimport { proxy } from 'hono/proxy';\nimport { mkdir, rm } from 'node:fs/promises';\nimport { createServer } from 'node:net';\nimport { join } from 'node:path';\nimport { Worker } from 'node:worker_threads';\nimport { DEV_OUT_DIR, createConfigs } from '../builder/rspack-config.js';\nimport type { RshonoConfig } from '../config.js';\nimport { NODE_PRESET } from '../deploy/presets.js';\nimport type { DevMessage } from '../runtime/dev-protocol.js';\nimport { SERVER_DEFAULTS } from '../server/server-config.js';\nimport { createStaticAssetsApp } from '../server/static.js';\n\nconst WORKER_READY_TIMEOUT_MS = 15_000;\n\n/** An error as the dev server shows it in the browser: the stack where there is one, since this is dev. */\nfunction describe(error: unknown): string {\n return error instanceof Error ? (error.stack ?? error.message) : String(error);\n}\n\n/**\n * Whether nothing is listening on the port yet — checked before the output directory is emptied.\n *\n * `rshono dev` clears its own output on startup, so a second one started against a running server\n * wipes the directory that server is still importing route chunks from, and only then exits on\n * EADDRINUSE. The first server keeps serving from files that no longer exist, and its watcher never\n * re-emits them — it believes it already wrote them — so it 500s until it is restarted.\n */\nfunction portAvailable(port: number, hostname: string): Promise<boolean> {\n const { promise, resolve } = Promise.withResolvers<boolean>();\n const probe = createServer();\n probe.once('error', () => resolve(false));\n probe.listen(port, hostname, () => probe.close(() => resolve(true)));\n return promise;\n}\n\ninterface DevOptions {\n rootDir: string;\n port?: number;\n config: RshonoConfig;\n}\n\nexport async function devCommand(options: DevOptions): Promise<void> {\n const { rootDir, config } = options;\n const port = options.port ?? SERVER_DEFAULTS.port;\n // Its own directory, never `dist/`: a `rshono build` in another terminal must not be able to\n // delete the chunks this server is still importing. See DEV_OUT_DIR.\n const outDir = join(rootDir, DEV_OUT_DIR);\n\n // Before the `rm` below, not at `serve` where the bind actually happens: see {@link portAvailable}.\n if (!(await portAvailable(port, '127.0.0.1'))) {\n console.error(` ✗ port ${port} is already in use`);\n process.exit(1);\n }\n\n await rm(outDir, { recursive: true, force: true });\n await mkdir(join(outDir, 'static'), { recursive: true });\n\n const encoder = new TextEncoder();\n const sseClients = new Set<ReadableStreamDefaultController<Uint8Array>>();\n let clientHash: string | undefined;\n\n const sseChunk = (data: unknown) => encoder.encode(`data: ${JSON.stringify(data)}\\n\\n`);\n\n /**\n * Writes one already-encoded SSE frame to every open client, dropping the ones that have gone away.\n * A browser that navigated or closed leaves a controller whose `enqueue` throws, and `cancel` is not\n * always reached first — so a failed write is what retires a client.\n */\n function sendToAll(chunk: Uint8Array): void {\n for (const controller of sseClients) {\n try {\n controller.enqueue(chunk);\n } catch {\n sseClients.delete(controller);\n }\n }\n }\n\n function broadcast(message: DevMessage): void {\n sendToAll(sseChunk(message));\n }\n\n let serverComponentsChanged = false;\n const [clientConfig, serverConfig] = createConfigs({\n rootDir,\n isDev: true,\n config,\n // Always Node, whatever `deploy` says: the dev server runs the bundle in a worker thread of this\n // process and fronts it on one port. `deploy` is a property of `build` output, not of developing.\n preset: NODE_PRESET,\n onServerComponentChanges: () => {\n serverComponentsChanged = true;\n },\n });\n const compiler = rspack([clientConfig, serverConfig]);\n const [clientCompiler, serverCompiler] = compiler.compilers;\n\n let currentWorker: Worker | null = null;\n let workerPort: number | null = null;\n let workerGate = createGate();\n let restartChain: Promise<void> = Promise.resolve();\n\n function createGate() {\n const { promise, resolve } = Promise.withResolvers<{ error?: string }>();\n return { promise, open: resolve };\n }\n\n function spawnWorker(): Promise<{ worker: Worker; port: number }> {\n return new Promise((resolve, reject) => {\n const worker = new Worker(join(outDir, 'server', 'main.mjs'), {\n workerData: { port: 0, hostname: '127.0.0.1' },\n execArgv: ['--enable-source-maps'],\n env: process.env as Record<string, string>,\n });\n const timeout = setTimeout(() => {\n worker.terminate();\n reject(new Error(`server worker did not become ready within ${WORKER_READY_TIMEOUT_MS / 1000}s`));\n }, WORKER_READY_TIMEOUT_MS);\n\n let ready = false;\n worker.once('message', (message: { type?: string; port?: number }) => {\n if (message?.type === 'ready' && typeof message.port === 'number') {\n ready = true;\n clearTimeout(timeout);\n resolve({ worker, port: message.port });\n }\n });\n // `on`, not `once`: an error *after* the worker is ready has no pending promise left to reject,\n // and a consumed `once` would leave that error with no listener at all — which Node turns into\n // an uncaught exception that takes the dev server down with the worker.\n worker.on('error', (error) => {\n if (ready) {\n console.error(' ✗ server worker crashed:', error);\n return;\n }\n clearTimeout(timeout);\n reject(error);\n });\n worker.on('exit', (code) => {\n if (worker === currentWorker && code !== 0) {\n console.error(` ✗ server worker exited with code ${code} — waiting for the next rebuild`);\n currentWorker = null;\n // Opened with the reason rather than left closed: a request arriving before the next rebuild\n // parks on this gate, and an unopened one would hang the browser with only the terminal\n // saying why. `hooks.invalid` installs a fresh closed gate the moment a file changes, so the\n // next build still holds requests until the worker is back.\n workerGate = createGate();\n workerGate.open({ error: `The server worker exited with code ${code}. See the terminal for the error it crashed with.` });\n }\n });\n });\n }\n\n serverCompiler.hooks.invalid.tap('rshono/gate', () => {\n workerGate = createGate();\n });\n\n serverCompiler.hooks.done.tapPromise('rshono/worker', async (stats: Stats) => {\n const gate = workerGate;\n restartChain = restartChain.then(async () => {\n if (stats.hasErrors()) {\n console.error(stats.toString({ preset: 'errors-warnings', colors: true }));\n gate.open({ error: stats.toString({ preset: 'errors-only', colors: false }) });\n return;\n }\n try {\n if (currentWorker) {\n const old = currentWorker;\n currentWorker = null;\n await old.terminate();\n }\n const { worker, port: newPort } = await spawnWorker();\n currentWorker = worker;\n workerPort = newPort;\n gate.open({});\n if (serverComponentsChanged) {\n serverComponentsChanged = false;\n broadcast({ type: 'rsc-update' });\n }\n } catch (error) {\n console.error(' ✗ failed to start server worker:', error);\n gate.open({ error: describe(error) });\n }\n });\n // No link in this queue may be left rejected: `.then` on a rejected promise short-circuits, and\n // from that point no worker is ever spawned again and no gate is ever opened — a dev server that\n // answers nothing and explains nothing. The `try` above covers the restart; this covers the rest.\n restartChain = restartChain.catch((error) => {\n console.error(' ✗ dev server restart failed:', error);\n gate.open({ error: describe(error) });\n });\n await restartChain;\n });\n\n clientCompiler.hooks.done.tap('rshono/hmr', (stats: Stats) => {\n if (stats.hasErrors()) {\n console.error(stats.toString({ preset: 'errors-warnings', colors: true }));\n return;\n }\n clientHash = stats.hash ?? undefined;\n if (clientHash) broadcast({ type: 'client-built', hash: clientHash });\n });\n\n let firstBuild = true;\n compiler.watch([{}, {}] as never, (err, multiStats) => {\n if (err) {\n console.error(' ✗ build failed:', err);\n return;\n }\n if (multiStats && !multiStats.hasErrors()) {\n const seconds = Math.max(...multiStats.stats.map((s) => (s.endTime ?? 0) - (s.startTime ?? 0))) / 1000;\n console.log(` ${firstBuild ? '✓ built' : '✓ rebuilt'} in ${seconds.toFixed(1)}s`);\n firstBuild = false;\n }\n });\n\n const front = new Hono();\n\n front.route('/_static', createStaticAssetsApp({ root: join(outDir, 'static'), isDev: true }));\n\n front.get('/_rshono/hmr', (c) => {\n let ctrl: ReadableStreamDefaultController<Uint8Array>;\n const stream = new ReadableStream<Uint8Array>({\n start(controller) {\n ctrl = controller;\n sseClients.add(controller);\n controller.enqueue(encoder.encode('retry: 500\\n\\n'));\n controller.enqueue(sseChunk({ type: 'hello', hash: clientHash } satisfies DevMessage));\n },\n cancel() {\n sseClients.delete(ctrl);\n },\n });\n return new Response(stream, {\n headers: {\n 'content-type': 'text/event-stream',\n 'cache-control': 'no-cache',\n connection: 'keep-alive',\n },\n });\n });\n\n // An SSE comment, not a message: it keeps an idle connection off a proxy's timeout without the\n // client having to know about a frame type that means nothing.\n const ping = encoder.encode(': ping\\n\\n');\n setInterval(() => sendToAll(ping), 15_000).unref();\n\n front.all('*', async (c) => {\n const { error } = await workerGate.promise;\n if (error || workerPort === null) {\n return c.text(`Build failed:\\n\\n${error ?? 'server not running'}`, 500);\n }\n\n const incoming = new URL(c.req.url);\n const target = `http://127.0.0.1:${workerPort}${incoming.pathname}${incoming.search}`;\n\n // Hono's proxy helper rather than a hand-rolled `fetch`: it carries the method, the streamed body\n // (with the `duplex` Node requires) and the client's abort signal, so a browser that goes away\n // takes the worker's render with it. On the way back it strips the hop-by-hop headers. `headers`\n // replaces the set wholesale, so the request's own are spread back in first.\n const response = await proxy(target, {\n raw: c.req.raw,\n // The worker's redirects are the app's answer to this request, not something to follow here —\n // they have to reach the browser, with the internal address rewritten off them below.\n redirect: 'manual',\n headers: {\n ...c.req.header(),\n // This front-end *is* the proxy the app sits behind, and `trustProxy` is forced on in dev for\n // exactly that reason: without these the app resolves every URL against the worker's random\n // 127.0.0.1 port instead of the address the browser actually used.\n 'x-forwarded-host': incoming.host,\n 'x-forwarded-proto': incoming.protocol.replace(':', ''),\n },\n });\n\n // A redirect to the worker's own address has to become a relative one, or the browser leaves the\n // dev server for a random port only this process knows about. `proxy` hands back a response whose\n // headers are still mutable, so the rewrite happens in place.\n const location = response.headers.get('location');\n const loc = location ? URL.parse(location, target) : null;\n if (loc && loc.host === `127.0.0.1:${workerPort}`) {\n response.headers.set('location', `${loc.pathname}${loc.search}${loc.hash}`);\n }\n return response;\n });\n\n serve({ fetch: front.fetch, port, hostname: '127.0.0.1' }, (info) => {\n console.log(` ➜ rshono dev server: http://localhost:${info.port}`);\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"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","sourcesContent":["import { serve } from '@hono/node-server';\nimport { rspack, type Stats } from '@rspack/core';\nimport { Hono } from 'hono';\nimport { proxy } from 'hono/proxy';\nimport { mkdir, rm } from 'node:fs/promises';\nimport { createServer } from 'node:net';\nimport { join } from 'node:path';\nimport { Worker } from 'node:worker_threads';\nimport { DEV_OUT_DIR, createConfigs } from '../builder/rspack-config.js';\nimport type { RshonoConfig } from '../config.js';\nimport { NODE_PRESET } from '../deploy/presets.js';\nimport type { DevMessage } from '../runtime/dev-protocol.js';\nimport { SERVER_DEFAULTS } from '../server/server-config.js';\nimport { createStaticAssetsApp } from '../server/static.js';\n\nconst WORKER_READY_TIMEOUT_MS = 15_000;\n\n/** An error as the dev server shows it in the browser: the stack where there is one, since this is dev. */\nfunction describe(error: unknown): string {\n return error instanceof Error ? (error.stack ?? error.message) : String(error);\n}\n\n/**\n * Whether nothing is listening on the port yet — checked before the output directory is emptied, because a\n * second `rshono dev` would otherwise wipe the chunks the running one is still importing and only then exit\n * on EADDRINUSE.\n */\nfunction portAvailable(port: number, hostname: string): Promise<boolean> {\n const { promise, resolve } = Promise.withResolvers<boolean>();\n const probe = createServer();\n probe.once('error', () => resolve(false));\n probe.listen(port, hostname, () => probe.close(() => resolve(true)));\n return promise;\n}\n\ninterface DevOptions {\n rootDir: string;\n port?: number;\n config: RshonoConfig;\n}\n\nexport async function devCommand(options: DevOptions): Promise<void> {\n const { rootDir, config } = options;\n const port = options.port ?? SERVER_DEFAULTS.port;\n // Its own directory, never `dist/`: a `rshono build` in another terminal must not be able to delete the\n // chunks this server is still importing.\n const outDir = join(rootDir, DEV_OUT_DIR);\n\n // Before the `rm` below, not at `serve` where the bind happens — see {@link portAvailable}.\n if (!(await portAvailable(port, '127.0.0.1'))) {\n console.error(` ✗ port ${port} is already in use`);\n process.exit(1);\n }\n\n await rm(outDir, { recursive: true, force: true });\n await mkdir(join(outDir, 'static'), { recursive: true });\n\n const encoder = new TextEncoder();\n const sseClients = new Set<ReadableStreamDefaultController<Uint8Array>>();\n let clientHash: string | undefined;\n\n const sseChunk = (data: unknown) => encoder.encode(`data: ${JSON.stringify(data)}\\n\\n`);\n\n /**\n * Writes one already-encoded SSE frame to every open client. A failed write is what retires a client:\n * `cancel` is not always reached first when a browser navigates away.\n */\n function sendToAll(chunk: Uint8Array): void {\n for (const controller of sseClients) {\n try {\n controller.enqueue(chunk);\n } catch {\n sseClients.delete(controller);\n }\n }\n }\n\n function broadcast(message: DevMessage): void {\n sendToAll(sseChunk(message));\n }\n\n let serverComponentsChanged = false;\n const [clientConfig, serverConfig] = createConfigs({\n rootDir,\n isDev: true,\n config,\n // Always Node, whatever `deploy` says: that is a property of `build` output, and the dev server runs the\n // bundle in a worker thread of this process.\n preset: NODE_PRESET,\n onServerComponentChanges: () => {\n serverComponentsChanged = true;\n },\n });\n const compiler = rspack([clientConfig, serverConfig]);\n const [clientCompiler, serverCompiler] = compiler.compilers;\n\n let currentWorker: Worker | null = null;\n let workerPort: number | null = null;\n let workerGate = createGate();\n let restartChain: Promise<void> = Promise.resolve();\n\n function createGate() {\n const { promise, resolve } = Promise.withResolvers<{ error?: string }>();\n return { promise, open: resolve };\n }\n\n function spawnWorker(): Promise<{ worker: Worker; port: number }> {\n return new Promise((resolve, reject) => {\n const worker = new Worker(join(outDir, 'server', 'main.mjs'), {\n workerData: { port: 0, hostname: '127.0.0.1' },\n execArgv: ['--enable-source-maps'],\n env: process.env as Record<string, string>,\n });\n const timeout = setTimeout(() => {\n // Nothing waits on the termination: the promise below is already being rejected, and a worker that\n // never reported ready has no state left worth draining.\n void worker.terminate();\n reject(new Error(`server worker did not become ready within ${WORKER_READY_TIMEOUT_MS / 1000}s`));\n }, WORKER_READY_TIMEOUT_MS);\n\n let ready = false;\n worker.once('message', (message: { type?: string; port?: number }) => {\n if (message?.type === 'ready' && typeof message.port === 'number') {\n ready = true;\n clearTimeout(timeout);\n resolve({ worker, port: message.port });\n }\n });\n // `on`, not `once`: an error after the worker is ready has no pending promise left to reject, and a\n // consumed `once` would leave it unlistened — which Node turns into an uncaught exception here.\n worker.on('error', (error: Error) => {\n if (ready) {\n console.error(' ✗ server worker crashed:', error);\n return;\n }\n clearTimeout(timeout);\n reject(error);\n });\n worker.on('exit', (code) => {\n if (worker === currentWorker && code !== 0) {\n console.error(` ✗ server worker exited with code ${code} — waiting for the next rebuild`);\n currentWorker = null;\n // Opened with the reason rather than left closed, so a request arriving before the next rebuild sees\n // it instead of hanging. `hooks.invalid` installs a fresh closed gate as soon as a file changes.\n workerGate = createGate();\n workerGate.open({ error: `The server worker exited with code ${code}. See the terminal for the error it crashed with.` });\n }\n });\n });\n }\n\n serverCompiler.hooks.invalid.tap('rshono/gate', () => {\n workerGate = createGate();\n });\n\n serverCompiler.hooks.done.tapPromise('rshono/worker', async (stats: Stats) => {\n const gate = workerGate;\n restartChain = restartChain.then(async () => {\n if (stats.hasErrors()) {\n console.error(stats.toString({ preset: 'errors-warnings', colors: true }));\n gate.open({ error: stats.toString({ preset: 'errors-only', colors: false }) });\n return;\n }\n try {\n if (currentWorker) {\n const old = currentWorker;\n currentWorker = null;\n await old.terminate();\n }\n const { worker, port: newPort } = await spawnWorker();\n currentWorker = worker;\n workerPort = newPort;\n gate.open({});\n if (serverComponentsChanged) {\n serverComponentsChanged = false;\n broadcast({ type: 'rsc-update' });\n }\n } catch (error) {\n console.error(' ✗ failed to start server worker:', error);\n gate.open({ error: describe(error) });\n }\n });\n // No link in this queue may be left rejected: `.then` on a rejected promise short-circuits, and from there\n // no worker is spawned and no gate is opened again.\n restartChain = restartChain.catch((error) => {\n console.error(' ✗ dev server restart failed:', error);\n gate.open({ error: describe(error) });\n });\n await restartChain;\n });\n\n clientCompiler.hooks.done.tap('rshono/hmr', (stats: Stats) => {\n if (stats.hasErrors()) {\n console.error(stats.toString({ preset: 'errors-warnings', colors: true }));\n return;\n }\n clientHash = stats.hash ?? undefined;\n if (clientHash) broadcast({ type: 'client-built', hash: clientHash });\n });\n\n let firstBuild = true;\n compiler.watch([{}, {}] as never, (err, multiStats) => {\n if (err) {\n console.error(' ✗ build failed:', err);\n return;\n }\n if (multiStats && !multiStats.hasErrors()) {\n const seconds = Math.max(...multiStats.stats.map((s) => (s.endTime ?? 0) - (s.startTime ?? 0))) / 1000;\n console.log(` ${firstBuild ? '✓ built' : '✓ rebuilt'} in ${seconds.toFixed(1)}s`);\n firstBuild = false;\n }\n });\n\n const front = new Hono();\n\n front.route('/_static', createStaticAssetsApp({ root: join(outDir, 'static'), isDev: true }));\n\n front.get('/_rshono/hmr', () => {\n let ctrl: ReadableStreamDefaultController<Uint8Array>;\n const stream = new ReadableStream<Uint8Array>({\n start(controller) {\n ctrl = controller;\n sseClients.add(controller);\n controller.enqueue(encoder.encode('retry: 500\\n\\n'));\n controller.enqueue(sseChunk({ type: 'hello', hash: clientHash } satisfies DevMessage));\n },\n cancel() {\n sseClients.delete(ctrl);\n },\n });\n return new Response(stream, {\n headers: {\n 'content-type': 'text/event-stream',\n 'cache-control': 'no-cache',\n connection: 'keep-alive',\n },\n });\n });\n\n // An SSE comment, not a message: it keeps an idle connection off a proxy's timeout without the client\n // having to know a frame type that means nothing.\n const ping = encoder.encode(': ping\\n\\n');\n setInterval(() => sendToAll(ping), 15_000).unref();\n\n front.all('*', async (c) => {\n const { error } = await workerGate.promise;\n if (error || workerPort === null) {\n return c.text(`Build failed:\\n\\n${error ?? 'server not running'}`, 500);\n }\n\n const incoming = new URL(c.req.url);\n const target = `http://127.0.0.1:${workerPort}${incoming.pathname}${incoming.search}`;\n\n // Hono's proxy helper rather than a hand-rolled `fetch`: it carries the method, the streamed body (with\n // the `duplex` Node requires) and the client's abort signal, and strips the hop-by-hop headers on the way\n // back. `headers` replaces the set wholesale, so the request's own are spread back in first.\n const response = await proxy(target, {\n raw: c.req.raw,\n // The worker's redirects are the app's answer to this request, to be rewritten below and passed on.\n redirect: 'manual',\n headers: {\n ...c.req.header(),\n // This front-end *is* the proxy the app sits behind, which is why `trustProxy` is forced on in dev:\n // without these the app resolves every URL against the worker's random 127.0.0.1 port.\n 'x-forwarded-host': incoming.host,\n 'x-forwarded-proto': incoming.protocol.replace(':', ''),\n },\n });\n\n // A redirect to the worker's own address has to become a relative one, or the browser leaves the dev\n // server for a random port only this process knows about.\n const location = response.headers.get('location');\n const loc = location ? URL.parse(location, target) : null;\n if (loc && loc.host === `127.0.0.1:${workerPort}`) {\n response.headers.set('location', `${loc.pathname}${loc.search}${loc.hash}`);\n }\n return response;\n });\n\n serve({ fetch: front.fetch, port, hostname: '127.0.0.1' }, (info) => {\n console.log(` ➜ rshono dev server: http://localhost:${info.port}`);\n });\n}\n"]}
|
package/dist/cli/index.js
CHANGED
|
@@ -3,9 +3,9 @@ import { parseArgs } from 'node:util';
|
|
|
3
3
|
import { DEPLOY_TARGETS, resolveDeployPreset } from '../deploy/presets.js';
|
|
4
4
|
import { loadConfig } from '../server/load-config.js';
|
|
5
5
|
import { loadEnvFiles } from '../server/load-env.js';
|
|
6
|
-
// The commands are imported where they are dispatched
|
|
7
|
-
//
|
|
8
|
-
//
|
|
6
|
+
// The commands are imported where they are dispatched: `build` and `dev` pull in Rspack, and a static import
|
|
7
|
+
// would load it for `start` too — ~30 MB of RSS and ~70ms of startup that would then sit in the server's own
|
|
8
|
+
// process for its whole life, since `start` imports the bundle rather than spawning it.
|
|
9
9
|
const HELP = `rshono — Hono + Rspack + React Server Components
|
|
10
10
|
|
|
11
11
|
Usage:
|
|
@@ -33,7 +33,8 @@ async function main() {
|
|
|
33
33
|
});
|
|
34
34
|
if (values.version) {
|
|
35
35
|
const require = createRequire(import.meta.url);
|
|
36
|
-
|
|
36
|
+
const { version } = require('@rshono/core/package.json');
|
|
37
|
+
console.log(version);
|
|
37
38
|
return;
|
|
38
39
|
}
|
|
39
40
|
const command = positionals[0];
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { createRequire } from 'node:module';\nimport { parseArgs } from 'node:util';\nimport { DEPLOY_TARGETS, resolveDeployPreset } from '../deploy/presets.js';\nimport { loadConfig } from '../server/load-config.js';\nimport { loadEnvFiles } from '../server/load-env.js';\n\n// The commands are imported where they are dispatched: `build` and `dev` pull in Rspack, and a static import\n// would load it for `start` too — ~30 MB of RSS and ~70ms of startup that would then sit in the server's own\n// process for its whole life, since `start` imports the bundle rather than spawning it.\n\nconst HELP = `rshono — Hono + Rspack + React Server Components\n\nUsage:\n rshono dev [--port 3000] start the dev server\n rshono build build for production (client + server + SSG)\n rshono start [--port 3000] run the production build\n\nOptions:\n -p, --port <n> port to listen on (default: PORT env or 3000)\n -c, --config <path> path to a config file (default: rshono.config.{ts,js,mjs})\n -d, --deploy <name> platform to build for: ${DEPLOY_TARGETS.join(' | ')} (default: node)\n -h, --help show this help\n -v, --version print the version\n`;\n\nasync function main(): Promise<void> {\n const { values, positionals } = parseArgs({\n options: {\n port: { type: 'string', short: 'p' },\n config: { type: 'string', short: 'c' },\n deploy: { type: 'string', short: 'd' },\n help: { type: 'boolean', short: 'h' },\n version: { type: 'boolean', short: 'v' },\n },\n allowPositionals: true,\n });\n\n if (values.version) {\n const require = createRequire(import.meta.url);\n const { version } = require('@rshono/core/package.json') as { version: string };\n console.log(version);\n return;\n }\n\n const command = positionals[0];\n if (values.help || !command) {\n console.log(HELP);\n return;\n }\n\n const rootDir = process.cwd();\n loadEnvFiles(rootDir);\n const config = await loadConfig(rootDir, values.config);\n\n const flagPort = values.port ? Number(values.port) : undefined;\n if (values.port && Number.isNaN(flagPort)) {\n console.error(`rshono: invalid --port \"${values.port}\"`);\n process.exit(1);\n }\n // Precedence: --port flag > PORT env > the command's built-in default.\n const envPort = process.env.PORT ? Number(process.env.PORT) : undefined;\n const port = flagPort ?? envPort;\n const host = process.env.HOST;\n\n switch (command) {\n case 'dev':\n return (await import('./dev.js')).devCommand({ rootDir, port, config });\n case 'build':\n return (await import('./build.js')).buildCommand({\n rootDir,\n config,\n preset: resolveDeployPreset({ flag: values.deploy, env: process.env.RSHONO_DEPLOY, config: config.deploy }),\n });\n case 'start':\n return (await import('./start.js')).startCommand({ rootDir, port, host });\n default:\n console.error(`rshono: unknown command \"${command}\"\\n`);\n console.log(HELP);\n process.exit(1);\n }\n}\n\nmain().catch((error) => {\n console.error(error);\n process.exit(1);\n});\n"]}
|
package/dist/cli/start.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/cli/start.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/cli/start.ts"],"names":[],"mappings":"AAMA,UAAU,YAAY;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BvE"}
|
package/dist/cli/start.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { spawn } from 'node:child_process';
|
|
2
1
|
import { existsSync } from 'node:fs';
|
|
3
2
|
import { join } from 'node:path';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
4
|
import { readBuildMarker } from '../deploy/build-marker.js';
|
|
5
5
|
import { deployHintFor } from '../deploy/presets.js';
|
|
6
|
-
import { onShutdown } from '../server/shutdown.js';
|
|
7
6
|
export async function startCommand(options) {
|
|
8
7
|
const { rootDir, port, host } = options;
|
|
9
8
|
const distDir = join(rootDir, 'dist');
|
|
@@ -12,9 +11,8 @@ export async function startCommand(options) {
|
|
|
12
11
|
console.error('rshono: no production build found — run `rshono build` first.');
|
|
13
12
|
process.exit(1);
|
|
14
13
|
}
|
|
15
|
-
// A bundle built for a hosting platform has no listener in it
|
|
16
|
-
//
|
|
17
|
-
// evaluating, so say what happened and point at the command that does deploy it.
|
|
14
|
+
// A bundle built for a hosting platform has no listener in it, so starting one here would exit silently the
|
|
15
|
+
// moment the module finished evaluating.
|
|
18
16
|
const target = readBuildMarker(distDir);
|
|
19
17
|
if (target !== null && target !== 'node') {
|
|
20
18
|
const hint = deployHintFor(target);
|
|
@@ -22,18 +20,16 @@ export async function startCommand(options) {
|
|
|
22
20
|
console.error(' Rebuild for a server with `rshono build --deploy node` to run it here.');
|
|
23
21
|
process.exit(1);
|
|
24
22
|
}
|
|
25
|
-
|
|
23
|
+
// Read by the bundle as it evaluates, which is what binds the port — so they have to be set first.
|
|
26
24
|
if (port !== undefined)
|
|
27
|
-
env.PORT = String(port);
|
|
25
|
+
process.env.PORT = String(port);
|
|
28
26
|
if (host !== undefined)
|
|
29
|
-
env.HOST = host;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
process.exit(signal ? 1 : (code ?? 1));
|
|
37
|
-
});
|
|
27
|
+
process.env.HOST = host;
|
|
28
|
+
// Imported into this process rather than spawned into a child. The child only ever existed to pass
|
|
29
|
+
// `--enable-source-maps`, and `bin/rshono.mjs` already enables the same thing in-process before the CLI
|
|
30
|
+
// loads — so a supervisor bought a second PID and its own heap in every container, an extra frame in every
|
|
31
|
+
// stack, and signal forwarding for signals the bundle already handles itself through `onShutdown`. `start`
|
|
32
|
+
// deliberately imports no Rspack, so the process this leaves behind is the server and little else.
|
|
33
|
+
await import(pathToFileURL(mainPath).href);
|
|
38
34
|
}
|
|
39
35
|
//# sourceMappingURL=start.js.map
|
package/dist/cli/start.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/cli/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/cli/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAQrD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAqB;IACtD,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IACxC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IACrD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,KAAK,CAAC,+DAA+D,CAAC,CAAC;QAC/E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,4GAA4G;IAC5G,yCAAyC;IACzC,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACzC,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;QACnC,OAAO,CAAC,KAAK,CAAC,8BAA8B,MAAM,sCAAsC,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;QACrH,OAAO,CAAC,KAAK,CAAC,0EAA0E,CAAC,CAAC;QAC1F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,mGAAmG;IACnG,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IACxD,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;IAEhD,mGAAmG;IACnG,wGAAwG;IACxG,2GAA2G;IAC3G,2GAA2G;IAC3G,mGAAmG;IACnG,MAAM,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC;AAC7C,CAAC","sourcesContent":["import { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { readBuildMarker } from '../deploy/build-marker.js';\nimport { deployHintFor } from '../deploy/presets.js';\n\ninterface StartOptions {\n rootDir: string;\n port?: number;\n host?: string;\n}\n\nexport async function startCommand(options: StartOptions): Promise<void> {\n const { rootDir, port, host } = options;\n const distDir = join(rootDir, 'dist');\n const mainPath = join(distDir, 'server', 'main.mjs');\n if (!existsSync(mainPath)) {\n console.error('rshono: no production build found — run `rshono build` first.');\n process.exit(1);\n }\n\n // A bundle built for a hosting platform has no listener in it, so starting one here would exit silently the\n // moment the module finished evaluating.\n const target = readBuildMarker(distDir);\n if (target !== null && target !== 'node') {\n const hint = deployHintFor(target);\n console.error(`rshono: this build targets ${target}, which \\`rshono start\\` cannot run${hint ? ` — ${hint}` : '.'}`);\n console.error(' Rebuild for a server with `rshono build --deploy node` to run it here.');\n process.exit(1);\n }\n\n // Read by the bundle as it evaluates, which is what binds the port — so they have to be set first.\n if (port !== undefined) process.env.PORT = String(port);\n if (host !== undefined) process.env.HOST = host;\n\n // Imported into this process rather than spawned into a child. The child only ever existed to pass\n // `--enable-source-maps`, and `bin/rshono.mjs` already enables the same thing in-process before the CLI\n // loads — so a supervisor bought a second PID and its own heap in every container, an extra frame in every\n // stack, and signal forwarding for signals the bundle already handles itself through `onShutdown`. `start`\n // deliberately imports no Rspack, so the process this leaves behind is the server and little else.\n await import(pathToFileURL(mainPath).href);\n}\n"]}
|
package/dist/config.d.ts
CHANGED
|
@@ -8,12 +8,11 @@ export interface RspackHookContext {
|
|
|
8
8
|
isDev: boolean;
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
|
-
* Project configuration
|
|
12
|
-
*
|
|
11
|
+
* Project configuration, default-exported from `rshono.config.ts` at the project root (`.js` / `.mjs`
|
|
12
|
+
* also work). Every field is optional; omit the file entirely to accept all defaults.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* already ships all of it and a config field would only be a worse way to spell the same call.
|
|
14
|
+
* It holds only what the *build* decides. Per-request concerns — CSRF, CSP, the body cap — are Hono
|
|
15
|
+
* middleware in `src/server.ts`, which is where Hono already ships all of them.
|
|
17
16
|
*
|
|
18
17
|
* @example
|
|
19
18
|
* ```ts
|
|
@@ -29,45 +28,43 @@ export interface RspackHookContext {
|
|
|
29
28
|
*/
|
|
30
29
|
export interface RshonoConfig {
|
|
31
30
|
/**
|
|
32
|
-
* The hosting platform `rshono build` targets. Default `'node'` — a long-lived server process
|
|
33
|
-
*
|
|
31
|
+
* The hosting platform `rshono build` targets. Default `'node'` — a long-lived server process run
|
|
32
|
+
* with `rshono start`.
|
|
34
33
|
*
|
|
35
|
-
* Overridden by the `--deploy` flag or the `RSHONO_DEPLOY` env var, so one config can
|
|
36
|
-
*
|
|
37
|
-
* server.
|
|
34
|
+
* Overridden by the `--deploy` flag or the `RSHONO_DEPLOY` env var, so one config can build for more
|
|
35
|
+
* than one place. `rshono dev` ignores it and always runs the Node dev server.
|
|
38
36
|
*
|
|
39
37
|
* @see {@link https://www.rshono.com/docs/deployment | Docs — deployment}
|
|
40
38
|
*/
|
|
41
39
|
deploy?: DeployTarget;
|
|
42
40
|
/**
|
|
43
|
-
* The public origin the site is served from, e.g. `'https://example.com'`.
|
|
41
|
+
* The public origin the site is served from, e.g. `'https://example.com'`. Must be a bare origin —
|
|
42
|
+
* a path is rejected rather than silently dropped.
|
|
44
43
|
*
|
|
45
|
-
* Only used when prerendering `render: 'static'` routes
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* routes resolve the URL per request and are unaffected.
|
|
49
|
-
*
|
|
50
|
-
* Must be a bare origin; a path is rejected rather than silently dropped.
|
|
44
|
+
* Only used when prerendering `render: 'static'` routes, which have no request to read a `Host`
|
|
45
|
+
* from: without it their `url` prop falls back to `http://localhost`, and that is what canonical
|
|
46
|
+
* tags, absolute links and `og:url` get baked with.
|
|
51
47
|
*
|
|
52
48
|
* @see {@link https://www.rshono.com/docs/configuration#siteurl | Docs — siteUrl}
|
|
53
49
|
*/
|
|
54
50
|
siteUrl?: string;
|
|
55
51
|
/**
|
|
56
|
-
* Honour `X-Forwarded-Host` / `X-Forwarded-Proto` when resolving the browser-facing request
|
|
57
|
-
*
|
|
52
|
+
* Honour `X-Forwarded-Host` / `X-Forwarded-Proto` when resolving the browser-facing request URL —
|
|
53
|
+
* `getRequestContext().url` and a page's `url` prop. Default `false`; always `true` under
|
|
54
|
+
* `rshono dev`.
|
|
55
|
+
*
|
|
56
|
+
* **Enable it only behind a proxy you control**: any client can send those headers, so with nothing
|
|
57
|
+
* stripping them at the edge one request can point every absolute URL the app builds at an
|
|
58
|
+
* attacker's host. Turn it on when you terminate TLS or rewrite `Host` at a reverse proxy.
|
|
58
59
|
*
|
|
59
|
-
* Middleware in `src/server.ts`
|
|
60
|
-
*
|
|
61
|
-
* `Host`, give it the public origin explicitly (`csrf({ origin: 'https://example.com' })`) rather
|
|
62
|
-
* than leaving it to compare against an address the browser never used.
|
|
60
|
+
* Middleware in `src/server.ts` reads Hono's `c.req.url` — the *internal* address — whatever this
|
|
61
|
+
* says, so give `csrf()` the public origin explicitly.
|
|
63
62
|
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* `rshono dev`, where the framework's own proxy sets them and binds to localhost. Default `false`.
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* export default defineConfig({ trustProxy: true });
|
|
66
|
+
* ```
|
|
69
67
|
*
|
|
70
|
-
* @see {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host | MDN — X-Forwarded-Host}
|
|
71
68
|
* @see {@link https://www.rshono.com/docs/configuration#proxy-headers | Docs — proxy headers}
|
|
72
69
|
*/
|
|
73
70
|
trustProxy?: boolean;
|
|
@@ -89,8 +86,8 @@ export interface RshonoConfig {
|
|
|
89
86
|
rspack?: (config: RspackOptions, ctx: RspackHookContext) => RspackOptions | void;
|
|
90
87
|
}
|
|
91
88
|
/**
|
|
92
|
-
*
|
|
93
|
-
*
|
|
89
|
+
* Types a config object for editor autocomplete, without an explicit annotation. Default-export the
|
|
90
|
+
* result from `rshono.config.ts`.
|
|
94
91
|
*
|
|
95
92
|
* @param config - The project's {@link RshonoConfig}; every field is optional.
|
|
96
93
|
* @returns The config, unchanged and fully typed.
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,kGAAkG;AAClG,MAAM,WAAW,iBAAiB;IAChC,oGAAoG;IACpG,QAAQ,EAAE,OAAO,CAAC;IAClB,+DAA+D;IAC/D,KAAK,EAAE,OAAO,CAAC;CAChB;AAED
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,kGAAkG;AAClG,MAAM,WAAW,iBAAiB;IAChC,oGAAoG;IACpG,QAAQ,EAAE,OAAO,CAAC;IAClB,+DAA+D;IAC/D,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;;;;;;;;;OAkBG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,iBAAiB,KAAK,aAAa,GAAG,IAAI,CAAC;CAClF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAE/D"}
|
package/dist/config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* Types a config object for editor autocomplete, without an explicit annotation. Default-export the
|
|
3
|
+
* result from `rshono.config.ts`.
|
|
4
4
|
*
|
|
5
5
|
* @param config - The project's {@link RshonoConfig}; every field is optional.
|
|
6
6
|
* @returns The config, unchanged and fully typed.
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AA0FA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,YAAY,CAAC,MAAoB;IAC/C,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import type { RspackOptions } from '@rspack/core';\nimport type { DeployTarget } from './deploy/contract.js';\n\n/** Which of the two Rspack compilers the {@link RshonoConfig.rspack} hook is being called for. */\nexport interface RspackHookContext {\n /** `true` for the server (`target: node`) bundle, `false` for the client (`target: web`) bundle. */\n isServer: boolean;\n /** `true` under `rshono dev`, `false` under `rshono build`. */\n isDev: boolean;\n}\n\n/**\n * Project configuration, default-exported from `rshono.config.ts` at the project root (`.js` / `.mjs`\n * also work). Every field is optional; omit the file entirely to accept all defaults.\n *\n * It holds only what the *build* decides. Per-request concerns — CSRF, CSP, the body cap — are Hono\n * middleware in `src/server.ts`, which is where Hono already ships all of them.\n *\n * @example\n * ```ts\n * import { defineConfig } from '@rshono/core';\n *\n * export default defineConfig({\n * deploy: 'cloudflare',\n * siteUrl: 'https://example.com',\n * });\n * ```\n *\n * @see {@link https://www.rshono.com/docs/configuration | Docs — configuration}\n */\nexport interface RshonoConfig {\n /**\n * The hosting platform `rshono build` targets. Default `'node'` — a long-lived server process run\n * with `rshono start`.\n *\n * Overridden by the `--deploy` flag or the `RSHONO_DEPLOY` env var, so one config can build for more\n * than one place. `rshono dev` ignores it and always runs the Node dev server.\n *\n * @see {@link https://www.rshono.com/docs/deployment | Docs — deployment}\n */\n deploy?: DeployTarget;\n /**\n * The public origin the site is served from, e.g. `'https://example.com'`. Must be a bare origin —\n * a path is rejected rather than silently dropped.\n *\n * Only used when prerendering `render: 'static'` routes, which have no request to read a `Host`\n * from: without it their `url` prop falls back to `http://localhost`, and that is what canonical\n * tags, absolute links and `og:url` get baked with.\n *\n * @see {@link https://www.rshono.com/docs/configuration#siteurl | Docs — siteUrl}\n */\n siteUrl?: string;\n /**\n * Honour `X-Forwarded-Host` / `X-Forwarded-Proto` when resolving the browser-facing request URL —\n * `getRequestContext().url` and a page's `url` prop. Default `false`; always `true` under\n * `rshono dev`.\n *\n * **Enable it only behind a proxy you control**: any client can send those headers, so with nothing\n * stripping them at the edge one request can point every absolute URL the app builds at an\n * attacker's host. Turn it on when you terminate TLS or rewrite `Host` at a reverse proxy.\n *\n * Middleware in `src/server.ts` reads Hono's `c.req.url` — the *internal* address — whatever this\n * says, so give `csrf()` the public origin explicitly.\n *\n * @example\n * ```ts\n * export default defineConfig({ trustProxy: true });\n * ```\n *\n * @see {@link https://www.rshono.com/docs/configuration#proxy-headers | Docs — proxy headers}\n */\n trustProxy?: boolean;\n /**\n * Escape hatch: mutate the generated Rspack config just before it's compiled. Called once per\n * compiler — inspect {@link RspackHookContext.isServer} to tell them apart. Mutate `config` in\n * place and return nothing, or return a replacement.\n *\n * @example\n * ```ts\n * rspack(config, { isServer }) {\n * config.module?.rules?.push({ test: /\\.svg$/, type: 'asset/source' });\n * }\n * ```\n *\n * @see {@link https://rspack.rs/config/ | Rspack — configuration reference}\n * @see {@link https://www.rshono.com/docs/configuration#the-rspack-hook | Docs — the rspack hook}\n */\n rspack?: (config: RspackOptions, ctx: RspackHookContext) => RspackOptions | void;\n}\n\n/**\n * Types a config object for editor autocomplete, without an explicit annotation. Default-export the\n * result from `rshono.config.ts`.\n *\n * @param config - The project's {@link RshonoConfig}; every field is optional.\n * @returns The config, unchanged and fully typed.\n *\n * @example\n * ```ts\n * // rshono.config.ts\n * import { defineConfig } from '@rshono/core';\n *\n * export default defineConfig({ deploy: 'cloudflare', siteUrl: 'https://example.com' });\n * ```\n *\n * @see {@link https://www.rshono.com/docs/configuration | Docs — configuration}\n */\nexport function defineConfig(config: RshonoConfig): RshonoConfig {\n return config;\n}\n"]}
|
|
@@ -2,13 +2,11 @@ import type { DeployRuntime } from '../contract.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* AWS Lambda behind a Function URL, in streaming mode.
|
|
4
4
|
*
|
|
5
|
-
* `streamHandle` wraps the app with `awslambda.streamifyResponse`,
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* anywhere but would hold every page until the last byte rendered.
|
|
5
|
+
* `streamHandle` wraps the app with `awslambda.streamifyResponse`, the only way a Lambda writes a response
|
|
6
|
+
* progressively — which is the whole point of a streamed SSR shell. It requires the Function URL's invoke mode
|
|
7
|
+
* to be `RESPONSE_STREAM`; the buffered `handle` would work anywhere but hold every page until its last byte.
|
|
9
8
|
*
|
|
10
|
-
* The filesystem capabilities are Node's: a Lambda unpacks the deployment package onto a read-only
|
|
11
|
-
* disk, so `dist/static`, `dist/public` and `dist/ssg` are read exactly as they are on a server.
|
|
9
|
+
* The filesystem capabilities are Node's: a Lambda unpacks the deployment package onto a read-only disk.
|
|
12
10
|
*/
|
|
13
11
|
export declare const runtime: DeployRuntime;
|
|
14
12
|
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/deploy/aws-lambda/runtime.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGpD
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/deploy/aws-lambda/runtime.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGpD;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,EAAE,aAQrB,CAAC"}
|
|
@@ -3,19 +3,16 @@ import { fileSystemRuntime } from '../filesystem.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* AWS Lambda behind a Function URL, in streaming mode.
|
|
5
5
|
*
|
|
6
|
-
* `streamHandle` wraps the app with `awslambda.streamifyResponse`,
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* anywhere but would hold every page until the last byte rendered.
|
|
6
|
+
* `streamHandle` wraps the app with `awslambda.streamifyResponse`, the only way a Lambda writes a response
|
|
7
|
+
* progressively — which is the whole point of a streamed SSR shell. It requires the Function URL's invoke mode
|
|
8
|
+
* to be `RESPONSE_STREAM`; the buffered `handle` would work anywhere but hold every page until its last byte.
|
|
10
9
|
*
|
|
11
|
-
* The filesystem capabilities are Node's: a Lambda unpacks the deployment package onto a read-only
|
|
12
|
-
* disk, so `dist/static`, `dist/public` and `dist/ssg` are read exactly as they are on a server.
|
|
10
|
+
* The filesystem capabilities are Node's: a Lambda unpacks the deployment package onto a read-only disk.
|
|
13
11
|
*/
|
|
14
12
|
export const runtime = {
|
|
15
13
|
...fileSystemRuntime,
|
|
16
14
|
serveApp(app) {
|
|
17
|
-
//
|
|
18
|
-
// bundle to prerender. Returning nothing then keeps that pass working; a real invocation has it.
|
|
15
|
+
// A global the Lambda runtime injects, so it is absent when the build imports this bundle to prerender.
|
|
19
16
|
if (typeof globalThis.awslambda === 'undefined')
|
|
20
17
|
return undefined;
|
|
21
18
|
return streamHandle(app);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/deploy/aws-lambda/runtime.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/deploy/aws-lambda/runtime.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,OAAO,GAAkB;IACpC,GAAG,iBAAiB;IAEpB,QAAQ,CAAC,GAAS;QAChB,wGAAwG;QACxG,IAAI,OAAQ,UAAsC,CAAC,SAAS,KAAK,WAAW;YAAE,OAAO,SAAS,CAAC;QAC/F,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;CACF,CAAC","sourcesContent":["import type { Hono } from 'hono';\nimport { streamHandle } from 'hono/aws-lambda';\nimport type { DeployRuntime } from '../contract.js';\nimport { fileSystemRuntime } from '../filesystem.js';\n\n/**\n * AWS Lambda behind a Function URL, in streaming mode.\n *\n * `streamHandle` wraps the app with `awslambda.streamifyResponse`, the only way a Lambda writes a response\n * progressively — which is the whole point of a streamed SSR shell. It requires the Function URL's invoke mode\n * to be `RESPONSE_STREAM`; the buffered `handle` would work anywhere but hold every page until its last byte.\n *\n * The filesystem capabilities are Node's: a Lambda unpacks the deployment package onto a read-only disk.\n */\nexport const runtime: DeployRuntime = {\n ...fileSystemRuntime,\n\n serveApp(app: Hono): unknown {\n // A global the Lambda runtime injects, so it is absent when the build imports this bundle to prerender.\n if (typeof (globalThis as { awslambda?: unknown }).awslambda === 'undefined') return undefined;\n return streamHandle(app);\n },\n};\n"]}
|
|
@@ -5,11 +5,9 @@ export interface BuildMarker {
|
|
|
5
5
|
}
|
|
6
6
|
export declare function writeBuildMarker(distDir: string, deploy: DeployTarget): void;
|
|
7
7
|
/**
|
|
8
|
-
* The target the build in `distDir` was produced for, or `null` when there is nothing to go on
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* and refusing to start one that would have worked is worse than the confusing failure this guards
|
|
12
|
-
* against.
|
|
8
|
+
* The target the build in `distDir` was produced for, or `null` when there is nothing to go on — a missing
|
|
9
|
+
* marker is not an error, since a build from an older rshono has none and refusing to start one that would
|
|
10
|
+
* have worked is worse than the failure this guards against.
|
|
13
11
|
*/
|
|
14
12
|
export declare function readBuildMarker(distDir: string): DeployTarget | null;
|
|
15
13
|
//# sourceMappingURL=build-marker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-marker.d.ts","sourceRoot":"","sources":["../../src/deploy/build-marker.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,8FAA8F;AAC9F,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,YAAY,CAAC;CACtB;AAID,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAE5E;AAED
|
|
1
|
+
{"version":3,"file":"build-marker.d.ts","sourceRoot":"","sources":["../../src/deploy/build-marker.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,8FAA8F;AAC9F,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,YAAY,CAAC;CACtB;AAID,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CASpE"}
|
|
@@ -5,11 +5,9 @@ export function writeBuildMarker(distDir, deploy) {
|
|
|
5
5
|
writeFileSync(join(distDir, MARKER_FILE), `${JSON.stringify({ deploy }, null, 2)}\n`);
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
|
-
* The target the build in `distDir` was produced for, or `null` when there is nothing to go on
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* and refusing to start one that would have worked is worse than the confusing failure this guards
|
|
12
|
-
* against.
|
|
8
|
+
* The target the build in `distDir` was produced for, or `null` when there is nothing to go on — a missing
|
|
9
|
+
* marker is not an error, since a build from an older rshono has none and refusing to start one that would
|
|
10
|
+
* have worked is worse than the failure this guards against.
|
|
13
11
|
*/
|
|
14
12
|
export function readBuildMarker(distDir) {
|
|
15
13
|
const file = join(distDir, MARKER_FILE);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-marker.js","sourceRoot":"","sources":["../../src/deploy/build-marker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAQjC,MAAM,WAAW,GAAG,mBAAmB,CAAC;AAExC,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,MAAoB;IACpE,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAwB,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AAC9G,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"build-marker.js","sourceRoot":"","sources":["../../src/deploy/build-marker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAQjC,MAAM,WAAW,GAAG,mBAAmB,CAAC;AAExC,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,MAAoB;IACpE,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAwB,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AAC9G,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IACxC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAyB,CAAC;QAC9E,OAAO,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC","sourcesContent":["import { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { DeployTarget } from './contract.js';\n\n/** Records which platform a build was for, so `rshono start` can refuse one it cannot run. */\nexport interface BuildMarker {\n deploy: DeployTarget;\n}\n\nconst MARKER_FILE = 'rshono-build.json';\n\nexport function writeBuildMarker(distDir: string, deploy: DeployTarget): void {\n writeFileSync(join(distDir, MARKER_FILE), `${JSON.stringify({ deploy } satisfies BuildMarker, null, 2)}\\n`);\n}\n\n/**\n * The target the build in `distDir` was produced for, or `null` when there is nothing to go on — a missing\n * marker is not an error, since a build from an older rshono has none and refusing to start one that would\n * have worked is worse than the failure this guards against.\n */\nexport function readBuildMarker(distDir: string): DeployTarget | null {\n const file = join(distDir, MARKER_FILE);\n if (!existsSync(file)) return null;\n try {\n const parsed = JSON.parse(readFileSync(file, 'utf8')) as Partial<BuildMarker>;\n return typeof parsed.deploy === 'string' ? parsed.deploy : null;\n } catch {\n return null;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/deploy/cloudflare/build.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/deploy/cloudflare/build.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAoDxD;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBpF"}
|
|
@@ -5,12 +5,9 @@ import { basename, join } from 'node:path';
|
|
|
5
5
|
const ASSETS_DIR = join('cloudflare', 'assets');
|
|
6
6
|
const WRANGLER_FILES = ['wrangler.jsonc', 'wrangler.json', 'wrangler.toml'];
|
|
7
7
|
/**
|
|
8
|
-
* Caching and crawler rules for the assembled tree, in the file Workers Assets reads them from
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* prerender tree is reachable under its own prefix (see `SSG_PREFIX` in `runtime.ts`) and holds a
|
|
12
|
-
* second copy of pages that already have real URLs, so it is marked `noindex` rather than left for a
|
|
13
|
-
* crawler to find twice.
|
|
8
|
+
* Caching and crawler rules for the assembled tree, in the file Workers Assets reads them from: the hashed
|
|
9
|
+
* bundle is immutable by construction, which the CDN cannot infer, and the prerender tree holds a second copy
|
|
10
|
+
* of pages that already have real URLs — so it is marked `noindex`.
|
|
14
11
|
*/
|
|
15
12
|
const HEADERS_FILE = `/_static/*
|
|
16
13
|
Cache-Control: public, max-age=31536000, immutable
|
|
@@ -27,7 +24,7 @@ function workerName(rootDir) {
|
|
|
27
24
|
return name || 'rshono-app';
|
|
28
25
|
}
|
|
29
26
|
// Fixed, not the day the build ran: wrangler's bundled workerd refuses a date newer than its own, so a config
|
|
30
|
-
// dated today would deploy fine and never start under `wrangler dev`.
|
|
27
|
+
// dated today would deploy fine and never start under `wrangler dev`.
|
|
31
28
|
const COMPATIBILITY_DATE = '2026-07-01';
|
|
32
29
|
function wranglerConfig(rootDir) {
|
|
33
30
|
return `${JSON.stringify({
|
|
@@ -35,7 +32,7 @@ function wranglerConfig(rootDir) {
|
|
|
35
32
|
name: workerName(rootDir),
|
|
36
33
|
main: 'dist/server/main.mjs',
|
|
37
34
|
compatibility_date: COMPATIBILITY_DATE,
|
|
38
|
-
// AsyncLocalStorage
|
|
35
|
+
// For AsyncLocalStorage, which is how the request context behind `getRequestContext()` is bound.
|
|
39
36
|
compatibility_flags: ['nodejs_compat'],
|
|
40
37
|
assets: {
|
|
41
38
|
directory: `dist/${ASSETS_DIR.split(/[\\/]/).join('/')}`,
|
|
@@ -50,8 +47,7 @@ function wranglerConfig(rootDir) {
|
|
|
50
47
|
*/
|
|
51
48
|
export async function finalizeCloudflareBuild(ctx) {
|
|
52
49
|
const assetsDir = join(ctx.distDir, ASSETS_DIR);
|
|
53
|
-
//
|
|
54
|
-
// not survive in the deployed tree.
|
|
50
|
+
// From scratch, so a deleted `public/` file or a route that stopped being static does not survive here.
|
|
55
51
|
await rm(assetsDir, { recursive: true, force: true });
|
|
56
52
|
mkdirSync(assetsDir, { recursive: true });
|
|
57
53
|
cpSync(ctx.staticDir, join(assetsDir, '_static'), { recursive: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../../src/deploy/cloudflare/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAG3C,2GAA2G;AAC3G,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;AAEhD,MAAM,cAAc,GAAG,CAAC,gBAAgB,EAAE,eAAe,EAAE,eAAe,CAAC,CAAC;AAE5E
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../../src/deploy/cloudflare/build.ts"],"names":[],"mappings":"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","sourcesContent":["import { cpSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { rm } from 'node:fs/promises';\nimport { basename, join } from 'node:path';\nimport type { DeployBuildContext } from '../presets.js';\n\n/** Wrangler serves one directory, so the three kinds of asset the build produces are assembled into it. */\nconst ASSETS_DIR = join('cloudflare', 'assets');\n\nconst WRANGLER_FILES = ['wrangler.jsonc', 'wrangler.json', 'wrangler.toml'];\n\n/**\n * Caching and crawler rules for the assembled tree, in the file Workers Assets reads them from: the hashed\n * bundle is immutable by construction, which the CDN cannot infer, and the prerender tree holds a second copy\n * of pages that already have real URLs — so it is marked `noindex`.\n */\nconst HEADERS_FILE = `/_static/*\n Cache-Control: public, max-age=31536000, immutable\n\n/__ssg/*\n X-Robots-Tag: noindex\n`;\n\n/** A Wrangler worker name: lowercase, and only the characters it accepts. */\nfunction workerName(rootDir: string): string {\n const name = basename(rootDir)\n .toLowerCase()\n .replace(/[^a-z0-9-]+/g, '-')\n .replace(/^-+|-+$/g, '');\n return name || 'rshono-app';\n}\n\n// Fixed, not the day the build ran: wrangler's bundled workerd refuses a date newer than its own, so a config\n// dated today would deploy fine and never start under `wrangler dev`.\nconst COMPATIBILITY_DATE = '2026-07-01';\n\nfunction wranglerConfig(rootDir: string): string {\n return `${JSON.stringify(\n {\n $schema: 'node_modules/wrangler/config-schema.json',\n name: workerName(rootDir),\n main: 'dist/server/main.mjs',\n compatibility_date: COMPATIBILITY_DATE,\n // For AsyncLocalStorage, which is how the request context behind `getRequestContext()` is bound.\n compatibility_flags: ['nodejs_compat'],\n assets: {\n directory: `dist/${ASSETS_DIR.split(/[\\\\/]/).join('/')}`,\n // Read by the worker for `public/` files and prerendered pages; the CDN still answers first.\n binding: 'ASSETS',\n },\n },\n null,\n 2,\n )}\\n`;\n}\n\n/**\n * Arranges a Workers deployment: one assets directory holding everything the CDN should serve, and a\n * `wrangler.jsonc` to deploy with if the project has no Wrangler config of its own.\n */\nexport async function finalizeCloudflareBuild(ctx: DeployBuildContext): Promise<void> {\n const assetsDir = join(ctx.distDir, ASSETS_DIR);\n // From scratch, so a deleted `public/` file or a route that stopped being static does not survive here.\n await rm(assetsDir, { recursive: true, force: true });\n mkdirSync(assetsDir, { recursive: true });\n\n cpSync(ctx.staticDir, join(assetsDir, '_static'), { recursive: true });\n if (ctx.publicDir) cpSync(ctx.publicDir, assetsDir, { recursive: true });\n if (existsSync(ctx.ssgDir)) cpSync(ctx.ssgDir, join(assetsDir, '__ssg'), { recursive: true });\n\n const headersFile = join(assetsDir, '_headers');\n if (existsSync(headersFile)) {\n console.warn(` ⚠ public/_headers is in the way of the generated one — /_static/* will not be marked immutable.`);\n } else {\n writeFileSync(headersFile, HEADERS_FILE);\n }\n\n const existing = WRANGLER_FILES.find((file) => existsSync(join(ctx.rootDir, file)));\n if (!existing) {\n writeFileSync(join(ctx.rootDir, 'wrangler.jsonc'), wranglerConfig(ctx.rootDir));\n console.log(' • wrote wrangler.jsonc (yours now — edit freely, the build will not touch it again)');\n }\n\n console.log(` • assembled ${join('dist', ASSETS_DIR)} for Workers Assets`);\n}\n"]}
|