@a2ui/web_core 0.8.0 → 0.9.0

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.
Files changed (436) hide show
  1. package/.tsbuildinfo +1 -0
  2. package/LICENSE +203 -0
  3. package/README.md +50 -4
  4. package/package.json +42 -72
  5. package/{dist/src → src}/v0_8/data/guards.js +13 -13
  6. package/src/v0_8/data/guards.test.d.ts +2 -0
  7. package/src/v0_8/data/guards.test.d.ts.map +1 -0
  8. package/src/v0_8/data/guards.test.js +174 -0
  9. package/src/v0_8/data/guards.test.js.map +1 -0
  10. package/{dist/src → src}/v0_8/data/model-processor.d.ts +1 -1
  11. package/{dist/src → src}/v0_8/data/model-processor.d.ts.map +1 -1
  12. package/{dist/src → src}/v0_8/data/model-processor.js +51 -40
  13. package/src/v0_8/data/model-processor.js.map +1 -0
  14. package/src/v0_8/data/model-processor.test.d.ts +2 -0
  15. package/src/v0_8/data/model-processor.test.d.ts.map +1 -0
  16. package/src/v0_8/data/model-processor.test.js +712 -0
  17. package/src/v0_8/data/model-processor.test.js.map +1 -0
  18. package/src/v0_8/errors.d.ts +35 -0
  19. package/src/v0_8/errors.d.ts.map +1 -0
  20. package/src/v0_8/errors.js +65 -0
  21. package/src/v0_8/errors.js.map +1 -0
  22. package/src/v0_8/events/validation-event.d.ts.map +1 -0
  23. package/{dist/src → src}/v0_8/events/validation-event.js.map +1 -1
  24. package/{dist/src → src}/v0_8/index.d.ts +35 -4
  25. package/{dist/src → src}/v0_8/index.d.ts.map +1 -1
  26. package/src/v0_8/index.js +28 -0
  27. package/src/v0_8/index.js.map +1 -0
  28. package/src/v0_8/schema/common-types.d.ts +1189 -0
  29. package/src/v0_8/schema/common-types.d.ts.map +1 -0
  30. package/src/v0_8/schema/common-types.js +381 -0
  31. package/src/v0_8/schema/common-types.js.map +1 -0
  32. package/src/v0_8/schema/server-to-client.d.ts +17949 -0
  33. package/src/v0_8/schema/server-to-client.d.ts.map +1 -0
  34. package/src/v0_8/schema/server-to-client.js +228 -0
  35. package/src/v0_8/schema/server-to-client.js.map +1 -0
  36. package/src/v0_8/schema/verify-schema.test.d.ts +17 -0
  37. package/src/v0_8/schema/verify-schema.test.d.ts.map +1 -0
  38. package/src/v0_8/schema/verify-schema.test.js +167 -0
  39. package/src/v0_8/schema/verify-schema.test.js.map +1 -0
  40. package/{dist/src → src}/v0_8/schemas/server_to_client.json +1 -1
  41. package/src/v0_8/schemas/server_to_client_with_standard_catalog.json +817 -787
  42. package/{dist/src → src}/v0_8/schemas/standard_catalog_definition.json +26 -0
  43. package/{dist/src → src}/v0_8/styles/behavior.js +13 -13
  44. package/{dist/src → src}/v0_8/styles/border.js +13 -13
  45. package/{dist/src → src}/v0_8/styles/colors.js +13 -13
  46. package/{dist/src → src}/v0_8/styles/colors.js.map +1 -1
  47. package/src/v0_8/styles/icons.d.ts +11 -0
  48. package/{dist/src → src}/v0_8/styles/icons.d.ts.map +1 -1
  49. package/{dist/src → src}/v0_8/styles/icons.js +17 -14
  50. package/{dist/src → src}/v0_8/styles/icons.js.map +1 -1
  51. package/src/v0_8/styles/index.js +35 -0
  52. package/{dist/src → src}/v0_8/styles/layout.js +13 -13
  53. package/{dist/src → src}/v0_8/styles/layout.js.map +1 -1
  54. package/src/v0_8/styles/opacity.js +24 -0
  55. package/src/v0_8/{events/index.ts → styles/shared.js} +3 -4
  56. package/src/v0_8/styles/styles.test.d.ts +2 -0
  57. package/src/v0_8/styles/styles.test.d.ts.map +1 -0
  58. package/src/v0_8/styles/styles.test.js +86 -0
  59. package/src/v0_8/styles/styles.test.js.map +1 -0
  60. package/{dist/src → src}/v0_8/styles/type.js +13 -13
  61. package/{dist/src → src}/v0_8/styles/utils.js +13 -13
  62. package/{dist/src → src}/v0_8/types/client-event.d.ts +10 -8
  63. package/src/v0_8/types/client-event.d.ts.map +1 -0
  64. package/src/v0_8/types/client-event.js +17 -0
  65. package/src/v0_8/types/colors.js +19 -0
  66. package/src/v0_8/types/components.d.ts +41 -0
  67. package/src/v0_8/types/components.d.ts.map +1 -0
  68. package/src/v0_8/types/components.js +17 -0
  69. package/src/v0_8/types/primitives.d.ts +9 -0
  70. package/src/v0_8/types/primitives.d.ts.map +1 -0
  71. package/src/v0_8/types/primitives.js +17 -0
  72. package/{dist/src → src}/v0_8/types/types.d.ts +44 -22
  73. package/src/v0_8/types/types.d.ts.map +1 -0
  74. package/src/v0_8/types/types.js +17 -0
  75. package/src/v0_9/basic_catalog/components/basic_components.d.ts +3359 -0
  76. package/src/v0_9/basic_catalog/components/basic_components.d.ts.map +1 -0
  77. package/src/v0_9/basic_catalog/components/basic_components.js +448 -0
  78. package/src/v0_9/basic_catalog/components/basic_components.js.map +1 -0
  79. package/src/v0_9/basic_catalog/components/basic_components.test.d.ts +2 -0
  80. package/src/v0_9/basic_catalog/components/basic_components.test.d.ts.map +1 -0
  81. package/src/v0_9/basic_catalog/components/basic_components.test.js +46 -0
  82. package/src/v0_9/basic_catalog/components/basic_components.test.js.map +1 -0
  83. package/src/v0_9/basic_catalog/expressions/expression_parser.d.ts +38 -0
  84. package/src/v0_9/basic_catalog/expressions/expression_parser.d.ts.map +1 -0
  85. package/src/v0_9/basic_catalog/expressions/expression_parser.js +294 -0
  86. package/src/v0_9/basic_catalog/expressions/expression_parser.js.map +1 -0
  87. package/src/v0_9/basic_catalog/expressions/expression_parser.test.d.ts +2 -0
  88. package/src/v0_9/basic_catalog/expressions/expression_parser.test.d.ts.map +1 -0
  89. package/src/v0_9/basic_catalog/expressions/expression_parser.test.js +126 -0
  90. package/src/v0_9/basic_catalog/expressions/expression_parser.test.js.map +1 -0
  91. package/src/v0_9/basic_catalog/functions/basic_functions.d.ts +32 -0
  92. package/src/v0_9/basic_catalog/functions/basic_functions.d.ts.map +1 -0
  93. package/src/v0_9/basic_catalog/functions/basic_functions.js +212 -0
  94. package/src/v0_9/basic_catalog/functions/basic_functions.js.map +1 -0
  95. package/src/v0_9/basic_catalog/functions/basic_functions.test.d.ts +2 -0
  96. package/src/v0_9/basic_catalog/functions/basic_functions.test.d.ts.map +1 -0
  97. package/src/v0_9/basic_catalog/functions/basic_functions.test.js +301 -0
  98. package/src/v0_9/basic_catalog/functions/basic_functions.test.js.map +1 -0
  99. package/src/v0_9/basic_catalog/functions/basic_functions_api.d.ts +930 -0
  100. package/src/v0_9/basic_catalog/functions/basic_functions_api.d.ts.map +1 -0
  101. package/src/v0_9/basic_catalog/functions/basic_functions_api.js +466 -0
  102. package/src/v0_9/basic_catalog/functions/basic_functions_api.js.map +1 -0
  103. package/src/v0_9/basic_catalog/index.d.ts +5 -0
  104. package/src/v0_9/basic_catalog/index.d.ts.map +1 -0
  105. package/src/v0_9/basic_catalog/index.js +20 -0
  106. package/src/v0_9/basic_catalog/index.js.map +1 -0
  107. package/src/v0_9/catalog/function_invoker.d.ts +12 -0
  108. package/src/v0_9/catalog/function_invoker.d.ts.map +1 -0
  109. package/src/v0_9/catalog/function_invoker.js +17 -0
  110. package/src/v0_9/catalog/function_invoker.js.map +1 -0
  111. package/src/v0_9/catalog/types.d.ts +80 -0
  112. package/src/v0_9/catalog/types.d.ts.map +1 -0
  113. package/src/v0_9/catalog/types.js +68 -0
  114. package/src/v0_9/catalog/types.js.map +1 -0
  115. package/src/v0_9/catalog/types.test.d.ts +2 -0
  116. package/src/v0_9/catalog/types.test.d.ts.map +1 -0
  117. package/src/v0_9/catalog/types.test.js +88 -0
  118. package/src/v0_9/catalog/types.test.js.map +1 -0
  119. package/src/v0_9/common/events.d.ts +45 -0
  120. package/src/v0_9/common/events.d.ts.map +1 -0
  121. package/src/v0_9/common/events.js +58 -0
  122. package/src/v0_9/common/events.js.map +1 -0
  123. package/src/v0_9/common/events.test.d.ts +2 -0
  124. package/src/v0_9/common/events.test.d.ts.map +1 -0
  125. package/src/v0_9/common/events.test.js +58 -0
  126. package/src/v0_9/common/events.test.js.map +1 -0
  127. package/src/v0_9/errors.d.ts +40 -0
  128. package/src/v0_9/errors.d.ts.map +1 -0
  129. package/src/v0_9/errors.js +69 -0
  130. package/src/v0_9/errors.js.map +1 -0
  131. package/src/v0_9/index.d.ts +152 -0
  132. package/src/v0_9/index.d.ts.map +1 -0
  133. package/src/v0_9/index.js +41 -0
  134. package/src/v0_9/index.js.map +1 -0
  135. package/src/v0_9/processing/message-processor.d.ts +70 -0
  136. package/src/v0_9/processing/message-processor.d.ts.map +1 -0
  137. package/src/v0_9/processing/message-processor.js +289 -0
  138. package/src/v0_9/processing/message-processor.js.map +1 -0
  139. package/src/v0_9/processing/message-processor.test.js +547 -0
  140. package/src/v0_9/processing/message-processor.test.js.map +1 -0
  141. package/src/v0_9/reactivity/signals.d.ts +43 -0
  142. package/src/v0_9/reactivity/signals.d.ts.map +1 -0
  143. package/src/v0_9/reactivity/signals.js +17 -0
  144. package/src/v0_9/reactivity/signals.js.map +1 -0
  145. package/src/v0_9/reactivity/signals.test.d.ts +17 -0
  146. package/src/v0_9/reactivity/signals.test.d.ts.map +1 -0
  147. package/src/v0_9/reactivity/signals.test.js +100 -0
  148. package/src/v0_9/reactivity/signals.test.js.map +1 -0
  149. package/src/v0_9/rendering/component-context.d.ts +35 -0
  150. package/src/v0_9/rendering/component-context.d.ts.map +1 -0
  151. package/src/v0_9/rendering/component-context.js +49 -0
  152. package/src/v0_9/rendering/component-context.js.map +1 -0
  153. package/src/v0_9/rendering/component-context.test.d.ts +2 -0
  154. package/src/v0_9/rendering/component-context.test.d.ts.map +1 -0
  155. package/src/v0_9/rendering/component-context.test.js +55 -0
  156. package/src/v0_9/rendering/component-context.test.js.map +1 -0
  157. package/src/v0_9/rendering/data-context.d.ts +99 -0
  158. package/src/v0_9/rendering/data-context.d.ts.map +1 -0
  159. package/src/v0_9/rendering/data-context.js +310 -0
  160. package/src/v0_9/rendering/data-context.js.map +1 -0
  161. package/src/v0_9/rendering/data-context.test.js +379 -0
  162. package/src/v0_9/rendering/data-context.test.js.map +1 -0
  163. package/src/v0_9/rendering/generic-binder.d.ts +122 -0
  164. package/src/v0_9/rendering/generic-binder.d.ts.map +1 -0
  165. package/src/v0_9/rendering/generic-binder.js +315 -0
  166. package/src/v0_9/rendering/generic-binder.js.map +1 -0
  167. package/src/v0_9/rendering/generic-binder.test.d.ts +2 -0
  168. package/src/v0_9/rendering/generic-binder.test.d.ts.map +1 -0
  169. package/src/v0_9/rendering/generic-binder.test.js +166 -0
  170. package/src/v0_9/rendering/generic-binder.test.js.map +1 -0
  171. package/src/v0_9/schema/client-capabilities.d.ts +34 -0
  172. package/src/v0_9/schema/client-capabilities.d.ts.map +1 -0
  173. package/src/v0_9/schema/client-capabilities.js +17 -0
  174. package/src/v0_9/schema/client-capabilities.js.map +1 -0
  175. package/src/v0_9/schema/client-to-server.d.ts +208 -0
  176. package/src/v0_9/schema/client-to-server.d.ts.map +1 -0
  177. package/src/v0_9/schema/client-to-server.js +104 -0
  178. package/src/v0_9/schema/client-to-server.js.map +1 -0
  179. package/src/v0_9/schema/client-to-server.test.d.ts +2 -0
  180. package/src/v0_9/schema/client-to-server.test.d.ts.map +1 -0
  181. package/src/v0_9/schema/client-to-server.test.js +85 -0
  182. package/src/v0_9/schema/client-to-server.test.js.map +1 -0
  183. package/{dist/src → src}/v0_9/schema/common-types.d.ts +318 -88
  184. package/src/v0_9/schema/common-types.d.ts.map +1 -0
  185. package/src/v0_9/schema/common-types.js +141 -0
  186. package/src/v0_9/schema/common-types.js.map +1 -0
  187. package/src/v0_9/schema/index.d.ts +5 -0
  188. package/src/v0_9/schema/index.d.ts.map +1 -0
  189. package/src/v0_9/schema/index.js +20 -0
  190. package/src/v0_9/schema/index.js.map +1 -0
  191. package/src/v0_9/schema/server-to-client.d.ts +307 -0
  192. package/src/v0_9/schema/server-to-client.d.ts.map +1 -0
  193. package/src/v0_9/schema/server-to-client.js +92 -0
  194. package/src/v0_9/schema/server-to-client.js.map +1 -0
  195. package/src/v0_9/schema/verify-schema.test.d.ts +17 -0
  196. package/src/v0_9/schema/verify-schema.test.d.ts.map +1 -0
  197. package/src/v0_9/schema/verify-schema.test.js +174 -0
  198. package/src/v0_9/schema/verify-schema.test.js.map +1 -0
  199. package/src/v0_9/schemas/basic_catalog.json +1387 -0
  200. package/src/v0_9/schemas/client_capabilities.json +97 -0
  201. package/src/v0_9/schemas/client_data_model.json +22 -0
  202. package/src/v0_9/schemas/client_to_server.json +104 -0
  203. package/src/v0_9/schemas/client_to_server_list.json +10 -0
  204. package/src/v0_9/schemas/common_types.json +315 -0
  205. package/src/v0_9/schemas/sample.json +22 -0
  206. package/src/v0_9/schemas/server_capabilities.json +26 -0
  207. package/src/v0_9/schemas/server_to_client.json +131 -0
  208. package/src/v0_9/schemas/server_to_client_list.json +10 -0
  209. package/src/v0_9/state/component-model.d.ts +36 -0
  210. package/src/v0_9/state/component-model.d.ts.map +1 -0
  211. package/src/v0_9/state/component-model.js +65 -0
  212. package/src/v0_9/state/component-model.js.map +1 -0
  213. package/{dist/src → src}/v0_9/state/component-model.test.js +23 -0
  214. package/src/v0_9/state/component-model.test.js.map +1 -0
  215. package/src/v0_9/state/data-model.d.ts +75 -0
  216. package/src/v0_9/state/data-model.d.ts.map +1 -0
  217. package/src/v0_9/state/data-model.js +235 -0
  218. package/src/v0_9/state/data-model.js.map +1 -0
  219. package/{dist/src → src}/v0_9/state/data-model.test.js +77 -17
  220. package/src/v0_9/state/data-model.test.js.map +1 -0
  221. package/src/v0_9/state/surface-components-model.d.ts +45 -0
  222. package/src/v0_9/state/surface-components-model.d.ts.map +1 -0
  223. package/src/v0_9/state/surface-components-model.js +86 -0
  224. package/src/v0_9/state/surface-components-model.js.map +1 -0
  225. package/{dist/src → src}/v0_9/state/surface-components-model.test.js +44 -2
  226. package/src/v0_9/state/surface-components-model.test.js.map +1 -0
  227. package/{dist/src → src}/v0_9/state/surface-group-model.d.ts +28 -1
  228. package/src/v0_9/state/surface-group-model.d.ts.map +1 -0
  229. package/{dist/src → src}/v0_9/state/surface-group-model.js +44 -1
  230. package/src/v0_9/state/surface-group-model.js.map +1 -0
  231. package/{dist/src → src}/v0_9/state/surface-group-model.test.js +47 -6
  232. package/src/v0_9/state/surface-group-model.test.js.map +1 -0
  233. package/src/v0_9/state/surface-model.d.ts +62 -0
  234. package/src/v0_9/state/surface-model.d.ts.map +1 -0
  235. package/src/v0_9/state/surface-model.js +101 -0
  236. package/src/v0_9/state/surface-model.js.map +1 -0
  237. package/src/v0_9/state/surface-model.test.js +93 -0
  238. package/src/v0_9/state/surface-model.test.js.map +1 -0
  239. package/src/v0_9/test/function_execution.spec.d.ts +17 -0
  240. package/src/v0_9/test/function_execution.spec.d.ts.map +1 -0
  241. package/src/v0_9/test/function_execution.spec.js +127 -0
  242. package/src/v0_9/test/function_execution.spec.js.map +1 -0
  243. package/src/v0_9/test/test-utils.d.ts.map +1 -0
  244. package/{dist/src → src}/v0_9/test/test-utils.js +15 -0
  245. package/src/v0_9/test/test-utils.js.map +1 -0
  246. package/dist/.tsbuildinfo +0 -1
  247. package/dist/src/v0_8/data/model-processor.js.map +0 -1
  248. package/dist/src/v0_8/events/validation-event.d.ts.map +0 -1
  249. package/dist/src/v0_8/index.js +0 -12
  250. package/dist/src/v0_8/index.js.map +0 -1
  251. package/dist/src/v0_8/schemas/server_to_client_with_standard_catalog.json +0 -823
  252. package/dist/src/v0_8/styles/icons.d.ts +0 -11
  253. package/dist/src/v0_8/styles/index.js +0 -35
  254. package/dist/src/v0_8/styles/opacity.js +0 -24
  255. package/dist/src/v0_8/styles/shared.js +0 -17
  256. package/dist/src/v0_8/types/client-event.d.ts.map +0 -1
  257. package/dist/src/v0_8/types/client-event.js +0 -17
  258. package/dist/src/v0_8/types/colors.js +0 -19
  259. package/dist/src/v0_8/types/components.d.ts +0 -176
  260. package/dist/src/v0_8/types/components.d.ts.map +0 -1
  261. package/dist/src/v0_8/types/components.js +0 -17
  262. package/dist/src/v0_8/types/primitives.d.ts +0 -43
  263. package/dist/src/v0_8/types/primitives.d.ts.map +0 -1
  264. package/dist/src/v0_8/types/primitives.js +0 -17
  265. package/dist/src/v0_8/types/types.d.ts.map +0 -1
  266. package/dist/src/v0_8/types/types.js +0 -17
  267. package/dist/src/v0_9/catalog/types.d.ts +0 -27
  268. package/dist/src/v0_9/catalog/types.d.ts.map +0 -1
  269. package/dist/src/v0_9/catalog/types.js +0 -11
  270. package/dist/src/v0_9/catalog/types.js.map +0 -1
  271. package/dist/src/v0_9/common/events.d.ts +0 -24
  272. package/dist/src/v0_9/common/events.d.ts.map +0 -1
  273. package/dist/src/v0_9/common/events.js +0 -29
  274. package/dist/src/v0_9/common/events.js.map +0 -1
  275. package/dist/src/v0_9/index.d.ts +0 -11
  276. package/dist/src/v0_9/index.d.ts.map +0 -1
  277. package/dist/src/v0_9/index.js +0 -11
  278. package/dist/src/v0_9/index.js.map +0 -1
  279. package/dist/src/v0_9/processing/message-processor.d.ts +0 -34
  280. package/dist/src/v0_9/processing/message-processor.d.ts.map +0 -1
  281. package/dist/src/v0_9/processing/message-processor.js +0 -128
  282. package/dist/src/v0_9/processing/message-processor.js.map +0 -1
  283. package/dist/src/v0_9/processing/message-processor.test.js +0 -112
  284. package/dist/src/v0_9/processing/message-processor.test.js.map +0 -1
  285. package/dist/src/v0_9/rendering/component-context.d.ts +0 -17
  286. package/dist/src/v0_9/rendering/component-context.d.ts.map +0 -1
  287. package/dist/src/v0_9/rendering/component-context.js +0 -21
  288. package/dist/src/v0_9/rendering/component-context.js.map +0 -1
  289. package/dist/src/v0_9/rendering/data-context.d.ts +0 -37
  290. package/dist/src/v0_9/rendering/data-context.d.ts.map +0 -1
  291. package/dist/src/v0_9/rendering/data-context.js +0 -97
  292. package/dist/src/v0_9/rendering/data-context.js.map +0 -1
  293. package/dist/src/v0_9/rendering/data-context.test.js +0 -71
  294. package/dist/src/v0_9/rendering/data-context.test.js.map +0 -1
  295. package/dist/src/v0_9/schema/common-types.d.ts.map +0 -1
  296. package/dist/src/v0_9/schema/common-types.js +0 -92
  297. package/dist/src/v0_9/schema/common-types.js.map +0 -1
  298. package/dist/src/v0_9/schema/index.d.ts +0 -3
  299. package/dist/src/v0_9/schema/index.d.ts.map +0 -1
  300. package/dist/src/v0_9/schema/index.js +0 -3
  301. package/dist/src/v0_9/schema/index.js.map +0 -1
  302. package/dist/src/v0_9/schema/server-to-client.d.ts +0 -84
  303. package/dist/src/v0_9/schema/server-to-client.d.ts.map +0 -1
  304. package/dist/src/v0_9/schema/server-to-client.js +0 -21
  305. package/dist/src/v0_9/schema/server-to-client.js.map +0 -1
  306. package/dist/src/v0_9/state/component-model.d.ts +0 -16
  307. package/dist/src/v0_9/state/component-model.d.ts.map +0 -1
  308. package/dist/src/v0_9/state/component-model.js +0 -24
  309. package/dist/src/v0_9/state/component-model.js.map +0 -1
  310. package/dist/src/v0_9/state/component-model.test.js.map +0 -1
  311. package/dist/src/v0_9/state/data-model.d.ts +0 -47
  312. package/dist/src/v0_9/state/data-model.d.ts.map +0 -1
  313. package/dist/src/v0_9/state/data-model.js +0 -191
  314. package/dist/src/v0_9/state/data-model.js.map +0 -1
  315. package/dist/src/v0_9/state/data-model.test.js.map +0 -1
  316. package/dist/src/v0_9/state/surface-components-model.d.ts +0 -19
  317. package/dist/src/v0_9/state/surface-components-model.d.ts.map +0 -1
  318. package/dist/src/v0_9/state/surface-components-model.js +0 -42
  319. package/dist/src/v0_9/state/surface-components-model.js.map +0 -1
  320. package/dist/src/v0_9/state/surface-components-model.test.js.map +0 -1
  321. package/dist/src/v0_9/state/surface-group-model.d.ts.map +0 -1
  322. package/dist/src/v0_9/state/surface-group-model.js.map +0 -1
  323. package/dist/src/v0_9/state/surface-group-model.test.js.map +0 -1
  324. package/dist/src/v0_9/state/surface-model.d.ts +0 -23
  325. package/dist/src/v0_9/state/surface-model.d.ts.map +0 -1
  326. package/dist/src/v0_9/state/surface-model.js +0 -28
  327. package/dist/src/v0_9/state/surface-model.js.map +0 -1
  328. package/dist/src/v0_9/state/surface-model.test.js +0 -39
  329. package/dist/src/v0_9/state/surface-model.test.js.map +0 -1
  330. package/dist/src/v0_9/test/test-utils.d.ts.map +0 -1
  331. package/dist/src/v0_9/test/test-utils.js.map +0 -1
  332. package/src/v0_8/data/guards.ts +0 -236
  333. package/src/v0_8/data/model-processor.ts +0 -855
  334. package/src/v0_8/events/base.ts +0 -24
  335. package/src/v0_8/events/validation-event.ts +0 -66
  336. package/src/v0_8/index.ts +0 -12
  337. package/src/v0_8/styles/behavior.ts +0 -55
  338. package/src/v0_8/styles/border.ts +0 -42
  339. package/src/v0_8/styles/colors.ts +0 -100
  340. package/src/v0_8/styles/icons.ts +0 -60
  341. package/src/v0_8/styles/index.ts +0 -37
  342. package/src/v0_8/styles/layout.ts +0 -235
  343. package/src/v0_8/styles/opacity.ts +0 -24
  344. package/src/v0_8/styles/shared.ts +0 -17
  345. package/src/v0_8/styles/type.ts +0 -156
  346. package/src/v0_8/styles/utils.ts +0 -104
  347. package/src/v0_8/types/client-event.ts +0 -80
  348. package/src/v0_8/types/colors.ts +0 -66
  349. package/src/v0_8/types/components.ts +0 -213
  350. package/src/v0_8/types/primitives.ts +0 -60
  351. package/src/v0_8/types/types.ts +0 -557
  352. package/src/v0_9/catalog/types.ts +0 -38
  353. package/src/v0_9/common/events.ts +0 -44
  354. package/src/v0_9/index.ts +0 -12
  355. package/src/v0_9/processing/message-processor.test.ts +0 -133
  356. package/src/v0_9/processing/message-processor.ts +0 -150
  357. package/src/v0_9/rendering/component-context.ts +0 -36
  358. package/src/v0_9/rendering/data-context.test.ts +0 -85
  359. package/src/v0_9/rendering/data-context.ts +0 -110
  360. package/src/v0_9/schema/common-types.ts +0 -125
  361. package/src/v0_9/schema/index.ts +0 -2
  362. package/src/v0_9/schema/server-to-client.ts +0 -23
  363. package/src/v0_9/state/component-model.test.ts +0 -50
  364. package/src/v0_9/state/component-model.ts +0 -32
  365. package/src/v0_9/state/data-model.test.ts +0 -257
  366. package/src/v0_9/state/data-model.ts +0 -239
  367. package/src/v0_9/state/surface-components-model.test.ts +0 -59
  368. package/src/v0_9/state/surface-components-model.ts +0 -48
  369. package/src/v0_9/state/surface-group-model.test.ts +0 -82
  370. package/src/v0_9/state/surface-group-model.ts +0 -66
  371. package/src/v0_9/state/surface-model.test.ts +0 -44
  372. package/src/v0_9/state/surface-model.ts +0 -39
  373. package/src/v0_9/test/test-utils.ts +0 -22
  374. /package/{dist/src → src}/v0_8/data/guards.d.ts +0 -0
  375. /package/{dist/src → src}/v0_8/data/guards.d.ts.map +0 -0
  376. /package/{dist/src → src}/v0_8/data/guards.js.map +0 -0
  377. /package/{dist/src → src}/v0_8/events/base.d.ts +0 -0
  378. /package/{dist/src → src}/v0_8/events/base.d.ts.map +0 -0
  379. /package/{dist/src → src}/v0_8/events/base.js +0 -0
  380. /package/{dist/src → src}/v0_8/events/base.js.map +0 -0
  381. /package/{dist/src → src}/v0_8/events/index.d.ts +0 -0
  382. /package/{dist/src → src}/v0_8/events/index.d.ts.map +0 -0
  383. /package/{dist/src → src}/v0_8/events/index.js +0 -0
  384. /package/{dist/src → src}/v0_8/events/index.js.map +0 -0
  385. /package/{dist/src → src}/v0_8/events/validation-event.d.ts +0 -0
  386. /package/{dist/src → src}/v0_8/events/validation-event.js +0 -0
  387. /package/{dist/src → src}/v0_8/schemas/a2ui_client_capabilities_schema.json +0 -0
  388. /package/{dist/src → src}/v0_8/schemas/catalog_description_schema.json +0 -0
  389. /package/{dist/src → src}/v0_8/schemas/client_to_server.json +0 -0
  390. /package/{dist/src → src}/v0_8/styles/behavior.d.ts +0 -0
  391. /package/{dist/src → src}/v0_8/styles/behavior.d.ts.map +0 -0
  392. /package/{dist/src → src}/v0_8/styles/behavior.js.map +0 -0
  393. /package/{dist/src → src}/v0_8/styles/border.d.ts +0 -0
  394. /package/{dist/src → src}/v0_8/styles/border.d.ts.map +0 -0
  395. /package/{dist/src → src}/v0_8/styles/border.js.map +0 -0
  396. /package/{dist/src → src}/v0_8/styles/colors.d.ts +0 -0
  397. /package/{dist/src → src}/v0_8/styles/colors.d.ts.map +0 -0
  398. /package/{dist/src → src}/v0_8/styles/index.d.ts +0 -0
  399. /package/{dist/src → src}/v0_8/styles/index.d.ts.map +0 -0
  400. /package/{dist/src → src}/v0_8/styles/index.js.map +0 -0
  401. /package/{dist/src → src}/v0_8/styles/layout.d.ts +0 -0
  402. /package/{dist/src → src}/v0_8/styles/layout.d.ts.map +0 -0
  403. /package/{dist/src → src}/v0_8/styles/opacity.d.ts +0 -0
  404. /package/{dist/src → src}/v0_8/styles/opacity.d.ts.map +0 -0
  405. /package/{dist/src → src}/v0_8/styles/opacity.js.map +0 -0
  406. /package/{dist/src → src}/v0_8/styles/shared.d.ts +0 -0
  407. /package/{dist/src → src}/v0_8/styles/shared.d.ts.map +0 -0
  408. /package/{dist/src → src}/v0_8/styles/shared.js.map +0 -0
  409. /package/{dist/src → src}/v0_8/styles/type.d.ts +0 -0
  410. /package/{dist/src → src}/v0_8/styles/type.d.ts.map +0 -0
  411. /package/{dist/src → src}/v0_8/styles/type.js.map +0 -0
  412. /package/{dist/src → src}/v0_8/styles/utils.d.ts +0 -0
  413. /package/{dist/src → src}/v0_8/styles/utils.d.ts.map +0 -0
  414. /package/{dist/src → src}/v0_8/styles/utils.js.map +0 -0
  415. /package/{dist/src → src}/v0_8/types/client-event.js.map +0 -0
  416. /package/{dist/src → src}/v0_8/types/colors.d.ts +0 -0
  417. /package/{dist/src → src}/v0_8/types/colors.d.ts.map +0 -0
  418. /package/{dist/src → src}/v0_8/types/colors.js.map +0 -0
  419. /package/{dist/src → src}/v0_8/types/components.js.map +0 -0
  420. /package/{dist/src → src}/v0_8/types/primitives.js.map +0 -0
  421. /package/{dist/src → src}/v0_8/types/types.js.map +0 -0
  422. /package/{dist/src → src}/v0_9/processing/message-processor.test.d.ts +0 -0
  423. /package/{dist/src → src}/v0_9/processing/message-processor.test.d.ts.map +0 -0
  424. /package/{dist/src → src}/v0_9/rendering/data-context.test.d.ts +0 -0
  425. /package/{dist/src → src}/v0_9/rendering/data-context.test.d.ts.map +0 -0
  426. /package/{dist/src → src}/v0_9/state/component-model.test.d.ts +0 -0
  427. /package/{dist/src → src}/v0_9/state/component-model.test.d.ts.map +0 -0
  428. /package/{dist/src → src}/v0_9/state/data-model.test.d.ts +0 -0
  429. /package/{dist/src → src}/v0_9/state/data-model.test.d.ts.map +0 -0
  430. /package/{dist/src → src}/v0_9/state/surface-components-model.test.d.ts +0 -0
  431. /package/{dist/src → src}/v0_9/state/surface-components-model.test.d.ts.map +0 -0
  432. /package/{dist/src → src}/v0_9/state/surface-group-model.test.d.ts +0 -0
  433. /package/{dist/src → src}/v0_9/state/surface-group-model.test.d.ts.map +0 -0
  434. /package/{dist/src → src}/v0_9/state/surface-model.test.d.ts +0 -0
  435. /package/{dist/src → src}/v0_9/state/surface-model.test.d.ts.map +0 -0
  436. /package/{dist/src → src}/v0_9/test/test-utils.d.ts +0 -0
@@ -1,50 +0,0 @@
1
- import assert from 'node:assert';
2
- import { describe, it, beforeEach } from 'node:test';
3
- import { ComponentModel } from './component-model.js';
4
-
5
- describe('ComponentModel', () => {
6
- let component: ComponentModel;
7
-
8
- beforeEach(() => {
9
- component = new ComponentModel('c1', 'Button', { label: 'Click Me' });
10
- });
11
-
12
- it('initializes properties', () => {
13
- assert.strictEqual(component.id, 'c1');
14
- assert.strictEqual(component.type, 'Button');
15
- assert.strictEqual(component.properties.label, 'Click Me');
16
- });
17
-
18
- it('updates properties', () => {
19
- component.properties = { label: 'Clicked' };
20
- assert.strictEqual(component.properties.label, 'Clicked');
21
- });
22
-
23
- it('notifies listeners on update', () => {
24
- let updatedComponent: ComponentModel | undefined;
25
-
26
- component.onUpdated.subscribe((c: ComponentModel) => {
27
- updatedComponent = c;
28
- });
29
-
30
- component.properties = { label: 'New' };
31
-
32
- assert.strictEqual(updatedComponent, component);
33
- assert.strictEqual(updatedComponent?.properties.label, 'New');
34
- });
35
-
36
- it('unsubscribes listeners', () => {
37
- let callCount = 0;
38
-
39
- const sub = component.onUpdated.subscribe(() => {
40
- callCount++;
41
- });
42
-
43
- component.properties = { label: '1' };
44
- assert.strictEqual(callCount, 1);
45
-
46
- sub.unsubscribe();
47
- component.properties = { label: '2' };
48
- assert.strictEqual(callCount, 1);
49
- });
50
- });
@@ -1,32 +0,0 @@
1
- import { EventEmitter, EventSource } from '../common/events.js';
2
-
3
- export class ComponentModel {
4
- private _properties: Record<string, any>;
5
- private readonly _onUpdated = new EventEmitter<ComponentModel>();
6
-
7
- /**
8
- * Fires whenever the component's properties are updated.
9
- */
10
- readonly onUpdated: EventSource<ComponentModel> = this._onUpdated;
11
-
12
- constructor(
13
- readonly id: string,
14
- readonly type: string,
15
- initialProperties: Record<string, any>
16
- ) {
17
- this._properties = initialProperties;
18
- }
19
-
20
- get properties(): Record<string, any> {
21
- return this._properties;
22
- }
23
-
24
- set properties(newProperties: Record<string, any>) {
25
- this._properties = newProperties;
26
- this._onUpdated.emit(this);
27
- }
28
-
29
- dispose(): void {
30
- this._onUpdated.dispose();
31
- }
32
- }
@@ -1,257 +0,0 @@
1
- import assert from 'node:assert';
2
- import { test, describe, it, beforeEach } from 'node:test';
3
- import { DataModel } from './data-model.js';
4
-
5
- describe('DataModel', () => {
6
- let model: DataModel;
7
-
8
- beforeEach(() => {
9
- model = new DataModel({
10
- user: {
11
- name: 'Alice',
12
- settings: {
13
- theme: 'dark'
14
- }
15
- },
16
- items: ['a', 'b', 'c']
17
- });
18
- });
19
-
20
- // --- Basic Retrieval ---
21
-
22
- it('retrieves root data', () => {
23
- assert.deepStrictEqual(model.get('/'), { user: { name: 'Alice', settings: { theme: 'dark' } }, items: ['a', 'b', 'c'] });
24
- });
25
-
26
- it('retrieves nested path', () => {
27
- assert.strictEqual(model.get('/user/name'), 'Alice');
28
- assert.strictEqual(model.get('/user/settings/theme'), 'dark');
29
- });
30
-
31
- it('retrieves array items', () => {
32
- assert.strictEqual(model.get('/items/0'), 'a');
33
- assert.strictEqual(model.get('/items/1'), 'b');
34
- });
35
-
36
- it('returns undefined for non-existent paths', () => {
37
- assert.strictEqual(model.get('/user/age'), undefined);
38
- assert.strictEqual(model.get('/unknown/path'), undefined);
39
- });
40
-
41
- // --- Updates ---
42
-
43
- it('sets value at existing path', () => {
44
- model.set('/user/name', 'Bob');
45
- assert.strictEqual(model.get('/user/name'), 'Bob');
46
- });
47
-
48
- it('sets value at new path', () => {
49
- model.set('/user/age', 30);
50
- assert.strictEqual(model.get('/user/age'), 30);
51
- });
52
-
53
- it('creates intermediate objects', () => {
54
- model.set('/a/b/c', 'foo');
55
- assert.strictEqual(model.get('/a/b/c'), 'foo');
56
- assert.notStrictEqual(model.get('/a/b'), undefined);
57
- });
58
-
59
- it('removes keys when value is undefined', () => {
60
- model.set('/user/name', undefined);
61
- assert.strictEqual(model.get('/user/name'), undefined);
62
- assert.strictEqual(Object.keys(model.get('/user')).includes('name'), false);
63
- });
64
-
65
- it('replaces root object on root update', () => {
66
- model.set('/', { newRoot: true });
67
- assert.deepStrictEqual(model.get('/'), { newRoot: true });
68
- });
69
-
70
- // --- Array / List Handling (Flutter Parity) ---
71
-
72
- it('List: set and get', () => {
73
- model.set('/list/0', 'hello');
74
- assert.strictEqual(model.get('/list/0'), 'hello');
75
- assert.ok(Array.isArray(model.get('/list')));
76
- });
77
-
78
- it('List: append and get', () => {
79
- model.set('/list/0', 'hello');
80
- model.set('/list/1', 'world');
81
- assert.strictEqual(model.get('/list/0'), 'hello');
82
- assert.strictEqual(model.get('/list/1'), 'world');
83
- assert.strictEqual(model.get('/list').length, 2);
84
- });
85
-
86
- it('List: update existing index', () => {
87
- model.set('/items/1', 'updated');
88
- assert.strictEqual(model.get('/items/1'), 'updated');
89
- });
90
-
91
- it('Nested structures are created automatically', () => {
92
- // Should create nested map and list: { a: { b: [ { c: 123 } ] } }
93
- model.set('/a/b/0/c', 123);
94
- assert.strictEqual(model.get('/a/b/0/c'), 123);
95
- assert.ok(Array.isArray(model.get('/a/b')));
96
- assert.ok(!Array.isArray(model.get('/a/b/0')));
97
-
98
- // Should create nested maps
99
- model.set('/x/y/z', 'hello');
100
- assert.strictEqual(model.get('/x/y/z'), 'hello');
101
-
102
- // Should create nested lists
103
- model.set('/nestedList/0/0', 'inner');
104
- assert.strictEqual(model.get('/nestedList/0/0'), 'inner');
105
- assert.ok(Array.isArray(model.get('/nestedList')));
106
- assert.ok(Array.isArray(model.get('/nestedList/0')));
107
- });
108
-
109
- // --- Subscriptions ---
110
-
111
- it('returns a subscription object', () => {
112
- model.set('/a', 1);
113
- const sub = model.subscribe<number>('/a', (val) => updatedValue = val);
114
- assert.strictEqual(sub.value, 1);
115
-
116
- let updatedValue: number | undefined;
117
-
118
-
119
- model.set('/a', 2);
120
- assert.strictEqual(sub.value, 2);
121
- assert.strictEqual(updatedValue, 2);
122
-
123
- sub.unsubscribe();
124
- // Verify listener removed
125
- model.set('/a', 3);
126
- assert.strictEqual(updatedValue, 2);
127
- });
128
-
129
- it('notifies subscribers on exact match', () => {
130
- let called = false;
131
- const sub = model.subscribe('/user/name', (val) => {
132
- assert.strictEqual(val, 'Charlie');
133
- called = true;
134
- });
135
- model.set('/user/name', 'Charlie');
136
- assert.strictEqual(called, true, 'Callback was never called');
137
- });
138
-
139
- it('notifies ancestor subscribers (Container Semantics)', () => {
140
- let called = false;
141
- const sub = model.subscribe('/user', (val: any) => {
142
- assert.strictEqual(val.name, 'Dave');
143
- called = true;
144
- });
145
- model.set('/user/name', 'Dave');
146
- assert.strictEqual(called, true, 'Callback was never called');
147
- });
148
-
149
- it('notifies descendant subscribers', () => {
150
- let called = false;
151
- const sub = model.subscribe('/user/settings/theme', (val) => {
152
- assert.strictEqual(val, 'light');
153
- called = true;
154
- });
155
-
156
- // We update the parent object
157
- model.set('/user/settings', { theme: 'light' });
158
- assert.strictEqual(called, true, 'Callback was never called');
159
- });
160
-
161
- it('notifies root subscriber', () => {
162
- let called = false;
163
- const sub = model.subscribe('/', (val: any) => {
164
- assert.strictEqual(val.newProp, 'test');
165
- called = true;
166
- });
167
- model.set('/newProp', 'test');
168
- assert.strictEqual(called, true, 'Callback was never called');
169
- });
170
-
171
- it('notifies parent when child updates', () => {
172
- model.set('/parent', { child: 'initial' });
173
-
174
- let parentValue: any;
175
- const sub = model.subscribe('/parent', (val) => parentValue = val);
176
-
177
- model.set('/parent/child', 'updated');
178
- assert.deepStrictEqual(parentValue, { child: 'updated' });
179
- });
180
-
181
- it('stops notifying after dispose', () => {
182
- let count = 0;
183
- const sub = model.subscribe('/', () => count++);
184
-
185
- model.dispose();
186
- model.set('/foo', 'bar');
187
- assert.strictEqual(count, 0);
188
- });
189
-
190
- it('supports multiple subscribers to the same path', () => {
191
- let callCount1 = 0;
192
- let callCount2 = 0;
193
-
194
- const sub1 = model.subscribe('/user/name', () => callCount1++);
195
-
196
- const sub2 = model.subscribe('/user/name', () => callCount2++);
197
-
198
- model.set('/user/name', 'Eve');
199
-
200
- assert.strictEqual(callCount1, 1);
201
- assert.strictEqual(callCount2, 1);
202
- assert.strictEqual(sub1.value, 'Eve');
203
- assert.strictEqual(sub2.value, 'Eve');
204
- });
205
-
206
- it('allows unsubscribing individual listeners', () => {
207
- let callCount1 = 0;
208
- let callCount2 = 0;
209
-
210
- const sub1 = model.subscribe('/user/name', () => callCount1++);
211
-
212
- const sub2 = model.subscribe('/user/name', () => callCount2++);
213
-
214
- sub1.unsubscribe();
215
-
216
- model.set('/user/name', 'Frank');
217
-
218
- assert.strictEqual(callCount1, 0); // sub1 was unsubscribed
219
- assert.strictEqual(callCount2, 1); // sub2 still active
220
- assert.strictEqual(sub2.value, 'Frank');
221
- });
222
-
223
- it('handles subscription to non-existent path', () => {
224
- let val: any;
225
- const sub = model.subscribe('/non/existent', (v) => val = v);
226
- assert.strictEqual(sub.value, undefined);
227
-
228
- model.set('/non/existent', 'exists now');
229
- assert.strictEqual(sub.value, 'exists now');
230
- assert.strictEqual(val, 'exists now');
231
- });
232
-
233
- it('handles updates to undefined', () => {
234
- model.set('/foo', 'bar');
235
- let val: any = 'initial';
236
- const sub = model.subscribe('/foo', (v) => val = v);
237
-
238
- model.set('/foo', undefined);
239
- assert.strictEqual(sub.value, undefined);
240
- assert.strictEqual(val, undefined);
241
- });
242
-
243
- it('throws when trying to set nested property through a primitive', () => {
244
- model.set('/user/name', 'not an object');
245
- assert.strictEqual(model.get('/user/name'), 'not an object');
246
-
247
- assert.throws(() => {
248
- model.set('/user/name/first', 'Alice');
249
- }, /Cannot set path/);
250
- });
251
-
252
- it('throws when using non-numeric segment on an array', () => {
253
- assert.throws(() => {
254
- model.set('/items/foo', 'bar');
255
- }, /Cannot use non-numeric segment/);
256
- });
257
- });
@@ -1,239 +0,0 @@
1
- /*
2
- Copyright 2025 Google LLC
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- https://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- */
16
-
17
- import { Subscription as BaseSubscription } from '../common/events.js';
18
-
19
- /**
20
- * Represents a reactive connection to a specific path in the data model.
21
- */
22
- export interface DataSubscription<T> extends BaseSubscription {
23
- /**
24
- * The current value at the subscribed path.
25
- */
26
- readonly value: T | undefined;
27
- }
28
-
29
- class SubscriptionImpl<T> implements DataSubscription<T> {
30
- private _value: T | undefined;
31
- private readonly _unsubscribe: () => void;
32
- public onChange: (value: T | undefined) => void;
33
-
34
- constructor(initialValue: T | undefined, onChange: (value: T | undefined) => void, unsubscribe: () => void) {
35
- this._value = initialValue;
36
- this.onChange = onChange;
37
- this._unsubscribe = unsubscribe;
38
- }
39
-
40
- get value(): T | undefined {
41
- return this._value;
42
- }
43
-
44
- setValue(value: T | undefined): void {
45
- this._value = value;
46
- this.onChange(value);
47
- }
48
-
49
- unsubscribe(): void {
50
- this._unsubscribe();
51
- }
52
- }
53
-
54
- function isNumeric(value: string): boolean {
55
- return /^\d+$/.test(value);
56
- }
57
-
58
- /**
59
- * A standalone, observable data store representing the client-side state.
60
- * It handles JSON Pointer path resolution and subscription management.
61
- */
62
- export class DataModel {
63
- private data: Record<string, unknown> = {};
64
- private readonly subscriptions: Map<string, Set<SubscriptionImpl<any>>> = new Map();
65
-
66
- constructor(initialData: Record<string, unknown> = {}) {
67
- this.data = initialData;
68
- }
69
-
70
- /**
71
- * Updates the model at the specific path and notifies all relevant subscribers.
72
- * If path is '/' or empty, replaces the entire root.
73
- *
74
- * Note on `undefined` values:
75
- * - For objects: Setting a property to `undefined` removes the key from the object.
76
- * - For arrays: Setting an index to `undefined` sets that index to `undefined` but preserves the array length (sparse array).
77
- */
78
- set(path: string, value: any): this {
79
- if (path === null || path === undefined) {
80
- throw new Error("Path cannot be null or undefined.");
81
- }
82
- if (path === '/' || path === '') {
83
- this.data = value;
84
- this.notifyAllSubscribers();
85
- return this;
86
- }
87
-
88
- const segments = this.parsePath(path);
89
- const lastSegment = segments.pop()!;
90
-
91
- let current: any = this.data;
92
- for (let i = 0; i < segments.length; i++) {
93
- const segment = segments[i];
94
-
95
- if (Array.isArray(current) && !isNumeric(segment)) {
96
- throw new Error(`Cannot use non-numeric segment '${segment}' on an array in path '${path}'.`);
97
- }
98
-
99
- // If we encounter a primitive where a container is expected, we cannot proceed.
100
- // We allow undefined/null to be overwritten by a new container.
101
- if (current[segment] !== undefined && current[segment] !== null && typeof current[segment] !== 'object') {
102
- throw new Error(`Cannot set path '${path}': segment '${segment}' is a primitive value.`);
103
- }
104
-
105
- if (current[segment] === undefined || current[segment] === null) {
106
- const nextSegment = (i < segments.length - 1) ? segments[i + 1] : lastSegment;
107
- current[segment] = isNumeric(nextSegment) ? [] : {};
108
- }
109
- current = current[segment];
110
- }
111
-
112
- if (Array.isArray(current) && !isNumeric(lastSegment)) {
113
- throw new Error(`Cannot use non-numeric segment '${lastSegment}' on an array in path '${path}'.`);
114
- }
115
-
116
- if (value === undefined) {
117
- if (Array.isArray(current)) {
118
- current[parseInt(lastSegment, 10)] = undefined;
119
- } else {
120
- delete current[lastSegment];
121
- }
122
- } else {
123
- current[lastSegment] = value;
124
- }
125
-
126
- this.notifySubscribers(path);
127
- return this;
128
- }
129
-
130
- /**
131
- * Retrieves data at a specific path.
132
- */
133
- get(path: string): any {
134
- if (path === null || path === undefined) {
135
- throw new Error("Path cannot be null or undefined.");
136
- }
137
- if (path === '/' || path === '') {
138
- return this.data;
139
- }
140
-
141
- const segments = this.parsePath(path);
142
- let current: any = this.data;
143
- for (const segment of segments) {
144
- if (current === undefined || current === null) {
145
- return undefined;
146
- }
147
- current = current[segment];
148
- }
149
- return current;
150
- }
151
-
152
- /**
153
- * Subscribes to changes at a specific path. Returns a Subscription object.
154
- */
155
- subscribe<T>(path: string, onChange: (value: T | undefined) => void): DataSubscription<T> {
156
- const normalizedPath = this.normalizePath(path);
157
- const initialValue = this.get(normalizedPath);
158
-
159
- const subscription = new SubscriptionImpl<T>(
160
- initialValue,
161
- onChange,
162
- () => {
163
- const set = this.subscriptions.get(normalizedPath);
164
- if (set) {
165
- set.delete(subscription);
166
- if (set.size === 0) {
167
- this.subscriptions.delete(normalizedPath);
168
- }
169
- }
170
- }
171
- );
172
-
173
- if (!this.subscriptions.has(normalizedPath)) {
174
- this.subscriptions.set(normalizedPath, new Set());
175
- }
176
- this.subscriptions.get(normalizedPath)!.add(subscription);
177
-
178
- return subscription;
179
- }
180
-
181
- /**
182
- * Clears all internal subscriptions.
183
- */
184
- dispose(): void {
185
- this.subscriptions.clear();
186
- }
187
-
188
- private normalizePath(path: string): string {
189
- if (path.length > 1 && path.endsWith('/')) {
190
- return path.slice(0, -1);
191
- }
192
- return path || '/';
193
- }
194
-
195
- private parsePath(path: string): string[] {
196
- return path.split('/').filter(p => p.length > 0);
197
- }
198
-
199
- private notifySubscribers(path: string): void {
200
- const normalizedPath = this.normalizePath(path);
201
- this.notify(normalizedPath);
202
-
203
- // Notify Ancestors
204
- let parentPath = normalizedPath;
205
- while (parentPath !== '/' && parentPath !== '') {
206
- parentPath = parentPath.substring(0, parentPath.lastIndexOf('/')) || '/';
207
- this.notify(parentPath);
208
- }
209
-
210
- // Notify Descendants
211
- for (const subPath of this.subscriptions.keys()) {
212
- if (this.isDescendant(subPath, normalizedPath)) {
213
- this.notify(subPath);
214
- }
215
- }
216
- }
217
-
218
- private notify(path: string): void {
219
- const set = this.subscriptions.get(path);
220
- if (!set) {
221
- return;
222
- }
223
- const value = this.get(path);
224
- set.forEach(sub => sub.setValue(value));
225
- }
226
-
227
- private notifyAllSubscribers(): void {
228
- for (const path of this.subscriptions.keys()) {
229
- this.notify(path);
230
- }
231
- }
232
-
233
- private isDescendant(childPath: string, parentPath: string): boolean {
234
- if (parentPath === '/' || parentPath === '') {
235
- return childPath !== '/';
236
- }
237
- return childPath.startsWith(parentPath + '/');
238
- }
239
- }
@@ -1,59 +0,0 @@
1
- import assert from 'node:assert';
2
- import { describe, it, beforeEach } from 'node:test';
3
- import { SurfaceComponentsModel } from './surface-components-model.js';
4
- import { ComponentModel } from './component-model.js';
5
-
6
- describe('SurfaceComponentsModel', () => {
7
- let model: SurfaceComponentsModel;
8
-
9
- beforeEach(() => {
10
- model = new SurfaceComponentsModel();
11
- });
12
-
13
- it('starts empty', () => {
14
- assert.strictEqual(model.get('any'), undefined);
15
- });
16
-
17
- it('adds a new component', () => {
18
- const c1 = new ComponentModel('c1', 'Button', { label: 'Click' });
19
- model.addComponent(c1);
20
- const retrieved = model.get('c1');
21
- assert.ok(retrieved);
22
- assert.strictEqual(retrieved?.id, 'c1');
23
- assert.strictEqual(retrieved?.type, 'Button');
24
- assert.strictEqual(retrieved?.properties.label, 'Click');
25
- });
26
-
27
- it('updates an existing component', () => {
28
- const c1 = new ComponentModel('c1', 'Button', { label: 'Initial' });
29
- model.addComponent(c1);
30
-
31
- // Track update on component itself
32
- let updateCount = 0;
33
- c1.onUpdated.subscribe(() => { updateCount++; });
34
-
35
- c1.properties = { label: 'Updated' };
36
-
37
- assert.strictEqual(c1.properties.label, 'Updated');
38
- assert.strictEqual(updateCount, 1);
39
- });
40
-
41
- it('notifies on component creation', () => {
42
- let createdComponent: ComponentModel | undefined;
43
- model.onCreated.subscribe((c) => {
44
- createdComponent = c;
45
- });
46
-
47
- model.addComponent(new ComponentModel('c1', 'Button', {}));
48
- assert.ok(createdComponent);
49
- assert.strictEqual(createdComponent?.id, 'c1');
50
- });
51
-
52
- it('throws when adding duplicate component', () => {
53
- const c1 = new ComponentModel('c1', 'Button', {});
54
- model.addComponent(c1);
55
- assert.throws(() => {
56
- model.addComponent(new ComponentModel('c1', 'Button', {}));
57
- }, /already exists/);
58
- });
59
- });
@@ -1,48 +0,0 @@
1
- import { ComponentModel } from './component-model.js';
2
- import { EventEmitter, EventSource } from '../common/events.js';
3
-
4
- /**
5
- * Manages the collection of components for a specific surface.
6
- */
7
- export class SurfaceComponentsModel {
8
- private components: Map<string, ComponentModel> = new Map();
9
-
10
- private readonly _onCreated = new EventEmitter<ComponentModel>();
11
- private readonly _onDeleted = new EventEmitter<string>();
12
-
13
- /** Fires when a new component is added to the model. */
14
- readonly onCreated: EventSource<ComponentModel> = this._onCreated;
15
- /** Fires when a component is removed, providing the ID of the deleted component. */
16
- readonly onDeleted: EventSource<string> = this._onDeleted;
17
-
18
- get(id: string): ComponentModel | undefined {
19
- return this.components.get(id);
20
- }
21
-
22
- addComponent(component: ComponentModel): void {
23
- if (this.components.has(component.id)) {
24
- throw new Error(`Component with id '${component.id}' already exists.`);
25
- }
26
-
27
- this.components.set(component.id, component);
28
- this._onCreated.emit(component);
29
- }
30
-
31
- removeComponent(id: string): void {
32
- const component = this.components.get(id);
33
- if (component) {
34
- this.components.delete(id);
35
- component.dispose();
36
- this._onDeleted.emit(id);
37
- }
38
- }
39
-
40
- dispose(): void {
41
- for (const component of this.components.values()) {
42
- component.dispose();
43
- }
44
- this.components.clear();
45
- this._onCreated.dispose();
46
- this._onDeleted.dispose();
47
- }
48
- }