@rshono/core 1.0.0-rc.12 → 1.0.0-rc.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +29 -8
  3. package/bin/rshono.mjs +3 -4
  4. package/dist/builder/env-shadow-loader.cjs +25 -6
  5. package/dist/builder/page-files.js +5 -5
  6. package/dist/builder/page-files.js.map +1 -1
  7. package/dist/builder/public-env.d.ts +5 -4
  8. package/dist/builder/public-env.d.ts.map +1 -1
  9. package/dist/builder/public-env.js +5 -4
  10. package/dist/builder/public-env.js.map +1 -1
  11. package/dist/builder/react-versions.d.ts +13 -0
  12. package/dist/builder/react-versions.d.ts.map +1 -0
  13. package/dist/builder/react-versions.js +74 -0
  14. package/dist/builder/react-versions.js.map +1 -0
  15. package/dist/builder/rspack-config.d.ts +5 -11
  16. package/dist/builder/rspack-config.d.ts.map +1 -1
  17. package/dist/builder/rspack-config.js +73 -55
  18. package/dist/builder/rspack-config.js.map +1 -1
  19. package/dist/cli/build.d.ts.map +1 -1
  20. package/dist/cli/build.js +6 -2
  21. package/dist/cli/build.js.map +1 -1
  22. package/dist/cli/dev.d.ts.map +1 -1
  23. package/dist/cli/dev.js +30 -40
  24. package/dist/cli/dev.js.map +1 -1
  25. package/dist/cli/index.js +5 -4
  26. package/dist/cli/index.js.map +1 -1
  27. package/dist/cli/start.d.ts.map +1 -1
  28. package/dist/cli/start.js +12 -16
  29. package/dist/cli/start.js.map +1 -1
  30. package/dist/config.d.ts +28 -31
  31. package/dist/config.d.ts.map +1 -1
  32. package/dist/config.js +2 -2
  33. package/dist/config.js.map +1 -1
  34. package/dist/deploy/aws-lambda/runtime.d.ts +4 -6
  35. package/dist/deploy/aws-lambda/runtime.d.ts.map +1 -1
  36. package/dist/deploy/aws-lambda/runtime.js +5 -8
  37. package/dist/deploy/aws-lambda/runtime.js.map +1 -1
  38. package/dist/deploy/build-marker.d.ts +3 -5
  39. package/dist/deploy/build-marker.d.ts.map +1 -1
  40. package/dist/deploy/build-marker.js +3 -5
  41. package/dist/deploy/build-marker.js.map +1 -1
  42. package/dist/deploy/cloudflare/build.d.ts.map +1 -1
  43. package/dist/deploy/cloudflare/build.js +6 -10
  44. package/dist/deploy/cloudflare/build.js.map +1 -1
  45. package/dist/deploy/cloudflare/runtime.d.ts +2 -5
  46. package/dist/deploy/cloudflare/runtime.d.ts.map +1 -1
  47. package/dist/deploy/cloudflare/runtime.js +19 -32
  48. package/dist/deploy/cloudflare/runtime.js.map +1 -1
  49. package/dist/deploy/contract.d.ts +25 -42
  50. package/dist/deploy/contract.d.ts.map +1 -1
  51. package/dist/deploy/contract.js.map +1 -1
  52. package/dist/deploy/filesystem.d.ts +3 -5
  53. package/dist/deploy/filesystem.d.ts.map +1 -1
  54. package/dist/deploy/filesystem.js +15 -11
  55. package/dist/deploy/filesystem.js.map +1 -1
  56. package/dist/deploy/node/runtime.d.ts +4 -5
  57. package/dist/deploy/node/runtime.d.ts.map +1 -1
  58. package/dist/deploy/node/runtime.js +9 -15
  59. package/dist/deploy/node/runtime.js.map +1 -1
  60. package/dist/deploy/presets.d.ts +19 -29
  61. package/dist/deploy/presets.d.ts.map +1 -1
  62. package/dist/deploy/presets.js +41 -24
  63. package/dist/deploy/presets.js.map +1 -1
  64. package/dist/deploy/vercel/build.d.ts.map +1 -1
  65. package/dist/deploy/vercel/build.js +19 -16
  66. package/dist/deploy/vercel/build.js.map +1 -1
  67. package/dist/deploy/vercel/runtime.d.ts +4 -7
  68. package/dist/deploy/vercel/runtime.d.ts.map +1 -1
  69. package/dist/deploy/vercel/runtime.js +13 -7
  70. package/dist/deploy/vercel/runtime.js.map +1 -1
  71. package/dist/index.d.ts +13 -9
  72. package/dist/index.d.ts.map +1 -1
  73. package/dist/index.js +15 -12
  74. package/dist/index.js.map +1 -1
  75. package/dist/router.d.ts +65 -93
  76. package/dist/router.d.ts.map +1 -1
  77. package/dist/router.js +2 -5
  78. package/dist/router.js.map +1 -1
  79. package/dist/runtime/boundaries.d.ts +24 -30
  80. package/dist/runtime/boundaries.d.ts.map +1 -1
  81. package/dist/runtime/boundaries.js +15 -22
  82. package/dist/runtime/boundaries.js.map +1 -1
  83. package/dist/runtime/client.d.ts +16 -7
  84. package/dist/runtime/client.d.ts.map +1 -1
  85. package/dist/runtime/client.js +16 -7
  86. package/dist/runtime/client.js.map +1 -1
  87. package/dist/runtime/context.d.ts +89 -118
  88. package/dist/runtime/context.d.ts.map +1 -1
  89. package/dist/runtime/context.js +122 -167
  90. package/dist/runtime/context.js.map +1 -1
  91. package/dist/runtime/control.js +3 -3
  92. package/dist/runtime/control.js.map +1 -1
  93. package/dist/runtime/dev-protocol.d.ts +4 -8
  94. package/dist/runtime/dev-protocol.d.ts.map +1 -1
  95. package/dist/runtime/dev-protocol.js.map +1 -1
  96. package/dist/runtime/entry.client.js +121 -113
  97. package/dist/runtime/entry.client.js.map +1 -1
  98. package/dist/runtime/entry.rsc.d.ts +5 -6
  99. package/dist/runtime/entry.rsc.d.ts.map +1 -1
  100. package/dist/runtime/entry.rsc.js +140 -129
  101. package/dist/runtime/entry.rsc.js.map +1 -1
  102. package/dist/runtime/entry.ssr.d.ts +7 -12
  103. package/dist/runtime/entry.ssr.d.ts.map +1 -1
  104. package/dist/runtime/entry.ssr.js +13 -24
  105. package/dist/runtime/entry.ssr.js.map +1 -1
  106. package/dist/runtime/flight-inject.d.ts +10 -17
  107. package/dist/runtime/flight-inject.d.ts.map +1 -1
  108. package/dist/runtime/flight-inject.js +63 -54
  109. package/dist/runtime/flight-inject.js.map +1 -1
  110. package/dist/runtime/hot-update.d.ts +20 -27
  111. package/dist/runtime/hot-update.d.ts.map +1 -1
  112. package/dist/runtime/hot-update.js +17 -23
  113. package/dist/runtime/hot-update.js.map +1 -1
  114. package/dist/runtime/navigation.d.ts +14 -19
  115. package/dist/runtime/navigation.d.ts.map +1 -1
  116. package/dist/runtime/navigation.js +9 -13
  117. package/dist/runtime/navigation.js.map +1 -1
  118. package/dist/runtime/request.d.ts +16 -10
  119. package/dist/runtime/request.d.ts.map +1 -1
  120. package/dist/runtime/request.js +30 -10
  121. package/dist/runtime/request.js.map +1 -1
  122. package/dist/runtime/server.d.ts +18 -10
  123. package/dist/runtime/server.d.ts.map +1 -1
  124. package/dist/runtime/server.js +21 -19
  125. package/dist/runtime/server.js.map +1 -1
  126. package/dist/server/headers.d.ts +8 -15
  127. package/dist/server/headers.d.ts.map +1 -1
  128. package/dist/server/headers.js +8 -15
  129. package/dist/server/headers.js.map +1 -1
  130. package/dist/server/load-config.d.ts +2 -2
  131. package/dist/server/load-config.d.ts.map +1 -1
  132. package/dist/server/load-config.js +6 -9
  133. package/dist/server/load-config.js.map +1 -1
  134. package/dist/server/prerendered.d.ts +40 -45
  135. package/dist/server/prerendered.d.ts.map +1 -1
  136. package/dist/server/prerendered.js +50 -33
  137. package/dist/server/prerendered.js.map +1 -1
  138. package/dist/server/server-config.d.ts +13 -28
  139. package/dist/server/server-config.d.ts.map +1 -1
  140. package/dist/server/server-config.js +5 -10
  141. package/dist/server/server-config.js.map +1 -1
  142. package/dist/server/shutdown.d.ts +5 -3
  143. package/dist/server/shutdown.d.ts.map +1 -1
  144. package/dist/server/shutdown.js +5 -3
  145. package/dist/server/shutdown.js.map +1 -1
  146. package/dist/server/ssg.d.ts +3 -6
  147. package/dist/server/ssg.d.ts.map +1 -1
  148. package/dist/server/ssg.js +12 -21
  149. package/dist/server/ssg.js.map +1 -1
  150. package/package.json +2 -2
@@ -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; 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.
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;AAuDpD;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,EAAE,aAgDrB,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
- * worker: one URL answers with a document or a flight payload depending on `Accept`, and a CDN keyed
7
- * on the path alone cannot make that choice. Assets miss, the worker runs, the worker negotiates.
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 on the `RSC` request header, 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 at all — so a caller can
20
- * tell "this deployment serves its assets some other way" from "that file is not there".
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 passed on only where the *client's* conditional and range requests should be answered
23
- * by the store: forwarding an `If-None-Match` while fetching a page to serve would come back 304 with
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 asset request carries this deployment's own origin; only 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; the CDN owns the
48
- * assets, so there is nothing to serve from disk; and there is no filesystem, so `.env` files and a
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
- // What Workers looks for on the default export. `app.fetch` already takes `(request, env, ctx)`,
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: with the scaffolded config the CDN answers `/_static/*` before the worker is
61
- // invoked at all. It exists so the deployment is still correct — if slower — under an assets
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; it is reachable directly from the CDN by design,
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: a Worker has no filesystem and no `.env`. Secrets and bindings arrive per
96
- // request as `c.env`, which `getRequestContext().env` already merges — see `runtime/context.ts`.
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":"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","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\n * worker: one URL answers with a document or a flight payload depending on `Accept`, and a CDN keyed\n * on the path alone cannot make that choice. Assets miss, the worker runs, the worker negotiates.\n *\n * The bytes are public either way — they are a public page — but they are also reachable under this\n * path, so `finalize` writes a `_headers` rule marking the tree `noindex` rather than leaving a\n * crawler to 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 at all — so a caller can\n * tell \"this deployment serves its assets some other way\" from \"that file is not there\".\n *\n * `headers` is passed on only where the *client's* conditional and range requests should be answered\n * by the store: forwarding an `If-None-Match` while fetching a page to serve would come back 304 with\n * no body, which is a useless answer to \"give me this page\".\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 asset request carries this deployment's own origin; only the\n // path is ever used to look one up.\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.\n *\n * Rebuilt rather than returned as-is because a `Response` that came from `fetch` has immutable\n * headers, and the framework's outermost middleware sets its baseline security headers 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; the CDN owns the\n * assets, so there is nothing to serve from disk; and there is no filesystem, so `.env` files and a\n * streaming gzip are both out.\n *\n * What is left is the assets binding, which every read here goes through.\n */\nexport const runtime: DeployRuntime = {\n serveApp(app: Hono): unknown {\n // What Workers looks for on the default export. `app.fetch` already takes `(request, env, ctx)`,\n // which is why bindings arrive as `c.env` — and so why `getRequestContext().env` sees them.\n return { fetch: app.fetch };\n },\n\n mountStaticAssets(app: Hono): void {\n // Normally dead: with the scaffolded config the CDN answers `/_static/*` before the worker is\n // invoked at all. It exists so the deployment is still correct — if slower — under an assets\n // 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; it is reachable directly from the CDN by design,\n // but the app itself only ever serves it through `readPrerendered`, negotiated on `Accept`.\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: a Worker has no filesystem and no `.env`. Secrets and bindings arrive per\n // request as `c.env`, which `getRequestContext().env` already merges — see `runtime/context.ts`.\n },\n};\n"]}
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/deploy/cloudflare/runtime.ts"],"names":[],"mappings":"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","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 on the `RSC` request header, 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, and resolved to a preset by `deploy/presets.ts`.
5
+ * `--deploy` flag or the `RSHONO_DEPLOY` env var.
6
6
  *
7
- * - `'node'` (the default) — rshono binds the port itself and you run the build with `rshono start`.
8
- * Covers a VPS, a container, a PaaS, and — through `node:` compatibility — Bun and Deno.
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 file streaming needs there.
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
- * One entry per *handoff* — who opens the socket, and what shape a request arrives in — because that
14
- * is the part an app cannot arrange for itself. There is deliberately no target whose only content
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
- * `rshono dev` always runs the `node` server whatever this says — the dev server owns the process,
19
- * watches both compilers and fronts them on one port, none of which a hosting platform provides.
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 is running on.
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 this per target, and the `@rshono/deploy` alias resolves to exactly that
28
- * module at build time (see `builder/rspack-config.ts`), so only the selected platform's code is
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 assembled app to the platform, and returns whatever the entry module should
39
- * `export default` there.
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` by `rshono build`, or `null` when there is none (in
60
- * which case the route renders per request, which is always a valid answer).
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} rather than just the path because on a platform with no
63
- * filesystem the store *is* a request-scoped binding — `c.env.ASSETS` on Workers. The path is
64
- * untrusted either way, so an implementation has to treat traversal as a miss, not a lookup
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, where the platform has a filesystem to read them from. Env is bindings elsewhere. */
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;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;;;OAOG;IACH,QAAQ,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC;IAC7B;;;;;OAKG;IACH,iBAAiB,CAAC,GAAG,EAAE,IAAI,GAAG,IAAI,CAAC;IACnC;;;OAGG;IACH,mBAAmB,CAAC,GAAG,EAAE,IAAI,GAAG,IAAI,CAAC;IACrC;;;;;;;;OAQG;IACH,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IACxF,4GAA4G;IAC5G,OAAO,IAAI,IAAI,CAAC;CACjB"}
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, and resolved to a preset by `deploy/presets.ts`.\n *\n * - `'node'` (the default) — rshono binds the port itself and you run the build with `rshono start`.\n * Covers a 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 file streaming needs there.\n * - `'aws-lambda'` — a streaming Lambda handler.\n *\n * One entry per *handoff* — who opens the socket, and what shape a request arrives in — because that\n * is the part an app cannot arrange for itself. There is deliberately no target whose only content\n * would be \"run the Node build\", which is why Bun and Deno have none: importing the `node` bundle\n * under those runtimes is the whole of what one would say.\n *\n * `rshono dev` always runs the `node` server whatever this says — the dev server owns the process,\n * watches both compilers and fronts them on one port, none of which a hosting platform provides.\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 is running on.\n *\n * One preset implements this per target, and the `@rshono/deploy` alias resolves to exactly that\n * module at build time (see `builder/rspack-config.ts`), so only the selected platform's code is\n * ever in the bundle. `runtime/entry.rsc.tsx` is written against this interface and nothing else —\n * it is the whole of what \"which platform is this\" means at request time.\n *\n * The members are the capabilities that genuinely differ between a host with a disk and one without:\n * who opens the socket, who serves the assets, where a prerendered page is read from, and whether\n * there is a `.env` to load at all.\n */\nexport interface DeployRuntime {\n /**\n * Hands the assembled app to the platform, and returns whatever the entry module should\n * `export default` there.\n *\n * The two shapes hosting takes, in one call: where rshono owns the process this binds a port and\n * returns nothing; where the host owns it, it returns the export the platform looks for —\n * `{ fetch }` on Workers, a handler function on Vercel and Lambda.\n */\n serveApp(app: Hono): unknown;\n /**\n * Mounts the hashed client bundle at `/_static`. A no-op where the platform's own CDN serves it\n * before a request ever reaches the app.\n *\n * Called *before* the app's routes, so the bundle is never shadowed by one.\n */\n mountStaticAssets(app: Hono): void;\n /**\n * Mounts the `public/` fallback at the web root — files served verbatim, and only for paths no\n * route claimed. Called *after* every route for exactly that reason.\n */\n mountPublicFallback(app: Hono): void;\n /**\n * Reads the page prerendered for `c.req.path` by `rshono build`, or `null` when there is none (in\n * which case the route renders per request, which is always a valid answer).\n *\n * Takes the whole {@link Context} rather than just the path because on a platform with no\n * filesystem the store *is* a request-scoped binding — `c.env.ASSETS` on Workers. The path is\n * untrusted either way, so an implementation has to treat traversal as a miss, not a lookup\n * (see `prerenderedRelPath`).\n */\n readPrerendered(c: Context, variant: PrerenderVariant): Promise<PrerenderedPage | null>;\n /** Loads `.env` files, where the platform has a filesystem to read them from. Env is bindings elsewhere. */\n loadEnv(): void;\n}\n"]}
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
- * Node and the serverless runtimes that unpack a bundle onto a read-only disk (Vercel, AWS Lambda)
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;AAqBnD;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,EAAE,IAAI,CAAC,aAAa,EAAE,UAAU,CAiB7D,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;AA4BnD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,IAAI,CAAC,aAAa,EAAE,UAAU,CAiB7D,CAAC"}
@@ -4,15 +4,21 @@ 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
6
  const { isDev, outDir } = __RSHONO_CONFIG__;
7
+ // The server bundle is minified and ships a source map, so this is what makes a production stack trace point
8
+ // at the original TypeScript. Done here rather than left to `--enable-source-maps` because a serverless host
9
+ // starts the process itself and passes no flags of ours: Vercel and Lambda would otherwise report minified
10
+ // frames to whatever `onServerError` forwards them to. Guarded because the same `DeployRuntime` shape is
11
+ // implemented for runtimes with no `process`.
12
+ if (typeof process !== 'undefined' && typeof process.setSourceMapsEnabled === 'function') {
13
+ process.setSourceMapsEnabled(true);
14
+ }
7
15
  /**
8
16
  * The project root, derived from where the bundle ended up: this module is compiled into
9
- * `<root>/<outDir>/server/main.mjs`, so `import.meta.dirname` is `<root>/<outDir>/server` at
10
- * runtime — which is why every output directory sits exactly one level under the root.
17
+ * `<root>/<outDir>/server/main.mjs`, which is why every output directory sits one level under the root.
11
18
  *
12
- * Derived rather than baked in at build time, because an absolute build-time path would tie the
13
- * output to the machine that produced it — and building in CI to run somewhere else is the normal
14
- * case. A preset that relocates the bundle keeps `dist/server/main.mjs` intact inside its own layout
15
- * for exactly this reason.
19
+ * Derived rather than baked in, because an absolute build-time path would tie the output to the machine that
20
+ * produced it — building in CI to run elsewhere is the normal case. A preset that relocates the bundle keeps
21
+ * `dist/server/main.mjs` intact inside its own layout for this reason.
16
22
  */
17
23
  const rootDir = join(import.meta.dirname, '..', '..');
18
24
  const staticDir = join(rootDir, outDir, 'static');
@@ -20,11 +26,9 @@ const ssgDir = join(rootDir, outDir, 'ssg');
20
26
  /** `public/` is copied into the build output, so a deployed build is self-contained; dev reads the source. */
21
27
  const publicDir = isDev ? join(rootDir, 'public') : join(rootDir, outDir, 'public');
22
28
  /**
23
- * Everything a deploy target with a real filesystem does the same way.
24
- *
25
- * Node and the serverless runtimes that unpack a bundle onto a read-only disk (Vercel, AWS Lambda)
26
- * differ only in how the finished app is handed over — so each of those presets is this object plus
27
- * its own {@link DeployRuntime.serveApp}, and the implementations live once, in `server/`.
29
+ * Everything a deploy target with a real filesystem does the same way. Node and the serverless runtimes that
30
+ * unpack onto a read-only disk (Vercel, AWS Lambda) differ only in how the app is handed over, so each of
31
+ * those presets is this object plus its own {@link DeployRuntime.serveApp}.
28
32
  */
29
33
  export const fileSystemRuntime = {
30
34
  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,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAAC;AAE5C;;;;;;;;;GASG;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;;;;;;GAMG;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`, so `import.meta.dirname` is `<root>/<outDir>/server` at\n * runtime — which is why every output directory sits exactly one level under the root.\n *\n * Derived rather than baked in at build time, because an absolute build-time path would tie the\n * output to the machine that produced it — and building in CI to run somewhere else is the normal\n * case. A preset that relocates the bundle keeps `dist/server/main.mjs` intact inside its own layout\n * for exactly 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.\n *\n * Node and the serverless runtimes that unpack a bundle onto a read-only disk (Vercel, AWS Lambda)\n * differ only in how the finished app is handed over — so each of those presets is this object plus\n * its own {@link DeployRuntime.serveApp}, and the implementations live once, in `server/`.\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
+ {"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,6GAA6G;AAC7G,6GAA6G;AAC7G,2GAA2G;AAC3G,yGAAyG;AACzG,8CAA8C;AAC9C,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,OAAO,CAAC,oBAAoB,KAAK,UAAU,EAAE,CAAC;IACzF,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;AACrC,CAAC;AAED;;;;;;;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// The server bundle is minified and ships a source map, so this is what makes a production stack trace point\n// at the original TypeScript. Done here rather than left to `--enable-source-maps` because a serverless host\n// starts the process itself and passes no flags of ours: Vercel and Lambda would otherwise report minified\n// frames to whatever `onServerError` forwards them to. Guarded because the same `DeployRuntime` shape is\n// implemented for runtimes with no `process`.\nif (typeof process !== 'undefined' && typeof process.setSourceMapsEnabled === 'function') {\n process.setSourceMapsEnabled(true);\n}\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. The shape
4
- * the framework was built against, and the only target `rshono dev` ever produces.
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 — a VPS, a container, a PaaS — and Bun and Deno
7
- * are expected to as well, since the listener below is `@hono/node-server` and both implement the
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;AAqBpD;;;;;;;GAOG;AACH,eAAO,MAAM,OAAO,EAAE,aA4BrB,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
- * Resolves the address to listen on: an explicit override (the dev server, which picks the port for its
10
- * worker) beats the environment, which beats the built-in default.
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. The shape
24
- * the framework was built against, and the only target `rshono dev` ever produces.
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 — a VPS, a container, a PaaS — and Bun and Deno
27
- * are expected to as well, since the listener below is `@hono/node-server` and both implement the
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
- // `rshono build` imports this bundle to prerender `render: 'static'` routes. That pass renders
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 bundle in a worker thread and picks the port itself, so its choice wins
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) => {
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/deploy/node/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,2FAA2F;AAC3F,MAAM,aAAa,GAAG,SAAS,CAAC;AAEhC;;;;;;GAMG;AACH,SAAS,aAAa,CAAC,SAAgD;IACrE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACtF,OAAO;QACL,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,OAAO,IAAI,eAAe,CAAC,IAAI;QACxD,QAAQ,EAAE,SAAS,EAAE,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,eAAe,CAAC,IAAI;KAC1E,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,OAAO,GAAkB;IACpC,GAAG,iBAAiB;IAEpB,QAAQ,CAAC,GAAS;QAChB,+FAA+F;QAC/F,+FAA+F;QAC/F,0BAA0B;QAC1B,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB;YAAE,OAAO;QAEzC,mGAAmG;QACnG,wBAAwB;QACxB,MAAM,SAAS,GAAG,UAAyD,CAAC;QAC5E,MAAM,OAAO,GAAG,aAAa,CAAC,SAAS,IAAI,SAAS,CAAC,CAAC;QAEtD,MAAM,MAAM,GAAG,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,OAAO,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE;YAC9D,IAAI,UAAU,EAAE,CAAC;gBACf,UAAU,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YAC7D,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,KAAK,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;gBACjF,OAAO,CAAC,GAAG,CAAC,gCAAgC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YACnE,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,UAAU,CAAC,GAAG,EAAE;YACd,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YACpC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;QAClD,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAC","sourcesContent":["import { serve } from '@hono/node-server';\nimport type { Hono } from 'hono';\nimport { parentPort, workerData } from 'node:worker_threads';\nimport { SERVER_DEFAULTS } from '../../server/server-config.js';\nimport { onShutdown } from '../../server/shutdown.js';\nimport type { DeployRuntime } from '../contract.js';\nimport { fileSystemRuntime } from '../filesystem.js';\n\n/** Bound to every interface — so the address printed on start is `localhost`, not this. */\nconst WILDCARD_HOST = '0.0.0.0';\n\n/**\n * Resolves the address to listen on: an explicit override (the dev server, which picks the port for its\n * worker) beats the environment, which beats the built-in default.\n *\n * `PORT` and `HOST` are the whole interface, because that is the deployment convention everywhere\n * this runs. `??` rather than `||` so an explicit `PORT=0`, meaning \"any free port\", is honoured.\n */\nfunction listenAddress(overrides?: { port?: number; hostname?: string }): { port: number; hostname: string } {\n const envPort = process.env.PORT !== undefined ? Number(process.env.PORT) : undefined;\n return {\n port: overrides?.port ?? envPort ?? SERVER_DEFAULTS.port,\n hostname: overrides?.hostname ?? process.env.HOST ?? SERVER_DEFAULTS.host,\n };\n}\n\n/**\n * Node: a long-lived process that owns its own port, with a filesystem behind every asset. The shape\n * the framework was built against, and the only target `rshono dev` ever produces.\n *\n * Anything that runs a Node process runs this build — a VPS, a container, a PaaS — and Bun and Deno\n * are expected to as well, since the listener below is `@hono/node-server` and both implement the\n * `node:` APIs it needs.\n */\nexport const runtime: DeployRuntime = {\n ...fileSystemRuntime,\n\n serveApp(app: Hono): undefined {\n // `rshono build` imports this bundle to prerender `render: 'static'` routes. That pass renders\n // through `app.fetch` directly and must not bind a port — nothing is listening for it, and the\n // build would never exit.\n if (process.env.RSHONO_PRERENDER) return;\n\n // The dev server runs this bundle in a worker thread and picks the port itself, so its choice wins\n // over the environment.\n const devWorker = workerData as { port?: number; hostname?: string } | null;\n const address = listenAddress(devWorker ?? undefined);\n\n const server = serve({ fetch: app.fetch, ...address }, (info) => {\n if (parentPort) {\n parentPort.postMessage({ type: 'ready', port: info.port });\n } else {\n const host = address.hostname === WILDCARD_HOST ? 'localhost' : address.hostname;\n console.log(` ➜ rshono serving on http://${host}:${info.port}`);\n }\n });\n\n onShutdown(() => {\n server.close(() => process.exit(0));\n setTimeout(() => process.exit(0), 3000).unref();\n });\n },\n};\n"]}
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/deploy/node/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,2FAA2F;AAC3F,MAAM,aAAa,GAAG,SAAS,CAAC;AAEhC;;;;GAIG;AACH,SAAS,aAAa,CAAC,SAAgD;IACrE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACtF,OAAO;QACL,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,OAAO,IAAI,eAAe,CAAC,IAAI;QACxD,QAAQ,EAAE,SAAS,EAAE,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,eAAe,CAAC,IAAI;KAC1E,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,OAAO,GAAkB;IACpC,GAAG,iBAAiB;IAEpB,QAAQ,CAAC,GAAS;QAChB,wGAAwG;QACxG,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB;YAAE,OAAO;QAEzC,6FAA6F;QAC7F,MAAM,SAAS,GAAG,UAAyD,CAAC;QAC5E,MAAM,OAAO,GAAG,aAAa,CAAC,SAAS,IAAI,SAAS,CAAC,CAAC;QAEtD,MAAM,MAAM,GAAG,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,OAAO,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE;YAC9D,IAAI,UAAU,EAAE,CAAC;gBACf,UAAU,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YAC7D,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,KAAK,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;gBACjF,OAAO,CAAC,GAAG,CAAC,gCAAgC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YACnE,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,UAAU,CAAC,GAAG,EAAE;YACd,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YACpC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;QAClD,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAC","sourcesContent":["import { serve } from '@hono/node-server';\nimport type { Hono } from 'hono';\nimport { parentPort, workerData } from 'node:worker_threads';\nimport { SERVER_DEFAULTS } from '../../server/server-config.js';\nimport { onShutdown } from '../../server/shutdown.js';\nimport type { DeployRuntime } from '../contract.js';\nimport { fileSystemRuntime } from '../filesystem.js';\n\n/** Bound to every interface — so the address printed on start is `localhost`, not this. */\nconst WILDCARD_HOST = '0.0.0.0';\n\n/**\n * The address to listen on: an explicit override (the dev server, which picks the port for its worker) beats\n * `PORT` / `HOST`, which beat the built-in default. `??` rather than `||`, so an explicit `PORT=0` — \"any free\n * port\" — is honoured.\n */\nfunction listenAddress(overrides?: { port?: number; hostname?: string }): { port: number; hostname: string } {\n const envPort = process.env.PORT !== undefined ? Number(process.env.PORT) : undefined;\n return {\n port: overrides?.port ?? envPort ?? SERVER_DEFAULTS.port,\n hostname: overrides?.hostname ?? process.env.HOST ?? SERVER_DEFAULTS.host,\n };\n}\n\n/**\n * Node: a long-lived process that owns its own port, with a filesystem behind every asset — the shape the\n * framework was built against, and the only target `rshono dev` produces.\n *\n * Anything that runs a Node process runs this build, Bun and Deno included: the listener is\n * `@hono/node-server`, and both implement the `node:` APIs it needs.\n */\nexport const runtime: DeployRuntime = {\n ...fileSystemRuntime,\n\n serveApp(app: Hono): undefined {\n // The prerender pass renders through `app.fetch` directly, and a bound port would keep the build alive.\n if (process.env.RSHONO_PRERENDER) return;\n\n // The dev server runs this in a worker thread and picks the port itself, so its choice wins.\n const devWorker = workerData as { port?: number; hostname?: string } | null;\n const address = listenAddress(devWorker ?? undefined);\n\n const server = serve({ fetch: app.fetch, ...address }, (info) => {\n if (parentPort) {\n parentPort.postMessage({ type: 'ready', port: info.port });\n } else {\n const host = address.hostname === WILDCARD_HOST ? 'localhost' : address.hostname;\n console.log(` ➜ rshono serving on http://${host}:${info.port}`);\n }\n });\n\n onShutdown(() => {\n server.close(() => process.exit(0));\n setTimeout(() => process.exit(0), 3000).unref();\n });\n },\n};\n"]}
@@ -14,12 +14,11 @@ export interface DeployBuildContext {
14
14
  ssgDir: string;
15
15
  }
16
16
  /**
17
- * The build-time half of a deploy target: which runtime module the bundle gets, how the server
18
- * compiler has to change to produce something the platform can run, and how the output is arranged
19
- * once it exists.
17
+ * The build-time half of a deploy target: which runtime module the bundle gets, how the server compiler has
18
+ * to change to produce something the platform can run, and how the output is arranged once it exists.
20
19
  *
21
- * The runtime half is {@link DeployRuntime}, in its own file because it is compiled *into* the app
22
- * bundle — this side only ever runs in the CLI.
20
+ * The runtime half is `DeployRuntime`, in its own file because it is compiled *into* the app bundle — this
21
+ * side only ever runs in the CLI.
23
22
  */
24
23
  export interface DeployPreset {
25
24
  readonly name: DeployTarget;
@@ -31,41 +30,34 @@ export interface DeployPreset {
31
30
  /** How to run what was just built, completing the "build complete —" line. */
32
31
  readonly deployHint: string;
33
32
  /**
34
- * Extra resolve conditions for the server bundle, most specific first.
35
- *
36
- * This is what picks the right build of React and the RSC runtime: both ship one per runtime behind
37
- * `workerd` / `deno` / `edge-light` / `node` conditions. Omit it to accept whatever the Rspack
38
- * target implies, which is correct for Node.
33
+ * Extra resolve conditions for the server bundle, most specific first — what picks the right build of React
34
+ * and the RSC runtime, both of which ship one per runtime. Omit to accept whatever the Rspack target
35
+ * implies, which is correct for Node.
39
36
  */
40
37
  readonly resolveConditions?: readonly string[];
41
38
  /** browserslist-style targets for the server bundle's swc pass. Defaults to Node. */
42
39
  readonly syntaxTargets?: readonly string[];
43
40
  /**
44
- * Adjusts the generated server Rspack config for this platform — target, externals policy, output
45
- * shape. Mutates in place, and runs *before* the user's `rspack` hook so that hook keeps the last
46
- * word.
41
+ * Adjusts the generated server Rspack config for this platform — target, externals policy, output shape.
42
+ * Mutates in place, and runs before the user's `rspack` hook so that hook keeps the last word.
47
43
  */
48
44
  configureServer?(config: RspackOptions): void;
49
45
  /**
50
- * Arranges the finished build for the platform: assembles whatever directory layout it expects,
51
- * emits its config file, and prints how to deploy.
52
- *
53
- * Runs last — after both bundles, the `public/` copy and the prerender pass — so everything it
54
- * needs to move is already on disk.
46
+ * Arranges the finished build for the platform: assembles the directory layout it expects, emits its config
47
+ * file, and prints how to deploy. Runs last, so everything it needs to move is already on disk.
55
48
  */
56
49
  finalize?(ctx: DeployBuildContext): Promise<void> | void;
57
50
  }
58
51
  /**
59
- * Node: a long-lived server process. The generated config is already this shape, so the preset has
60
- * nothing to contribute — the settings in `builder/rspack-config.ts` (`target: 'node'`, the externals
61
- * policy, ESM chunk output) are the Node ones by default.
52
+ * Node: a long-lived server process. The generated config is already this shape — `target: 'node'`, the
53
+ * externals policy and ESM chunk output are all defaults — so the preset has nothing to contribute.
62
54
  */
63
55
  export declare const NODE_PRESET: DeployPreset;
64
56
  /** Every target `deploy` accepts, for error messages and docs. */
65
57
  export declare const DEPLOY_TARGETS: DeployTarget[];
66
58
  /**
67
- * How to deploy what a given target built, or `null` for a name this rshono does not know — which a
68
- * `dist/` produced by a newer version can legitimately carry.
59
+ * How to deploy what a given target built, or `null` for a name this rshono does not know — which a `dist/`
60
+ * from a newer version can legitimately carry.
69
61
  */
70
62
  export declare function deployHintFor(target: string): string | null;
71
63
  /** Where a deploy target can be named, in precedence order. */
@@ -74,15 +66,13 @@ export interface DeploySources {
74
66
  flag?: string;
75
67
  /** The `RSHONO_DEPLOY` env var — for a CI job that deploys the same app to more than one place. */
76
68
  env?: string;
77
- /** {@link RshonoConfig.deploy} from `rshono.config.ts`. */
69
+ /** The `deploy` field in `rshono.config.ts`. */
78
70
  config?: string;
79
71
  }
80
72
  /**
81
- * Resolves the preset to build with: the flag wins over the environment, which wins over the config
82
- * file, which wins over the `node` default.
83
- *
84
- * Blank values are ignored at every level, so an unset-but-present `RSHONO_DEPLOY=` in a CI
85
- * environment falls through to the config file instead of failing the build.
73
+ * Resolves the preset to build with: the flag wins over the environment, which wins over the config file,
74
+ * which wins over the `node` default. Blank values are ignored at every level, so an unset-but-present
75
+ * `RSHONO_DEPLOY=` in CI falls through rather than failing the build.
86
76
  */
87
77
  export declare function resolveDeployPreset(sources?: DeploySources): DeployPreset;
88
78
  //# sourceMappingURL=presets.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/deploy/presets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlD,6FAA6F;AAC7F,MAAM,WAAW,kBAAkB;IACjC,uGAAuG;IACvG,OAAO,EAAE,MAAM,CAAC;IAChB,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAC;IAClB,2FAA2F;IAC3F,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,kGAAkG;IAClG,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,8EAA8E;IAC9E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,qFAAqF;IACrF,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C;;;;OAIG;IACH,eAAe,CAAC,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9C;;;;;;OAMG;IACH,QAAQ,CAAC,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC1D;AAED;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,YAIzB,CAAC;AA4DF,kEAAkE;AAClE,eAAO,MAAM,cAAc,EAA2B,YAAY,EAAE,CAAC;AAErE;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE3D;AAED,+DAA+D;AAC/D,MAAM,WAAW,aAAa;IAC5B,2BAA2B;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mGAAmG;IACnG,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,aAAkB,GAAG,YAAY,CAS7E"}
1
+ {"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/deploy/presets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlD,6FAA6F;AAC7F,MAAM,WAAW,kBAAkB;IACjC,uGAAuG;IACvG,OAAO,EAAE,MAAM,CAAC;IAChB,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAC;IAClB,2FAA2F;IAC3F,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,kGAAkG;IAClG,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,8EAA8E;IAC9E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,qFAAqF;IACrF,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C;;;OAGG;IACH,eAAe,CAAC,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9C;;;OAGG;IACH,QAAQ,CAAC,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC1D;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,YAIzB,CAAC;AAiFF,kEAAkE;AAClE,eAAO,MAAM,cAAc,EAA2B,YAAY,EAAE,CAAC;AAErE;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE3D;AAED,+DAA+D;AAC/D,MAAM,WAAW,aAAa;IAC5B,2BAA2B;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mGAAmG;IACnG,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,aAAkB,GAAG,YAAY,CAS7E"}