Repository navigation
Description
Summary
When MessageProcessor.applyComponentUpdate processes a v1.0 component carrying metadata: { extensions: { ... } }, it stores metadata on ComponentModel.metadata (typescript/core/web_core/src/state/component-model.ts line 45).
However, when NodeResolver builds the reactive ComponentNode tree (typescript/core/web_core/src/resolution/component-node.ts and node-resolver.ts):
ComponentNode(MutableComponentNode) has nometadataproperty or getter.ComponentNode.toJSON()(lines 213–226 ofcomponent-node.ts) serializes{ id, type, ...props }and completely omitsmetadata(unlikeComponentModel.componentTree, which includes...(this.metadata !== undefined ? {metadata: this.metadata} : {})).- When
ComponentModel.metadatais updated on an existing component (existing.metadata = metadata; existing.properties = properties;atmessage-processor.tslines 1059–1060), ifpropertiesare shallow-equal (setPropsincomponent-node.tsline 238),node.propsdoes not emit and React views subscribed viauseNodeViewin@a2ui/reactdo not re-render on a metadata-only update.
Affected Component / Files
- Repository commit:
e9dbcc3(main) and npm packages@a2ui/[email protected],@a2ui/[email protected] - File path(s):
typescript/core/web_core/src/resolution/component-node.ts(lines 50–119, 213–241)typescript/core/web_core/src/resolution/node-resolver.ts(lines 380–450)typescript/renderers/react/src/node-view.tsx(lines 207–266)
Steps to Reproduce / Evidence
import { MessageProcessor, NodeResolver, basicCatalog } from '@a2ui/web_core/v1_0';
const processor = new MessageProcessor([basicCatalog], undefined, { version: 'v1.0' });
processor.processMessages([
{
version: 'v1.0',
createSurface: {
surfaceId: 's1',
catalogId: basicCatalog.id,
components: [
{
id: 'root',
component: 'Text',
text: 'Hello',
metadata: {
extensions: {
custom_theme: { variant: 'dark' },
},
},
},
],
},
},
]);
const surface = processor.model.getSurface('s1');
const resolver = new NodeResolver(surface);
const rootNode = resolver.rootNode.peek();
console.log('ComponentModel.componentTree:', surface.componentsModel.get('root').componentTree);
// Includes: metadata: { extensions: { custom_theme: { variant: 'dark' } } }
console.log('ComponentNode.toJSON():', rootNode.toJSON());
// Actual output: { id: 'root', type: 'Text', text: 'Hello', variant: 'body' }
// `metadata` is completely missing from ComponentNode and rootNode.toJSON()!Expected Behavior
ComponentNodeshould exposemetadata(or reactivemetadatasignal/property fromcontext?.componentModel.metadata) and includemetadatainComponentNode.toJSON()when defined.- Updating a component's
metadata.extensionsviaupdateComponentsshould notifyNodeResolver/useNodeViewsubscribers even when component schema properties (text,variant, etc.) are unchanged.
Actual Behavior
ComponentNode omits metadata from its interface and toJSON(), and metadata-only updateComponents payloads do not trigger node.props updates when schema properties are unchanged.
Suggested Fix
Expose readonly metadata?: Record<string, unknown> on ComponentNode (backed by this.context?.componentModel.metadata), include metadata in MutableComponentNode.toJSON() when defined, and include metadata in NodeResolver's change detection when ComponentModel.onUpdated fires.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsIn Progress
Activity
josemontespg commentedon Oct 23, 2026
Confirmed on
main.ComponentNode(typescript/core/web_core/src/resolution/component-node.ts) currently omitsmetadatafrom the resolved node interface andtoJSON(), andMutableComponentNodeonly checksshallowEqualonpropsso metadata-only updates do not notify subscribers. Closing this issue for now as a minor (P2) improvement since we do not have the capacity to prioritize it around the v1.0 launch.feat(metadata): implement v1.0 extension metadata APIs across SDKs
feat(metadata): implement v1.0 extension metadata APIs across SDKs
feat(metadata): implement v1.0 extension metadata APIs across SDKs (#…