@rshono/core 1.0.0-rc.0

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.
Files changed (189) hide show
  1. package/README.md +273 -0
  2. package/bin/rshono.mjs +15 -0
  3. package/dist/builder/env-shadow-loader.cjs +26 -0
  4. package/dist/builder/page-entry-loader.cjs +7 -0
  5. package/dist/builder/page-files.d.ts +2 -0
  6. package/dist/builder/page-files.d.ts.map +1 -0
  7. package/dist/builder/page-files.js +45 -0
  8. package/dist/builder/page-files.js.map +1 -0
  9. package/dist/builder/public-env.d.ts +2 -0
  10. package/dist/builder/public-env.d.ts.map +1 -0
  11. package/dist/builder/public-env.js +5 -0
  12. package/dist/builder/public-env.js.map +1 -0
  13. package/dist/builder/rspack-config.d.ts +14 -0
  14. package/dist/builder/rspack-config.d.ts.map +1 -0
  15. package/dist/builder/rspack-config.js +235 -0
  16. package/dist/builder/rspack-config.js.map +1 -0
  17. package/dist/cli/build.d.ts +11 -0
  18. package/dist/cli/build.d.ts.map +1 -0
  19. package/dist/cli/build.js +64 -0
  20. package/dist/cli/build.js.map +1 -0
  21. package/dist/cli/dev.d.ts +9 -0
  22. package/dist/cli/dev.d.ts.map +1 -0
  23. package/dist/cli/dev.js +210 -0
  24. package/dist/cli/dev.js.map +1 -0
  25. package/dist/cli/index.d.ts +2 -0
  26. package/dist/cli/index.d.ts.map +1 -0
  27. package/dist/cli/index.js +77 -0
  28. package/dist/cli/index.js.map +1 -0
  29. package/dist/cli/start.d.ts +8 -0
  30. package/dist/cli/start.d.ts.map +1 -0
  31. package/dist/cli/start.js +39 -0
  32. package/dist/cli/start.js.map +1 -0
  33. package/dist/config.d.ts +121 -0
  34. package/dist/config.d.ts.map +1 -0
  35. package/dist/config.js +5 -0
  36. package/dist/config.js.map +1 -0
  37. package/dist/deploy/aws-lambda/runtime.d.ts +14 -0
  38. package/dist/deploy/aws-lambda/runtime.d.ts.map +1 -0
  39. package/dist/deploy/aws-lambda/runtime.js +24 -0
  40. package/dist/deploy/aws-lambda/runtime.js.map +1 -0
  41. package/dist/deploy/build-marker.d.ts +15 -0
  42. package/dist/deploy/build-marker.d.ts.map +1 -0
  43. package/dist/deploy/build-marker.js +26 -0
  44. package/dist/deploy/build-marker.js.map +1 -0
  45. package/dist/deploy/bun/runtime.d.ts +11 -0
  46. package/dist/deploy/bun/runtime.d.ts.map +1 -0
  47. package/dist/deploy/bun/runtime.js +22 -0
  48. package/dist/deploy/bun/runtime.js.map +1 -0
  49. package/dist/deploy/cloudflare/build.d.ts +7 -0
  50. package/dist/deploy/cloudflare/build.d.ts.map +1 -0
  51. package/dist/deploy/cloudflare/build.js +74 -0
  52. package/dist/deploy/cloudflare/build.js.map +1 -0
  53. package/dist/deploy/cloudflare/runtime.d.ts +10 -0
  54. package/dist/deploy/cloudflare/runtime.d.ts.map +1 -0
  55. package/dist/deploy/cloudflare/runtime.js +129 -0
  56. package/dist/deploy/cloudflare/runtime.js.map +1 -0
  57. package/dist/deploy/contract.d.ts +65 -0
  58. package/dist/deploy/contract.d.ts.map +1 -0
  59. package/dist/deploy/contract.js +2 -0
  60. package/dist/deploy/contract.js.map +1 -0
  61. package/dist/deploy/deno/runtime.d.ts +11 -0
  62. package/dist/deploy/deno/runtime.d.ts.map +1 -0
  63. package/dist/deploy/deno/runtime.js +16 -0
  64. package/dist/deploy/deno/runtime.js.map +1 -0
  65. package/dist/deploy/filesystem.d.ts +10 -0
  66. package/dist/deploy/filesystem.d.ts.map +1 -0
  67. package/dist/deploy/filesystem.js +47 -0
  68. package/dist/deploy/filesystem.js.map +1 -0
  69. package/dist/deploy/listen.d.ts +20 -0
  70. package/dist/deploy/listen.d.ts.map +1 -0
  71. package/dist/deploy/listen.js +24 -0
  72. package/dist/deploy/listen.js.map +1 -0
  73. package/dist/deploy/netlify/build.d.ts +8 -0
  74. package/dist/deploy/netlify/build.d.ts.map +1 -0
  75. package/dist/deploy/netlify/build.js +52 -0
  76. package/dist/deploy/netlify/build.js.map +1 -0
  77. package/dist/deploy/netlify/runtime.d.ts +13 -0
  78. package/dist/deploy/netlify/runtime.d.ts.map +1 -0
  79. package/dist/deploy/netlify/runtime.js +24 -0
  80. package/dist/deploy/netlify/runtime.js.map +1 -0
  81. package/dist/deploy/node/runtime.d.ts +7 -0
  82. package/dist/deploy/node/runtime.d.ts.map +1 -0
  83. package/dist/deploy/node/runtime.js +36 -0
  84. package/dist/deploy/node/runtime.js.map +1 -0
  85. package/dist/deploy/presets.d.ts +88 -0
  86. package/dist/deploy/presets.d.ts.map +1 -0
  87. package/dist/deploy/presets.js +110 -0
  88. package/dist/deploy/presets.js.map +1 -0
  89. package/dist/deploy/vercel/build.d.ts +3 -0
  90. package/dist/deploy/vercel/build.d.ts.map +1 -0
  91. package/dist/deploy/vercel/build.js +56 -0
  92. package/dist/deploy/vercel/build.js.map +1 -0
  93. package/dist/deploy/vercel/runtime.d.ts +14 -0
  94. package/dist/deploy/vercel/runtime.d.ts.map +1 -0
  95. package/dist/deploy/vercel/runtime.js +26 -0
  96. package/dist/deploy/vercel/runtime.js.map +1 -0
  97. package/dist/index.d.ts +23 -0
  98. package/dist/index.d.ts.map +1 -0
  99. package/dist/index.js +17 -0
  100. package/dist/index.js.map +1 -0
  101. package/dist/router.d.ts +337 -0
  102. package/dist/router.d.ts.map +1 -0
  103. package/dist/router.js +18 -0
  104. package/dist/router.js.map +1 -0
  105. package/dist/runtime/boundaries.d.ts +102 -0
  106. package/dist/runtime/boundaries.d.ts.map +1 -0
  107. package/dist/runtime/boundaries.js +101 -0
  108. package/dist/runtime/boundaries.js.map +1 -0
  109. package/dist/runtime/client.d.ts +16 -0
  110. package/dist/runtime/client.d.ts.map +1 -0
  111. package/dist/runtime/client.js +16 -0
  112. package/dist/runtime/client.js.map +1 -0
  113. package/dist/runtime/context.d.ts +271 -0
  114. package/dist/runtime/context.d.ts.map +1 -0
  115. package/dist/runtime/context.js +360 -0
  116. package/dist/runtime/context.js.map +1 -0
  117. package/dist/runtime/control.d.ts +18 -0
  118. package/dist/runtime/control.d.ts.map +1 -0
  119. package/dist/runtime/control.js +39 -0
  120. package/dist/runtime/control.js.map +1 -0
  121. package/dist/runtime/dev-protocol.d.ts +22 -0
  122. package/dist/runtime/dev-protocol.d.ts.map +1 -0
  123. package/dist/runtime/dev-protocol.js +2 -0
  124. package/dist/runtime/dev-protocol.js.map +1 -0
  125. package/dist/runtime/empty-server-app.d.ts +3 -0
  126. package/dist/runtime/empty-server-app.d.ts.map +1 -0
  127. package/dist/runtime/empty-server-app.js +2 -0
  128. package/dist/runtime/empty-server-app.js.map +1 -0
  129. package/dist/runtime/entry.client.d.ts +2 -0
  130. package/dist/runtime/entry.client.d.ts.map +1 -0
  131. package/dist/runtime/entry.client.js +453 -0
  132. package/dist/runtime/entry.client.js.map +1 -0
  133. package/dist/runtime/entry.rsc.d.ts +32 -0
  134. package/dist/runtime/entry.rsc.d.ts.map +1 -0
  135. package/dist/runtime/entry.rsc.js +466 -0
  136. package/dist/runtime/entry.rsc.js.map +1 -0
  137. package/dist/runtime/entry.ssr.d.ts +25 -0
  138. package/dist/runtime/entry.ssr.d.ts.map +1 -0
  139. package/dist/runtime/entry.ssr.js +86 -0
  140. package/dist/runtime/entry.ssr.js.map +1 -0
  141. package/dist/runtime/navigation.d.ts +114 -0
  142. package/dist/runtime/navigation.d.ts.map +1 -0
  143. package/dist/runtime/navigation.js +112 -0
  144. package/dist/runtime/navigation.js.map +1 -0
  145. package/dist/runtime/request.d.ts +35 -0
  146. package/dist/runtime/request.d.ts.map +1 -0
  147. package/dist/runtime/request.js +39 -0
  148. package/dist/runtime/request.js.map +1 -0
  149. package/dist/runtime/server.d.ts +24 -0
  150. package/dist/runtime/server.d.ts.map +1 -0
  151. package/dist/runtime/server.js +24 -0
  152. package/dist/runtime/server.js.map +1 -0
  153. package/dist/server/compress.d.ts +15 -0
  154. package/dist/server/compress.d.ts.map +1 -0
  155. package/dist/server/compress.js +76 -0
  156. package/dist/server/compress.js.map +1 -0
  157. package/dist/server/headers.d.ts +24 -0
  158. package/dist/server/headers.d.ts.map +1 -0
  159. package/dist/server/headers.js +44 -0
  160. package/dist/server/headers.js.map +1 -0
  161. package/dist/server/load-config.d.ts +7 -0
  162. package/dist/server/load-config.d.ts.map +1 -0
  163. package/dist/server/load-config.js +41 -0
  164. package/dist/server/load-config.js.map +1 -0
  165. package/dist/server/load-env.d.ts +2 -0
  166. package/dist/server/load-env.d.ts.map +1 -0
  167. package/dist/server/load-env.js +10 -0
  168. package/dist/server/load-env.js.map +1 -0
  169. package/dist/server/prerendered.d.ts +67 -0
  170. package/dist/server/prerendered.d.ts.map +1 -0
  171. package/dist/server/prerendered.js +39 -0
  172. package/dist/server/prerendered.js.map +1 -0
  173. package/dist/server/server-config.d.ts +72 -0
  174. package/dist/server/server-config.d.ts.map +1 -0
  175. package/dist/server/server-config.js +94 -0
  176. package/dist/server/server-config.js.map +1 -0
  177. package/dist/server/shutdown.d.ts +7 -0
  178. package/dist/server/shutdown.d.ts.map +1 -0
  179. package/dist/server/shutdown.js +11 -0
  180. package/dist/server/shutdown.js.map +1 -0
  181. package/dist/server/ssg.d.ts +25 -0
  182. package/dist/server/ssg.d.ts.map +1 -0
  183. package/dist/server/ssg.js +160 -0
  184. package/dist/server/ssg.js.map +1 -0
  185. package/dist/server/static.d.ts +14 -0
  186. package/dist/server/static.d.ts.map +1 -0
  187. package/dist/server/static.js +30 -0
  188. package/dist/server/static.js.map +1 -0
  189. package/package.json +86 -0
@@ -0,0 +1,77 @@
1
+ import { createRequire } from 'node:module';
2
+ import { parseArgs } from 'node:util';
3
+ import { DEPLOY_TARGETS, resolveDeployPreset } from '../deploy/presets.js';
4
+ import { loadConfig } from '../server/load-config.js';
5
+ import { loadEnvFiles } from '../server/load-env.js';
6
+ import { buildCommand } from './build.js';
7
+ import { devCommand } from './dev.js';
8
+ import { startCommand } from './start.js';
9
+ const HELP = `rshono — Hono + Rspack + React Server Components
10
+
11
+ Usage:
12
+ rshono dev [--port 3000] start the dev server
13
+ rshono build build for production (client + server + SSG)
14
+ rshono start [--port 3000] run the production build
15
+
16
+ Options:
17
+ -p, --port <n> port to listen on (default: PORT env or rshono.config.ts or 3000)
18
+ -c, --config <path> path to a config file (default: rshono.config.{ts,js,mjs})
19
+ -d, --deploy <name> platform to build for: ${DEPLOY_TARGETS.join(' | ')} (default: node)
20
+ -h, --help show this help
21
+ -v, --version print the version
22
+ `;
23
+ async function main() {
24
+ const { values, positionals } = parseArgs({
25
+ options: {
26
+ port: { type: 'string', short: 'p' },
27
+ config: { type: 'string', short: 'c' },
28
+ deploy: { type: 'string', short: 'd' },
29
+ help: { type: 'boolean', short: 'h' },
30
+ version: { type: 'boolean', short: 'v' },
31
+ },
32
+ allowPositionals: true,
33
+ });
34
+ if (values.version) {
35
+ const require = createRequire(import.meta.url);
36
+ console.log(require('@rshono/core/package.json').version);
37
+ return;
38
+ }
39
+ const command = positionals[0];
40
+ if (values.help || !command) {
41
+ console.log(HELP);
42
+ return;
43
+ }
44
+ const rootDir = process.cwd();
45
+ loadEnvFiles(rootDir);
46
+ const config = await loadConfig(rootDir, values.config);
47
+ const flagPort = values.port ? Number(values.port) : undefined;
48
+ if (values.port && Number.isNaN(flagPort)) {
49
+ console.error(`rshono: invalid --port "${values.port}"`);
50
+ process.exit(1);
51
+ }
52
+ // Precedence: --port flag > PORT env > rshono.config.ts > the command's built-in default.
53
+ const envPort = process.env.PORT ? Number(process.env.PORT) : undefined;
54
+ const port = flagPort ?? envPort ?? config.port;
55
+ const host = process.env.HOST ?? config.host;
56
+ switch (command) {
57
+ case 'dev':
58
+ return devCommand({ rootDir, port, config });
59
+ case 'build':
60
+ return buildCommand({
61
+ rootDir,
62
+ config,
63
+ preset: resolveDeployPreset({ flag: values.deploy, env: process.env.RSHONO_DEPLOY, config: config.deploy }),
64
+ });
65
+ case 'start':
66
+ return startCommand({ rootDir, port, host });
67
+ default:
68
+ console.error(`rshono: unknown command "${command}"\n`);
69
+ console.log(HELP);
70
+ process.exit(1);
71
+ }
72
+ }
73
+ main().catch((error) => {
74
+ console.error(error);
75
+ process.exit(1);
76
+ });
77
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
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';\nimport { buildCommand } from './build.js';\nimport { devCommand } from './dev.js';\nimport { startCommand } from './start.js';\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 rshono.config.ts 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 console.log(require('@rshono/core/package.json').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 > rshono.config.ts > the command's built-in default.\n const envPort = process.env.PORT ? Number(process.env.PORT) : undefined;\n const port = flagPort ?? envPort ?? config.port;\n const host = process.env.HOST ?? config.host;\n\n switch (command) {\n case 'dev':\n return devCommand({ rootDir, port, config });\n case 'build':\n return 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 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"]}
@@ -0,0 +1,8 @@
1
+ interface StartOptions {
2
+ rootDir: string;
3
+ port?: number;
4
+ host?: string;
5
+ }
6
+ export declare function startCommand(options: StartOptions): Promise<void>;
7
+ export {};
8
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/cli/start.ts"],"names":[],"mappings":"AAOA,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,CAiCvE"}
@@ -0,0 +1,39 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { existsSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { readBuildMarker } from '../deploy/build-marker.js';
5
+ import { deployHintFor } from '../deploy/presets.js';
6
+ import { onShutdown } from '../server/shutdown.js';
7
+ export async function startCommand(options) {
8
+ const { rootDir, port, host } = options;
9
+ const distDir = join(rootDir, 'dist');
10
+ const mainPath = join(distDir, 'server', 'main.mjs');
11
+ if (!existsSync(mainPath)) {
12
+ console.error('rshono: no production build found — run `rshono build` first.');
13
+ process.exit(1);
14
+ }
15
+ // A bundle built for a hosting platform has no listener in it — its entry hands a `fetch` handler to
16
+ // whatever is running it. Starting one here would exit silently the moment the module finished
17
+ // evaluating, so say what happened and point at the command that does deploy it.
18
+ const target = readBuildMarker(distDir);
19
+ if (target !== null && target !== 'node') {
20
+ const hint = deployHintFor(target);
21
+ console.error(`rshono: this build targets ${target}, which \`rshono start\` cannot run${hint ? ` — ${hint}` : '.'}`);
22
+ console.error(' Rebuild for a server with `rshono build --deploy node` to run it here.');
23
+ process.exit(1);
24
+ }
25
+ const env = { ...process.env };
26
+ if (port !== undefined)
27
+ env.PORT = String(port);
28
+ if (host !== undefined)
29
+ env.HOST = host;
30
+ const child = spawn(process.execPath, ['--enable-source-maps', mainPath], {
31
+ stdio: 'inherit',
32
+ env,
33
+ });
34
+ onShutdown((signal) => child.kill(signal));
35
+ child.on('exit', (code, signal) => {
36
+ process.exit(signal ? 1 : (code ?? 1));
37
+ });
38
+ }
39
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/cli/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAQnD,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,qGAAqG;IACrG,+FAA+F;IAC/F,iFAAiF;IACjF,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,MAAM,GAAG,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC/B,IAAI,IAAI,KAAK,SAAS;QAAE,GAAG,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAChD,IAAI,IAAI,KAAK,SAAS;QAAE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;IAExC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,sBAAsB,EAAE,QAAQ,CAAC,EAAE;QACxE,KAAK,EAAE,SAAS;QAChB,GAAG;KACJ,CAAC,CAAC;IAEH,UAAU,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3C,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;QAChC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { spawn } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { readBuildMarker } from '../deploy/build-marker.js';\nimport { deployHintFor } from '../deploy/presets.js';\nimport { onShutdown } from '../server/shutdown.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 — its entry hands a `fetch` handler to\n // whatever is running it. Starting one here would exit silently the moment the module finished\n // evaluating, so say what happened and point at the command that does deploy it.\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 const env = { ...process.env };\n if (port !== undefined) env.PORT = String(port);\n if (host !== undefined) env.HOST = host;\n\n const child = spawn(process.execPath, ['--enable-source-maps', mainPath], {\n stdio: 'inherit',\n env,\n });\n\n onShutdown((signal) => child.kill(signal));\n child.on('exit', (code, signal) => {\n process.exit(signal ? 1 : (code ?? 1));\n });\n}\n"]}
@@ -0,0 +1,121 @@
1
+ import type { RspackOptions } from '@rspack/core';
2
+ import type { DeployTarget } from './deploy/contract.js';
3
+ /** Which of the two Rspack compilers the {@link RSHonoConfig.rspack} hook is being called for. */
4
+ export interface RspackHookContext {
5
+ /** `true` for the server (`target: node`) bundle, `false` for the client (`target: web`) bundle. */
6
+ isServer: boolean;
7
+ /** `true` under `rshono dev`, `false` under `rshono build`. */
8
+ isDev: boolean;
9
+ }
10
+ /**
11
+ * Project configuration for rshono, default-exported from `rshono.config.ts` at the project root
12
+ * (`.js` / `.mjs` also work). Every field is optional; omit the file entirely to accept all defaults.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import { defineConfig } from '@rshono/core';
17
+ *
18
+ * export default defineConfig({
19
+ * csp: true,
20
+ * bodySizeLimit: '4mb',
21
+ * allowedOrigins: ['https://admin.example.com'],
22
+ * });
23
+ * ```
24
+ */
25
+ export interface RSHonoConfig {
26
+ /**
27
+ * The hosting platform `rshono build` targets. Default `'node'` — a long-lived server process, for
28
+ * a VPS, a container or anywhere else you run `rshono start`.
29
+ *
30
+ * Overridden by the `--deploy` flag or the `RSHONO_DEPLOY` env var, so one config can still be
31
+ * built for more than one place. `rshono dev` ignores it entirely and always runs the Node dev
32
+ * server.
33
+ */
34
+ deploy?: DeployTarget;
35
+ /**
36
+ * The public origin the site is served from, e.g. `'https://example.com'`.
37
+ *
38
+ * Only used when prerendering `render: 'static'` routes. A prerendered page is one fixed file
39
+ * handed to everyone, so any absolute URL inside it has to be decided at build time — there is no
40
+ * request to read a `Host` from. That is what a page's `url` prop is, so without this a static
41
+ * page bakes in `http://localhost` wherever it builds a canonical tag, an absolute link or an
42
+ * `og:url`. Dynamic routes are unaffected: they resolve the URL per request.
43
+ *
44
+ * The origin is what's used; a path is rejected rather than silently dropped.
45
+ */
46
+ siteUrl?: string;
47
+ /** Default port for `dev` / `start`. Overridden by the `--port` flag or the `PORT` env var. Default `3000`. */
48
+ port?: number;
49
+ /** Bind address for `start`. Overridden by the `HOST` env var. Default `'0.0.0.0'`. */
50
+ host?: string;
51
+ /**
52
+ * Honour `X-Forwarded-Host` / `X-Forwarded-Proto` when resolving the browser-facing request
53
+ * URL (`getContext().url`, a page's `url` prop, and the origin the CSRF check compares against).
54
+ *
55
+ * **Off by default, and leave it off unless a proxy you control sets those headers**, because
56
+ * any client can send them: with it on and nothing stripping them at the edge, one request can
57
+ * point every absolute URL your app builds at an attacker's host (and poison a shared cache).
58
+ * Turn it on when you terminate TLS or rewrite `Host` at a reverse proxy / load balancer.
59
+ * Always `true` under `rshono dev`, where the framework's own proxy sets them and binds to
60
+ * localhost. Default `false`.
61
+ */
62
+ trustProxy?: boolean;
63
+ /**
64
+ * CSRF origin check on server-action POSTs — rejects a cross-origin request with 403.
65
+ * Turn off only behind a gateway that already enforces it. Default `true`.
66
+ */
67
+ checkOrigin?: boolean;
68
+ /**
69
+ * Extra origins allowed to post server actions, in addition to the app's own origin.
70
+ * Accepts full origins or bare hosts, e.g. `['https://admin.example.com', 'localhost:4000']`.
71
+ */
72
+ allowedOrigins?: string[];
73
+ /**
74
+ * Send a strict per-request-nonce `Content-Security-Policy` with every HTML document.
75
+ * While enabled, `render: 'static'` routes render per request (a prerendered file can't carry a
76
+ * per-request nonce). Default `false`.
77
+ */
78
+ csp?: boolean;
79
+ /**
80
+ * Directives merged over the built-in {@link csp} policy, which is deliberately strict
81
+ * (`default-src 'self'`, no framing, no plugins) and so blocks third-party images, fonts and
82
+ * API hosts until you widen it here. Set a directive to `''` to drop it entirely.
83
+ *
84
+ * The per-request nonce is always appended to `script-src`, whatever you put there.
85
+ * Ignored unless `csp` is `true`.
86
+ *
87
+ * @example
88
+ * ```ts
89
+ * cspDirectives: {
90
+ * 'img-src': "'self' data: https://images.example.com",
91
+ * 'font-src': "'self' https://fonts.gstatic.com",
92
+ * 'frame-ancestors': "'self'",
93
+ * }
94
+ * ```
95
+ */
96
+ cspDirectives?: Record<string, string>;
97
+ /**
98
+ * Max server-action request body before it's rejected with 413 — a memory-exhaustion guard.
99
+ * A number is bytes; a string carries a unit (`'512kb'`, `'4mb'`); `false` (or `0`) disables the cap.
100
+ * Default `'1mb'`.
101
+ */
102
+ bodySizeLimit?: string | number | false;
103
+ /** Deadline in milliseconds for a single page render (flight + SSR). Default `10000`. */
104
+ renderTimeout?: number;
105
+ /**
106
+ * Gzip compressible responses (HTML, flight payloads, JSON, CSS, JS). Streaming-safe — each
107
+ * chunk the renderer flushes is flushed on the wire too. Default `true`.
108
+ *
109
+ * Set `false` behind a proxy or CDN that already compresses, to avoid doing the work twice.
110
+ */
111
+ compress?: boolean;
112
+ /**
113
+ * Escape hatch: mutate the generated Rspack config just before it's compiled. Called once per
114
+ * compiler — inspect {@link RspackHookContext.isServer} to tell them apart. Mutate `config` in
115
+ * place and return nothing, or return a replacement.
116
+ */
117
+ rspack?: (config: RspackOptions, ctx: RspackHookContext) => RspackOptions | void;
118
+ }
119
+ /** Identity helper that types a config object — gives editor autocomplete without an explicit annotation. */
120
+ export declare function defineConfig(config: RSHonoConfig): RSHonoConfig;
121
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +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;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+GAA+G;IAC/G,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uFAAuF;IACvF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;OAIG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;;;;;;;;;;;;;;;;OAgBG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;IACxC,yFAAyF;IACzF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,iBAAiB,KAAK,aAAa,GAAG,IAAI,CAAC;CAClF;AAED,6GAA6G;AAC7G,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAE/D"}
package/dist/config.js ADDED
@@ -0,0 +1,5 @@
1
+ /** Identity helper that types a config object — gives editor autocomplete without an explicit annotation. */
2
+ export function defineConfig(config) {
3
+ return config;
4
+ }
5
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAyHA,6GAA6G;AAC7G,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 for rshono, default-exported from `rshono.config.ts` at the project root\n * (`.js` / `.mjs` also work). Every field is optional; omit the file entirely to accept all defaults.\n *\n * @example\n * ```ts\n * import { defineConfig } from '@rshono/core';\n *\n * export default defineConfig({\n * csp: true,\n * bodySizeLimit: '4mb',\n * allowedOrigins: ['https://admin.example.com'],\n * });\n * ```\n */\nexport interface RSHonoConfig {\n /**\n * The hosting platform `rshono build` targets. Default `'node'` — a long-lived server process, for\n * a VPS, a container or anywhere else you run `rshono start`.\n *\n * Overridden by the `--deploy` flag or the `RSHONO_DEPLOY` env var, so one config can still be\n * built for more than one place. `rshono dev` ignores it entirely and always runs the Node dev\n * server.\n */\n deploy?: DeployTarget;\n /**\n * The public origin the site is served from, e.g. `'https://example.com'`.\n *\n * Only used when prerendering `render: 'static'` routes. A prerendered page is one fixed file\n * handed to everyone, so any absolute URL inside it has to be decided at build time — there is no\n * request to read a `Host` from. That is what a page's `url` prop is, so without this a static\n * page bakes in `http://localhost` wherever it builds a canonical tag, an absolute link or an\n * `og:url`. Dynamic routes are unaffected: they resolve the URL per request.\n *\n * The origin is what's used; a path is rejected rather than silently dropped.\n */\n siteUrl?: string;\n /** Default port for `dev` / `start`. Overridden by the `--port` flag or the `PORT` env var. Default `3000`. */\n port?: number;\n /** Bind address for `start`. Overridden by the `HOST` env var. Default `'0.0.0.0'`. */\n host?: string;\n /**\n * Honour `X-Forwarded-Host` / `X-Forwarded-Proto` when resolving the browser-facing request\n * URL (`getContext().url`, a page's `url` prop, and the origin the CSRF check compares against).\n *\n * **Off by default, and leave it off unless a proxy you control sets those headers**, because\n * any client can send them: with it on and nothing stripping them at the edge, one request can\n * point every absolute URL your app builds at an attacker's host (and poison a shared cache).\n * Turn it on when you terminate TLS or rewrite `Host` at a reverse proxy / load balancer.\n * Always `true` under `rshono dev`, where the framework's own proxy sets them and binds to\n * localhost. Default `false`.\n */\n trustProxy?: boolean;\n /**\n * CSRF origin check on server-action POSTs — rejects a cross-origin request with 403.\n * Turn off only behind a gateway that already enforces it. Default `true`.\n */\n checkOrigin?: boolean;\n /**\n * Extra origins allowed to post server actions, in addition to the app's own origin.\n * Accepts full origins or bare hosts, e.g. `['https://admin.example.com', 'localhost:4000']`.\n */\n allowedOrigins?: string[];\n /**\n * Send a strict per-request-nonce `Content-Security-Policy` with every HTML document.\n * While enabled, `render: 'static'` routes render per request (a prerendered file can't carry a\n * per-request nonce). Default `false`.\n */\n csp?: boolean;\n /**\n * Directives merged over the built-in {@link csp} policy, which is deliberately strict\n * (`default-src 'self'`, no framing, no plugins) and so blocks third-party images, fonts and\n * API hosts until you widen it here. Set a directive to `''` to drop it entirely.\n *\n * The per-request nonce is always appended to `script-src`, whatever you put there.\n * Ignored unless `csp` is `true`.\n *\n * @example\n * ```ts\n * cspDirectives: {\n * 'img-src': \"'self' data: https://images.example.com\",\n * 'font-src': \"'self' https://fonts.gstatic.com\",\n * 'frame-ancestors': \"'self'\",\n * }\n * ```\n */\n cspDirectives?: Record<string, string>;\n /**\n * Max server-action request body before it's rejected with 413 — a memory-exhaustion guard.\n * A number is bytes; a string carries a unit (`'512kb'`, `'4mb'`); `false` (or `0`) disables the cap.\n * Default `'1mb'`.\n */\n bodySizeLimit?: string | number | false;\n /** Deadline in milliseconds for a single page render (flight + SSR). Default `10000`. */\n renderTimeout?: number;\n /**\n * Gzip compressible responses (HTML, flight payloads, JSON, CSS, JS). Streaming-safe — each\n * chunk the renderer flushes is flushed on the wire too. Default `true`.\n *\n * Set `false` behind a proxy or CDN that already compresses, to avoid doing the work twice.\n */\n compress?: 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 rspack?: (config: RspackOptions, ctx: RspackHookContext) => RspackOptions | void;\n}\n\n/** Identity helper that types a config object — gives editor autocomplete without an explicit annotation. */\nexport function defineConfig(config: RSHonoConfig): RSHonoConfig {\n return config;\n}\n"]}
@@ -0,0 +1,14 @@
1
+ import type { DeployRuntime } from '../contract.js';
2
+ /**
3
+ * AWS Lambda behind a Function URL, in streaming mode.
4
+ *
5
+ * `streamHandle` wraps the app with `awslambda.streamifyResponse`, which is the only way a Lambda can
6
+ * write a response progressively — and progressive is the whole point of a streamed SSR shell. It
7
+ * requires the Function URL's invoke mode to be `RESPONSE_STREAM`; the buffered `handle` would work
8
+ * anywhere but would hold every page until the last byte rendered.
9
+ *
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.
12
+ */
13
+ export declare const runtime: DeployRuntime;
14
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +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;;;;;;;;;;GAUG;AACH,eAAO,MAAM,OAAO,EAAE,aASrB,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { streamHandle } from 'hono/aws-lambda';
2
+ import { fileSystemRuntime } from '../filesystem.js';
3
+ /**
4
+ * AWS Lambda behind a Function URL, in streaming mode.
5
+ *
6
+ * `streamHandle` wraps the app with `awslambda.streamifyResponse`, which is the only way a Lambda can
7
+ * write a response progressively — and progressive is the whole point of a streamed SSR shell. It
8
+ * requires the Function URL's invoke mode to be `RESPONSE_STREAM`; the buffered `handle` would work
9
+ * anywhere but would hold every page until the last byte rendered.
10
+ *
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.
13
+ */
14
+ export const runtime = {
15
+ ...fileSystemRuntime,
16
+ serveApp(app) {
17
+ // `awslambda` is a global the Lambda runtime injects, so it is absent when the build imports this
18
+ // bundle to prerender. Returning nothing then keeps that pass working; a real invocation has it.
19
+ if (typeof globalThis.awslambda === 'undefined')
20
+ return undefined;
21
+ return streamHandle(app);
22
+ },
23
+ };
24
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +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;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,OAAO,GAAkB;IACpC,GAAG,iBAAiB;IAEpB,QAAQ,CAAC,GAAS;QAChB,kGAAkG;QAClG,iGAAiG;QACjG,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`, which is the only way a Lambda can\n * write a response progressively — and progressive is the whole point of a streamed SSR shell. It\n * requires the Function URL's invoke mode to be `RESPONSE_STREAM`; the buffered `handle` would work\n * anywhere but would hold every page until the last byte rendered.\n *\n * The filesystem capabilities are Node's: a Lambda unpacks the deployment package onto a read-only\n * disk, so `dist/static`, `dist/public` and `dist/ssg` are read exactly as they are on a server.\n */\nexport const runtime: DeployRuntime = {\n ...fileSystemRuntime,\n\n serveApp(app: Hono): unknown {\n // `awslambda` is a global the Lambda runtime injects, so it is absent when the build imports this\n // bundle to prerender. Returning nothing then keeps that pass working; a real invocation has it.\n if (typeof (globalThis as { awslambda?: unknown }).awslambda === 'undefined') return undefined;\n return streamHandle(app);\n },\n};\n"]}
@@ -0,0 +1,15 @@
1
+ import type { DeployTarget } from './contract.js';
2
+ /** Records which platform a build was for, so `rshono start` can refuse one it cannot run. */
3
+ export interface BuildMarker {
4
+ deploy: DeployTarget;
5
+ }
6
+ export declare function writeBuildMarker(distDir: string, deploy: DeployTarget): void;
7
+ /**
8
+ * The target the build in `distDir` was produced for, or `null` when there is nothing to go on.
9
+ *
10
+ * A missing or unreadable marker is deliberately not an error: a build from an older rshono has none,
11
+ * and refusing to start one that would have worked is worse than the confusing failure this guards
12
+ * against.
13
+ */
14
+ export declare function readBuildMarker(distDir: string): DeployTarget | null;
15
+ //# sourceMappingURL=build-marker.d.ts.map
@@ -0,0 +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;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CASpE"}
@@ -0,0 +1,26 @@
1
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ const MARKER_FILE = 'rshono-build.json';
4
+ export function writeBuildMarker(distDir, deploy) {
5
+ writeFileSync(join(distDir, MARKER_FILE), `${JSON.stringify({ deploy }, null, 2)}\n`);
6
+ }
7
+ /**
8
+ * The target the build in `distDir` was produced for, or `null` when there is nothing to go on.
9
+ *
10
+ * A missing or unreadable marker is deliberately not an error: a build from an older rshono has none,
11
+ * and refusing to start one that would have worked is worse than the confusing failure this guards
12
+ * against.
13
+ */
14
+ export function readBuildMarker(distDir) {
15
+ const file = join(distDir, MARKER_FILE);
16
+ if (!existsSync(file))
17
+ return null;
18
+ try {
19
+ const parsed = JSON.parse(readFileSync(file, 'utf8'));
20
+ return typeof parsed.deploy === 'string' ? parsed.deploy : null;
21
+ }
22
+ catch {
23
+ return null;
24
+ }
25
+ }
26
+ //# sourceMappingURL=build-marker.js.map
@@ -0,0 +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;;;;;;GAMG;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,CAAE,MAAM,CAAC,MAAuB,CAAC,CAAC,CAAC,IAAI,CAAC;IACpF,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.\n *\n * A missing or unreadable marker is deliberately not an error: a build from an older rshono has none,\n * and refusing to start one that would have worked is worse than the confusing failure this guards\n * 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 as DeployTarget) : null;\n } catch {\n return null;\n }\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import type { DeployRuntime } from '../contract.js';
2
+ /**
3
+ * Bun: a long-lived process like Node, but the runtime — not the app — opens the socket. Bun reads
4
+ * `fetch`, `port` and `hostname` off the module's default export and serves it, so there is nothing to
5
+ * bind here and no server handle to close on shutdown.
6
+ *
7
+ * Everything else is Node's: Bun implements the `node:` APIs `server/` uses, so assets, gzip and
8
+ * `.env` loading are the same code.
9
+ */
10
+ export declare const runtime: DeployRuntime;
11
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/deploy/bun/runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIpD;;;;;;;GAOG;AACH,eAAO,MAAM,OAAO,EAAE,aAUrB,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { fileSystemRuntime } from '../filesystem.js';
2
+ import { listenAddress, readyMessage } from '../listen.js';
3
+ /**
4
+ * Bun: a long-lived process like Node, but the runtime — not the app — opens the socket. Bun reads
5
+ * `fetch`, `port` and `hostname` off the module's default export and serves it, so there is nothing to
6
+ * bind here and no server handle to close on shutdown.
7
+ *
8
+ * Everything else is Node's: Bun implements the `node:` APIs `server/` uses, so assets, gzip and
9
+ * `.env` loading are the same code.
10
+ */
11
+ export const runtime = {
12
+ ...fileSystemRuntime,
13
+ serveApp(app) {
14
+ const address = listenAddress();
15
+ // The prerender pass imports this bundle; returning the export is inert either way, so unlike the
16
+ // Node preset there is nothing to suppress. Only the log line is worth skipping.
17
+ if (!process.env.RSHONO_PRERENDER)
18
+ console.log(readyMessage(address));
19
+ return { fetch: app.fetch, ...address };
20
+ },
21
+ };
22
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/deploy/bun/runtime.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,OAAO,GAAkB;IACpC,GAAG,iBAAiB;IAEpB,QAAQ,CAAC,GAAS;QAChB,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;QAChC,kGAAkG;QAClG,iFAAiF;QACjF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB;YAAE,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;QACtE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,OAAO,EAAE,CAAC;IAC1C,CAAC;CACF,CAAC","sourcesContent":["import type { Hono } from 'hono';\nimport type { DeployRuntime } from '../contract.js';\nimport { fileSystemRuntime } from '../filesystem.js';\nimport { listenAddress, readyMessage } from '../listen.js';\n\n/**\n * Bun: a long-lived process like Node, but the runtime — not the app — opens the socket. Bun reads\n * `fetch`, `port` and `hostname` off the module's default export and serves it, so there is nothing to\n * bind here and no server handle to close on shutdown.\n *\n * Everything else is Node's: Bun implements the `node:` APIs `server/` uses, so assets, gzip and\n * `.env` loading are the same code.\n */\nexport const runtime: DeployRuntime = {\n ...fileSystemRuntime,\n\n serveApp(app: Hono): unknown {\n const address = listenAddress();\n // The prerender pass imports this bundle; returning the export is inert either way, so unlike the\n // Node preset there is nothing to suppress. Only the log line is worth skipping.\n if (!process.env.RSHONO_PRERENDER) console.log(readyMessage(address));\n return { fetch: app.fetch, ...address };\n },\n};\n"]}
@@ -0,0 +1,7 @@
1
+ import type { DeployBuildContext } from '../presets.js';
2
+ /**
3
+ * Arranges a Workers deployment: one assets directory holding everything the CDN should serve, and a
4
+ * `wrangler.jsonc` to deploy with if the project has no Wrangler config of its own.
5
+ */
6
+ export declare function finalizeCloudflareBuild(ctx: DeployBuildContext): Promise<void>;
7
+ //# sourceMappingURL=build.d.ts.map
@@ -0,0 +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;AAmDxD;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BpF"}
@@ -0,0 +1,74 @@
1
+ import { cpSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';
2
+ import { rm } from 'node:fs/promises';
3
+ import { basename, join } from 'node:path';
4
+ /** Wrangler serves one directory, so the three kinds of asset the build produces are assembled into it. */
5
+ const ASSETS_DIR = join('cloudflare', 'assets');
6
+ const WRANGLER_FILES = ['wrangler.jsonc', 'wrangler.json', 'wrangler.toml'];
7
+ /**
8
+ * Caching and crawler rules for the assembled tree, in the file Workers Assets reads them from.
9
+ *
10
+ * The hashed bundle is immutable by construction, which is the one thing the CDN cannot infer. The
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.
14
+ */
15
+ const HEADERS_FILE = `/_static/*
16
+ Cache-Control: public, max-age=31536000, immutable
17
+
18
+ /__ssg/*
19
+ X-Robots-Tag: noindex
20
+ `;
21
+ /** A Wrangler worker name: lowercase, and only the characters it accepts. */
22
+ function workerName(rootDir) {
23
+ const name = basename(rootDir)
24
+ .toLowerCase()
25
+ .replace(/[^a-z0-9-]+/g, '-')
26
+ .replace(/^-+|-+$/g, '');
27
+ return name || 'rshono-app';
28
+ }
29
+ function wranglerConfig(rootDir, today) {
30
+ return `${JSON.stringify({
31
+ $schema: 'node_modules/wrangler/config-schema.json',
32
+ name: workerName(rootDir),
33
+ main: 'dist/server/main.mjs',
34
+ compatibility_date: today,
35
+ // AsyncLocalStorage — how the framework binds the request context that `getContext()` reads.
36
+ compatibility_flags: ['nodejs_compat'],
37
+ assets: {
38
+ directory: `dist/${ASSETS_DIR.split(/[\\/]/).join('/')}`,
39
+ // Read by the worker for `public/` files and prerendered pages; the CDN still answers first.
40
+ binding: 'ASSETS',
41
+ },
42
+ }, null, 2)}\n`;
43
+ }
44
+ /**
45
+ * Arranges a Workers deployment: one assets directory holding everything the CDN should serve, and a
46
+ * `wrangler.jsonc` to deploy with if the project has no Wrangler config of its own.
47
+ */
48
+ export async function finalizeCloudflareBuild(ctx) {
49
+ const assetsDir = join(ctx.distDir, ASSETS_DIR);
50
+ // Rebuilt from scratch, so a file deleted from `public/` or a route that stopped being static does
51
+ // not survive in the deployed tree.
52
+ await rm(assetsDir, { recursive: true, force: true });
53
+ mkdirSync(assetsDir, { recursive: true });
54
+ cpSync(ctx.staticDir, join(assetsDir, '_static'), { recursive: true });
55
+ if (ctx.publicDir)
56
+ cpSync(ctx.publicDir, assetsDir, { recursive: true });
57
+ if (existsSync(ctx.ssgDir))
58
+ cpSync(ctx.ssgDir, join(assetsDir, '__ssg'), { recursive: true });
59
+ const headersFile = join(assetsDir, '_headers');
60
+ if (existsSync(headersFile)) {
61
+ console.warn(` ⚠ public/_headers is in the way of the generated one — /_static/* will not be marked immutable.`);
62
+ }
63
+ else {
64
+ writeFileSync(headersFile, HEADERS_FILE);
65
+ }
66
+ const existing = WRANGLER_FILES.find((file) => existsSync(join(ctx.rootDir, file)));
67
+ if (!existing) {
68
+ const today = new Date().toISOString().slice(0, 10);
69
+ writeFileSync(join(ctx.rootDir, 'wrangler.jsonc'), wranglerConfig(ctx.rootDir, today));
70
+ console.log(' • wrote wrangler.jsonc (yours now — edit freely, the build will not touch it again)');
71
+ }
72
+ console.log(` • assembled ${join('dist', ASSETS_DIR)} for Workers Assets`);
73
+ }
74
+ //# sourceMappingURL=build.js.map
@@ -0,0 +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;;;;;;;GAOG;AACH,MAAM,YAAY,GAAG;;;;;CAKpB,CAAC;AAEF,6EAA6E;AAC7E,SAAS,UAAU,CAAC,OAAe;IACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC;SAC3B,WAAW,EAAE;SACb,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC;SAC5B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC3B,OAAO,IAAI,IAAI,YAAY,CAAC;AAC9B,CAAC;AAED,SAAS,cAAc,CAAC,OAAe,EAAE,KAAa;IACpD,OAAO,GAAG,IAAI,CAAC,SAAS,CACtB;QACE,OAAO,EAAE,0CAA0C;QACnD,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC;QACzB,IAAI,EAAE,sBAAsB;QAC5B,kBAAkB,EAAE,KAAK;QACzB,6FAA6F;QAC7F,mBAAmB,EAAE,CAAC,eAAe,CAAC;QACtC,MAAM,EAAE;YACN,SAAS,EAAE,QAAQ,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;YACxD,6FAA6F;YAC7F,OAAO,EAAE,QAAQ;SAClB;KACF,EACD,IAAI,EACJ,CAAC,CACF,IAAI,CAAC;AACR,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,GAAuB;IACnE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAChD,mGAAmG;IACnG,oCAAoC;IACpC,MAAM,EAAE,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1C,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvE,IAAI,GAAG,CAAC,SAAS;QAAE,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzE,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC;QAAE,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE9F,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAChD,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,IAAI,CAAC,mGAAmG,CAAC,CAAC;IACpH,CAAC;SAAM,CAAC;QACN,aAAa,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IACpF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACpD,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,gBAAgB,CAAC,EAAE,cAAc,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;QACvF,OAAO,CAAC,GAAG,CAAC,uFAAuF,CAAC,CAAC;IACvG,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,qBAAqB,CAAC,CAAC;AAC9E,CAAC","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.\n *\n * The hashed bundle is immutable by construction, which is the one thing the CDN cannot infer. The\n * prerender tree is reachable under its own prefix (see `SSG_PREFIX` in `runtime.ts`) and holds a\n * second copy of pages that already have real URLs, so it is marked `noindex` rather than left for a\n * crawler to find twice.\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\nfunction wranglerConfig(rootDir: string, today: 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: today,\n // AsyncLocalStorage — how the framework binds the request context that `getContext()` reads.\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 // Rebuilt from scratch, so a file deleted from `public/` or a route that stopped being static does\n // not survive in the deployed tree.\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 const today = new Date().toISOString().slice(0, 10);\n writeFileSync(join(ctx.rootDir, 'wrangler.jsonc'), wranglerConfig(ctx.rootDir, today));\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"]}
@@ -0,0 +1,10 @@
1
+ import type { DeployRuntime } from '../contract.js';
2
+ /**
3
+ * Cloudflare Workers: the host owns the process, so there is nothing to listen on; the CDN owns the
4
+ * assets, so there is nothing to serve from disk; and there is no filesystem, so `.env` files and a
5
+ * streaming gzip are both out.
6
+ *
7
+ * What is left is the assets binding, which every read here goes through.
8
+ */
9
+ export declare const runtime: DeployRuntime;
10
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +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;AA2EpD;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,EAAE,aA4DrB,CAAC"}