thread node id through toHtml for deterministic+unique export ids
renderNode now passes the Craft node id as toHtml's 3rd argument (props, childrenHtml, nodeId). Backward compatible: the resolver map is untyped (any), so existing 2-arg toHtml implementations/tests are unaffected. Adds scopeId()/stableHash() helpers in utils/escape.ts: scopeId derives a scope string from the node id (deterministic AND unique, since Craft node ids are unique per node and stable across repeated exports of the same page) with a stableHash(seed) fallback for legacy call sites without a node id. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -74,10 +74,19 @@ function renderNode(nodes: Record<string, any>, nodeId: string): { html: string
|
||||
// Build data attributes for responsive visibility and animations
|
||||
const dataAttrs = buildDataAttrs(props);
|
||||
|
||||
// Look up component in resolver and call toHtml
|
||||
// Look up component in resolver and call toHtml. `nodeId` is the Craft.js
|
||||
// node id for this node -- unique per node in the tree and stable across
|
||||
// repeated exports of the same saved page. It's passed as a 3rd argument
|
||||
// so components can derive deterministic AND unique scope ids for their
|
||||
// exported element ids / aria-wiring / inline-script function names
|
||||
// (see `scopeId` in utils/escape.ts) instead of Math.random() (unique but
|
||||
// non-deterministic) or a content hash (deterministic but collides when
|
||||
// two instances share default/identical content). Components that don't
|
||||
// need a scope id simply ignore the extra argument -- backward compatible
|
||||
// with existing 2-arg `toHtml(props, childrenHtml)` implementations/tests.
|
||||
const component = resolver[typeName];
|
||||
if (component && typeof component.toHtml === 'function') {
|
||||
const result = component.toHtml(props, allChildrenHtml);
|
||||
const result = component.toHtml(props, allChildrenHtml, nodeId);
|
||||
const html = result.html || '';
|
||||
return { html: injectAttrs(html, dataAttrs) };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user