@rshono/core 1.0.0-rc.11 → 1.0.0-rc.13
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/README.md +2 -1
- package/bin/rshono.mjs +3 -4
- package/dist/builder/env-shadow-loader.cjs +5 -5
- 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/rspack-config.d.ts +10 -0
- package/dist/builder/rspack-config.d.ts.map +1 -1
- package/dist/builder/rspack-config.js +38 -40
- package/dist/builder/rspack-config.js.map +1 -1
- package/dist/cli/build.js +4 -4
- package/dist/cli/build.js.map +1 -1
- package/dist/cli/dev.d.ts.map +1 -1
- package/dist/cli/dev.js +50 -37
- package/dist/cli/dev.js.map +1 -1
- package/dist/cli/index.js +4 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/start.d.ts.map +1 -1
- package/dist/cli/start.js +2 -3
- 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 +12 -15
- 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 +18 -25
- package/dist/deploy/presets.js.map +1 -1
- package/dist/deploy/vercel/build.d.ts.map +1 -1
- package/dist/deploy/vercel/build.js +9 -12
- 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 +4 -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 +107 -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.d.ts.map +1 -1
- package/dist/runtime/entry.client.js +92 -120
- 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 +67 -122
- 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 +35 -53
- package/dist/runtime/flight-inject.js.map +1 -1
- package/dist/runtime/hot-update.d.ts +45 -0
- package/dist/runtime/hot-update.d.ts.map +1 -0
- package/dist/runtime/hot-update.js +44 -0
- package/dist/runtime/hot-update.js.map +1 -0
- 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 +4 -6
- package/dist/runtime/request.d.ts.map +1 -1
- package/dist/runtime/request.js +2 -3
- 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 +30 -43
- package/dist/server/prerendered.d.ts.map +1 -1
- package/dist/server/prerendered.js +20 -29
- package/dist/server/prerendered.js.map +1 -1
- package/dist/server/server-config.d.ts +18 -25
- package/dist/server/server-config.d.ts.map +1 -1
- package/dist/server/server-config.js +7 -11
- package/dist/server/server-config.js.map +1 -1
- package/dist/server/shutdown.d.ts +2 -3
- package/dist/server/shutdown.d.ts.map +1 -1
- package/dist/server/shutdown.js +2 -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 +11 -20
- package/dist/server/ssg.js.map +1 -1
- package/package.json +1 -1
|
@@ -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"]}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import type { DeployRuntime } from '../contract.js';
|
|
2
2
|
/**
|
|
3
|
-
* Cloudflare Workers: the host owns the process, so there is nothing to listen on
|
|
4
|
-
*
|
|
5
|
-
* streaming gzip are both out.
|
|
6
|
-
*
|
|
7
|
-
* What is left is the assets binding, which every read here goes through.
|
|
3
|
+
* Cloudflare Workers: the host owns the process, so there is nothing to listen on, and there is no filesystem,
|
|
4
|
+
* so `.env` files are out. What is left is the assets binding, which every read here goes through.
|
|
8
5
|
*/
|
|
9
6
|
export declare const runtime: DeployRuntime;
|
|
10
7
|
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/deploy/cloudflare/runtime.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/deploy/cloudflare/runtime.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAgDpD;;;GAGG;AACH,eAAO,MAAM,OAAO,EAAE,aA6CrB,CAAC"}
|
|
@@ -2,13 +2,10 @@ import { createPageCache, prerenderedRelPath, toPrerenderedPage } from '../../se
|
|
|
2
2
|
/**
|
|
3
3
|
* Where `finalize` puts the prerendered pages inside the assets directory.
|
|
4
4
|
*
|
|
5
|
-
* A prefix of its own, rather than the pages' real URLs, is what keeps every page URL reaching the
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* The bytes are public either way — they are a public page — but they are also reachable under this
|
|
10
|
-
* path, so `finalize` writes a `_headers` rule marking the tree `noindex` rather than leaving a
|
|
11
|
-
* crawler to find the same page twice.
|
|
5
|
+
* A prefix of its own, rather than the pages' real URLs, is what keeps every page URL reaching the worker: one
|
|
6
|
+
* URL answers with a document or a flight payload depending on `Accept`, and a path-keyed CDN cannot make that
|
|
7
|
+
* choice. The tree is reachable here too, so `finalize` marks it `noindex` rather than leaving a crawler to
|
|
8
|
+
* find the same page twice.
|
|
12
9
|
*/
|
|
13
10
|
const SSG_PREFIX = '/__ssg';
|
|
14
11
|
function assetsBinding(c) {
|
|
@@ -16,27 +13,23 @@ function assetsBinding(c) {
|
|
|
16
13
|
return binding && typeof binding.fetch === 'function' ? binding : null;
|
|
17
14
|
}
|
|
18
15
|
/**
|
|
19
|
-
* Asks the assets binding for one path, or `null` when there is no binding
|
|
20
|
-
*
|
|
16
|
+
* Asks the assets binding for one path, or `null` when there is no binding — which is how a caller tells "this
|
|
17
|
+
* deployment serves its assets some other way" from "that file is not there".
|
|
21
18
|
*
|
|
22
|
-
* `headers` is
|
|
23
|
-
*
|
|
24
|
-
* no body, which is a useless answer to "give me this page".
|
|
19
|
+
* `headers` is forwarded only where the *client's* conditional and range requests should be answered by the
|
|
20
|
+
* store: an `If-None-Match` on a page being fetched to serve would come back 304 with no body.
|
|
25
21
|
*/
|
|
26
22
|
async function assetResponse(c, path, headers) {
|
|
27
23
|
const binding = assetsBinding(c);
|
|
28
24
|
if (!binding)
|
|
29
25
|
return null;
|
|
30
|
-
// Resolved against the request so the
|
|
31
|
-
// path is ever used to look one up.
|
|
26
|
+
// Resolved against the request so the lookup carries this deployment's own origin; only the path is used.
|
|
32
27
|
const url = new URL(path, c.req.url);
|
|
33
28
|
return binding.fetch(new Request(url, { method: 'GET', headers }));
|
|
34
29
|
}
|
|
35
30
|
/**
|
|
36
|
-
* Hands an asset response back as the app's own.
|
|
37
|
-
*
|
|
38
|
-
* Rebuilt rather than returned as-is because a `Response` that came from `fetch` has immutable
|
|
39
|
-
* headers, and the framework's outermost middleware sets its baseline security headers on the way out.
|
|
31
|
+
* Hands an asset response back as the app's own. Rebuilt rather than returned as-is, because a `Response` from
|
|
32
|
+
* `fetch` has immutable headers and the framework's outermost middleware writes to them on the way out.
|
|
40
33
|
*/
|
|
41
34
|
function serveAsset(asset) {
|
|
42
35
|
return new Response(asset.body, asset);
|
|
@@ -44,22 +37,17 @@ function serveAsset(asset) {
|
|
|
44
37
|
/** Prerendered pages, keyed by the path that produced them. Per isolate rather than per process. */
|
|
45
38
|
const pageCache = createPageCache();
|
|
46
39
|
/**
|
|
47
|
-
* Cloudflare Workers: the host owns the process, so there is nothing to listen on
|
|
48
|
-
*
|
|
49
|
-
* streaming gzip are both out.
|
|
50
|
-
*
|
|
51
|
-
* What is left is the assets binding, which every read here goes through.
|
|
40
|
+
* Cloudflare Workers: the host owns the process, so there is nothing to listen on, and there is no filesystem,
|
|
41
|
+
* so `.env` files are out. What is left is the assets binding, which every read here goes through.
|
|
52
42
|
*/
|
|
53
43
|
export const runtime = {
|
|
54
44
|
serveApp(app) {
|
|
55
|
-
//
|
|
56
|
-
// which is why bindings arrive as `c.env` — and so why `getRequestContext().env` sees them.
|
|
45
|
+
// `app.fetch` already takes `(request, env, ctx)`, which is why bindings arrive as `c.env`.
|
|
57
46
|
return { fetch: app.fetch };
|
|
58
47
|
},
|
|
59
48
|
mountStaticAssets(app) {
|
|
60
|
-
// Normally dead
|
|
61
|
-
//
|
|
62
|
-
// configuration that routes everything to the worker first.
|
|
49
|
+
// Normally dead — the CDN answers `/_static/*` before the worker is invoked — but keeps the deployment
|
|
50
|
+
// correct, if slower, under an assets configuration that routes everything to the worker first.
|
|
63
51
|
app.on(['GET', 'HEAD'], '/_static/*', async (c, next) => {
|
|
64
52
|
const asset = await assetResponse(c, c.req.path, c.req.raw.headers);
|
|
65
53
|
return asset && asset.status !== 404 ? serveAsset(asset) : next();
|
|
@@ -67,8 +55,7 @@ export const runtime = {
|
|
|
67
55
|
},
|
|
68
56
|
mountPublicFallback(app) {
|
|
69
57
|
app.on(['GET', 'HEAD'], '/*', async (c, next) => {
|
|
70
|
-
// The prerender tree lives in the same store
|
|
71
|
-
// but the app itself only ever serves it through `readPrerendered`, negotiated on `Accept`.
|
|
58
|
+
// The prerender tree lives in the same store, but the app only serves it through `readPrerendered`.
|
|
72
59
|
if (c.req.path.startsWith(`${SSG_PREFIX}/`))
|
|
73
60
|
return next();
|
|
74
61
|
const asset = await assetResponse(c, c.req.path, c.req.raw.headers);
|
|
@@ -92,8 +79,8 @@ export const runtime = {
|
|
|
92
79
|
return page;
|
|
93
80
|
},
|
|
94
81
|
loadEnv() {
|
|
95
|
-
// Nothing to load:
|
|
96
|
-
//
|
|
82
|
+
// Nothing to load: secrets and bindings arrive per request as `c.env`, which `getRequestContext().env`
|
|
83
|
+
// already merges.
|
|
97
84
|
},
|
|
98
85
|
};
|
|
99
86
|
//# sourceMappingURL=runtime.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/deploy/cloudflare/runtime.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,iBAAiB,EAAwB,MAAM,6BAA6B,CAAC;AAG3H
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/deploy/cloudflare/runtime.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,iBAAiB,EAAwB,MAAM,6BAA6B,CAAC;AAG3H;;;;;;;GAOG;AACH,MAAM,UAAU,GAAG,QAAQ,CAAC;AAO5B,SAAS,aAAa,CAAC,CAAU;IAC/B,MAAM,OAAO,GAAI,CAAC,CAAC,GAA8C,EAAE,MAAM,CAAC;IAC1E,OAAO,OAAO,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACzE,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,aAAa,CAAC,CAAU,EAAE,IAAY,EAAE,OAAiB;IACtE,MAAM,OAAO,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;IACjC,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,0GAA0G;IAC1G,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACrC,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;AACrE,CAAC;AAED;;;GAGG;AACH,SAAS,UAAU,CAAC,KAAe;IACjC,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACzC,CAAC;AAED,oGAAoG;AACpG,MAAM,SAAS,GAAG,eAAe,EAAE,CAAC;AAEpC;;;GAGG;AACH,MAAM,CAAC,MAAM,OAAO,GAAkB;IACpC,QAAQ,CAAC,GAAS;QAChB,4FAA4F;QAC5F,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC;IAC9B,CAAC;IAED,iBAAiB,CAAC,GAAS;QACzB,uGAAuG;QACvG,gGAAgG;QAChG,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;YACtD,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACpE,OAAO,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACpE,CAAC,CAAC,CAAC;IACL,CAAC;IAED,mBAAmB,CAAC,GAAS;QAC3B,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;YAC9C,oGAAoG;YACpG,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,UAAU,GAAG,CAAC;gBAAE,OAAO,IAAI,EAAE,CAAC;YAC3D,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACpE,OAAO,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACpE,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,CAAU,EAAE,OAAO;QACvC,MAAM,OAAO,GAAG,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACxD,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAElC,MAAM,GAAG,GAAG,GAAG,OAAO,KAAK,OAAO,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAE1B,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,CAAC,EAAE,GAAG,UAAU,IAAI,OAAO,EAAE,CAAC,CAAC;QACjE,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAEhD,uFAAuF;QACvF,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3G,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,uGAAuG;QACvG,kBAAkB;IACpB,CAAC;CACF,CAAC","sourcesContent":["import type { Context, Hono } from 'hono';\nimport { createPageCache, prerenderedRelPath, toPrerenderedPage, type PrerenderedPage } from '../../server/prerendered.js';\nimport type { DeployRuntime } from '../contract.js';\n\n/**\n * Where `finalize` puts the prerendered pages inside the assets directory.\n *\n * A prefix of its own, rather than the pages' real URLs, is what keeps every page URL reaching the worker: one\n * URL answers with a document or a flight payload depending on `Accept`, and a path-keyed CDN cannot make that\n * choice. The tree is reachable here too, so `finalize` marks it `noindex` rather than leaving a crawler to\n * find the same page twice.\n */\nconst SSG_PREFIX = '/__ssg';\n\n/** The Workers Assets binding, as much of it as this file uses. */\ninterface AssetsBinding {\n fetch(request: Request): Promise<Response>;\n}\n\nfunction assetsBinding(c: Context): AssetsBinding | null {\n const binding = (c.env as { ASSETS?: AssetsBinding } | undefined)?.ASSETS;\n return binding && typeof binding.fetch === 'function' ? binding : null;\n}\n\n/**\n * Asks the assets binding for one path, or `null` when there is no binding — which is how a caller tells \"this\n * deployment serves its assets some other way\" from \"that file is not there\".\n *\n * `headers` is forwarded only where the *client's* conditional and range requests should be answered by the\n * store: an `If-None-Match` on a page being fetched to serve would come back 304 with no body.\n */\nasync function assetResponse(c: Context, path: string, headers?: Headers): Promise<Response | null> {\n const binding = assetsBinding(c);\n if (!binding) return null;\n // Resolved against the request so the lookup carries this deployment's own origin; only the path is used.\n const url = new URL(path, c.req.url);\n return binding.fetch(new Request(url, { method: 'GET', headers }));\n}\n\n/**\n * Hands an asset response back as the app's own. Rebuilt rather than returned as-is, because a `Response` from\n * `fetch` has immutable headers and the framework's outermost middleware writes to them on the way out.\n */\nfunction serveAsset(asset: Response): Response {\n return new Response(asset.body, asset);\n}\n\n/** Prerendered pages, keyed by the path that produced them. Per isolate rather than per process. */\nconst pageCache = createPageCache();\n\n/**\n * Cloudflare Workers: the host owns the process, so there is nothing to listen on, and there is no filesystem,\n * so `.env` files are out. What is left is the assets binding, which every read here goes through.\n */\nexport const runtime: DeployRuntime = {\n serveApp(app: Hono): unknown {\n // `app.fetch` already takes `(request, env, ctx)`, which is why bindings arrive as `c.env`.\n return { fetch: app.fetch };\n },\n\n mountStaticAssets(app: Hono): void {\n // Normally dead — the CDN answers `/_static/*` before the worker is invoked — but keeps the deployment\n // correct, if slower, under an assets configuration that routes everything to the worker first.\n app.on(['GET', 'HEAD'], '/_static/*', async (c, next) => {\n const asset = await assetResponse(c, c.req.path, c.req.raw.headers);\n return asset && asset.status !== 404 ? serveAsset(asset) : next();\n });\n },\n\n mountPublicFallback(app: Hono): void {\n app.on(['GET', 'HEAD'], '/*', async (c, next) => {\n // The prerender tree lives in the same store, but the app only serves it through `readPrerendered`.\n if (c.req.path.startsWith(`${SSG_PREFIX}/`)) return next();\n const asset = await assetResponse(c, c.req.path, c.req.raw.headers);\n return asset && asset.status !== 404 ? serveAsset(asset) : next();\n });\n },\n\n async readPrerendered(c: Context, variant): Promise<PrerenderedPage | null> {\n const relPath = prerenderedRelPath(c.req.path, variant);\n if (relPath === null) return null;\n\n const key = `${variant}\\0${relPath}`;\n const cached = pageCache.get(key);\n if (cached) return cached;\n\n const asset = await assetResponse(c, `${SSG_PREFIX}/${relPath}`);\n if (!asset || asset.status !== 200) return null;\n\n // The store's own validator where it has one — it already describes these exact bytes.\n const page = await toPrerenderedPage(new Uint8Array(await asset.arrayBuffer()), asset.headers.get('etag'));\n pageCache.set(key, page);\n return page;\n },\n\n loadEnv(): void {\n // Nothing to load: secrets and bindings arrive per request as `c.env`, which `getRequestContext().env`\n // already merges.\n },\n};\n"]}
|
|
@@ -2,70 +2,53 @@ import type { Context, Hono } from 'hono';
|
|
|
2
2
|
import type { PrerenderVariant, PrerenderedPage } from '../server/prerendered.js';
|
|
3
3
|
/**
|
|
4
4
|
* A hosting platform `rshono build` targets. Selected with `deploy` in `rshono.config.ts`, the
|
|
5
|
-
* `--deploy` flag or the `RSHONO_DEPLOY` env var
|
|
5
|
+
* `--deploy` flag or the `RSHONO_DEPLOY` env var.
|
|
6
6
|
*
|
|
7
|
-
* - `'node'` (the default) — rshono binds the port
|
|
8
|
-
*
|
|
7
|
+
* - `'node'` (the default) — rshono binds the port and you run the build with `rshono start`. Covers a
|
|
8
|
+
* VPS, a container, a PaaS, and — through `node:` compatibility — Bun and Deno.
|
|
9
9
|
* - `'cloudflare'` — a Worker; the entry exports `{ fetch }`.
|
|
10
|
-
* - `'vercel'` — a Vercel function, plus the on-disk layout and config
|
|
10
|
+
* - `'vercel'` — a Vercel function, plus the on-disk layout and config streaming needs there.
|
|
11
11
|
* - `'aws-lambda'` — a streaming Lambda handler.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
* is the part an app cannot arrange for itself.
|
|
15
|
-
* would be "run the Node build", which is why Bun and Deno have none: importing the `node` bundle
|
|
16
|
-
* under those runtimes is the whole of what one would say.
|
|
13
|
+
* There is one target per *handoff* — who opens the socket, and what shape a request arrives in — since
|
|
14
|
+
* that is the part an app cannot arrange for itself. `rshono dev` always runs the `node` server.
|
|
17
15
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* export default defineConfig({ deploy: 'cloudflare' });
|
|
19
|
+
* ```
|
|
20
20
|
*
|
|
21
21
|
* @see {@link https://www.rshono.com/docs/deployment#the-targets | Docs — the targets}
|
|
22
22
|
*/
|
|
23
23
|
export type DeployTarget = 'node' | 'cloudflare' | 'vercel' | 'aws-lambda';
|
|
24
24
|
/**
|
|
25
|
-
* Everything the app server needs from the platform it
|
|
25
|
+
* Everything the app server needs from the platform it runs on — the whole of what "which platform is
|
|
26
|
+
* this" means at request time, since `runtime/entry.rsc.tsx` is written against this and nothing else.
|
|
26
27
|
*
|
|
27
|
-
* One preset implements
|
|
28
|
-
* module
|
|
29
|
-
* ever in the bundle. `runtime/entry.rsc.tsx` is written against this interface and nothing else —
|
|
30
|
-
* it is the whole of what "which platform is this" means at request time.
|
|
31
|
-
*
|
|
32
|
-
* The members are the capabilities that genuinely differ between a host with a disk and one without:
|
|
33
|
-
* who opens the socket, who serves the assets, where a prerendered page is read from, and whether
|
|
34
|
-
* there is a `.env` to load at all.
|
|
28
|
+
* One preset implements it per target, and the build-time `@rshono/deploy` alias resolves to exactly
|
|
29
|
+
* that module, so only the selected platform's code is ever in the bundle.
|
|
35
30
|
*/
|
|
36
31
|
export interface DeployRuntime {
|
|
37
32
|
/**
|
|
38
|
-
* Hands the
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* The two shapes hosting takes, in one call: where rshono owns the process this binds a port and
|
|
42
|
-
* returns nothing; where the host owns it, it returns the export the platform looks for —
|
|
43
|
-
* `{ fetch }` on Workers, a handler function on Vercel and Lambda.
|
|
33
|
+
* Hands the app to the platform and returns whatever the entry module should `export default` there:
|
|
34
|
+
* nothing where rshono owns the process (this binds the port), otherwise the export the platform looks
|
|
35
|
+
* for — `{ fetch }` on Workers, a handler function on Vercel and Lambda.
|
|
44
36
|
*/
|
|
45
37
|
serveApp(app: Hono): unknown;
|
|
46
|
-
/**
|
|
47
|
-
* Mounts the hashed client bundle at `/_static`. A no-op where the platform's own CDN serves it
|
|
48
|
-
* before a request ever reaches the app.
|
|
49
|
-
*
|
|
50
|
-
* Called *before* the app's routes, so the bundle is never shadowed by one.
|
|
51
|
-
*/
|
|
38
|
+
/** Mounts the hashed client bundle at `/_static`, ahead of the app's routes. A no-op where a CDN serves it. */
|
|
52
39
|
mountStaticAssets(app: Hono): void;
|
|
53
|
-
/**
|
|
54
|
-
* Mounts the `public/` fallback at the web root — files served verbatim, and only for paths no
|
|
55
|
-
* route claimed. Called *after* every route for exactly that reason.
|
|
56
|
-
*/
|
|
40
|
+
/** Mounts `public/` at the web root, after every route, so it only answers paths no route claimed. */
|
|
57
41
|
mountPublicFallback(app: Hono): void;
|
|
58
42
|
/**
|
|
59
|
-
* Reads the page prerendered for `c.req.path
|
|
60
|
-
*
|
|
43
|
+
* Reads the page prerendered for `c.req.path`, or `null` when there is none — in which case the route
|
|
44
|
+
* renders per request.
|
|
61
45
|
*
|
|
62
|
-
* Takes the whole {@link Context}
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* (see `prerenderedRelPath`).
|
|
46
|
+
* Takes the whole {@link Context} because without a filesystem the store *is* a request-scoped
|
|
47
|
+
* binding (`c.env.ASSETS` on Workers). The path is untrusted either way, so an implementation treats
|
|
48
|
+
* traversal as a miss — see `prerenderedRelPath`.
|
|
66
49
|
*/
|
|
67
50
|
readPrerendered(c: Context, variant: PrerenderVariant): Promise<PrerenderedPage | null>;
|
|
68
|
-
/** Loads `.env` files
|
|
51
|
+
/** Loads `.env` files where the platform has a filesystem. Env is bindings elsewhere. */
|
|
69
52
|
loadEnv(): void;
|
|
70
53
|
}
|
|
71
54
|
//# sourceMappingURL=contract.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/deploy/contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAElF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,YAAY,GAAG,QAAQ,GAAG,YAAY,CAAC;AAE3E
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/deploy/contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAElF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,YAAY,GAAG,QAAQ,GAAG,YAAY,CAAC;AAE3E;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC;IAC7B,+GAA+G;IAC/G,iBAAiB,CAAC,GAAG,EAAE,IAAI,GAAG,IAAI,CAAC;IACnC,sGAAsG;IACtG,mBAAmB,CAAC,GAAG,EAAE,IAAI,GAAG,IAAI,CAAC;IACrC;;;;;;;OAOG;IACH,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IACxF,yFAAyF;IACzF,OAAO,IAAI,IAAI,CAAC;CACjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../../src/deploy/contract.ts"],"names":[],"mappings":"","sourcesContent":["import type { Context, Hono } from 'hono';\nimport type { PrerenderVariant, PrerenderedPage } from '../server/prerendered.js';\n\n/**\n * A hosting platform `rshono build` targets. Selected with `deploy` in `rshono.config.ts`, the\n * `--deploy` flag or the `RSHONO_DEPLOY` env var
|
|
1
|
+
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../../src/deploy/contract.ts"],"names":[],"mappings":"","sourcesContent":["import type { Context, Hono } from 'hono';\nimport type { PrerenderVariant, PrerenderedPage } from '../server/prerendered.js';\n\n/**\n * A hosting platform `rshono build` targets. Selected with `deploy` in `rshono.config.ts`, the\n * `--deploy` flag or the `RSHONO_DEPLOY` env var.\n *\n * - `'node'` (the default) — rshono binds the port and you run the build with `rshono start`. Covers a\n * VPS, a container, a PaaS, and — through `node:` compatibility — Bun and Deno.\n * - `'cloudflare'` — a Worker; the entry exports `{ fetch }`.\n * - `'vercel'` — a Vercel function, plus the on-disk layout and config streaming needs there.\n * - `'aws-lambda'` — a streaming Lambda handler.\n *\n * There is one target per *handoff* — who opens the socket, and what shape a request arrives in — since\n * that is the part an app cannot arrange for itself. `rshono dev` always runs the `node` server.\n *\n * @example\n * ```ts\n * export default defineConfig({ deploy: 'cloudflare' });\n * ```\n *\n * @see {@link https://www.rshono.com/docs/deployment#the-targets | Docs — the targets}\n */\nexport type DeployTarget = 'node' | 'cloudflare' | 'vercel' | 'aws-lambda';\n\n/**\n * Everything the app server needs from the platform it runs on — the whole of what \"which platform is\n * this\" means at request time, since `runtime/entry.rsc.tsx` is written against this and nothing else.\n *\n * One preset implements it per target, and the build-time `@rshono/deploy` alias resolves to exactly\n * that module, so only the selected platform's code is ever in the bundle.\n */\nexport interface DeployRuntime {\n /**\n * Hands the app to the platform and returns whatever the entry module should `export default` there:\n * nothing where rshono owns the process (this binds the port), otherwise the export the platform looks\n * for — `{ fetch }` on Workers, a handler function on Vercel and Lambda.\n */\n serveApp(app: Hono): unknown;\n /** Mounts the hashed client bundle at `/_static`, ahead of the app's routes. A no-op where a CDN serves it. */\n mountStaticAssets(app: Hono): void;\n /** Mounts `public/` at the web root, after every route, so it only answers paths no route claimed. */\n mountPublicFallback(app: Hono): void;\n /**\n * Reads the page prerendered for `c.req.path`, or `null` when there is none — in which case the route\n * renders per request.\n *\n * Takes the whole {@link Context} because without a filesystem the store *is* a request-scoped\n * binding (`c.env.ASSETS` on Workers). The path is untrusted either way, so an implementation treats\n * traversal as a miss — see `prerenderedRelPath`.\n */\n readPrerendered(c: Context, variant: PrerenderVariant): Promise<PrerenderedPage | null>;\n /** Loads `.env` files where the platform has a filesystem. Env is bindings elsewhere. */\n loadEnv(): void;\n}\n"]}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import type { DeployRuntime } from './contract.js';
|
|
2
2
|
/**
|
|
3
|
-
* Everything a deploy target with a real filesystem does the same way.
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* differ only in how the finished app is handed over — so each of those presets is this object plus
|
|
7
|
-
* its own {@link DeployRuntime.serveApp}, and the implementations live once, in `server/`.
|
|
3
|
+
* Everything a deploy target with a real filesystem does the same way. Node and the serverless runtimes that
|
|
4
|
+
* unpack onto a read-only disk (Vercel, AWS Lambda) differ only in how the app is handed over, so each of
|
|
5
|
+
* those presets is this object plus its own {@link DeployRuntime.serveApp}.
|
|
8
6
|
*/
|
|
9
7
|
export declare const fileSystemRuntime: Omit<DeployRuntime, 'serveApp'>;
|
|
10
8
|
//# sourceMappingURL=filesystem.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../../src/deploy/filesystem.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../../src/deploy/filesystem.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAmBnD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,IAAI,CAAC,aAAa,EAAE,UAAU,CAiB7D,CAAC"}
|
|
@@ -3,27 +3,24 @@ import { join } from 'node:path';
|
|
|
3
3
|
import { loadEnvFiles } from '../server/load-env.js';
|
|
4
4
|
import { readPrerendered } from '../server/ssg.js';
|
|
5
5
|
import { createPublicFallback, createStaticAssetsApp } from '../server/static.js';
|
|
6
|
-
const isDev = __RSHONO_CONFIG__
|
|
6
|
+
const { isDev, outDir } = __RSHONO_CONFIG__;
|
|
7
7
|
/**
|
|
8
8
|
* The project root, derived from where the bundle ended up: this module is compiled into
|
|
9
|
-
* `<root>/
|
|
9
|
+
* `<root>/<outDir>/server/main.mjs`, which is why every output directory sits one level under the root.
|
|
10
10
|
*
|
|
11
|
-
* Derived rather than baked in
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* for exactly this reason.
|
|
11
|
+
* Derived rather than baked in, because an absolute build-time path would tie the output to the machine that
|
|
12
|
+
* produced it — building in CI to run elsewhere is the normal case. A preset that relocates the bundle keeps
|
|
13
|
+
* `dist/server/main.mjs` intact inside its own layout for this reason.
|
|
15
14
|
*/
|
|
16
15
|
const rootDir = join(import.meta.dirname, '..', '..');
|
|
17
|
-
const staticDir = join(rootDir,
|
|
18
|
-
const ssgDir = join(rootDir,
|
|
19
|
-
/** `public/` is copied into
|
|
20
|
-
const publicDir = isDev ? join(rootDir, 'public') : join(rootDir,
|
|
16
|
+
const staticDir = join(rootDir, outDir, 'static');
|
|
17
|
+
const ssgDir = join(rootDir, outDir, 'ssg');
|
|
18
|
+
/** `public/` is copied into the build output, so a deployed build is self-contained; dev reads the source. */
|
|
19
|
+
const publicDir = isDev ? join(rootDir, 'public') : join(rootDir, outDir, 'public');
|
|
21
20
|
/**
|
|
22
|
-
* Everything a deploy target with a real filesystem does the same way.
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* differ only in how the finished app is handed over — so each of those presets is this object plus
|
|
26
|
-
* its own {@link DeployRuntime.serveApp}, and the implementations live once, in `server/`.
|
|
21
|
+
* Everything a deploy target with a real filesystem does the same way. Node and the serverless runtimes that
|
|
22
|
+
* unpack onto a read-only disk (Vercel, AWS Lambda) differ only in how the app is handed over, so each of
|
|
23
|
+
* those presets is this object plus its own {@link DeployRuntime.serveApp}.
|
|
27
24
|
*/
|
|
28
25
|
export const fileSystemRuntime = {
|
|
29
26
|
mountStaticAssets(app) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filesystem.js","sourceRoot":"","sources":["../../src/deploy/filesystem.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAGlF,MAAM,KAAK,GAAG,iBAAiB,CAAC
|
|
1
|
+
{"version":3,"file":"filesystem.js","sourceRoot":"","sources":["../../src/deploy/filesystem.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAGlF,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAAC;AAE5C;;;;;;;GAOG;AACH,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAEtD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;AAClD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AAC5C,8GAA8G;AAC9G,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;AAEpF;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAoC;IAChE,iBAAiB,CAAC,GAAS;QACzB,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,qBAAqB,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED,mBAAmB,CAAC,GAAS;QAC3B,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO;QACnC,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,oBAAoB,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAClF,CAAC;IAED,eAAe,CAAC,CAAC,EAAE,OAAO;QACxB,OAAO,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAED,OAAO;QACL,YAAY,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;CACF,CAAC","sourcesContent":["import type { Hono } from 'hono';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { loadEnvFiles } from '../server/load-env.js';\nimport { readPrerendered } from '../server/ssg.js';\nimport { createPublicFallback, createStaticAssetsApp } from '../server/static.js';\nimport type { DeployRuntime } from './contract.js';\n\nconst { isDev, outDir } = __RSHONO_CONFIG__;\n\n/**\n * The project root, derived from where the bundle ended up: this module is compiled into\n * `<root>/<outDir>/server/main.mjs`, which is why every output directory sits one level under the root.\n *\n * Derived rather than baked in, because an absolute build-time path would tie the output to the machine that\n * produced it — building in CI to run elsewhere is the normal case. A preset that relocates the bundle keeps\n * `dist/server/main.mjs` intact inside its own layout for this reason.\n */\nconst rootDir = join(import.meta.dirname, '..', '..');\n\nconst staticDir = join(rootDir, outDir, 'static');\nconst ssgDir = join(rootDir, outDir, 'ssg');\n/** `public/` is copied into the build output, so a deployed build is self-contained; dev reads the source. */\nconst publicDir = isDev ? join(rootDir, 'public') : join(rootDir, outDir, 'public');\n\n/**\n * Everything a deploy target with a real filesystem does the same way. Node and the serverless runtimes that\n * unpack onto a read-only disk (Vercel, AWS Lambda) differ only in how the app is handed over, so each of\n * those presets is this object plus its own {@link DeployRuntime.serveApp}.\n */\nexport const fileSystemRuntime: Omit<DeployRuntime, 'serveApp'> = {\n mountStaticAssets(app: Hono): void {\n app.route('/_static', createStaticAssetsApp({ root: staticDir, isDev }));\n },\n\n mountPublicFallback(app: Hono): void {\n if (!existsSync(publicDir)) return;\n app.on(['GET', 'HEAD'], '/*', createPublicFallback({ root: publicDir, isDev }));\n },\n\n readPrerendered(c, variant) {\n return readPrerendered(ssgDir, c.req.path, variant);\n },\n\n loadEnv(): void {\n loadEnvFiles(rootDir);\n },\n};\n"]}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import type { DeployRuntime } from '../contract.js';
|
|
2
2
|
/**
|
|
3
|
-
* Node: a long-lived process that owns its own port, with a filesystem behind every asset
|
|
4
|
-
*
|
|
3
|
+
* Node: a long-lived process that owns its own port, with a filesystem behind every asset — the shape the
|
|
4
|
+
* framework was built against, and the only target `rshono dev` produces.
|
|
5
5
|
*
|
|
6
|
-
* Anything that runs a Node process runs this build
|
|
7
|
-
*
|
|
8
|
-
* `node:` APIs it needs.
|
|
6
|
+
* Anything that runs a Node process runs this build, Bun and Deno included: the listener is
|
|
7
|
+
* `@hono/node-server`, and both implement the `node:` APIs it needs.
|
|
9
8
|
*/
|
|
10
9
|
export declare const runtime: DeployRuntime;
|
|
11
10
|
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/deploy/node/runtime.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/deploy/node/runtime.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAmBpD;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,EAAE,aAyBrB,CAAC"}
|
|
@@ -6,11 +6,9 @@ import { fileSystemRuntime } from '../filesystem.js';
|
|
|
6
6
|
/** Bound to every interface — so the address printed on start is `localhost`, not this. */
|
|
7
7
|
const WILDCARD_HOST = '0.0.0.0';
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* `PORT` and `HOST` are the whole interface, because that is the deployment convention everywhere
|
|
13
|
-
* this runs. `??` rather than `||` so an explicit `PORT=0`, meaning "any free port", is honoured.
|
|
9
|
+
* The address to listen on: an explicit override (the dev server, which picks the port for its worker) beats
|
|
10
|
+
* `PORT` / `HOST`, which beat the built-in default. `??` rather than `||`, so an explicit `PORT=0` — "any free
|
|
11
|
+
* port" — is honoured.
|
|
14
12
|
*/
|
|
15
13
|
function listenAddress(overrides) {
|
|
16
14
|
const envPort = process.env.PORT !== undefined ? Number(process.env.PORT) : undefined;
|
|
@@ -20,23 +18,19 @@ function listenAddress(overrides) {
|
|
|
20
18
|
};
|
|
21
19
|
}
|
|
22
20
|
/**
|
|
23
|
-
* Node: a long-lived process that owns its own port, with a filesystem behind every asset
|
|
24
|
-
*
|
|
21
|
+
* Node: a long-lived process that owns its own port, with a filesystem behind every asset — the shape the
|
|
22
|
+
* framework was built against, and the only target `rshono dev` produces.
|
|
25
23
|
*
|
|
26
|
-
* Anything that runs a Node process runs this build
|
|
27
|
-
*
|
|
28
|
-
* `node:` APIs it needs.
|
|
24
|
+
* Anything that runs a Node process runs this build, Bun and Deno included: the listener is
|
|
25
|
+
* `@hono/node-server`, and both implement the `node:` APIs it needs.
|
|
29
26
|
*/
|
|
30
27
|
export const runtime = {
|
|
31
28
|
...fileSystemRuntime,
|
|
32
29
|
serveApp(app) {
|
|
33
|
-
//
|
|
34
|
-
// through `app.fetch` directly and must not bind a port — nothing is listening for it, and the
|
|
35
|
-
// build would never exit.
|
|
30
|
+
// The prerender pass renders through `app.fetch` directly, and a bound port would keep the build alive.
|
|
36
31
|
if (process.env.RSHONO_PRERENDER)
|
|
37
32
|
return;
|
|
38
|
-
// The dev server runs this
|
|
39
|
-
// over the environment.
|
|
33
|
+
// The dev server runs this in a worker thread and picks the port itself, so its choice wins.
|
|
40
34
|
const devWorker = workerData;
|
|
41
35
|
const address = listenAddress(devWorker ?? undefined);
|
|
42
36
|
const server = serve({ fetch: app.fetch, ...address }, (info) => {
|