mnfst-render 0.5.7 → 0.5.9
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/manifest.render.mjs +55 -25
- package/package.json +1 -1
package/manifest.render.mjs
CHANGED
|
@@ -248,9 +248,9 @@ function resolveConfig() {
|
|
|
248
248
|
debugPrerender: !!cli.debugPrerender,
|
|
249
249
|
// Cap on the manifest:render-ready wait. When the data plugin dispatches
|
|
250
250
|
// the event, we resolve immediately; when it doesn't (most projects), we
|
|
251
|
-
// fall back to the timeout.
|
|
252
|
-
//
|
|
253
|
-
pipelineTimeout:
|
|
251
|
+
// fall back to the timeout. 10s gives slow data plugin pipelines a
|
|
252
|
+
// chance while bounding worst-case per-path overhead.
|
|
253
|
+
pipelineTimeout: 10000,
|
|
254
254
|
};
|
|
255
255
|
}
|
|
256
256
|
|
|
@@ -980,8 +980,13 @@ function markPrerenderedManifestComponents(html) {
|
|
|
980
980
|
// the runtime restoration reinstate the <x-*> tag and the components
|
|
981
981
|
// plugin processes it normally on load.
|
|
982
982
|
if (/\bdata-hydrate\b/i.test(a)) return full;
|
|
983
|
-
|
|
984
|
-
|
|
983
|
+
// CRITICAL: always insert a leading space before the injected attribute.
|
|
984
|
+
// For tags with no existing attributes (e.g. `<x-sidebar>`), `a` is empty
|
|
985
|
+
// and concatenating directly produces `<x-sidebardata-pre-rendered=...>`,
|
|
986
|
+
// which mangles the tag name and prevents the components plugin from
|
|
987
|
+
// recognising it. The trailing-space normalisation on `a` keeps the
|
|
988
|
+
// output tidy when there ARE existing attributes.
|
|
989
|
+
return `<${tag}${a.replace(/\s+$/, '')} data-pre-rendered="1">`;
|
|
985
990
|
});
|
|
986
991
|
}
|
|
987
992
|
|
|
@@ -2028,21 +2033,27 @@ async function runPrerender(config) {
|
|
|
2028
2033
|
timeout: Math.min(timeout, 30000),
|
|
2029
2034
|
});
|
|
2030
2035
|
|
|
2031
|
-
//
|
|
2032
|
-
//
|
|
2033
|
-
//
|
|
2034
|
-
//
|
|
2035
|
-
//
|
|
2036
|
+
// Settle waits. These give Manifest plugins (especially the components
|
|
2037
|
+
// plugin, which lazy-fetches each component HTML over the network) time
|
|
2038
|
+
// to finish loading and expanding everything before we snapshot. Each
|
|
2039
|
+
// wait is bounded; large projects with many components need the full
|
|
2040
|
+
// budget on cold runs, but small projects settle long before the cap.
|
|
2041
|
+
//
|
|
2042
|
+
// Lowered from the original "any wait could hold the prerender for ~50s
|
|
2043
|
+
// per path" defaults, but kept generous enough that Playcom-scale sites
|
|
2044
|
+
// (~10 preloaded components, dozens of lazy components) actually finish
|
|
2045
|
+
// expanding before snapshot. Earlier reductions were too aggressive and
|
|
2046
|
+
// left unexpanded `<x-*>` placeholders in the output.
|
|
2036
2047
|
await Promise.race([
|
|
2037
2048
|
page.evaluate(() => {
|
|
2038
2049
|
return new Promise((resolve) => {
|
|
2039
2050
|
const done = () => resolve();
|
|
2040
|
-
const t = setTimeout(done,
|
|
2051
|
+
const t = setTimeout(done, 3000);
|
|
2041
2052
|
window.addEventListener(
|
|
2042
2053
|
'manifest:routing-ready',
|
|
2043
2054
|
() => {
|
|
2044
2055
|
clearTimeout(t);
|
|
2045
|
-
setTimeout(done,
|
|
2056
|
+
setTimeout(done, 1000);
|
|
2046
2057
|
},
|
|
2047
2058
|
{ once: true }
|
|
2048
2059
|
);
|
|
@@ -2052,12 +2063,13 @@ async function runPrerender(config) {
|
|
|
2052
2063
|
]).catch(() => { });
|
|
2053
2064
|
|
|
2054
2065
|
// Ensure the dynamic loader has injected at least one plugin script.
|
|
2055
|
-
// In practice this happens within ~100ms
|
|
2066
|
+
// In practice this happens within ~100ms but allow up to 3s for cold
|
|
2067
|
+
// CDN cache or slow disk.
|
|
2056
2068
|
await page.evaluate(() => {
|
|
2057
2069
|
return new Promise((resolve) => {
|
|
2058
2070
|
const check = () => document.querySelectorAll('script[src*="manifest"]').length >= 2;
|
|
2059
2071
|
if (check()) return resolve();
|
|
2060
|
-
const deadline = Date.now() +
|
|
2072
|
+
const deadline = Date.now() + 3000;
|
|
2061
2073
|
const t = setInterval(() => {
|
|
2062
2074
|
if (check() || Date.now() >= deadline) {
|
|
2063
2075
|
clearInterval(t);
|
|
@@ -2067,21 +2079,21 @@ async function runPrerender(config) {
|
|
|
2067
2079
|
});
|
|
2068
2080
|
}).catch(() => { });
|
|
2069
2081
|
|
|
2070
|
-
// Network idle:
|
|
2071
|
-
//
|
|
2072
|
-
|
|
2082
|
+
// Network idle: drain pending fetches (component templates, data sources,
|
|
2083
|
+
// markdown files, icon SVGs). Larger projects need the full window;
|
|
2084
|
+
// small ones settle in well under 1 second.
|
|
2085
|
+
await page.waitForNetworkIdle({ idleTime: 1000, timeout: 8000 }).catch(() => { });
|
|
2073
2086
|
|
|
2074
|
-
// DOM stability
|
|
2075
|
-
// already drained pending fetches.
|
|
2087
|
+
// DOM stability after network idle.
|
|
2076
2088
|
await page.evaluate(() => {
|
|
2077
2089
|
return new Promise((resolve) => {
|
|
2078
2090
|
const observer = new MutationObserver(() => {
|
|
2079
2091
|
clearTimeout(stable);
|
|
2080
|
-
stable = setTimeout(finish,
|
|
2092
|
+
stable = setTimeout(finish, 500);
|
|
2081
2093
|
});
|
|
2082
2094
|
observer.observe(document.documentElement, { childList: true, subtree: true, characterData: true });
|
|
2083
2095
|
const finish = () => { observer.disconnect(); resolve(); };
|
|
2084
|
-
let stable = setTimeout(finish,
|
|
2096
|
+
let stable = setTimeout(finish, 500);
|
|
2085
2097
|
});
|
|
2086
2098
|
}).catch(() => { });
|
|
2087
2099
|
|
|
@@ -3030,7 +3042,25 @@ async function runPrerender(config) {
|
|
|
3030
3042
|
|
|
3031
3043
|
}
|
|
3032
3044
|
|
|
3033
|
-
main()
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3045
|
+
// Only run main() when invoked as the CLI entry point — this lets tests
|
|
3046
|
+
// import this module to access internal helpers (e.g.
|
|
3047
|
+
// markPrerenderedManifestComponents) without triggering a full prerender.
|
|
3048
|
+
const isCliEntry = (() => {
|
|
3049
|
+
try {
|
|
3050
|
+
const invoked = process.argv[1] && new URL('file://' + process.argv[1]).href;
|
|
3051
|
+
return invoked === import.meta.url;
|
|
3052
|
+
} catch {
|
|
3053
|
+
return false;
|
|
3054
|
+
}
|
|
3055
|
+
})();
|
|
3056
|
+
|
|
3057
|
+
if (isCliEntry) {
|
|
3058
|
+
main().catch((err) => {
|
|
3059
|
+
console.error('prerender:', err);
|
|
3060
|
+
process.exit(1);
|
|
3061
|
+
});
|
|
3062
|
+
}
|
|
3063
|
+
|
|
3064
|
+
// Exports for unit testing. These are intentionally not part of any public
|
|
3065
|
+
// API — they exist so the e2e harness can directly exercise pure helpers.
|
|
3066
|
+
export { markPrerenderedManifestComponents };
|