@@ -115,6 +115,13 @@ class DataContext {
115115/// Manages the application's Object? data model and provides
116116/// a subscription-based mechanism for reactive UI updates.
117117class DataModel {
118+ static const _a2uiValueKeys = [
119+ 'valueString' ,
120+ 'valueNumber' ,
121+ 'valueBoolean' ,
122+ 'valueMap' ,
123+ ];
124+
118125 JsonMap _data = {};
119126 final Map <DataPath , ValueNotifier <Object ?>> _subscriptions = {};
120127 final Map <DataPath , ValueNotifier <Object ?>> _valueSubscriptions = {};
@@ -129,13 +136,20 @@ class DataModel {
129136 'DataModel.update: path=$absolutePath , contents='
130137 '${const JsonEncoder .withIndent (' ' ).convert (contents )}' ,
131138 );
132- final Object ? parsedContents = contents is List
139+ final bool isAdjacencyList = contents is List && _isAdjacencyList (contents);
140+ final Object ? parsedContents = isAdjacencyList
133141 ? _parseDataModelContents (contents)
134142 : contents;
135143
136144 if (absolutePath == null || absolutePath.segments.isEmpty) {
137- if (contents is List ) {
145+ if (parsedContents is Map ) {
138146 _data = parsedContents as Map <String , Object ?>;
147+ } else if (parsedContents is List ) {
148+ genUiLogger.warning (
149+ 'DataModel.update: literal list cannot be used as '
150+ 'root data model: $contents ' ,
151+ );
152+ _data = < String , Object ? > {};
139153 } else if (contents is Map ) {
140154 // Permissive: Allow a map to be sent for the root, even though the
141155 // schema expects a list.
@@ -188,6 +202,18 @@ class DataModel {
188202 return notifier;
189203 }
190204
205+ /// Determines if the given contents are likely an A2UI adjacency list.
206+ bool _isAdjacencyList (List <Object ?> contents) {
207+ if (contents.isEmpty) return false ;
208+ for (final item in contents) {
209+ if (item is ! Map ) return false ;
210+ if (! item.containsKey ('key' )) return false ;
211+
212+ if (! _a2uiValueKeys.any (item.containsKey)) return false ;
213+ }
214+ return true ;
215+ }
216+
191217 /// Retrieves a static, one-time value from the data model at the
192218 /// specified absolute path without creating a subscription.
193219 T ? getValue <T >(DataPath absolutePath) {
@@ -211,13 +237,7 @@ class DataModel {
211237 Object ? value;
212238 var valueCount = 0 ;
213239
214- const valueKeys = [
215- 'valueString' ,
216- 'valueNumber' ,
217- 'valueBoolean' ,
218- 'valueMap' ,
219- ];
220- for (final valueKey in valueKeys) {
240+ for (final String valueKey in _a2uiValueKeys) {
221241 if (item.containsKey (valueKey)) {
222242 if (valueCount == 0 ) {
223243 if (valueKey == 'valueMap' ) {
0 commit comments