@rsc-kit/core 0.30.22 → 0.30.24
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/dist/clientImports.d.ts +27 -7
- package/dist/clientImports.js +72 -4
- package/dist/clientImports.js.map +1 -1
- package/dist/js/RouteErrorBoundary.d.ts +5 -1
- package/dist/js/RouteErrorBoundary.js +17 -5
- package/dist/js/RouteErrorBoundary.js.map +1 -1
- package/dist/request.d.ts +1 -0
- package/dist/request.js.map +1 -1
- package/dist/served.d.ts +35 -0
- package/dist/served.js +80 -0
- package/dist/served.js.map +1 -0
- package/dist/vite.d.ts +22 -5
- package/dist/vite.js +30 -24
- package/dist/vite.js.map +1 -1
- package/package.json +1 -1
package/dist/served.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run the handler and call onRequest once the response it answers is over.
|
|
3
|
+
*
|
|
4
|
+
* The body is passed through rather than read, so streaming is untouched: each
|
|
5
|
+
* chunk goes out as it is produced. onRequest is never awaited and a throw
|
|
6
|
+
* from it is reported, not raised - a logger that fails must not fail the page.
|
|
7
|
+
*/
|
|
8
|
+
export async function observeServed(request, serve, onRequest, headerNames = []) {
|
|
9
|
+
const started = performance.now();
|
|
10
|
+
let reported = false;
|
|
11
|
+
const report = (status, aborted, error) => {
|
|
12
|
+
if (reported)
|
|
13
|
+
return;
|
|
14
|
+
reported = true;
|
|
15
|
+
const served = {
|
|
16
|
+
method: request.method,
|
|
17
|
+
pathname: new URL(request.url).pathname,
|
|
18
|
+
status,
|
|
19
|
+
durationMs: performance.now() - started,
|
|
20
|
+
aborted,
|
|
21
|
+
headers: pickHeaders(request.headers, headerNames),
|
|
22
|
+
...(error === undefined ? {} : { error }),
|
|
23
|
+
};
|
|
24
|
+
try {
|
|
25
|
+
Promise.resolve(onRequest(served)).catch(failed);
|
|
26
|
+
}
|
|
27
|
+
catch (thrown) {
|
|
28
|
+
failed(thrown);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
let response;
|
|
32
|
+
try {
|
|
33
|
+
response = await serve(request);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
report(500, false, error);
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
if (!response.body) {
|
|
40
|
+
report(response.status, false);
|
|
41
|
+
return response;
|
|
42
|
+
}
|
|
43
|
+
const reader = response.body.getReader();
|
|
44
|
+
const body = new ReadableStream({
|
|
45
|
+
async pull(controller) {
|
|
46
|
+
try {
|
|
47
|
+
const { done, value } = await reader.read();
|
|
48
|
+
if (done) {
|
|
49
|
+
controller.close();
|
|
50
|
+
report(response.status, false);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
controller.enqueue(value);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
controller.error(error);
|
|
58
|
+
report(response.status, false, error);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
cancel(reason) {
|
|
62
|
+
report(response.status, true);
|
|
63
|
+
return reader.cancel(reason);
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
return new Response(body, { status: response.status, statusText: response.statusText, headers: response.headers });
|
|
67
|
+
}
|
|
68
|
+
function pickHeaders(headers, names) {
|
|
69
|
+
const picked = {};
|
|
70
|
+
for (const name of names) {
|
|
71
|
+
const value = headers.get(name);
|
|
72
|
+
if (value !== null)
|
|
73
|
+
picked[name.toLowerCase()] = value;
|
|
74
|
+
}
|
|
75
|
+
return Object.freeze(picked);
|
|
76
|
+
}
|
|
77
|
+
function failed(error) {
|
|
78
|
+
console.error("[rsc-kit] instrumentation.ts onRequest() failed:", error);
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=served.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"served.js","sourceRoot":"","sources":["../src/served.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What instrumentation.ts's onRequest() is told, once a response is over.\n *\n * \"Over\" is the part an app cannot see for itself: a page streams, so the\n * handler has long returned when the last byte leaves, and a visitor who\n * closes the tab mid-stream ends it early. Only the engine holds the body, so\n * only the engine can say which happened, and when.\n */\nexport interface ServedRequest {\n method: string;\n /** The url's path, never its query string: a query carries what people typed. */\n pathname: string;\n status: number;\n /** From the request arriving to the last byte sent, or to the stream ending early. */\n durationMs: number;\n /** The client went away before the body was sent - a closed tab, a navigation elsewhere. */\n aborted: boolean;\n /** The render failed: the handler threw, or the body errored partway. */\n error?: unknown;\n /**\n * Only the headers instrumentation.ts names in `onRequestHeaders`, by\n * lowercase name, and only those the request had. Nothing else is passed:\n * not cookies, not authorization.\n */\n headers: Readonly<Record<string, string>>;\n}\n\nexport type OnRequest = (served: ServedRequest) => unknown;\n\n/**\n * Run the handler and call onRequest once the response it answers is over.\n *\n * The body is passed through rather than read, so streaming is untouched: each\n * chunk goes out as it is produced. onRequest is never awaited and a throw\n * from it is reported, not raised - a logger that fails must not fail the page.\n */\nexport async function observeServed(\n request: Request,\n serve: (request: Request) => Promise<Response>,\n onRequest: OnRequest,\n headerNames: readonly string[] = [],\n): Promise<Response> {\n const started = performance.now();\n let reported = false;\n\n const report = (status: number, aborted: boolean, error?: unknown) => {\n if (reported) return;\n reported = true;\n\n const served: ServedRequest = {\n method: request.method,\n pathname: new URL(request.url).pathname,\n status,\n durationMs: performance.now() - started,\n aborted,\n headers: pickHeaders(request.headers, headerNames),\n ...(error === undefined ? {} : { error }),\n };\n\n try {\n Promise.resolve(onRequest(served)).catch(failed);\n } catch (thrown) {\n failed(thrown);\n }\n };\n\n let response: Response;\n\n try {\n response = await serve(request);\n } catch (error) {\n report(500, false, error);\n throw error;\n }\n\n if (!response.body) {\n report(response.status, false);\n return response;\n }\n\n const reader = response.body.getReader();\n const body = new ReadableStream<Uint8Array>({\n async pull(controller) {\n try {\n const { done, value } = await reader.read();\n\n if (done) {\n controller.close();\n report(response.status, false);\n } else {\n controller.enqueue(value);\n }\n } catch (error) {\n controller.error(error);\n report(response.status, false, error);\n }\n },\n cancel(reason) {\n report(response.status, true);\n return reader.cancel(reason);\n },\n });\n\n return new Response(body, { status: response.status, statusText: response.statusText, headers: response.headers });\n}\n\nfunction pickHeaders(headers: Headers, names: readonly string[]): Readonly<Record<string, string>> {\n const picked: Record<string, string> = {};\n\n for (const name of names) {\n const value = headers.get(name);\n if (value !== null) picked[name.toLowerCase()] = value;\n }\n\n return Object.freeze(picked);\n}\n\nfunction failed(error: unknown): void {\n console.error(\"[rsc-kit] instrumentation.ts onRequest() failed:\", error);\n}\n"]}
|
package/dist/vite.d.ts
CHANGED
|
@@ -465,6 +465,26 @@ export declare function compileStep(root: string): {
|
|
|
465
465
|
compile?: string;
|
|
466
466
|
binary?: string;
|
|
467
467
|
};
|
|
468
|
+
/**
|
|
469
|
+
* The app's process bootstrap, if it has one: `instrumentation.ts` beside
|
|
470
|
+
* `app/`, the name Next uses so a reader arriving from there knows what it
|
|
471
|
+
* is.
|
|
472
|
+
*
|
|
473
|
+
* Two things make it a framework concern rather than an import the app
|
|
474
|
+
* adds. Module evaluation order: a page that configures a shared package at
|
|
475
|
+
* import time runs before any module the app could put first, and only the
|
|
476
|
+
* generated entry can import something before the pages. And "before the
|
|
477
|
+
* first request": an async `register()` — connecting, validating env — has
|
|
478
|
+
* to be awaited by every entry point a host or a prerender can call, which
|
|
479
|
+
* is a list the app cannot see.
|
|
480
|
+
*/
|
|
481
|
+
type InstrumentationFile = {
|
|
482
|
+
file: string;
|
|
483
|
+
hasRegister: boolean;
|
|
484
|
+
hasShutdown: boolean;
|
|
485
|
+
hasOnRequest?: boolean;
|
|
486
|
+
hasOnRequestHeaders?: boolean;
|
|
487
|
+
};
|
|
468
488
|
/**
|
|
469
489
|
* How the generated entry imports instrumentation.ts, as `__instrumentation`.
|
|
470
490
|
*
|
|
@@ -474,11 +494,7 @@ export declare function compileStep(root: string): {
|
|
|
474
494
|
* "Import `shutdown` will always be undefined") - the app told off for a file
|
|
475
495
|
* written exactly as documented. The rest are simply absent from the object.
|
|
476
496
|
*/
|
|
477
|
-
export declare function instrumentationImport(instrumentation:
|
|
478
|
-
file: string;
|
|
479
|
-
hasRegister: boolean;
|
|
480
|
-
hasShutdown: boolean;
|
|
481
|
-
} | null): string;
|
|
497
|
+
export declare function instrumentationImport(instrumentation: InstrumentationFile | null): string;
|
|
482
498
|
/**
|
|
483
499
|
* The worker the dev server serves at /sw.js: it removes the one a production
|
|
484
500
|
* run left on this origin, and the caches with it, then reloads each page it
|
|
@@ -576,3 +592,4 @@ export declare function publicVariablesSet(mode: string, envDir?: string | false
|
|
|
576
592
|
where: string;
|
|
577
593
|
}[];
|
|
578
594
|
export declare function rscKit(options?: RscKitOptions): PluginOption[];
|
|
595
|
+
export {};
|
package/dist/vite.js
CHANGED
|
@@ -1907,18 +1907,17 @@ async function prerenderAfterBundles(bundle, staticDir, assetsDir, knownActions
|
|
|
1907
1907
|
console.log(" React's cache() dedupes only inside a component render; in a guard, an action or\n" +
|
|
1908
1908
|
" an api route it calls straight through. Import it from @rsc-kit/core/cache instead.");
|
|
1909
1909
|
}
|
|
1910
|
-
// Server files
|
|
1911
|
-
//
|
|
1912
|
-
//
|
|
1913
|
-
// library's internals run on the server. Said, with the packages and the
|
|
1914
|
-
// importer, so the person reading can tell which it is.
|
|
1910
|
+
// Server files whose code, or a library's under them, reaches a hook on the
|
|
1911
|
+
// server (clientImports.ts). The render that calls one fails naming React,
|
|
1912
|
+
// not the file; this names the file, the package and the hook.
|
|
1915
1913
|
if (clientLibraryImports.length > 0) {
|
|
1916
|
-
console.log(`\n \u2139 ${clientLibraryImports.length} server ${clientLibraryImports.length === 1 ? "file
|
|
1914
|
+
console.log(`\n \u2139 ${clientLibraryImports.length} server ${clientLibraryImports.length === 1 ? "file reaches" : "files reach"} client-only React: ` +
|
|
1917
1915
|
clientLibraryImports
|
|
1918
|
-
.map((c) => `${c.file} (${c.packages.join(", ")}${c.from ? `; imported by ${c.from}` : ""})`)
|
|
1916
|
+
.map((c) => `${c.file} (${c.packages.length > 0 ? `${c.packages.join(", ")}: ` : ""}${c.calls.join(", ")}${c.from ? `; imported by ${c.from}` : ""})`)
|
|
1919
1917
|
.join("; "));
|
|
1920
|
-
console.log('
|
|
1921
|
-
|
|
1918
|
+
console.log(' The server has none of these, so a render that calls one fails with "... is not a function".\n' +
|
|
1919
|
+
' A file that only wraps client components wants "use client" - as shadcn ships it. A library\n' +
|
|
1920
|
+
" export holding a hook the page never renders is fine.");
|
|
1922
1921
|
}
|
|
1923
1922
|
// Written from the rows that were just printed rather than recomputed: the
|
|
1924
1923
|
// report and the terminal must not be able to disagree about what happened.
|
|
@@ -3121,19 +3120,6 @@ function installHostCallsOnce(): void {
|
|
|
3121
3120
|
}
|
|
3122
3121
|
|
|
3123
3122
|
`;
|
|
3124
|
-
/**
|
|
3125
|
-
* The app's process bootstrap, if it has one: `instrumentation.ts` beside
|
|
3126
|
-
* `app/`, the name Next uses so a reader arriving from there knows what it
|
|
3127
|
-
* is.
|
|
3128
|
-
*
|
|
3129
|
-
* Two things make it a framework concern rather than an import the app
|
|
3130
|
-
* adds. Module evaluation order: a page that configures a shared package at
|
|
3131
|
-
* import time runs before any module the app could put first, and only the
|
|
3132
|
-
* generated entry can import something before the pages. And "before the
|
|
3133
|
-
* first request": an async `register()` — connecting, validating env — has
|
|
3134
|
-
* to be awaited by every entry point a host or a prerender can call, which
|
|
3135
|
-
* is a list the app cannot see.
|
|
3136
|
-
*/
|
|
3137
3123
|
function instrumentationFile() {
|
|
3138
3124
|
for (const ext of ["ts", "tsx", "mts", "js", "mjs"]) {
|
|
3139
3125
|
const file = join(sourceDir, `instrumentation.${ext}`);
|
|
@@ -3146,7 +3132,13 @@ function instrumentationFile() {
|
|
|
3146
3132
|
// a file written exactly as documented.
|
|
3147
3133
|
const source = readFileSync(file, "utf-8");
|
|
3148
3134
|
const exports = (name) => new RegExp(`export\\s+(?:async\\s+)?(?:function\\s+${name}\\b|const\\s+${name}\\b|let\\s+${name}\\b|\\{[^}]*\\b${name}\\b[^}]*\\})`).test(source);
|
|
3149
|
-
return {
|
|
3135
|
+
return {
|
|
3136
|
+
file,
|
|
3137
|
+
hasRegister: exports("register"),
|
|
3138
|
+
hasShutdown: exports("shutdown"),
|
|
3139
|
+
hasOnRequest: exports("onRequest"),
|
|
3140
|
+
hasOnRequestHeaders: exports("onRequestHeaders"),
|
|
3141
|
+
};
|
|
3150
3142
|
}
|
|
3151
3143
|
return null;
|
|
3152
3144
|
}
|
|
@@ -3160,12 +3152,14 @@ function instrumentationFile() {
|
|
|
3160
3152
|
* written exactly as documented. The rest are simply absent from the object.
|
|
3161
3153
|
*/
|
|
3162
3154
|
export function instrumentationImport(instrumentation) {
|
|
3163
|
-
const type = "{ register?: () => unknown; shutdown?: () => unknown }";
|
|
3155
|
+
const type = "{ register?: () => unknown; shutdown?: () => unknown; onRequest?: (served: never) => unknown; onRequestHeaders?: readonly string[] }";
|
|
3164
3156
|
if (!instrumentation)
|
|
3165
3157
|
return `const __instrumentation: ${type} = {}`;
|
|
3166
3158
|
const hooks = [
|
|
3167
3159
|
...(instrumentation.hasRegister ? ["register"] : []),
|
|
3168
3160
|
...(instrumentation.hasShutdown ? ["shutdown"] : []),
|
|
3161
|
+
...(instrumentation.hasOnRequest ? ["onRequest"] : []),
|
|
3162
|
+
...(instrumentation.hasOnRequestHeaders ? ["onRequestHeaders"] : []),
|
|
3169
3163
|
];
|
|
3170
3164
|
const from = JSON.stringify(instrumentation.file);
|
|
3171
3165
|
// No hooks: still imported, first, for what its import does.
|
|
@@ -3270,6 +3264,7 @@ import { httpHostCalls } from ${JSON.stringify(join(packageDir, "hostCalls"))}
|
|
|
3270
3264
|
import { backendVersions, installBackendVersionSource } from ${JSON.stringify(join(packageDir, "changed"))}
|
|
3271
3265
|
import { RefreshOn } from ${JSON.stringify(join(packageDir, "js/refreshOn"))}
|
|
3272
3266
|
import { prerenderedBeside } from ${JSON.stringify(join(packageDir, "files"))}
|
|
3267
|
+
import { observeServed } from ${JSON.stringify(join(packageDir, "served"))}
|
|
3273
3268
|
import { renderToReadableStream, decodeReply, decodeAction, decodeFormState, loadServerAction } from '@vitejs/plugin-rsc/rsc'
|
|
3274
3269
|
import { isQuery, queryCacheControl, isQueryValidationError, queryRefusal } from ${JSON.stringify(join(packageDir, "query"))}
|
|
3275
3270
|
import { isActionValidationError, isActionRefusal, isClientBuilt } from ${JSON.stringify(join(packageDir, "action"))}
|
|
@@ -5936,6 +5931,16 @@ ${backendPathConsts()}${fallbackOrigin === false ? "" : FALLBACK_CONSTS.replace(
|
|
|
5936
5931
|
let devHandler: ((request: Request) => Promise<Response | null>) | null = null
|
|
5937
5932
|
|
|
5938
5933
|
export default async function handler(request: Request): Promise<Response> {
|
|
5934
|
+
// instrumentation.ts's onRequest(), once each response is over - streamed to
|
|
5935
|
+
// the end, or cut off. Not for the startup probe: no visitor asked for it.
|
|
5936
|
+
if (__instrumentation.onRequest && request.headers.get('x-rsc-kit-startup') === null) {
|
|
5937
|
+
return observeServed(request, served, __instrumentation.onRequest as never, __instrumentation.onRequestHeaders)
|
|
5938
|
+
}
|
|
5939
|
+
|
|
5940
|
+
return served(request)
|
|
5941
|
+
}
|
|
5942
|
+
|
|
5943
|
+
async function served(request: Request): Promise<Response> {
|
|
5939
5944
|
try {
|
|
5940
5945
|
return await serve(request)
|
|
5941
5946
|
} catch (error) {
|
|
@@ -7122,6 +7127,7 @@ function clientImportsAudit() {
|
|
|
7122
7127
|
moduleIds: () => this.getModuleIds(),
|
|
7123
7128
|
importedIds: (id) => this.getModuleInfo(id)?.importedIds ?? [],
|
|
7124
7129
|
importers: (id) => this.getModuleInfo(id)?.importers ?? [],
|
|
7130
|
+
code: (id) => this.getModuleInfo(id)?.code ?? null,
|
|
7125
7131
|
}, {
|
|
7126
7132
|
sourceDir,
|
|
7127
7133
|
clientPackages,
|