@rshono/core 1.0.0-rc.12 → 1.0.0-rc.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/rshono.mjs +3 -4
- package/dist/builder/env-shadow-loader.cjs +5 -5
- package/dist/builder/page-files.js +5 -5
- package/dist/builder/page-files.js.map +1 -1
- package/dist/builder/public-env.d.ts +5 -4
- package/dist/builder/public-env.d.ts.map +1 -1
- package/dist/builder/public-env.js +5 -4
- package/dist/builder/public-env.js.map +1 -1
- package/dist/builder/rspack-config.d.ts +5 -11
- package/dist/builder/rspack-config.d.ts.map +1 -1
- package/dist/builder/rspack-config.js +28 -50
- package/dist/builder/rspack-config.js.map +1 -1
- package/dist/cli/build.js +2 -2
- package/dist/cli/build.js.map +1 -1
- package/dist/cli/dev.d.ts.map +1 -1
- package/dist/cli/dev.js +30 -40
- package/dist/cli/dev.js.map +1 -1
- package/dist/cli/index.js +4 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/start.d.ts.map +1 -1
- package/dist/cli/start.js +2 -3
- package/dist/cli/start.js.map +1 -1
- package/dist/config.d.ts +28 -31
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/deploy/aws-lambda/runtime.d.ts +4 -6
- package/dist/deploy/aws-lambda/runtime.d.ts.map +1 -1
- package/dist/deploy/aws-lambda/runtime.js +5 -8
- package/dist/deploy/aws-lambda/runtime.js.map +1 -1
- package/dist/deploy/build-marker.d.ts +3 -5
- package/dist/deploy/build-marker.d.ts.map +1 -1
- package/dist/deploy/build-marker.js +3 -5
- package/dist/deploy/build-marker.js.map +1 -1
- package/dist/deploy/cloudflare/build.d.ts.map +1 -1
- package/dist/deploy/cloudflare/build.js +6 -10
- package/dist/deploy/cloudflare/build.js.map +1 -1
- package/dist/deploy/cloudflare/runtime.d.ts +2 -5
- package/dist/deploy/cloudflare/runtime.d.ts.map +1 -1
- package/dist/deploy/cloudflare/runtime.js +19 -32
- package/dist/deploy/cloudflare/runtime.js.map +1 -1
- package/dist/deploy/contract.d.ts +25 -42
- package/dist/deploy/contract.d.ts.map +1 -1
- package/dist/deploy/contract.js.map +1 -1
- package/dist/deploy/filesystem.d.ts +3 -5
- package/dist/deploy/filesystem.d.ts.map +1 -1
- package/dist/deploy/filesystem.js +7 -11
- package/dist/deploy/filesystem.js.map +1 -1
- package/dist/deploy/node/runtime.d.ts +4 -5
- package/dist/deploy/node/runtime.d.ts.map +1 -1
- package/dist/deploy/node/runtime.js +9 -15
- package/dist/deploy/node/runtime.js.map +1 -1
- package/dist/deploy/presets.d.ts +19 -29
- package/dist/deploy/presets.d.ts.map +1 -1
- package/dist/deploy/presets.js +18 -25
- package/dist/deploy/presets.js.map +1 -1
- package/dist/deploy/vercel/build.d.ts.map +1 -1
- package/dist/deploy/vercel/build.js +9 -12
- package/dist/deploy/vercel/build.js.map +1 -1
- package/dist/deploy/vercel/runtime.d.ts +4 -7
- package/dist/deploy/vercel/runtime.d.ts.map +1 -1
- package/dist/deploy/vercel/runtime.js +4 -7
- package/dist/deploy/vercel/runtime.js.map +1 -1
- package/dist/index.d.ts +13 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -12
- package/dist/index.js.map +1 -1
- package/dist/router.d.ts +65 -93
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +2 -5
- package/dist/router.js.map +1 -1
- package/dist/runtime/boundaries.d.ts +24 -30
- package/dist/runtime/boundaries.d.ts.map +1 -1
- package/dist/runtime/boundaries.js +15 -22
- package/dist/runtime/boundaries.js.map +1 -1
- package/dist/runtime/client.d.ts +16 -7
- package/dist/runtime/client.d.ts.map +1 -1
- package/dist/runtime/client.js +16 -7
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/context.d.ts +89 -118
- package/dist/runtime/context.d.ts.map +1 -1
- package/dist/runtime/context.js +107 -167
- package/dist/runtime/context.js.map +1 -1
- package/dist/runtime/control.js +3 -3
- package/dist/runtime/control.js.map +1 -1
- package/dist/runtime/dev-protocol.d.ts +4 -8
- package/dist/runtime/dev-protocol.d.ts.map +1 -1
- package/dist/runtime/dev-protocol.js.map +1 -1
- package/dist/runtime/entry.client.js +69 -105
- package/dist/runtime/entry.client.js.map +1 -1
- package/dist/runtime/entry.rsc.d.ts +5 -6
- package/dist/runtime/entry.rsc.d.ts.map +1 -1
- package/dist/runtime/entry.rsc.js +67 -122
- package/dist/runtime/entry.rsc.js.map +1 -1
- package/dist/runtime/entry.ssr.d.ts +7 -12
- package/dist/runtime/entry.ssr.d.ts.map +1 -1
- package/dist/runtime/entry.ssr.js +13 -24
- package/dist/runtime/entry.ssr.js.map +1 -1
- package/dist/runtime/flight-inject.d.ts +10 -17
- package/dist/runtime/flight-inject.d.ts.map +1 -1
- package/dist/runtime/flight-inject.js +35 -53
- package/dist/runtime/flight-inject.js.map +1 -1
- package/dist/runtime/hot-update.d.ts +20 -27
- package/dist/runtime/hot-update.d.ts.map +1 -1
- package/dist/runtime/hot-update.js +17 -23
- package/dist/runtime/hot-update.js.map +1 -1
- package/dist/runtime/navigation.d.ts +14 -19
- package/dist/runtime/navigation.d.ts.map +1 -1
- package/dist/runtime/navigation.js +9 -13
- package/dist/runtime/navigation.js.map +1 -1
- package/dist/runtime/request.d.ts +4 -6
- package/dist/runtime/request.d.ts.map +1 -1
- package/dist/runtime/request.js +2 -3
- package/dist/runtime/request.js.map +1 -1
- package/dist/runtime/server.d.ts +18 -10
- package/dist/runtime/server.d.ts.map +1 -1
- package/dist/runtime/server.js +21 -19
- package/dist/runtime/server.js.map +1 -1
- package/dist/server/headers.d.ts +8 -15
- package/dist/server/headers.d.ts.map +1 -1
- package/dist/server/headers.js +8 -15
- package/dist/server/headers.js.map +1 -1
- package/dist/server/load-config.d.ts +2 -2
- package/dist/server/load-config.d.ts.map +1 -1
- package/dist/server/load-config.js +6 -9
- package/dist/server/load-config.js.map +1 -1
- package/dist/server/prerendered.d.ts +30 -43
- package/dist/server/prerendered.d.ts.map +1 -1
- package/dist/server/prerendered.js +20 -29
- package/dist/server/prerendered.js.map +1 -1
- package/dist/server/server-config.d.ts +13 -28
- package/dist/server/server-config.d.ts.map +1 -1
- package/dist/server/server-config.js +5 -10
- package/dist/server/server-config.js.map +1 -1
- package/dist/server/shutdown.d.ts +2 -3
- package/dist/server/shutdown.d.ts.map +1 -1
- package/dist/server/shutdown.js +2 -3
- package/dist/server/shutdown.js.map +1 -1
- package/dist/server/ssg.d.ts +3 -6
- package/dist/server/ssg.d.ts.map +1 -1
- package/dist/server/ssg.js +11 -20
- package/dist/server/ssg.js.map +1 -1
- package/package.json +1 -1
package/dist/server/headers.d.ts
CHANGED
|
@@ -1,24 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* thing that only shows up behind a CDN.
|
|
2
|
+
* Header utilities shared by the response-header defaults and the prerendered-page cache. Their own module
|
|
3
|
+
* because getting `Vary` and `ETag` comparison subtly wrong only shows up behind a CDN.
|
|
5
4
|
*/
|
|
6
5
|
/**
|
|
7
|
-
* Adds `value` to the `Vary` header without discarding what is already there
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* one URL) is not necessarily the only one: a route, a middleware or a proxy may have added its own.
|
|
11
|
-
* A plain `set` would drop the others, and a cache would then serve one variant in place of another.
|
|
12
|
-
* `*` is left alone: it already means "never reuse this".
|
|
6
|
+
* Adds `value` to the `Vary` header without discarding what is already there — a route, a middleware or a proxy
|
|
7
|
+
* may have added its own entry, and a plain `set` would drop it, leaving a cache free to serve one variant in
|
|
8
|
+
* place of another. `*` is left alone: it already means "never reuse this".
|
|
13
9
|
*/
|
|
14
10
|
export declare function appendVary(headers: Headers, value: string): void;
|
|
15
11
|
/**
|
|
16
|
-
* True when an `If-None-Match`
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* The header carries a *list*, and each entry may be weak (`W/"…"`). The weak prefix is ignored on
|
|
20
|
-
* both sides: a proxy or CDN that gzips on the way out changes the bytes without changing the
|
|
21
|
-
* representation, and is entitled to weaken the validator when it does.
|
|
12
|
+
* True when an `If-None-Match` matches `etag` — the client already holds this body and can be answered with a
|
|
13
|
+
* 304. The header carries a list, and the weak prefix is ignored on both sides: a CDN that gzips on the way out
|
|
14
|
+
* changes the bytes without changing the representation, and may weaken the validator when it does.
|
|
22
15
|
*/
|
|
23
16
|
export declare function etagMatches(ifNoneMatch: string | undefined, etag: string): boolean;
|
|
24
17
|
//# sourceMappingURL=headers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../../src/server/headers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../../src/server/headers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAShE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAQlF"}
|
package/dist/server/headers.js
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* thing that only shows up behind a CDN.
|
|
2
|
+
* Header utilities shared by the response-header defaults and the prerendered-page cache. Their own module
|
|
3
|
+
* because getting `Vary` and `ETag` comparison subtly wrong only shows up behind a CDN.
|
|
5
4
|
*/
|
|
6
5
|
/**
|
|
7
|
-
* Adds `value` to the `Vary` header without discarding what is already there
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* one URL) is not necessarily the only one: a route, a middleware or a proxy may have added its own.
|
|
11
|
-
* A plain `set` would drop the others, and a cache would then serve one variant in place of another.
|
|
12
|
-
* `*` is left alone: it already means "never reuse this".
|
|
6
|
+
* Adds `value` to the `Vary` header without discarding what is already there — a route, a middleware or a proxy
|
|
7
|
+
* may have added its own entry, and a plain `set` would drop it, leaving a cache free to serve one variant in
|
|
8
|
+
* place of another. `*` is left alone: it already means "never reuse this".
|
|
13
9
|
*/
|
|
14
10
|
export function appendVary(headers, value) {
|
|
15
11
|
const existing = headers.get('vary');
|
|
@@ -24,12 +20,9 @@ export function appendVary(headers, value) {
|
|
|
24
20
|
headers.set('vary', `${existing}, ${value}`);
|
|
25
21
|
}
|
|
26
22
|
/**
|
|
27
|
-
* True when an `If-None-Match`
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* The header carries a *list*, and each entry may be weak (`W/"…"`). The weak prefix is ignored on
|
|
31
|
-
* both sides: a proxy or CDN that gzips on the way out changes the bytes without changing the
|
|
32
|
-
* representation, and is entitled to weaken the validator when it does.
|
|
23
|
+
* True when an `If-None-Match` matches `etag` — the client already holds this body and can be answered with a
|
|
24
|
+
* 304. The header carries a list, and the weak prefix is ignored on both sides: a CDN that gzips on the way out
|
|
25
|
+
* changes the bytes without changing the representation, and may weaken the validator when it does.
|
|
33
26
|
*/
|
|
34
27
|
export function etagMatches(ifNoneMatch, etag) {
|
|
35
28
|
if (!ifNoneMatch)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"headers.js","sourceRoot":"","sources":["../../src/server/headers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"headers.js","sourceRoot":"","sources":["../../src/server/headers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,OAAgB,EAAE,KAAa;IACxD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC3B,OAAO;IACT,CAAC;IACD,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG;QAAE,OAAO;IACpC,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IACxG,IAAI,CAAC,OAAO;QAAE,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,QAAQ,KAAK,KAAK,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,WAA+B,EAAE,IAAY;IACvE,IAAI,CAAC,WAAW;QAAE,OAAO,KAAK,CAAC;IAC/B,MAAM,SAAS,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACtE,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;QAC3C,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QACnC,OAAO,SAAS,KAAK,GAAG,IAAI,SAAS,KAAK,MAAM,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * Header utilities shared by the response-header defaults and the prerendered-page cache. Their own module\n * because getting `Vary` and `ETag` comparison subtly wrong only shows up behind a CDN.\n */\n\n/**\n * Adds `value` to the `Vary` header without discarding what is already there — a route, a middleware or a proxy\n * may have added its own entry, and a plain `set` would drop it, leaving a cache free to serve one variant in\n * place of another. `*` is left alone: it already means \"never reuse this\".\n */\nexport function appendVary(headers: Headers, value: string): void {\n const existing = headers.get('vary');\n if (existing === null) {\n headers.set('vary', value);\n return;\n }\n if (existing.trim() === '*') return;\n const already = existing.split(',').some((entry) => entry.trim().toLowerCase() === value.toLowerCase());\n if (!already) headers.set('vary', `${existing}, ${value}`);\n}\n\n/**\n * True when an `If-None-Match` matches `etag` — the client already holds this body and can be answered with a\n * 304. The header carries a list, and the weak prefix is ignored on both sides: a CDN that gzips on the way out\n * changes the bytes without changing the representation, and may weaken the validator when it does.\n */\nexport function etagMatches(ifNoneMatch: string | undefined, etag: string): boolean {\n if (!ifNoneMatch) return false;\n const normalize = (value: string) => value.trim().replace(/^W\\//, '');\n const wanted = normalize(etag);\n return ifNoneMatch.split(',').some((entry) => {\n const candidate = normalize(entry);\n return candidate === '*' || candidate === wanted;\n });\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { RshonoConfig } from '../config.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Loads the project config, or `{}` if there is none: scans `rshono.config.{ts,js,mjs}` at `rootDir`, unless an
|
|
4
|
+
* explicit `configPath` is given (resolved relative to `cwd`).
|
|
5
5
|
*/
|
|
6
6
|
export declare function loadConfig(rootDir: string, configPath?: string): Promise<RshonoConfig>;
|
|
7
7
|
//# sourceMappingURL=load-config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load-config.d.ts","sourceRoot":"","sources":["../../src/server/load-config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"load-config.d.ts","sourceRoot":"","sources":["../../src/server/load-config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAgBjD;;;GAGG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA6B5F"}
|
|
@@ -3,22 +3,19 @@ import { isAbsolute, join, resolve } from 'node:path';
|
|
|
3
3
|
import { pathToFileURL } from 'node:url';
|
|
4
4
|
const CONFIG_FILES = ['rshono.config.ts', 'rshono.config.js', 'rshono.config.mjs'];
|
|
5
5
|
/**
|
|
6
|
-
* Imports the config module.
|
|
7
|
-
*
|
|
8
|
-
* A `.ts` config needs no loader of its own: Node strips types natively from 22.18 on, which is what
|
|
9
|
-
* the package's `engines` floor is for. That replaced a `tsx` dependency whose only job was these two
|
|
10
|
-
* lines — and `tsx` bundles esbuild, so it was the largest thing in the install.
|
|
6
|
+
* Imports the config module. A `.ts` config needs no loader: Node strips types natively from 22.18 on, which is
|
|
7
|
+
* what the package's `engines` floor is for.
|
|
11
8
|
*
|
|
12
9
|
* The one thing native stripping will not do is resolve a `.js` specifier to a `.ts` file, so a config
|
|
13
|
-
*
|
|
14
|
-
*
|
|
10
|
+
* importing a sibling has to name it with its real extension — {@link loadConfig} turns that resolution failure
|
|
11
|
+
* into the advice rather than letting a raw `ERR_MODULE_NOT_FOUND` out.
|
|
15
12
|
*/
|
|
16
13
|
function importConfig(file) {
|
|
17
14
|
return import(pathToFileURL(file).href);
|
|
18
15
|
}
|
|
19
16
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
17
|
+
* Loads the project config, or `{}` if there is none: scans `rshono.config.{ts,js,mjs}` at `rootDir`, unless an
|
|
18
|
+
* explicit `configPath` is given (resolved relative to `cwd`).
|
|
22
19
|
*/
|
|
23
20
|
export async function loadConfig(rootDir, configPath) {
|
|
24
21
|
const file = configPath
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load-config.js","sourceRoot":"","sources":["../../src/server/load-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,MAAM,YAAY,GAAG,CAAC,kBAAkB,EAAE,kBAAkB,EAAE,mBAAmB,CAAC,CAAC;AAEnF
|
|
1
|
+
{"version":3,"file":"load-config.js","sourceRoot":"","sources":["../../src/server/load-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,MAAM,YAAY,GAAG,CAAC,kBAAkB,EAAE,kBAAkB,EAAE,mBAAmB,CAAC,CAAC;AAEnF;;;;;;;GAOG;AACH,SAAS,YAAY,CAAC,IAAY;IAChC,OAAO,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAwC,CAAC;AACjF,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAe,EAAE,UAAmB;IACnE,MAAM,IAAI,GAAG,UAAU;QACrB,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;YACtB,CAAC,CAAC,UAAU;YACZ,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC;QACtC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/D,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,mCAAmC,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,GAA+B,CAAC;IACpC,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,0FAA0F;QAC1F,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAK,KAAkC,EAAE,IAAI,KAAK,sBAAsB,EAAE,CAAC;YACpG,MAAM,IAAI,KAAK,CACb,YAAY,IAAI,6CAA8C,KAAe,CAAC,OAAO,IAAI;gBACvF,kGAAkG;gBAClG,sFAAsF,EACxF,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,YAAY,IAAI,yEAAyE,CAAC,CAAC;IAC7G,CAAC;IACD,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC","sourcesContent":["import { existsSync } from 'node:fs';\nimport { isAbsolute, join, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type { RshonoConfig } from '../config.js';\n\nconst CONFIG_FILES = ['rshono.config.ts', 'rshono.config.js', 'rshono.config.mjs'];\n\n/**\n * Imports the config module. A `.ts` config needs no loader: Node strips types natively from 22.18 on, which is\n * what the package's `engines` floor is for.\n *\n * The one thing native stripping will not do is resolve a `.js` specifier to a `.ts` file, so a config\n * importing a sibling has to name it with its real extension — {@link loadConfig} turns that resolution failure\n * into the advice rather than letting a raw `ERR_MODULE_NOT_FOUND` out.\n */\nfunction importConfig(file: string): Promise<{ default?: RshonoConfig }> {\n return import(pathToFileURL(file).href) as Promise<{ default?: RshonoConfig }>;\n}\n\n/**\n * Loads the project config, or `{}` if there is none: scans `rshono.config.{ts,js,mjs}` at `rootDir`, unless an\n * explicit `configPath` is given (resolved relative to `cwd`).\n */\nexport async function loadConfig(rootDir: string, configPath?: string): Promise<RshonoConfig> {\n const file = configPath\n ? isAbsolute(configPath)\n ? configPath\n : resolve(process.cwd(), configPath)\n : CONFIG_FILES.map((f) => join(rootDir, f)).find(existsSync);\n if (!file) return {};\n if (!existsSync(file)) {\n throw new Error(`[rshono] config file not found: ${file}`);\n }\n let mod: { default?: RshonoConfig };\n try {\n mod = await importConfig(file);\n } catch (error) {\n // The one failure mode native type stripping has that a TypeScript-aware loader does not.\n if (/\\.[cm]?ts$/.test(file) && (error as { code?: string } | null)?.code === 'ERR_MODULE_NOT_FOUND') {\n throw new Error(\n `[rshono] ${file} imports a module Node could not resolve: ${(error as Error).message}\\n` +\n ' A .ts config is loaded by Node itself, which does not rewrite a .js specifier to the .ts file ' +\n 'beside it. Import it by its real extension, or move the config to rshono.config.mjs.',\n { cause: error },\n );\n }\n throw error;\n }\n if (!mod.default) {\n throw new Error(`[rshono] ${file} must \\`export default\\` a config object (use \\`defineConfig({ … })\\`).`);\n }\n return mod.default;\n}\n"]}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Everything about a prerendered page that doesn't need a filesystem: where the build puts it, and
|
|
3
|
-
*
|
|
2
|
+
* Everything about a prerendered page that doesn't need a filesystem: where the build puts it, and what it
|
|
3
|
+
* looks like once read back.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Apart from `ssg.ts`, which does the reading and writing through `node:fs`, because a deploy target without a
|
|
6
|
+
* filesystem reads the same layout out of an asset store — and importing it from there would drag `node:fs`
|
|
7
|
+
* into a bundle that has neither.
|
|
8
8
|
*/
|
|
9
9
|
/**
|
|
10
|
-
* The two representations of a page, prerendered side by side: a hard load wants the HTML document, a
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* The two representations of a page, prerendered side by side: a hard load wants the HTML document, a soft
|
|
11
|
+
* navigation asks the same URL for a flight payload. Without both, every in-app click would re-render a page
|
|
12
|
+
* that was already built.
|
|
13
13
|
*/
|
|
14
14
|
export type PrerenderVariant = 'html' | 'flight';
|
|
15
15
|
export declare const VARIANTS: {
|
|
@@ -25,70 +25,57 @@ export declare const VARIANTS: {
|
|
|
25
25
|
};
|
|
26
26
|
};
|
|
27
27
|
/**
|
|
28
|
-
* Where a route's prerendered output lives, relative to the output root — or `null` for a path that
|
|
29
|
-
*
|
|
28
|
+
* Where a route's prerendered output lives, relative to the output root — or `null` for a path that cannot be
|
|
29
|
+
* prerendered at all, one with a param or a wildcard left in it.
|
|
30
30
|
*
|
|
31
|
-
* Always `/`-separated
|
|
32
|
-
*
|
|
33
|
-
* where a backslash would simply be the wrong character.
|
|
31
|
+
* Always `/`-separated: the same string addresses a file on a filesystem, which accepts forward slashes on
|
|
32
|
+
* Windows too, and a key in an asset store, where a backslash would be the wrong character.
|
|
34
33
|
*/
|
|
35
34
|
export declare function ssgFilePath(routePath: string, variant?: PrerenderVariant): string | null;
|
|
36
35
|
/**
|
|
37
|
-
* {@link ssgFilePath} for a path that came off a request, so traversal is a miss rather than a lookup.
|
|
38
|
-
*
|
|
39
|
-
* The first line of defence for every deploy target: a store addressed by key has no `resolve()` to
|
|
40
|
-
* fall back on, so `..` has to be refused here or not at all.
|
|
36
|
+
* {@link ssgFilePath} for a path that came off a request, so traversal is a miss rather than a lookup. A store
|
|
37
|
+
* addressed by key has no `resolve()` to fall back on, so `..` is refused here or not at all.
|
|
41
38
|
*/
|
|
42
39
|
export declare function prerenderedRelPath(requestPath: string, variant: PrerenderVariant): string | null;
|
|
43
40
|
/**
|
|
44
|
-
* A bounded, insertion-ordered cache of prerendered pages
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* build in memory. Only *hits* are ever stored: caching misses would let anyone mint entries by
|
|
48
|
-
* requesting paths that don't exist. The files are written at build time and never change while the
|
|
49
|
-
* server is up, so an entry never needs invalidating.
|
|
41
|
+
* A bounded, insertion-ordered cache of prerendered pages, so a site with thousands of them keeps a working set
|
|
42
|
+
* rather than the whole build in memory. Only *hits* are stored — caching misses would let anyone mint entries
|
|
43
|
+
* by requesting paths that don't exist — and the files never change while the server is up.
|
|
50
44
|
*/
|
|
51
45
|
export declare function createPageCache(max?: number): {
|
|
52
46
|
get(key: string): PrerenderedPage | undefined;
|
|
53
47
|
set(key: string, page: PrerenderedPage): void;
|
|
54
48
|
};
|
|
55
49
|
/**
|
|
56
|
-
* A weak `ETag` for a page body — see {@link PrerenderedPage.etag} for why weak.
|
|
57
|
-
*
|
|
58
|
-
* Web Crypto rather than `node:crypto`, so the one implementation serves both a Node server and
|
|
59
|
-
* `workerd`.
|
|
50
|
+
* A weak `ETag` for a page body — see {@link PrerenderedPage.etag} for why weak. Web Crypto rather than
|
|
51
|
+
* `node:crypto`, so one implementation serves both a Node server and `workerd`.
|
|
60
52
|
*/
|
|
61
53
|
export declare function weakEtag(body: Uint8Array<ArrayBuffer>): Promise<string>;
|
|
62
54
|
/**
|
|
63
|
-
* Assembles a {@link PrerenderedPage} from a body just read out of the build.
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* exact bytes, so it is preferred over hashing them again, and only weakened.
|
|
55
|
+
* Assembles a {@link PrerenderedPage} from a body just read out of the build. `storeEtag` is the validator the
|
|
56
|
+
* store supplied, where it has one: it already describes these exact bytes, so it is weakened rather than
|
|
57
|
+
* replaced by a fresh hash.
|
|
67
58
|
*/
|
|
68
59
|
export declare function toPrerenderedPage(body: Uint8Array<ArrayBuffer>, storeEtag?: string | null): Promise<PrerenderedPage>;
|
|
69
60
|
/** A prerendered page, ready to serve: its body and a validator derived from those exact bytes. */
|
|
70
61
|
export interface PrerenderedPage {
|
|
71
62
|
/**
|
|
72
|
-
* The document or the flight payload, depending on which {@link PrerenderVariant} was read.
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* hits it — held as a string, each of those would pay a fresh UTF-8 encode of the whole page on the
|
|
76
|
-
* way out. Read once, encoded never.
|
|
63
|
+
* The document or the flight payload, depending on which {@link PrerenderVariant} was read. Bytes rather
|
|
64
|
+
* than a string, because this cache entry is served verbatim to every request that hits it — as a string,
|
|
65
|
+
* each would pay a fresh UTF-8 encode of the whole page.
|
|
77
66
|
*/
|
|
78
67
|
body: Uint8Array<ArrayBuffer>;
|
|
79
68
|
/**
|
|
80
|
-
* `Content-Length` for {@link body}, in bytes
|
|
81
|
-
*
|
|
82
|
-
* decisions with it — whether gzipping this response is worth the framing, most obviously.
|
|
69
|
+
* `Content-Length` for {@link body}, in bytes. Served explicitly because Hono sets no length for an
|
|
70
|
+
* in-memory body, and a proxy in front is entitled to make decisions with it.
|
|
83
71
|
*/
|
|
84
72
|
contentLength: string;
|
|
85
73
|
/**
|
|
86
74
|
* `ETag` for the page, so a revalidating client can be answered with a 304 instead of the body.
|
|
87
75
|
*
|
|
88
|
-
* Deliberately **weak
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* "the same representation", which is what stays true across content codings.
|
|
76
|
+
* Deliberately **weak**: the bytes on the wire depend on whether something in front re-encoded them, so a
|
|
77
|
+
* strong validator would differ per coding and a cache would treat the 200 and the 304 that revalidates it
|
|
78
|
+
* as different pages. A weak tag says "the same representation", which stays true across codings.
|
|
92
79
|
*/
|
|
93
80
|
etag: string;
|
|
94
81
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prerendered.d.ts","sourceRoot":"","sources":["../../src/server/prerendered.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEjD,eAAO,MAAM,QAAQ;;iBACX,IAAI,EAAE,YAAY;iBAAE,MAAM,EAAE,WAAW;iBAAE,WAAW,EAAE,WAAW;;;iBAC/D,IAAI,EAAE,WAAW;iBAAE,MAAM,EAAE,kBAAkB;iBAAE,WAAW,EAAE,kBAAkB;;CACU,CAAC;AAErG
|
|
1
|
+
{"version":3,"file":"prerendered.d.ts","sourceRoot":"","sources":["../../src/server/prerendered.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEjD,eAAO,MAAM,QAAQ;;iBACX,IAAI,EAAE,YAAY;iBAAE,MAAM,EAAE,WAAW;iBAAE,WAAW,EAAE,WAAW;;;iBAC/D,IAAI,EAAE,WAAW;iBAAE,MAAM,EAAE,kBAAkB;iBAAE,WAAW,EAAE,kBAAkB;;CACU,CAAC;AAErG;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAyB,GAAG,MAAM,GAAG,IAAI,CAKhG;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAGhG;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,SAAM,GAAG;IAAE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAAC;IAAC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,IAAI,CAAA;CAAE,CAU3I;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAO7E;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,UAAU,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAM1H;AAED,mGAAmG;AACnG,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,IAAI,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IAC9B;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;;;;;OAMG;IACH,IAAI,EAAE,MAAM,CAAC;CACd"}
|
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Everything about a prerendered page that doesn't need a filesystem: where the build puts it, and
|
|
3
|
-
*
|
|
2
|
+
* Everything about a prerendered page that doesn't need a filesystem: where the build puts it, and what it
|
|
3
|
+
* looks like once read back.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Apart from `ssg.ts`, which does the reading and writing through `node:fs`, because a deploy target without a
|
|
6
|
+
* filesystem reads the same layout out of an asset store — and importing it from there would drag `node:fs`
|
|
7
|
+
* into a bundle that has neither.
|
|
8
8
|
*/
|
|
9
9
|
export const VARIANTS = {
|
|
10
10
|
html: { file: 'index.html', accept: 'text/html', contentType: 'text/html' },
|
|
11
11
|
flight: { file: 'index.rsc', accept: 'text/x-component', contentType: 'text/x-component' },
|
|
12
12
|
};
|
|
13
13
|
/**
|
|
14
|
-
* Where a route's prerendered output lives, relative to the output root — or `null` for a path that
|
|
15
|
-
*
|
|
14
|
+
* Where a route's prerendered output lives, relative to the output root — or `null` for a path that cannot be
|
|
15
|
+
* prerendered at all, one with a param or a wildcard left in it.
|
|
16
16
|
*
|
|
17
|
-
* Always `/`-separated
|
|
18
|
-
*
|
|
19
|
-
* where a backslash would simply be the wrong character.
|
|
17
|
+
* Always `/`-separated: the same string addresses a file on a filesystem, which accepts forward slashes on
|
|
18
|
+
* Windows too, and a key in an asset store, where a backslash would be the wrong character.
|
|
20
19
|
*/
|
|
21
20
|
export function ssgFilePath(routePath, variant = 'html') {
|
|
22
21
|
if (/[:*]/.test(routePath))
|
|
@@ -26,10 +25,8 @@ export function ssgFilePath(routePath, variant = 'html') {
|
|
|
26
25
|
return trimmed === '' ? file : `${trimmed}/${file}`;
|
|
27
26
|
}
|
|
28
27
|
/**
|
|
29
|
-
* {@link ssgFilePath} for a path that came off a request, so traversal is a miss rather than a lookup.
|
|
30
|
-
*
|
|
31
|
-
* The first line of defence for every deploy target: a store addressed by key has no `resolve()` to
|
|
32
|
-
* fall back on, so `..` has to be refused here or not at all.
|
|
28
|
+
* {@link ssgFilePath} for a path that came off a request, so traversal is a miss rather than a lookup. A store
|
|
29
|
+
* addressed by key has no `resolve()` to fall back on, so `..` is refused here or not at all.
|
|
33
30
|
*/
|
|
34
31
|
export function prerenderedRelPath(requestPath, variant) {
|
|
35
32
|
if (/(^|\/)\.\.?(\/|$)/.test(requestPath))
|
|
@@ -37,12 +34,9 @@ export function prerenderedRelPath(requestPath, variant) {
|
|
|
37
34
|
return ssgFilePath(requestPath, variant);
|
|
38
35
|
}
|
|
39
36
|
/**
|
|
40
|
-
* A bounded, insertion-ordered cache of prerendered pages
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* build in memory. Only *hits* are ever stored: caching misses would let anyone mint entries by
|
|
44
|
-
* requesting paths that don't exist. The files are written at build time and never change while the
|
|
45
|
-
* server is up, so an entry never needs invalidating.
|
|
37
|
+
* A bounded, insertion-ordered cache of prerendered pages, so a site with thousands of them keeps a working set
|
|
38
|
+
* rather than the whole build in memory. Only *hits* are stored — caching misses would let anyone mint entries
|
|
39
|
+
* by requesting paths that don't exist — and the files never change while the server is up.
|
|
46
40
|
*/
|
|
47
41
|
export function createPageCache(max = 128) {
|
|
48
42
|
const pages = new Map();
|
|
@@ -50,17 +44,15 @@ export function createPageCache(max = 128) {
|
|
|
50
44
|
get: (key) => pages.get(key),
|
|
51
45
|
set(key, page) {
|
|
52
46
|
pages.set(key, page);
|
|
53
|
-
// Insertion-ordered, so the first key is the oldest.
|
|
47
|
+
// Insertion-ordered, so the first key is the oldest.
|
|
54
48
|
if (pages.size > max)
|
|
55
49
|
pages.delete(pages.keys().next().value);
|
|
56
50
|
},
|
|
57
51
|
};
|
|
58
52
|
}
|
|
59
53
|
/**
|
|
60
|
-
* A weak `ETag` for a page body — see {@link PrerenderedPage.etag} for why weak.
|
|
61
|
-
*
|
|
62
|
-
* Web Crypto rather than `node:crypto`, so the one implementation serves both a Node server and
|
|
63
|
-
* `workerd`.
|
|
54
|
+
* A weak `ETag` for a page body — see {@link PrerenderedPage.etag} for why weak. Web Crypto rather than
|
|
55
|
+
* `node:crypto`, so one implementation serves both a Node server and `workerd`.
|
|
64
56
|
*/
|
|
65
57
|
export async function weakEtag(body) {
|
|
66
58
|
const digest = await crypto.subtle.digest('SHA-256', body);
|
|
@@ -71,10 +63,9 @@ export async function weakEtag(body) {
|
|
|
71
63
|
return `W/"${base64url.slice(0, 22)}"`;
|
|
72
64
|
}
|
|
73
65
|
/**
|
|
74
|
-
* Assembles a {@link PrerenderedPage} from a body just read out of the build.
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* exact bytes, so it is preferred over hashing them again, and only weakened.
|
|
66
|
+
* Assembles a {@link PrerenderedPage} from a body just read out of the build. `storeEtag` is the validator the
|
|
67
|
+
* store supplied, where it has one: it already describes these exact bytes, so it is weakened rather than
|
|
68
|
+
* replaced by a fresh hash.
|
|
78
69
|
*/
|
|
79
70
|
export async function toPrerenderedPage(body, storeEtag) {
|
|
80
71
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prerendered.js","sourceRoot":"","sources":["../../src/server/prerendered.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,IAAI,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE;IAC3E,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,kBAAkB,EAAE,WAAW,EAAE,kBAAkB,EAAE;CACQ,CAAC;AAErG
|
|
1
|
+
{"version":3,"file":"prerendered.js","sourceRoot":"","sources":["../../src/server/prerendered.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,IAAI,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE;IAC3E,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,kBAAkB,EAAE,WAAW,EAAE,kBAAkB,EAAE;CACQ,CAAC;AAErG;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,SAAiB,EAAE,OAAO,GAAqB,MAAM;IAC/E,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;IACpC,OAAO,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,IAAI,EAAE,CAAC;AACtD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAmB,EAAE,OAAyB;IAC/E,IAAI,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IACvD,OAAO,WAAW,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,GAAG,GAAG,GAAG;IACvC,MAAM,KAAK,GAAG,IAAI,GAAG,EAA2B,CAAC;IACjD,OAAO;QACL,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;QAC5B,GAAG,CAAC,GAAG,EAAE,IAAI;YACX,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACrB,qDAAqD;YACrD,IAAI,KAAK,CAAC,IAAI,GAAG,GAAG;gBAAE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAM,CAAC,CAAC;QACjE,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAA6B;IAC1D,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;SACnE,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACtB,OAAO,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAA6B,EAAE,SAAyB;IAC9F,OAAO;QACL,IAAI;QACJ,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;QACtC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC;KAC7E,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Everything about a prerendered page that doesn't need a filesystem: where the build puts it, and what it\n * looks like once read back.\n *\n * Apart from `ssg.ts`, which does the reading and writing through `node:fs`, because a deploy target without a\n * filesystem reads the same layout out of an asset store — and importing it from there would drag `node:fs`\n * into a bundle that has neither.\n */\n\n/**\n * The two representations of a page, prerendered side by side: a hard load wants the HTML document, a soft\n * navigation asks the same URL for a flight payload. Without both, every in-app click would re-render a page\n * that was already built.\n */\nexport type PrerenderVariant = 'html' | 'flight';\n\nexport const VARIANTS = {\n html: { file: 'index.html', accept: 'text/html', contentType: 'text/html' },\n flight: { file: 'index.rsc', accept: 'text/x-component', contentType: 'text/x-component' },\n} as const satisfies Record<PrerenderVariant, { file: string; accept: string; contentType: string }>;\n\n/**\n * Where a route's prerendered output lives, relative to the output root — or `null` for a path that cannot be\n * prerendered at all, one with a param or a wildcard left in it.\n *\n * Always `/`-separated: the same string addresses a file on a filesystem, which accepts forward slashes on\n * Windows too, and a key in an asset store, where a backslash would be the wrong character.\n */\nexport function ssgFilePath(routePath: string, variant: PrerenderVariant = 'html'): string | null {\n if (/[:*]/.test(routePath)) return null;\n const trimmed = routePath.replace(/^\\/+|\\/+$/g, '');\n const file = VARIANTS[variant].file;\n return trimmed === '' ? file : `${trimmed}/${file}`;\n}\n\n/**\n * {@link ssgFilePath} for a path that came off a request, so traversal is a miss rather than a lookup. A store\n * addressed by key has no `resolve()` to fall back on, so `..` is refused here or not at all.\n */\nexport function prerenderedRelPath(requestPath: string, variant: PrerenderVariant): string | null {\n if (/(^|\\/)\\.\\.?(\\/|$)/.test(requestPath)) return null;\n return ssgFilePath(requestPath, variant);\n}\n\n/**\n * A bounded, insertion-ordered cache of prerendered pages, so a site with thousands of them keeps a working set\n * rather than the whole build in memory. Only *hits* are stored — caching misses would let anyone mint entries\n * by requesting paths that don't exist — and the files never change while the server is up.\n */\nexport function createPageCache(max = 128): { get(key: string): PrerenderedPage | undefined; set(key: string, page: PrerenderedPage): void } {\n const pages = new Map<string, PrerenderedPage>();\n return {\n get: (key) => pages.get(key),\n set(key, page) {\n pages.set(key, page);\n // Insertion-ordered, so the first key is the oldest.\n if (pages.size > max) pages.delete(pages.keys().next().value!);\n },\n };\n}\n\n/**\n * A weak `ETag` for a page body — see {@link PrerenderedPage.etag} for why weak. Web Crypto rather than\n * `node:crypto`, so one implementation serves both a Node server and `workerd`.\n */\nexport async function weakEtag(body: Uint8Array<ArrayBuffer>): Promise<string> {\n const digest = await crypto.subtle.digest('SHA-256', body);\n const base64url = btoa(String.fromCharCode(...new Uint8Array(digest)))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '');\n return `W/\"${base64url.slice(0, 22)}\"`;\n}\n\n/**\n * Assembles a {@link PrerenderedPage} from a body just read out of the build. `storeEtag` is the validator the\n * store supplied, where it has one: it already describes these exact bytes, so it is weakened rather than\n * replaced by a fresh hash.\n */\nexport async function toPrerenderedPage(body: Uint8Array<ArrayBuffer>, storeEtag?: string | null): Promise<PrerenderedPage> {\n return {\n body,\n contentLength: String(body.byteLength),\n etag: storeEtag ? storeEtag.replace(/^(?!W\\/)/, 'W/') : await weakEtag(body),\n };\n}\n\n/** A prerendered page, ready to serve: its body and a validator derived from those exact bytes. */\nexport interface PrerenderedPage {\n /**\n * The document or the flight payload, depending on which {@link PrerenderVariant} was read. Bytes rather\n * than a string, because this cache entry is served verbatim to every request that hits it — as a string,\n * each would pay a fresh UTF-8 encode of the whole page.\n */\n body: Uint8Array<ArrayBuffer>;\n /**\n * `Content-Length` for {@link body}, in bytes. Served explicitly because Hono sets no length for an\n * in-memory body, and a proxy in front is entitled to make decisions with it.\n */\n contentLength: string;\n /**\n * `ETag` for the page, so a revalidating client can be answered with a 304 instead of the body.\n *\n * Deliberately **weak**: the bytes on the wire depend on whether something in front re-encoded them, so a\n * strong validator would differ per coding and a cache would treat the 200 and the 304 that revalidates it\n * as different pages. A weak tag says \"the same representation\", which stays true across codings.\n */\n etag: string;\n}\n"]}
|
|
@@ -1,51 +1,36 @@
|
|
|
1
1
|
import type { RshonoConfig } from '../config.js';
|
|
2
2
|
/**
|
|
3
|
-
* The framework settings the server bundle needs at request time, fully resolved
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* and compiled into the server bundle as the `__RSHONO_CONFIG__` literal (see
|
|
7
|
-
* `builder/rspack-config.ts`) — there is no runtime env-var interface for these.
|
|
8
|
-
*
|
|
9
|
-
* Only what the *build* decides. The per-request security controls that used to live alongside these
|
|
10
|
-
* — the CSRF check, the CSP, the body cap — are Hono middleware an app registers in `src/server.ts`,
|
|
11
|
-
* where they can be configured per route and per environment instead of once per bundle.
|
|
3
|
+
* The framework settings the server bundle needs at request time, fully resolved — produced once by
|
|
4
|
+
* {@link resolveServerConfig} and compiled in as the `__RSHONO_CONFIG__` literal. There is no runtime env-var
|
|
5
|
+
* interface for these, and nothing here is a per-request concern: those are Hono middleware in `src/server.ts`.
|
|
12
6
|
*/
|
|
13
7
|
export interface ServerConfig {
|
|
14
8
|
/**
|
|
15
|
-
* `true` when the bundle came from `rshono dev`.
|
|
16
|
-
*
|
|
17
|
-
* Baked in rather than read from `process.env.NODE_ENV` at runtime: it is decided by which command
|
|
18
|
-
* produced the bundle, and a deploy target need not have a `process` to read it from.
|
|
9
|
+
* `true` when the bundle came from `rshono dev`. Baked in rather than read from `process.env.NODE_ENV`,
|
|
10
|
+
* because a deploy target need not have a `process`.
|
|
19
11
|
*/
|
|
20
12
|
isDev: boolean;
|
|
21
13
|
/** Honour `X-Forwarded-Host` / `-Proto` when resolving the browser-facing URL. Forced on in dev. */
|
|
22
14
|
trustProxy: boolean;
|
|
23
15
|
/**
|
|
24
|
-
* The output directory this bundle was written to, relative to the project root
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* Carried into the bundle because `deploy/filesystem.ts` locates the static assets and the
|
|
28
|
-
* prerendered pages beside it at runtime, and only the compiler knows which directory it used.
|
|
16
|
+
* The output directory this bundle was written to, relative to the project root. Carried into the bundle
|
|
17
|
+
* because `deploy/filesystem.ts` locates the assets and prerendered pages beside it at runtime, and only the
|
|
18
|
+
* compiler knows which directory it used.
|
|
29
19
|
*/
|
|
30
20
|
outDir: string;
|
|
31
21
|
}
|
|
32
22
|
/**
|
|
33
|
-
* The framework's built-in defaults.
|
|
34
|
-
*
|
|
35
|
-
* `port` and `host` are not config fields at all — they come from `PORT` / `HOST` (or `--port`)
|
|
36
|
-
* wherever the address is resolved, `deploy/node/runtime.ts` for a server bundle and `cli/dev.ts`
|
|
37
|
-
* for the dev server, and this is what both fall back to.
|
|
23
|
+
* The framework's built-in defaults. `port` and `host` are not config fields — they come from `PORT` / `HOST`
|
|
24
|
+
* or `--port` wherever the address is resolved, and this is what those fall back to.
|
|
38
25
|
*/
|
|
39
26
|
export declare const SERVER_DEFAULTS: {
|
|
40
27
|
readonly port: 3000;
|
|
41
28
|
readonly host: '0.0.0.0';
|
|
42
29
|
};
|
|
43
30
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* `
|
|
47
|
-
* shouldn't have to: `trustProxy` is forced on under `rshono dev`, where the framework's own proxy
|
|
48
|
-
* is the only way in (it sets the forwarded headers itself and binds to localhost).
|
|
31
|
+
* Resolves the user's config into the {@link ServerConfig} baked into the bundle. `isDev` is a build-time input
|
|
32
|
+
* rather than a config field because it decides one thing the user should not have to: `trustProxy` is forced on
|
|
33
|
+
* under `rshono dev`, where the framework's own localhost proxy is the only way in.
|
|
49
34
|
*/
|
|
50
35
|
export declare function resolveServerConfig(config: RshonoConfig, { isDev, outDir }: {
|
|
51
36
|
isDev: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../src/server/server-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD
|
|
1
|
+
{"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../src/server/server-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,KAAK,EAAE,OAAO,CAAC;IACf,oGAAoG;IACpG,UAAU,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe;aAC1B,IAAI,EAAE,IAAI;aACV,IAAI,EAAE,SAAS;CACP,CAAC;AAEX;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,YAAY,CAM7H"}
|
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The framework's built-in defaults.
|
|
3
|
-
*
|
|
4
|
-
* `port` and `host` are not config fields at all — they come from `PORT` / `HOST` (or `--port`)
|
|
5
|
-
* wherever the address is resolved, `deploy/node/runtime.ts` for a server bundle and `cli/dev.ts`
|
|
6
|
-
* for the dev server, and this is what both fall back to.
|
|
2
|
+
* The framework's built-in defaults. `port` and `host` are not config fields — they come from `PORT` / `HOST`
|
|
3
|
+
* or `--port` wherever the address is resolved, and this is what those fall back to.
|
|
7
4
|
*/
|
|
8
5
|
export const SERVER_DEFAULTS = {
|
|
9
6
|
port: 3000,
|
|
10
7
|
host: '0.0.0.0',
|
|
11
8
|
};
|
|
12
9
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* `
|
|
16
|
-
* shouldn't have to: `trustProxy` is forced on under `rshono dev`, where the framework's own proxy
|
|
17
|
-
* is the only way in (it sets the forwarded headers itself and binds to localhost).
|
|
10
|
+
* Resolves the user's config into the {@link ServerConfig} baked into the bundle. `isDev` is a build-time input
|
|
11
|
+
* rather than a config field because it decides one thing the user should not have to: `trustProxy` is forced on
|
|
12
|
+
* under `rshono dev`, where the framework's own localhost proxy is the only way in.
|
|
18
13
|
*/
|
|
19
14
|
export function resolveServerConfig(config, { isDev, outDir }) {
|
|
20
15
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-config.js","sourceRoot":"","sources":["../../src/server/server-config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server-config.js","sourceRoot":"","sources":["../../src/server/server-config.ts"],"names":[],"mappings":"AAuBA;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,SAAS;CACP,CAAC;AAEX;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAoB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAsC;IAC7G,OAAO;QACL,KAAK;QACL,UAAU,EAAE,KAAK,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,KAAK,CAAC;QACjD,MAAM;KACP,CAAC;AACJ,CAAC","sourcesContent":["import type { RshonoConfig } from '../config.js';\n\n/**\n * The framework settings the server bundle needs at request time, fully resolved — produced once by\n * {@link resolveServerConfig} and compiled in as the `__RSHONO_CONFIG__` literal. There is no runtime env-var\n * interface for these, and nothing here is a per-request concern: those are Hono middleware in `src/server.ts`.\n */\nexport interface ServerConfig {\n /**\n * `true` when the bundle came from `rshono dev`. Baked in rather than read from `process.env.NODE_ENV`,\n * because a deploy target need not have a `process`.\n */\n isDev: boolean;\n /** Honour `X-Forwarded-Host` / `-Proto` when resolving the browser-facing URL. Forced on in dev. */\n trustProxy: boolean;\n /**\n * The output directory this bundle was written to, relative to the project root. Carried into the bundle\n * because `deploy/filesystem.ts` locates the assets and prerendered pages beside it at runtime, and only the\n * compiler knows which directory it used.\n */\n outDir: string;\n}\n\n/**\n * The framework's built-in defaults. `port` and `host` are not config fields — they come from `PORT` / `HOST`\n * or `--port` wherever the address is resolved, and this is what those fall back to.\n */\nexport const SERVER_DEFAULTS = {\n port: 3000,\n host: '0.0.0.0',\n} as const;\n\n/**\n * Resolves the user's config into the {@link ServerConfig} baked into the bundle. `isDev` is a build-time input\n * rather than a config field because it decides one thing the user should not have to: `trustProxy` is forced on\n * under `rshono dev`, where the framework's own localhost proxy is the only way in.\n */\nexport function resolveServerConfig(config: RshonoConfig, { isDev, outDir }: { isDev: boolean; outDir: string }): ServerConfig {\n return {\n isDev,\n trustProxy: isDev || (config.trustProxy ?? false),\n outDir,\n };\n}\n"]}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Registers `handler` for both `SIGINT` and `SIGTERM` — the two signals a process
|
|
3
|
-
*
|
|
4
|
-
* wiring shared by the server bundle and the `start` launcher.
|
|
2
|
+
* Registers `handler` for both `SIGINT` and `SIGTERM` — the two signals a process manager or `Ctrl-C` uses to
|
|
3
|
+
* ask for a graceful stop. Shared by the server bundle and the `start` launcher.
|
|
5
4
|
*/
|
|
6
5
|
export declare function onShutdown(handler: (signal: NodeJS.Signals) => void): void;
|
|
7
6
|
//# sourceMappingURL=shutdown.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["../../src/server/shutdown.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["../../src/server/shutdown.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,GAAG,IAAI,CAI1E"}
|
package/dist/server/shutdown.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Registers `handler` for both `SIGINT` and `SIGTERM` — the two signals a process
|
|
3
|
-
*
|
|
4
|
-
* wiring shared by the server bundle and the `start` launcher.
|
|
2
|
+
* Registers `handler` for both `SIGINT` and `SIGTERM` — the two signals a process manager or `Ctrl-C` uses to
|
|
3
|
+
* ask for a graceful stop. Shared by the server bundle and the `start` launcher.
|
|
5
4
|
*/
|
|
6
5
|
export function onShutdown(handler) {
|
|
7
6
|
for (const signal of ['SIGINT', 'SIGTERM']) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../src/server/shutdown.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../src/server/shutdown.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,OAAyC;IAClE,KAAK,MAAM,MAAM,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAU,EAAE,CAAC;QACpD,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC","sourcesContent":["/**\n * Registers `handler` for both `SIGINT` and `SIGTERM` — the two signals a process manager or `Ctrl-C` uses to\n * ask for a graceful stop. Shared by the server bundle and the `start` launcher.\n */\nexport function onShutdown(handler: (signal: NodeJS.Signals) => void): void {\n for (const signal of ['SIGINT', 'SIGTERM'] as const) {\n process.on(signal, () => handler(signal));\n }\n}\n"]}
|