@rsc-kit/core 0.30.27 → 0.30.29
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/edgeShells.d.ts +52 -0
- package/dist/edgeShells.js +98 -0
- package/dist/edgeShells.js.map +1 -0
- package/dist/headers.d.ts +17 -4
- package/dist/headers.js +17 -4
- package/dist/headers.js.map +1 -1
- package/dist/host.js +161 -84
- package/dist/host.js.map +1 -1
- package/dist/vite.d.ts +15 -0
- package/dist/vite.js +63 -2
- package/dist/vite.js.map +1 -1
- package/package.json +1 -1
package/dist/vite.d.ts
CHANGED
|
@@ -421,6 +421,21 @@ export declare function bootsTheApp(file: string): boolean;
|
|
|
421
421
|
* that changes what the worker holds is a new worker.
|
|
422
422
|
*/
|
|
423
423
|
export declare function workerVersion(precache: string[], storedDir: string | null): string;
|
|
424
|
+
/**
|
|
425
|
+
* The PPR contract's build: what an edge checks a cached shell against.
|
|
426
|
+
*
|
|
427
|
+
* Not the client's build id, which is what a browser tab is told and covers
|
|
428
|
+
* only what the browser downloads - a release that changed only what the
|
|
429
|
+
* server renders kept it, and an edge holding the old shell would have joined
|
|
430
|
+
* it to the new server's holes. So it is that id and the bytes of every shell
|
|
431
|
+
* and its postponed state. A server change that reaches a shell is a new
|
|
432
|
+
* build to the edge; one that leaves them all byte for byte the same is not,
|
|
433
|
+
* because the shell the edge holds is then this build's. A tab is not made to
|
|
434
|
+
* reload for either.
|
|
435
|
+
*/
|
|
436
|
+
export declare function pprBuildId(clientBuild: string, storedDir: string): string;
|
|
437
|
+
/** Where the host reads the PPR build back, beside the shells it describes. */
|
|
438
|
+
export declare const PPR_BUILD_FILE = "_ppr.build";
|
|
424
439
|
export declare function smallStylesheetReader(assetsDir: string, setting: "auto" | true | number): (href: string) => string | null;
|
|
425
440
|
/** A server action the bundle registered: where it is and what it is called. */
|
|
426
441
|
export interface KnownAction {
|
package/dist/vite.js
CHANGED
|
@@ -23,6 +23,7 @@ import rsc, { getPluginApi } from "@vitejs/plugin-rsc";
|
|
|
23
23
|
import { loadEnv, parseAst } from "vite";
|
|
24
24
|
import { stampDisplayNames } from "./stableNames.js";
|
|
25
25
|
import { REPORT_FILE, buildReport } from "./buildReport.js";
|
|
26
|
+
import { edgeShells, pprMarker } from "./edgeShells.js";
|
|
26
27
|
import { MANIFEST_PATH, manifestWarning, webManifest } from "./webManifest.js";
|
|
27
28
|
import { ASSET_BASE, allAppAssets, assetFile, appAssets, headTags, shareImageUrls, typeOf, } from "./appAssets.js";
|
|
28
29
|
import { reactCacheImports } from "./reactCache.js";
|
|
@@ -1607,6 +1608,41 @@ export function workerVersion(precache, storedDir) {
|
|
|
1607
1608
|
}
|
|
1608
1609
|
return version.digest("hex").slice(0, 12);
|
|
1609
1610
|
}
|
|
1611
|
+
/**
|
|
1612
|
+
* The PPR contract's build: what an edge checks a cached shell against.
|
|
1613
|
+
*
|
|
1614
|
+
* Not the client's build id, which is what a browser tab is told and covers
|
|
1615
|
+
* only what the browser downloads - a release that changed only what the
|
|
1616
|
+
* server renders kept it, and an edge holding the old shell would have joined
|
|
1617
|
+
* it to the new server's holes. So it is that id and the bytes of every shell
|
|
1618
|
+
* and its postponed state. A server change that reaches a shell is a new
|
|
1619
|
+
* build to the edge; one that leaves them all byte for byte the same is not,
|
|
1620
|
+
* because the shell the edge holds is then this build's. A tab is not made to
|
|
1621
|
+
* reload for either.
|
|
1622
|
+
*/
|
|
1623
|
+
export function pprBuildId(clientBuild, storedDir) {
|
|
1624
|
+
const id = createHash("sha256");
|
|
1625
|
+
id.update(clientBuild);
|
|
1626
|
+
const shells = [];
|
|
1627
|
+
const walk = (dir) => {
|
|
1628
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
1629
|
+
const path = join(dir, entry.name);
|
|
1630
|
+
if (entry.isDirectory())
|
|
1631
|
+
walk(path);
|
|
1632
|
+
else if (/\.(?:ppr\.html|postponed\.json)$/.test(entry.name))
|
|
1633
|
+
shells.push(path);
|
|
1634
|
+
}
|
|
1635
|
+
};
|
|
1636
|
+
if (existsSync(storedDir))
|
|
1637
|
+
walk(storedDir);
|
|
1638
|
+
for (const path of shells.sort()) {
|
|
1639
|
+
id.update("\n" + relative(storedDir, path) + "\n");
|
|
1640
|
+
id.update(readFileSync(path));
|
|
1641
|
+
}
|
|
1642
|
+
return id.digest("hex").slice(0, 16);
|
|
1643
|
+
}
|
|
1644
|
+
/** Where the host reads the PPR build back, beside the shells it describes. */
|
|
1645
|
+
export const PPR_BUILD_FILE = "_ppr.build";
|
|
1610
1646
|
function writeServiceWorker(clientDir, frozen = [], offlineUrl = null,
|
|
1611
1647
|
// The pages the build stored, which the worker serves cache-first. Their
|
|
1612
1648
|
// bytes are part of what a version is - see below.
|
|
@@ -1764,6 +1800,7 @@ async function prerenderAfterBundles(bundle, staticDir, assetsDir, knownActions
|
|
|
1764
1800
|
const collected = [];
|
|
1765
1801
|
let refusal = null;
|
|
1766
1802
|
let results;
|
|
1803
|
+
const build = await engine.buildId?.();
|
|
1767
1804
|
try {
|
|
1768
1805
|
results = await prerender({
|
|
1769
1806
|
engine,
|
|
@@ -1774,7 +1811,7 @@ async function prerenderAfterBundles(bundle, staticDir, assetsDir, knownActions
|
|
|
1774
1811
|
// them, and replayed against a different bundle React finds the
|
|
1775
1812
|
// wrong name in every slot. Unstamped - which is what every build
|
|
1776
1813
|
// before this one wrote - the host cannot tell and resumes anyway.
|
|
1777
|
-
version:
|
|
1814
|
+
version: build,
|
|
1778
1815
|
serviceWorker: offline,
|
|
1779
1816
|
stylesheet: inlineStylesheets === false
|
|
1780
1817
|
? undefined
|
|
@@ -1972,6 +2009,8 @@ ${legend(counted)}
|
|
|
1972
2009
|
.filter((r) => existsSync(join(staticDir, pathKeyOf(r.url) + ".html")))
|
|
1973
2010
|
.map((r) => r.url),
|
|
1974
2011
|
results,
|
|
2012
|
+
shells: edgeShells(results, manifest.routes),
|
|
2013
|
+
build,
|
|
1975
2014
|
};
|
|
1976
2015
|
}
|
|
1977
2016
|
/**
|
|
@@ -8073,7 +8112,12 @@ export function rscKit(options = {}) {
|
|
|
8073
8112
|
const staticDir = clientOut
|
|
8074
8113
|
? join(dirname(clientOut), "server", NITRO_STATIC_DIR)
|
|
8075
8114
|
: join(outDir, NITRO_STATIC_DIR);
|
|
8076
|
-
const { frozen, results } = await prerenderAfterBundles(bundle, staticDir, clientOut ?? publicAssetsDir, builder ? knownActionsOf(builder.config, projectRoot) : []);
|
|
8115
|
+
const { frozen, results, shells, build: clientBuild } = await prerenderAfterBundles(bundle, staticDir, clientOut ?? publicAssetsDir, builder ? knownActionsOf(builder.config, projectRoot) : []);
|
|
8116
|
+
// Before the pages are packed into a module or the assets, so the host
|
|
8117
|
+
// finds it wherever it reads the shells from.
|
|
8118
|
+
const build = clientBuild ? pprBuildId(clientBuild, staticDir) : undefined;
|
|
8119
|
+
if (build && existsSync(staticDir))
|
|
8120
|
+
writeFileSync(join(staticDir, PPR_BUILD_FILE), build);
|
|
8077
8121
|
// The same pages once more, as a module. A Worker has no filesystem, and
|
|
8078
8122
|
// until this existed every Cloudflare deploy rendered its "static" pages
|
|
8079
8123
|
// live, silently - the reader found no directory and fell through. The
|
|
@@ -8109,6 +8153,9 @@ export function rscKit(options = {}) {
|
|
|
8109
8153
|
// after the prerender, and an export taken any earlier left them out.
|
|
8110
8154
|
if (output === "export")
|
|
8111
8155
|
await exportAfterPrerender(results, staticDir, clientOut ?? publicAssetsDir);
|
|
8156
|
+
if (shells.left.length) {
|
|
8157
|
+
log(`ppr: not listed for an edge in ppr.json, so served by the origin: ${shells.left.join("; ")}`);
|
|
8158
|
+
}
|
|
8112
8159
|
// What this build produced, where a deploy can read it without parsing
|
|
8113
8160
|
// vite.config.ts - which can turn export on through RSC_OUTPUT, or
|
|
8114
8161
|
// compute it - or knowing where rsc-kit keeps things inside .output.
|
|
@@ -8122,6 +8169,20 @@ export function rscKit(options = {}) {
|
|
|
8122
8169
|
...compileStep(projectRoot),
|
|
8123
8170
|
...(buildCommands().length ? { commands: buildCommands().map((c) => c.name) } : {}),
|
|
8124
8171
|
}, null, 2) + "\n");
|
|
8172
|
+
// The PPR contract's marker: the pages an edge may answer from a
|
|
8173
|
+
// cached shell, and the build both endpoints will say they belong to.
|
|
8174
|
+
// Written by every server build, with an empty list when there is no
|
|
8175
|
+
// PPR page, so a platform can tell "none" from "an rsc-kit too old to
|
|
8176
|
+
// say". Not by an export, which has no origin to resume against.
|
|
8177
|
+
const marker = join(dirname(clientOut), "ppr.json");
|
|
8178
|
+
if (output !== "export" && build) {
|
|
8179
|
+
writeFileSync(marker, JSON.stringify(pprMarker(build, shells.shells), null, 2) + "\n");
|
|
8180
|
+
}
|
|
8181
|
+
else {
|
|
8182
|
+
// One left by an earlier server build would promise an origin that
|
|
8183
|
+
// is not there.
|
|
8184
|
+
rmSync(marker, { force: true });
|
|
8185
|
+
}
|
|
8125
8186
|
}
|
|
8126
8187
|
},
|
|
8127
8188
|
configResolved(config) {
|