@symbo.ls/brender 3.8.1 → 3.8.2
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/package.json +1 -1
- package/render.js +48 -2
package/package.json
CHANGED
package/render.js
CHANGED
|
@@ -543,6 +543,40 @@ const UIKIT_STUBS = {
|
|
|
543
543
|
Text: { tag: 'span' }
|
|
544
544
|
}
|
|
545
545
|
|
|
546
|
+
// ── BR path registry ─────────────────────────────────────────────────────────
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Walks a DOMQL element tree (after mapKeysToElements has set __brKey on each
|
|
550
|
+
* element) and returns a plain object mapping "element path" → "data-br key".
|
|
551
|
+
*
|
|
552
|
+
* The path is a dot-separated chain of element keys from root to leaf:
|
|
553
|
+
* '' (root element itself) → '__root'
|
|
554
|
+
* 'Header' → 'Header'
|
|
555
|
+
* 'Header.Nav' → 'Header.Nav'
|
|
556
|
+
*
|
|
557
|
+
* The registry is serialized into the pre-rendered HTML so the browser can
|
|
558
|
+
* assign the correct brKey to each skeleton element during true hydration.
|
|
559
|
+
*/
|
|
560
|
+
const buildPathRegistry = (element, path = '') => {
|
|
561
|
+
if (!element || !element.__ref) return {}
|
|
562
|
+
const registry = {}
|
|
563
|
+
|
|
564
|
+
const brKey = element.__ref.__brKey
|
|
565
|
+
if (brKey) registry[path === '' ? '__root' : path] = brKey
|
|
566
|
+
|
|
567
|
+
if (element.__ref.__children) {
|
|
568
|
+
for (const childKey of element.__ref.__children) {
|
|
569
|
+
const child = element[childKey]
|
|
570
|
+
if (child && child.__ref) {
|
|
571
|
+
const childPath = path === '' ? childKey : `${path}.${childKey}`
|
|
572
|
+
Object.assign(registry, buildPathRegistry(child, childPath))
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
return registry
|
|
578
|
+
}
|
|
579
|
+
|
|
546
580
|
/**
|
|
547
581
|
* Renders a Symbols/DOMQL project to HTML on the server.
|
|
548
582
|
*
|
|
@@ -740,6 +774,10 @@ export const render = async (data, options = {}) => {
|
|
|
740
774
|
|
|
741
775
|
const registry = mapKeysToElements(element)
|
|
742
776
|
|
|
777
|
+
// Build element path → brKey registry for client-side true hydration.
|
|
778
|
+
// Walks the element tree after mapKeysToElements has set __brKey on each element.
|
|
779
|
+
const brRegistry = buildPathRegistry(element)
|
|
780
|
+
|
|
743
781
|
// Extract metadata for the rendered route
|
|
744
782
|
// Pass the rendered element and its state so function-valued metadata
|
|
745
783
|
// (e.g. detail page titles from fetched data) can be resolved
|
|
@@ -809,7 +847,7 @@ export const render = async (data, options = {}) => {
|
|
|
809
847
|
if (_prevLoc !== undefined) globalThis.location = _prevLoc
|
|
810
848
|
else delete globalThis.location
|
|
811
849
|
|
|
812
|
-
return { html, metadata, registry, element, emotionCSS, document, window, ssrTranslations, prefetchedPages }
|
|
850
|
+
return { html, metadata, registry, brRegistry, element, emotionCSS, document, window, ssrTranslations, prefetchedPages }
|
|
813
851
|
}
|
|
814
852
|
|
|
815
853
|
/**
|
|
@@ -1171,6 +1209,7 @@ export const renderRoute = async (data, options = {}) => {
|
|
|
1171
1209
|
fontLinks: generateFontLinks(ds),
|
|
1172
1210
|
metadata: result.metadata || extractMetadata(data, route),
|
|
1173
1211
|
brKeyCount: result.registry ? Object.keys(result.registry).length : 0,
|
|
1212
|
+
brRegistry: result.brRegistry || {},
|
|
1174
1213
|
ssrTranslations: result.ssrTranslations,
|
|
1175
1214
|
prefetchedState,
|
|
1176
1215
|
activeLang
|
|
@@ -1265,7 +1304,14 @@ export const renderPage = async (data, route = '/', options = {}) => {
|
|
|
1265
1304
|
translationSeed = `<script>try{${seedEntries.join(';')}}catch(e){}</script>\n`
|
|
1266
1305
|
}
|
|
1267
1306
|
}
|
|
1268
|
-
|
|
1307
|
+
// Embed BR registry for true DOM-adoption hydration
|
|
1308
|
+
const brRegistryJson = result.brRegistry && Object.keys(result.brRegistry).length
|
|
1309
|
+
? JSON.stringify(result.brRegistry)
|
|
1310
|
+
: null
|
|
1311
|
+
const brRegistryScript = brRegistryJson
|
|
1312
|
+
? `<script>window.__BR_REGISTRY__=${brRegistryJson}</script>\n`
|
|
1313
|
+
: ''
|
|
1314
|
+
isrBody = `${translationSeed}${brRegistryScript}<script>window.__BRENDER__=true</script>
|
|
1269
1315
|
<script type="module" src="${prefix}${isr.clientScript}"></script>`
|
|
1270
1316
|
} else {
|
|
1271
1317
|
// Legacy swap mode: SPA creates new DOM, MutationObserver removes brender nodes
|