mnfst-render 0.4.4 → 0.4.6
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 +42 -0
- package/package.json +1 -1
package/manifest.render.mjs
CHANGED
|
@@ -2153,6 +2153,48 @@ async function runPrerender(config) {
|
|
|
2153
2153
|
pushDebug({ path: displayPath, stage: 'post-xfor-mark', metrics: afterMark });
|
|
2154
2154
|
}
|
|
2155
2155
|
|
|
2156
|
+
// For static x-for clones that contain data-hydrate elements, inject the loop-scope
|
|
2157
|
+
// variable as x-data on the clone element itself. This ensures that after the loop
|
|
2158
|
+
// template is removed, data-hydrate bindings referencing loop variables (e.g.
|
|
2159
|
+
// plan?.price?.[currency]?.[frequency]) continue to work at runtime via the injected scope.
|
|
2160
|
+
// The parent Alpine scope (e.g. <main x-data="{ currency, frequency }") remains accessible.
|
|
2161
|
+
await page.evaluate(() => {
|
|
2162
|
+
const loopVarRx = /^\s*(?:\(\s*([A-Za-z_$][\w$]*)(?:\s*,\s*([A-Za-z_$][\w$]*))?\s*\)|([A-Za-z_$][\w$]*))\s+in\s+/;
|
|
2163
|
+
document.querySelectorAll('template[x-for][data-prerender-static-generated="1"]').forEach((tpl) => {
|
|
2164
|
+
if (tpl.hasAttribute('data-prerender-hydrate') || tpl.closest('[data-prerender-hydrate]')) return;
|
|
2165
|
+
const xFor = (tpl.getAttribute('x-for') || '').trim();
|
|
2166
|
+
const m = xFor.match(loopVarRx);
|
|
2167
|
+
const itemVar = m ? (m[1] || m[3] || '') : '';
|
|
2168
|
+
if (!itemVar) return;
|
|
2169
|
+
const first = tpl.content && tpl.content.firstElementChild;
|
|
2170
|
+
if (!first) return;
|
|
2171
|
+
const tag = first.tagName;
|
|
2172
|
+
const cls = first.getAttribute('class') || '';
|
|
2173
|
+
let n = tpl.nextElementSibling;
|
|
2174
|
+
while (n && n.tagName === tag && (n.getAttribute('class') || '') === cls) {
|
|
2175
|
+
// Only process clones that contain data-hydrate descendants
|
|
2176
|
+
if (
|
|
2177
|
+
!n.hasAttribute('x-data') &&
|
|
2178
|
+
(n.hasAttribute('data-prerender-hydrate') || n.querySelector('[data-prerender-hydrate]'))
|
|
2179
|
+
) {
|
|
2180
|
+
try {
|
|
2181
|
+
const A = window.Alpine;
|
|
2182
|
+
if (A && typeof A.$data === 'function') {
|
|
2183
|
+
const scope = A.$data(n);
|
|
2184
|
+
if (scope && Object.prototype.hasOwnProperty.call(scope, itemVar)) {
|
|
2185
|
+
const raw = scope[itemVar];
|
|
2186
|
+
// Serialize only own-enumerable properties to avoid circular refs / proxies
|
|
2187
|
+
const snapshot = JSON.parse(JSON.stringify(raw));
|
|
2188
|
+
n.setAttribute('x-data', JSON.stringify({ [itemVar]: snapshot }));
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
} catch { /* serialisation failed — leave binding as-is */ }
|
|
2192
|
+
}
|
|
2193
|
+
n = n.nextElementSibling;
|
|
2194
|
+
}
|
|
2195
|
+
});
|
|
2196
|
+
});
|
|
2197
|
+
|
|
2156
2198
|
// Strip loop-scope bindings from x-for clones while <template> nodes still exist.
|
|
2157
2199
|
// (If we remove static templates first, querySelectorAll('template[x-for]') misses them and clones
|
|
2158
2200
|
// keep x-text/x-bind referencing card/item — Alpine then mutates or errors on the static HTML.)
|