@tmorrow/cre8-wc 2.0.6 → 2.0.8

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 (326) hide show
  1. package/a2ui/catalog +5 -5
  2. package/a2ui/catalog-kg.json +156 -20
  3. package/a2ui/catalog.json +394 -35
  4. package/a2ui/catalog.svg +2445 -2445
  5. package/a2ui/examples/compound-families.json +298 -0
  6. package/a2ui/examples/llm-observability.json +678 -650
  7. package/a2ui/generate-catalog.mjs +116 -3
  8. package/a2ui/inert-props.json +32 -0
  9. package/a2ui/render-audit.mjs +294 -0
  10. package/a2ui/renderer.d.ts +2 -1
  11. package/a2ui/renderer.js +1 -1
  12. package/a2ui/renderer.ts +1 -1
  13. package/a2ui/smoke-test.mjs +3 -3
  14. package/a2ui/stream/diff-test.mjs +299 -0
  15. package/a2ui/stream/diff.d.ts +28 -0
  16. package/a2ui/stream/diff.js +130 -0
  17. package/a2ui/stream/diff.ts +145 -0
  18. package/a2ui/stream/index.d.ts +11 -0
  19. package/a2ui/stream/index.js +11 -0
  20. package/a2ui/stream/index.ts +43 -0
  21. package/a2ui/stream/model.d.ts +66 -0
  22. package/a2ui/stream/model.js +429 -0
  23. package/a2ui/stream/model.ts +472 -0
  24. package/a2ui/stream/pointer.d.ts +34 -0
  25. package/a2ui/stream/pointer.js +146 -0
  26. package/a2ui/stream/pointer.ts +147 -0
  27. package/a2ui/stream/renderer.d.ts +51 -0
  28. package/a2ui/stream/renderer.js +282 -0
  29. package/a2ui/stream/renderer.ts +291 -0
  30. package/a2ui/stream/stream-test.mjs +592 -0
  31. package/a2ui/stream/types.d.ts +173 -0
  32. package/a2ui/stream/types.js +17 -0
  33. package/a2ui/stream/types.ts +127 -0
  34. package/cdn/cre8-wc.esm.js +3528 -3227
  35. package/cdn/cre8-wc.esm.js.map +1 -1
  36. package/cdn/cre8-wc.min.js +290 -290
  37. package/cdn/cre8-wc.min.js.map +1 -1
  38. package/dist/assets/{Changelog-Documentation-BguNswiM.js → Changelog-Documentation-CeOetLxK.js} +1 -1
  39. package/dist/assets/{Code-Guidelines-BM3dZyzL.js → Code-Guidelines-BjdezAjj.js} +1 -1
  40. package/dist/assets/{Color-6AOWCN3U-C4AEGNk3.js → Color-6AOWCN3U-DPFGZitI.js} +1 -1
  41. package/dist/assets/{Contributing-Guidelines-DZURVehh.js → Contributing-Guidelines-B1M2V1hW.js} +1 -1
  42. package/dist/assets/{DocsRenderer-JROSPFPF-DeZmCI9u.js → DocsRenderer-JROSPFPF-BBy8KWNl.js} +1 -1
  43. package/dist/assets/{Tokens-Documentation-ZecGbtQg.js → Tokens-Documentation-CdTxFDLe.js} +1 -1
  44. package/dist/assets/{WithTooltip-7X4HQR7L-2Hfrkir-.js → WithTooltip-7X4HQR7L-DZzTNMQ7.js} +1 -1
  45. package/dist/assets/{accordion-item.stories-D-MjrX5G.js → accordion-item.stories-Bl26JlHp.js} +1 -9
  46. package/dist/assets/{accordion.stories-icgNa1dl.js → accordion.stories-DjoLApQw.js} +3 -11
  47. package/dist/assets/{alert.stories-BzDaXtj-.js → alert.stories-pO1y3YCQ.js} +15 -31
  48. package/dist/assets/{badge-C5wOWgyg.js → badge-BTxW3bN2.js} +3 -11
  49. package/dist/assets/{badge.stories-5GfB4jVI.js → badge.stories-vqh63RJ2.js} +1 -1
  50. package/dist/assets/{band.stories-DhXaP_kL.js → band.stories-CjKRppSb.js} +1 -9
  51. package/dist/assets/{blocks-DhUVut8Z.js → blocks-1be_-L6v.js} +5 -5
  52. package/dist/assets/{breadcrumbs.stories-CrPUBVk1.js → breadcrumbs.stories-Doyfy3V9.js} +2 -18
  53. package/dist/assets/{button-CJL8yzAT.js → button-CgaWukz0.js} +1 -9
  54. package/dist/assets/{button-group-BgwgtSFC.js → button-group-G7qN4MwM.js} +1 -9
  55. package/dist/assets/{button-group.stories-W-07gO63.js → button-group.stories-cL3Kay6M.js} +1 -1
  56. package/dist/assets/{button.stories-BPzJ-sCv.js → button.stories-C9HSpxWb.js} +6 -6
  57. package/dist/assets/{card.stories-mlFGY2Xn.js → card.stories-BbU8YymD.js} +3 -11
  58. package/dist/assets/{chart.stories-C8yuHHeK.js → chart.stories-BL4FxIA_.js} +1 -1
  59. package/dist/assets/{checkbox-field-item-iHcdmTNw.js → checkbox-field-item-DIMHcWM0.js} +1 -9
  60. package/dist/assets/{checkbox-field-item.stories-D1aVLDXn.js → checkbox-field-item.stories-XbB4x_lO.js} +1 -1
  61. package/dist/assets/{checkbox-field.stories-BoVB2jCx.js → checkbox-field.stories-YnqFUI4K.js} +2 -10
  62. package/dist/assets/{cre8-element-DfmMtHJO.js → cre8-element-B35i4Lyg.js} +1 -1
  63. package/dist/assets/{cre8-form-element-bQpK8UYN.js → cre8-form-element-Cfc5VeYV.js} +1 -1
  64. package/dist/assets/{danger-button.stories-Cb4ljnhQ.js → danger-button.stories-xh25hmfd.js} +1 -9
  65. package/dist/assets/{date-picker.stories-Cje3qk8D.js → date-picker.stories-DD_ctzEF.js} +1 -49
  66. package/dist/assets/{divider-B_PXBGWD.js → divider-xZ2KARHf.js} +2 -10
  67. package/dist/assets/{divider.stories-CtfeBqVV.js → divider.stories-Bk9oF-OV.js} +1 -1
  68. package/dist/assets/{dropdown-Cgwne34I.js → dropdown-BEP5x3CW.js} +6 -22
  69. package/dist/assets/{dropdown-item.stories-pXkDLRuv.js → dropdown-item.stories-Iaw_UrEP.js} +1 -1
  70. package/dist/assets/{dropdown.stories-DZnmHieY.js → dropdown.stories-B0OlKD7h.js} +1 -1
  71. package/dist/assets/{example-drug-card.stories-DTzLXTFx.js → example-drug-card.stories-Bp5JIeE_.js} +1 -1
  72. package/dist/assets/{f-po-C2WpbOFJ.js → f-po-BdPzDRD-.js} +1 -1
  73. package/dist/assets/{feature.stories-DffXdJch.js → feature.stories-DYE1Js70.js} +1 -9
  74. package/dist/assets/{field-DzYRqQb2.js → field-BpUYyRW1.js} +1 -9
  75. package/dist/assets/{field-note-DKXZiXLU.js → field-note-fccBckVl.js} +3 -11
  76. package/dist/assets/{field-note.stories-DS_0bQul.js → field-note.stories-BH9AZMbF.js} +1 -1
  77. package/dist/assets/{field.stories-BvXn0oG6.js → field.stories-BQPtmziK.js} +1 -1
  78. package/dist/assets/{footer.stories-C3ZibisU.js → footer.stories-DCWEciqD.js} +1 -9
  79. package/dist/assets/{form-example.stories-C-TuOeF2.js → form-example.stories-9IDC0AgX.js} +1 -1
  80. package/dist/assets/{formatter-L2YTDE3Q-CJVnxOUW.js → formatter-L2YTDE3Q-B9u1AOWn.js} +1 -1
  81. package/dist/assets/{global-nav-item-xQL7wVjY.js → global-nav-item-T4htN-yO.js} +6 -14
  82. package/dist/assets/{global-nav-item.stories-Dp9TE3aR.js → global-nav-item.stories-2dWRfCXv.js} +1 -1
  83. package/dist/assets/{global-nav.stories-B5Nk8JZ0.js → global-nav.stories-Fh1gScqg.js} +2 -10
  84. package/dist/assets/{grid-DYgnZBsd.js → grid-C5CKMXNe.js} +3 -19
  85. package/dist/assets/{grid.stories-BFiXTq2C.js → grid.stories-BLmCNdeA.js} +1 -1
  86. package/dist/assets/{header.stories-D1f7xhjV.js → header.stories-BkDrjJtj.js} +1 -9
  87. package/dist/assets/{heading-485Jz7JZ.js → heading-Dbka33DK.js} +2 -10
  88. package/dist/assets/{heading.stories-gPF_SmTc.js → heading.stories-Be40_bmG.js} +1 -1
  89. package/dist/assets/{hero.stories-BHlFNdvF.js → hero.stories-vRu7PZG9.js} +1 -9
  90. package/dist/assets/{icon-DeTLDzTS.js → icon-ChfRWXWy.js} +2 -10
  91. package/dist/assets/{icon-description-o-YaiEjK.js → icon-description-BBSwDykJ.js} +1 -1
  92. package/dist/assets/{icon-description.stories-BdPRvEwe.js → icon-description.stories-Cg6ekOme.js} +1 -1
  93. package/dist/assets/{icon.stories-BxWpqxT5.js → icon.stories-Cj4U7L5G.js} +1 -1
  94. package/dist/assets/if-defined-Bxnzk64Q.js +1 -0
  95. package/dist/assets/{iframe-dHvya7sk.js → iframe-BNJP6ovU.js} +35 -35
  96. package/dist/assets/{inline-alert.stories-FH0bQ0jh.js → inline-alert.stories-CygBYI02.js} +1 -9
  97. package/dist/assets/{layout-container.stories-D6Z6Kx78.js → layout-container.stories-TMyIJteJ.js} +2 -10
  98. package/dist/assets/{layout.stories-CNYuwC_r.js → layout.stories-ylRM-ANL.js} +7 -23
  99. package/dist/assets/{linelength-container.stories-pCRXZvxS.js → linelength-container.stories-Br2v8jXE.js} +1 -9
  100. package/dist/assets/{link-BpCiLxNW.js → link-CRE0Eqdo.js} +1 -9
  101. package/dist/assets/{link-list.stories-12vsAa1P.js → link-list.stories--y-urrVo.js} +7 -23
  102. package/dist/assets/{link.stories-DAoQtY4_.js → link.stories-C3WQOgkY.js} +2 -2
  103. package/dist/assets/{list.stories-D0N3yBIf.js → list.stories-Bd2bxkxn.js} +7 -23
  104. package/dist/assets/{loading-spinner-g6iJajXH.js → loading-spinner-C52KNq6y.js} +4 -12
  105. package/dist/assets/{loading-spinner.stories-B6_mgPxB.js → loading-spinner.stories-DPRGEeHT.js} +1 -1
  106. package/dist/assets/{logo.stories-BvMwN2qg.js → logo.stories-2LBqqraT.js} +1 -9
  107. package/dist/assets/{main.stories-pL4zefbs.js → main.stories-BQzD7iWD.js} +2 -10
  108. package/dist/assets/{medication-card.stories-DK1XGJic.js → medication-card.stories-Wc-hA0-s.js} +5 -5
  109. package/dist/assets/{medication-form.stories-Bj5dLp5S.js → medication-form.stories-DfFOCDaU.js} +1 -1
  110. package/dist/assets/{modal-CO0M4e_8.js → modal-CCfbY4fF.js} +1 -9
  111. package/dist/assets/{modal-BNu8xy08.js → modal-GglWRNJp.js} +1 -1
  112. package/dist/assets/{modal.stories-CHYBrq_E.js → modal.stories-CpybCs79.js} +1 -1
  113. package/dist/assets/{multi-select.stories-C9XXsWio.js → multi-select.stories-BhzEKRui.js} +1 -9
  114. package/dist/assets/{nav-container.stories-DU9fhvDu.js → nav-container.stories-Be1YlegP.js} +3 -11
  115. package/dist/assets/{page-header.stories-BrstKiEY.js → page-header.stories-BOVLQ0YF.js} +1 -9
  116. package/dist/assets/{pagination.stories-Bw2M2iOn.js → pagination.stories-D62sa_1K.js} +9 -25
  117. package/dist/assets/{percent-bar.stories-UQRXYUqd.js → percent-bar.stories-CYi4El7T.js} +1 -9
  118. package/dist/assets/{popover.stories-ZkwrRFpR.js → popover.stories-B9O8F4yv.js} +1 -9
  119. package/dist/assets/{primary-nav.stories-wqOKwgQn.js → primary-nav.stories-Bt-o7h45.js} +1 -17
  120. package/dist/assets/{progress-meter-TzASasu0.js → progress-meter-Dit59091.js} +1 -9
  121. package/dist/assets/{progress-meter.stories-qfJALZf8.js → progress-meter.stories-CYnOCmjo.js} +1 -1
  122. package/dist/assets/{progress-steps-item-KvW1d_7L.js → progress-steps-item-CWJsad0s.js} +1 -9
  123. package/dist/assets/{progress-steps-item.stories-uOn6tJ1W.js → progress-steps-item.stories-ePn_6bPn.js} +1 -1
  124. package/dist/assets/{progress-steps.stories-CKFPx8D0.js → progress-steps.stories-CblrEcXF.js} +1 -9
  125. package/dist/assets/{radio-field-item-CTaR50XR.js → radio-field-item-Bm-0RWPe.js} +5 -21
  126. package/dist/assets/{radio-field-item.stories-DQSLj8W1.js → radio-field-item.stories-y_TrTRIW.js} +1 -1
  127. package/dist/assets/{radio-field.stories-Btmc_Iep.js → radio-field.stories-CSWrbUrn.js} +1 -1
  128. package/dist/assets/{remove-tag-BSEZ7VT8.js → remove-tag-lCr57c5r.js} +1 -9
  129. package/dist/assets/{remove-tag.stories-diRKi7Ua.js → remove-tag.stories-CDfwCdvZ.js} +1 -1
  130. package/dist/assets/{request-prescription.stories-DQvra7ia.js → request-prescription.stories-O4zqokfb.js} +1 -1
  131. package/dist/assets/{sample-modal.stories-deE1EBfZ.js → sample-modal.stories-BZ4N2R2Z.js} +1 -1
  132. package/dist/assets/{section.stories-DF4mcy2O.js → section.stories-D_1InThX.js} +1 -9
  133. package/dist/assets/{select-tile-D-C8oSrm.js → select-tile-BqqB3ZtE.js} +2 -10
  134. package/dist/assets/{select-tile-list.stories-vsBQUIcl.js → select-tile-list.stories-Di4ILgV8.js} +1 -9
  135. package/dist/assets/{select-tile.stories-CqHzN5fc.js → select-tile.stories-D3h_6zlV.js} +6 -6
  136. package/dist/assets/{select.stories-8aOGxTtr.js → select.stories-BB2phP9A.js} +1 -9
  137. package/dist/assets/{skeleton-loader.stories-CwR2-aC5.js → skeleton-loader.stories-y4uml_kV.js} +5 -13
  138. package/dist/assets/{split-button.stories-CyfdrK4u.js → split-button.stories-C_82I4ME.js} +2 -10
  139. package/dist/assets/{spread-BPiNgQQF.js → spread-CnPic3C2.js} +1 -1
  140. package/dist/assets/state-DkQhleoO.js +1 -0
  141. package/dist/assets/{submenu.stories-CDhNzZzh.js → submenu.stories-UDtaREr1.js} +2 -18
  142. package/dist/assets/{syntaxhighlighter-T5IQBZDB-BzI6WxUR.js → syntaxhighlighter-T5IQBZDB-D-I_s_yD.js} +1 -1
  143. package/dist/assets/{table-header-CfcchoYz.js → table-header-2837i43H.js} +3 -51
  144. package/dist/assets/{table-object.stories-Bd5qdfMU.js → table-object.stories-D4KoI-wA.js} +1 -9
  145. package/dist/assets/{table.stories-DxuBe9dJ.js → table.stories-DUJDibEp.js} +1 -1
  146. package/dist/assets/{tabs.stories-Cpc3OHJx.js → tabs.stories-C06SngOF.js} +5 -29
  147. package/dist/assets/{tag-list.stories-BmyCmrTF.js → tag-list.stories-Du-IoYzu.js} +2 -10
  148. package/dist/assets/{tag-vQFuZneb.js → tag-oHGdclJl.js} +1 -9
  149. package/dist/assets/{tag.stories-DGzrNUbb.js → tag.stories-C5D5IbuK.js} +1 -1
  150. package/dist/assets/{tertiary-nav.stories-D4q5K-am.js → tertiary-nav.stories-B1GU8Zi4.js} +3 -19
  151. package/dist/assets/{text-link-4qLRIeJB.js → text-link-B3m3KEqY.js} +1 -9
  152. package/dist/assets/{text-link.stories-D6BRm2I5.js → text-link.stories-4O6qn82H.js} +1 -1
  153. package/dist/assets/{text-passage-DGaI5i2I.js → text-passage-xQVosjOr.js} +3 -19
  154. package/dist/assets/{text-passage.stories-DkmXVUhH.js → text-passage.stories-Da1nspwG.js} +1 -1
  155. package/dist/assets/{tooltip.stories-B7ADDq7o.js → tooltip.stories-DLKyyeKn.js} +6 -14
  156. package/dist/assets/{utility-nav.stories-ffXVvyLp.js → utility-nav.stories-B6xBFe7z.js} +5 -21
  157. package/dist/design-tokens/brands/cre8/css/tokens_brand.css +1 -1
  158. package/dist/design-tokens/core/scss/theming/component.css +1 -1
  159. package/dist/design-tokens/core/scss/theming/variables.css +1 -7
  160. package/dist/design-tokens/core/scss/theming/variables.scss +0 -11
  161. package/dist/icons/cre8-icons.svg +1 -1
  162. package/dist/iframe.html +1 -24
  163. package/dist/index.html +25 -77
  164. package/dist/project.json +1 -1
  165. package/lib/a2ui/renderer.d.ts +2 -1
  166. package/lib/a2ui/renderer.d.ts.map +1 -1
  167. package/lib/a2ui/renderer.js +1 -1
  168. package/lib/a2ui/renderer.js.map +1 -1
  169. package/lib/a2ui/stream/diff.d.ts +29 -0
  170. package/lib/a2ui/stream/diff.d.ts.map +1 -0
  171. package/lib/a2ui/stream/diff.js +131 -0
  172. package/lib/a2ui/stream/diff.js.map +1 -0
  173. package/lib/a2ui/stream/index.d.ts +12 -0
  174. package/lib/a2ui/stream/index.d.ts.map +1 -0
  175. package/lib/a2ui/stream/index.js +12 -0
  176. package/lib/a2ui/stream/index.js.map +1 -0
  177. package/lib/a2ui/stream/model.d.ts +67 -0
  178. package/lib/a2ui/stream/model.d.ts.map +1 -0
  179. package/lib/a2ui/stream/model.js +423 -0
  180. package/lib/a2ui/stream/model.js.map +1 -0
  181. package/lib/a2ui/stream/pointer.d.ts +35 -0
  182. package/lib/a2ui/stream/pointer.d.ts.map +1 -0
  183. package/lib/a2ui/stream/pointer.js +147 -0
  184. package/lib/a2ui/stream/pointer.js.map +1 -0
  185. package/lib/a2ui/stream/renderer.d.ts +52 -0
  186. package/lib/a2ui/stream/renderer.d.ts.map +1 -0
  187. package/lib/a2ui/stream/renderer.js +279 -0
  188. package/lib/a2ui/stream/renderer.js.map +1 -0
  189. package/lib/a2ui/stream/types.d.ts +174 -0
  190. package/lib/a2ui/stream/types.d.ts.map +1 -0
  191. package/lib/a2ui/stream/types.js +18 -0
  192. package/lib/a2ui/stream/types.js.map +1 -0
  193. package/lib/components/accordion/accordion.d.ts +15 -0
  194. package/lib/components/accordion/accordion.d.ts.map +1 -1
  195. package/lib/components/accordion/accordion.js +23 -0
  196. package/lib/components/accordion/accordion.js.map +1 -1
  197. package/lib/components/badge/badge.d.ts +5 -18
  198. package/lib/components/badge/badge.d.ts.map +1 -1
  199. package/lib/components/badge/badge.js +0 -15
  200. package/lib/components/badge/badge.js.map +1 -1
  201. package/lib/components/breadcrumbs/breadcrumbs.d.ts +14 -0
  202. package/lib/components/breadcrumbs/breadcrumbs.d.ts.map +1 -1
  203. package/lib/components/breadcrumbs/breadcrumbs.js +21 -0
  204. package/lib/components/breadcrumbs/breadcrumbs.js.map +1 -1
  205. package/lib/components/chart/chart.d.ts +3 -3
  206. package/lib/components/chart/chart.js +6 -6
  207. package/lib/components/chart/chart.js.map +1 -1
  208. package/lib/components/checkbox-field/checkbox-field.d.ts +19 -0
  209. package/lib/components/checkbox-field/checkbox-field.d.ts.map +1 -1
  210. package/lib/components/checkbox-field/checkbox-field.js +28 -0
  211. package/lib/components/checkbox-field/checkbox-field.js.map +1 -1
  212. package/lib/components/cre8-element.d.ts +19 -0
  213. package/lib/components/cre8-element.d.ts.map +1 -1
  214. package/lib/components/cre8-element.js +51 -2
  215. package/lib/components/cre8-element.js.map +1 -1
  216. package/lib/components/divider/divider.d.ts +1 -1
  217. package/lib/components/divider/divider.d.ts.map +1 -1
  218. package/lib/components/divider/divider.js.map +1 -1
  219. package/lib/components/dropdown/dropdown.d.ts +13 -0
  220. package/lib/components/dropdown/dropdown.d.ts.map +1 -1
  221. package/lib/components/dropdown/dropdown.js +19 -0
  222. package/lib/components/dropdown/dropdown.js.map +1 -1
  223. package/lib/components/dropdown-item/dropdown-item.d.ts +1 -1
  224. package/lib/components/dropdown-item/dropdown-item.js +2 -2
  225. package/lib/components/dropdown-item/dropdown-item.js.map +1 -1
  226. package/lib/components/heading/heading.d.ts +3 -5
  227. package/lib/components/heading/heading.d.ts.map +1 -1
  228. package/lib/components/heading/heading.js +2 -4
  229. package/lib/components/heading/heading.js.map +1 -1
  230. package/lib/components/icon/icon.d.ts +4 -4
  231. package/lib/components/icon/icon.js +6 -6
  232. package/lib/components/icon/icon.js.map +1 -1
  233. package/lib/components/link-list/link-list.d.ts +19 -0
  234. package/lib/components/link-list/link-list.d.ts.map +1 -1
  235. package/lib/components/link-list/link-list.js +19 -0
  236. package/lib/components/link-list/link-list.js.map +1 -1
  237. package/lib/components/list/list.d.ts +13 -0
  238. package/lib/components/list/list.d.ts.map +1 -1
  239. package/lib/components/list/list.js +15 -0
  240. package/lib/components/list/list.js.map +1 -1
  241. package/lib/components/modal/modal.d.ts +2 -2
  242. package/lib/components/modal/modal.js +2 -2
  243. package/lib/components/modal/modal.js.map +1 -1
  244. package/lib/components/multi-select/multi-select.d.ts +2 -2
  245. package/lib/components/multi-select/multi-select.js +5 -5
  246. package/lib/components/multi-select/multi-select.js.map +1 -1
  247. package/lib/components/pagination/pagination.d.ts +1 -1
  248. package/lib/components/pagination/pagination.js +2 -2
  249. package/lib/components/pagination/pagination.js.map +1 -1
  250. package/lib/components/percent-bar/percent-bar.d.ts +2 -0
  251. package/lib/components/percent-bar/percent-bar.d.ts.map +1 -1
  252. package/lib/components/percent-bar/percent-bar.js +3 -1
  253. package/lib/components/percent-bar/percent-bar.js.map +1 -1
  254. package/lib/components/popover/popover.d.ts +6 -7
  255. package/lib/components/popover/popover.d.ts.map +1 -1
  256. package/lib/components/popover/popover.js +4 -4
  257. package/lib/components/popover/popover.js.map +1 -1
  258. package/lib/components/progress-meter/progress-meter.d.ts +0 -8
  259. package/lib/components/progress-meter/progress-meter.d.ts.map +1 -1
  260. package/lib/components/progress-meter/progress-meter.js +0 -7
  261. package/lib/components/progress-meter/progress-meter.js.map +1 -1
  262. package/lib/components/progress-steps/progress-steps.d.ts +16 -0
  263. package/lib/components/progress-steps/progress-steps.d.ts.map +1 -1
  264. package/lib/components/progress-steps/progress-steps.js +25 -0
  265. package/lib/components/progress-steps/progress-steps.js.map +1 -1
  266. package/lib/components/progress-steps-item/progress-steps-item.d.ts +1 -3
  267. package/lib/components/progress-steps-item/progress-steps-item.d.ts.map +1 -1
  268. package/lib/components/progress-steps-item/progress-steps-item.js +0 -1
  269. package/lib/components/progress-steps-item/progress-steps-item.js.map +1 -1
  270. package/lib/components/radio-field/radio-field.d.ts +33 -0
  271. package/lib/components/radio-field/radio-field.d.ts.map +1 -1
  272. package/lib/components/radio-field/radio-field.js +62 -0
  273. package/lib/components/radio-field/radio-field.js.map +1 -1
  274. package/lib/components/remove-tag/remove-tag.d.ts +1 -1
  275. package/lib/components/remove-tag/remove-tag.js +3 -3
  276. package/lib/components/remove-tag/remove-tag.js.map +1 -1
  277. package/lib/components/split-button/split-button.d.ts +3 -0
  278. package/lib/components/split-button/split-button.d.ts.map +1 -1
  279. package/lib/components/split-button/split-button.js +5 -2
  280. package/lib/components/split-button/split-button.js.map +1 -1
  281. package/lib/components/tab/tab.d.ts +1 -1
  282. package/lib/components/tab/tab.js +3 -3
  283. package/lib/components/tab/tab.js.map +1 -1
  284. package/lib/components/table/table.d.ts +36 -0
  285. package/lib/components/table/table.d.ts.map +1 -1
  286. package/lib/components/table/table.js +55 -0
  287. package/lib/components/table/table.js.map +1 -1
  288. package/lib/components/tabs/tabs.d.ts +20 -3
  289. package/lib/components/tabs/tabs.d.ts.map +1 -1
  290. package/lib/components/tabs/tabs.js +33 -5
  291. package/lib/components/tabs/tabs.js.map +1 -1
  292. package/lib/components/tag-list/tag-list.d.ts +17 -0
  293. package/lib/components/tag-list/tag-list.d.ts.map +1 -1
  294. package/lib/components/tag-list/tag-list.js +25 -0
  295. package/lib/components/tag-list/tag-list.js.map +1 -1
  296. package/lib/components/tooltip/tooltip.d.ts +2 -2
  297. package/lib/components/tooltip/tooltip.js +4 -4
  298. package/lib/components/tooltip/tooltip.js.map +1 -1
  299. package/lib/components/utils/light-children.d.ts +40 -0
  300. package/lib/components/utils/light-children.d.ts.map +1 -0
  301. package/lib/components/utils/light-children.js +100 -0
  302. package/lib/components/utils/light-children.js.map +1 -0
  303. package/lib/design-tokens/brands/cre8/css/tokens_brand.css +1 -1
  304. package/lib/directives/if-truthy.d.ts +1 -1
  305. package/lib/icons/cre8-icons.svg +1 -1
  306. package/lib/light-children-TlEXev5S.js +39 -0
  307. package/lib/scripts/generate-react-wrappers.d.ts +8 -1
  308. package/lib/scripts/generate-react-wrappers.d.ts.map +1 -1
  309. package/lib/scripts/generate-react-wrappers.js +45 -1
  310. package/lib/scripts/generate-react-wrappers.js.map +1 -1
  311. package/mcp-manifest.json +163 -53
  312. package/package.json +11 -4
  313. package/react-manifest.json +154 -48
  314. package/dist/assets/if-defined-HKKhGupN.js +0 -1
  315. package/dist/assets/iframe-CWwoGI65.css +0 -1
  316. package/dist/assets/state-CfuknrX8.js +0 -1
  317. package/dist/fonts/PlusJakartaSans-Bold.woff2 +0 -0
  318. package/dist/fonts/PlusJakartaSans-Medium.woff2 +0 -0
  319. package/dist/fonts/PlusJakartaSans-Regular.woff2 +0 -0
  320. package/dist/fonts/PlusJakartaSans-SemiBold.woff2 +0 -0
  321. package/dist/logo.svg +0 -1
  322. package/dist/sb-addons/storybook-4/manager-bundle.js +0 -8
  323. /package/dist/icons/{express-scripts copy.svg → pharmacy copy.svg} +0 -0
  324. /package/dist/icons/{express-scripts.svg → pharmacy.svg} +0 -0
  325. /package/lib/icons/{express-scripts copy.svg → pharmacy copy.svg} +0 -0
  326. /package/lib/icons/{express-scripts.svg → pharmacy.svg} +0 -0
@@ -0,0 +1,472 @@
1
+ /**
2
+ * SurfaceModel — the authoritative, DOM-free state of a streaming surface.
3
+ *
4
+ * The model runs identically in Node and in the browser. That is the point: the
5
+ * MCP server applies a patch to reject it at the tool boundary and to keep a
6
+ * canonical snapshot for late joiners, and the browser applies the same patch to
7
+ * move real DOM. One set of apply-semantics, two hosts.
8
+ *
9
+ * Every message is applied atomically to a draft. If any op fails validation,
10
+ * the draft is discarded and the surface is left exactly as it was — a rejected
11
+ * patch never half-lands.
12
+ */
13
+
14
+ import type { ComponentSpec, RegisteredCatalog, SpecChild } from '../types.js';
15
+ import { validateSpec } from '../registry.js';
16
+ import { childPath, parsePath, pointerGet, pointerRemove, pointerSet } from './pointer.js';
17
+ import {
18
+ A2UI_STREAM_VERSION,
19
+ isBindingRef,
20
+ type ContentTarget,
21
+ type DataPatch,
22
+ type PatchOp,
23
+ type SurfaceChange,
24
+ type SurfaceMessage,
25
+ type SurfaceState,
26
+ } from './types.js';
27
+
28
+ export interface SurfaceModelOptions {
29
+ surfaceId?: string;
30
+ title?: string;
31
+ data?: Record<string, unknown>;
32
+ /**
33
+ * Reject a message whose `seq` is not exactly one past the last applied one.
34
+ * On by default — a silent gap is how a streamed UI ends up subtly wrong.
35
+ * Messages with no `seq` are always accepted (local, in-process use).
36
+ */
37
+ strictSeq?: boolean;
38
+ }
39
+
40
+ export interface ApplyResult {
41
+ changes: SurfaceChange[];
42
+ seq: number;
43
+ }
44
+
45
+ export class SurfaceSeqGapError extends Error {
46
+ constructor(
47
+ readonly expected: number,
48
+ readonly received: number
49
+ ) {
50
+ super(`surface message out of order: expected seq ${expected}, received ${received}`);
51
+ this.name = 'SurfaceSeqGapError';
52
+ }
53
+ }
54
+
55
+ function clone<T>(value: T): T {
56
+ if (value === undefined || value === null) return value;
57
+ const sc = (globalThis as { structuredClone?: <U>(v: U) => U }).structuredClone;
58
+ return sc ? sc(value) : (JSON.parse(JSON.stringify(value)) as T);
59
+ }
60
+
61
+ /**
62
+ * Deep-copy a node with `{ $bind }` prop values replaced by their data-model
63
+ * values. An unresolvable binding with no `default` drops the prop entirely
64
+ * rather than passing `undefined` through — a prop that is absent is a prop the
65
+ * validator and the renderer both handle correctly.
66
+ */
67
+ export function resolveNode(node: SpecChild, data: Record<string, unknown>): SpecChild {
68
+ if (typeof node === 'string') return node;
69
+ const out: ComponentSpec = { component: node.component };
70
+
71
+ if (node.props) {
72
+ const props: Record<string, unknown> = {};
73
+ for (const [key, value] of Object.entries(node.props)) {
74
+ if (isBindingRef(value)) {
75
+ const resolved = pointerGet(data, value.$bind);
76
+ const effective = resolved === undefined ? value.default : resolved;
77
+ if (effective !== undefined) props[key] = clone(effective);
78
+ } else {
79
+ props[key] = clone(value);
80
+ }
81
+ }
82
+ out.props = props;
83
+ }
84
+
85
+ if (node.events) out.events = clone(node.events);
86
+ if (node.children) out.children = node.children.map((c) => resolveNode(c, data));
87
+ if (node.slots) {
88
+ const slots: Record<string, SpecChild[]> = {};
89
+ for (const [name, arr] of Object.entries(node.slots)) {
90
+ slots[name] = arr.map((c) => resolveNode(c, data));
91
+ }
92
+ out.slots = slots;
93
+ }
94
+ return out;
95
+ }
96
+
97
+ export class SurfaceModel {
98
+ readonly catalog: RegisteredCatalog;
99
+ surfaceId: string;
100
+ title: string | undefined;
101
+ state: SurfaceState = 'idle';
102
+ seq = 0;
103
+ data: Record<string, unknown>;
104
+
105
+ private readonly strictSeq: boolean;
106
+ private _root: ComponentSpec | null = null;
107
+
108
+ constructor(catalog: RegisteredCatalog, options: SurfaceModelOptions = {}) {
109
+ this.catalog = catalog;
110
+ this.surfaceId = options.surfaceId ?? 'surface';
111
+ this.title = options.title;
112
+ this.data = options.data ? clone(options.data) : {};
113
+ this.strictSeq = options.strictSeq !== false;
114
+ }
115
+
116
+ get root(): ComponentSpec | null {
117
+ return this._root;
118
+ }
119
+
120
+ /** The tree with every binding resolved — what a renderer or snapshot sees. */
121
+ snapshot(): ComponentSpec | null {
122
+ return this._root ? (resolveNode(this._root, this.data) as ComponentSpec) : null;
123
+ }
124
+
125
+ /** The raw (unresolved) node at `path`. Throws if nothing is there. */
126
+ nodeAt(path: string): SpecChild {
127
+ return nodeAtIn(this._root, path);
128
+ }
129
+
130
+ /** The resolved node at `path` — bindings substituted. */
131
+ resolvedAt(path: string): SpecChild {
132
+ return resolveNode(this.nodeAt(path), this.data);
133
+ }
134
+
135
+ apply(message: SurfaceMessage): ApplyResult {
136
+ const version = (message as { v?: number }).v;
137
+ if (version !== undefined && version !== A2UI_STREAM_VERSION) {
138
+ throw new Error(`unsupported surface protocol version ${String(version)}`);
139
+ }
140
+ if (this.strictSeq && typeof message.seq === 'number' && message.type !== 'surface.create') {
141
+ const expected = this.seq + 1;
142
+ if (message.seq !== expected) throw new SurfaceSeqGapError(expected, message.seq);
143
+ }
144
+
145
+ let changes: SurfaceChange[];
146
+ switch (message.type) {
147
+ case 'surface.create':
148
+ changes = this.applyCreate(message);
149
+ break;
150
+ case 'surface.patch':
151
+ changes = this.applyOps(message.ops);
152
+ break;
153
+ case 'surface.data':
154
+ changes = this.applyData(message.patches);
155
+ break;
156
+ case 'surface.status':
157
+ this.state = message.state;
158
+ changes = [];
159
+ break;
160
+ case 'surface.delete':
161
+ this._root = null;
162
+ this.state = 'done';
163
+ changes = [{ kind: 'root' }];
164
+ break;
165
+ default: {
166
+ const bad = message as { type?: unknown };
167
+ throw new Error(`unknown surface message type ${JSON.stringify(bad.type)}`);
168
+ }
169
+ }
170
+
171
+ if (typeof message.seq === 'number') this.seq = message.seq;
172
+ else this.seq += 1;
173
+ return { changes, seq: this.seq };
174
+ }
175
+
176
+ private applyCreate(message: Extract<SurfaceMessage, { type: 'surface.create' }>): SurfaceChange[] {
177
+ if (message.catalogId && message.catalogId !== this.catalog.id) {
178
+ throw new Error(
179
+ `surface.create: catalogId "${message.catalogId}" does not match registered catalog "${this.catalog.id}"`
180
+ );
181
+ }
182
+ this.surfaceId = message.surfaceId ?? this.surfaceId;
183
+ if (message.title !== undefined) this.title = message.title;
184
+ this.data = message.data ? clone(message.data) : {};
185
+ if (message.root) {
186
+ const draft = clone(message.root);
187
+ validateSpec(resolveNode(draft, this.data), this.catalog, '$');
188
+ this._root = draft;
189
+ } else {
190
+ this._root = null;
191
+ }
192
+ this.state = 'streaming';
193
+ return [{ kind: 'root' }];
194
+ }
195
+
196
+ private applyData(patches: DataPatch[]): SurfaceChange[] {
197
+ if (!Array.isArray(patches)) throw new Error('surface.data: patches must be an array');
198
+ const draft = clone(this.data);
199
+ let next: Record<string, unknown> = draft;
200
+ for (const patch of patches) {
201
+ if (!patch || typeof patch.pointer !== 'string') {
202
+ throw new Error('surface.data: each patch needs a string "pointer"');
203
+ }
204
+ if (patch.op === 'remove') pointerRemove(next, patch.pointer);
205
+ else next = pointerSet(next, patch.pointer, patch.value) as Record<string, unknown>;
206
+ }
207
+ // A binding can feed a validated enum prop, so data changes are validated too.
208
+ if (this._root) validateSpec(resolveNode(this._root, next), this.catalog, '$');
209
+ this.data = next;
210
+ return [{ kind: 'data' }];
211
+ }
212
+
213
+ private applyOps(ops: PatchOp[]): SurfaceChange[] {
214
+ if (!Array.isArray(ops)) throw new Error('surface.patch: ops must be an array');
215
+
216
+ // Ops mutate the live tree in place, because node object identity is how a
217
+ // renderer keeps an element (and its focus and state) across a patch. The
218
+ // backup buys back atomicity: if any op in the message fails, the surface is
219
+ // restored whole and the error is marked `rolledBack` so a renderer knows
220
+ // its identity map is now stale and it must remount.
221
+ const backup: ComponentSpec | null = clone(this._root);
222
+ const draft = { root: this._root };
223
+ const changes: SurfaceChange[] = [];
224
+ // Paths whose subtree must revalidate. Validating a container covers the
225
+ // nodes inserted into it, because validateSpec recurses.
226
+ const toValidate = new Set<string>();
227
+
228
+ try {
229
+ for (const op of ops) {
230
+ changes.push(...this.applyOp(draft, op, toValidate));
231
+ }
232
+ for (const path of toValidate) {
233
+ if (path === '$') {
234
+ if (draft.root) validateSpec(resolveNode(draft.root, this.data), this.catalog, '$');
235
+ continue;
236
+ }
237
+ const node = nodeAtIn(draft.root, path);
238
+ if (typeof node === 'string') continue;
239
+ validateSpec(resolveNode(node, this.data), this.catalog, path);
240
+ }
241
+ } catch (error) {
242
+ this._root = backup;
243
+ if (error instanceof Error) (error as Error & { rolledBack?: boolean }).rolledBack = true;
244
+ throw error;
245
+ }
246
+
247
+ this._root = draft.root;
248
+ return changes;
249
+ }
250
+
251
+ private applyOp(
252
+ draft: { root: ComponentSpec | null },
253
+ op: PatchOp,
254
+ toValidate: Set<string>
255
+ ): SurfaceChange[] {
256
+ if (!op || typeof (op as { op?: unknown }).op !== 'string') {
257
+ throw new Error('surface.patch: each op needs a string "op"');
258
+ }
259
+ if (typeof op.path !== 'string') {
260
+ throw new Error(`surface.patch: op "${op.op}" needs a string "path"`);
261
+ }
262
+
263
+ // Root-level structural ops are their own case: there is no parent to splice.
264
+ if (op.path === '$' && (op.op === 'replace' || op.op === 'remove')) {
265
+ if (op.op === 'remove') {
266
+ draft.root = null;
267
+ return [{ kind: 'root' }];
268
+ }
269
+ if (typeof op.node === 'string') {
270
+ throw new Error('$: the surface root must be a component, not a text node');
271
+ }
272
+ draft.root = clone(op.node);
273
+ toValidate.add('$');
274
+ return [{ kind: 'root' }];
275
+ }
276
+
277
+ if (op.op === 'replace' || op.op === 'remove') {
278
+ const { parent, list, index, slot, parentPath } = locateChild(draft.root, op.path);
279
+ if (op.op === 'remove') {
280
+ list.splice(index, 1);
281
+ pruneEmpty(parent, slot, list);
282
+ } else {
283
+ list[index] = clone(op.node);
284
+ }
285
+ toValidate.add(parentPath);
286
+ return [{ kind: 'content', path: parentPath, slot }];
287
+ }
288
+
289
+ const target = requireComponent(draft.root, op.path);
290
+
291
+ switch (op.op) {
292
+ case 'setProps': {
293
+ if (!op.props || typeof op.props !== 'object' || Array.isArray(op.props)) {
294
+ throw new Error(`${op.path}: setProps needs a "props" object`);
295
+ }
296
+ const props = { ...(target.props ?? {}) };
297
+ for (const [key, value] of Object.entries(op.props)) {
298
+ if (value === null) delete props[key];
299
+ else props[key] = clone(value);
300
+ }
301
+ if (Object.keys(props).length) target.props = props;
302
+ else delete target.props;
303
+ toValidate.add(op.path);
304
+ return [{ kind: 'props', path: op.path }];
305
+ }
306
+
307
+ case 'setEvents': {
308
+ if (!op.events || typeof op.events !== 'object' || Array.isArray(op.events)) {
309
+ throw new Error(`${op.path}: setEvents needs an "events" object`);
310
+ }
311
+ const events = { ...(target.events ?? {}) } as Record<string, unknown>;
312
+ for (const [key, value] of Object.entries(op.events)) {
313
+ if (value === null) delete events[key];
314
+ else events[key] = clone(value);
315
+ }
316
+ if (Object.keys(events).length) target.events = events as ComponentSpec['events'];
317
+ else delete target.events;
318
+ toValidate.add(op.path);
319
+ return [{ kind: 'events', path: op.path }];
320
+ }
321
+
322
+ case 'append':
323
+ case 'insert': {
324
+ const nodes = op.nodes;
325
+ if (!Array.isArray(nodes)) throw new Error(`${op.path}: ${op.op} needs a "nodes" array`);
326
+ const slot = normalizeSlot(op.slot);
327
+ const list = contentList(target, slot);
328
+ const at = op.op === 'append' ? list.length : clampIndex(op.index, list.length, op.path);
329
+ list.splice(at, 0, ...nodes.map((n) => clone(n)));
330
+ toValidate.add(op.path);
331
+ return [{ kind: 'content', path: op.path, slot }];
332
+ }
333
+
334
+ case 'clear': {
335
+ const slot = normalizeSlot(op.slot);
336
+ const list = contentList(target, slot);
337
+ list.length = 0;
338
+ pruneEmpty(target, slot, list);
339
+ toValidate.add(op.path);
340
+ return [{ kind: 'content', path: op.path, slot }];
341
+ }
342
+
343
+ case 'setText': {
344
+ if (typeof op.text !== 'string') throw new Error(`${op.path}: setText needs a "text" string`);
345
+ const slot = normalizeSlot(op.slot);
346
+ const list = contentList(target, slot);
347
+ list.length = 0;
348
+ list.push(op.text);
349
+ toValidate.add(op.path);
350
+ return [{ kind: 'content', path: op.path, slot }];
351
+ }
352
+
353
+ case 'appendText': {
354
+ if (typeof op.text !== 'string') {
355
+ throw new Error(`${op.path}: appendText needs a "text" string`);
356
+ }
357
+ const slot = normalizeSlot(op.slot);
358
+ const list = contentList(target, slot);
359
+ const last = list[list.length - 1];
360
+ if (typeof last === 'string') {
361
+ list[list.length - 1] = last + op.text;
362
+ toValidate.add(op.path);
363
+ return [{ kind: 'text', path: op.path, slot }];
364
+ }
365
+ list.push(op.text);
366
+ toValidate.add(op.path);
367
+ return [{ kind: 'content', path: op.path, slot }];
368
+ }
369
+
370
+ default: {
371
+ const bad = op as { op?: unknown };
372
+ throw new Error(`unknown patch op ${JSON.stringify(bad.op)}`);
373
+ }
374
+ }
375
+ }
376
+ }
377
+
378
+ // ─── helpers ────────────────────────────────────────────────────────────────
379
+
380
+ function normalizeSlot(slot: ContentTarget | undefined): ContentTarget {
381
+ return slot === undefined ? null : slot;
382
+ }
383
+
384
+ function clampIndex(index: unknown, length: number, path: string): number {
385
+ if (!Number.isInteger(index)) throw new Error(`${path}: insert needs an integer "index"`);
386
+ const i = index as number;
387
+ if (i < 0 || i > length) {
388
+ throw new Error(`${path}: insert index ${i} out of range 0..${length}`);
389
+ }
390
+ return i;
391
+ }
392
+
393
+ function contentList(spec: ComponentSpec, slot: ContentTarget): SpecChild[] {
394
+ if (slot === null) {
395
+ if (!spec.children) spec.children = [];
396
+ return spec.children;
397
+ }
398
+ if (!spec.slots) spec.slots = {};
399
+ if (!spec.slots[slot]) spec.slots[slot] = [];
400
+ return spec.slots[slot];
401
+ }
402
+
403
+ /**
404
+ * Drop an emptied `children`/`slots` container. Leaving `children: []` behind on
405
+ * a slot-only component would turn a legal spec into a validation error the next
406
+ * time anything touched it.
407
+ */
408
+ function pruneEmpty(spec: ComponentSpec, slot: ContentTarget, list: SpecChild[]): void {
409
+ if (list.length > 0) return;
410
+ if (slot === null) {
411
+ delete spec.children;
412
+ return;
413
+ }
414
+ if (spec.slots) {
415
+ delete spec.slots[slot];
416
+ if (Object.keys(spec.slots).length === 0) delete spec.slots;
417
+ }
418
+ }
419
+
420
+ function nodeAtIn(root: ComponentSpec | null, path: string): SpecChild {
421
+ if (!root) throw new Error(`${path}: surface has no root`);
422
+ let cur: SpecChild = root;
423
+ for (const seg of parsePath(path)) {
424
+ if (typeof cur === 'string') throw new Error(`${path}: cannot descend into a text node`);
425
+ const list: SpecChild[] | undefined =
426
+ seg.kind === 'children' ? cur.children : cur.slots?.[seg.name];
427
+ const next: SpecChild | undefined = list?.[seg.index];
428
+ if (next === undefined) throw new Error(`${path}: no node at this path`);
429
+ cur = next;
430
+ }
431
+ return cur;
432
+ }
433
+
434
+ function requireComponent(root: ComponentSpec | null, path: string): ComponentSpec {
435
+ const node = nodeAtIn(root, path);
436
+ if (typeof node === 'string') {
437
+ throw new Error(`${path}: expected a component node, found a text node`);
438
+ }
439
+ return node;
440
+ }
441
+
442
+ /** Resolve a child path to its parent, the list holding it, and its index. */
443
+ function locateChild(
444
+ root: ComponentSpec | null,
445
+ path: string
446
+ ): {
447
+ parent: ComponentSpec;
448
+ parentPath: string;
449
+ list: SpecChild[];
450
+ index: number;
451
+ slot: ContentTarget;
452
+ } {
453
+ const segments = parsePath(path);
454
+ if (segments.length === 0) throw new Error('$: has no parent');
455
+ const last = segments[segments.length - 1];
456
+ const parentPath = segments.length === 1 ? '$' : pathOf(segments.slice(0, -1));
457
+ const parent = requireComponent(root, parentPath);
458
+ const slot: ContentTarget = last.kind === 'children' ? null : last.name;
459
+ const list = last.kind === 'children' ? parent.children : parent.slots?.[last.name];
460
+ if (!list || list[last.index] === undefined) throw new Error(`${path}: no node at this path`);
461
+ return { parent, parentPath, list, index: last.index, slot };
462
+ }
463
+
464
+ function pathOf(segments: ReturnType<typeof parsePath>): string {
465
+ let out = '$';
466
+ for (const seg of segments) {
467
+ out += seg.kind === 'children' ? `.children[${seg.index}]` : `.slots.${seg.name}[${seg.index}]`;
468
+ }
469
+ return out;
470
+ }
471
+
472
+ export { childPath };
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Two addressing schemes, kept in one file because they are easy to confuse.
3
+ *
4
+ * **Spec paths** (`$.slots.footer[0].children[2]`) address nodes in the
5
+ * component tree. This grammar is not invented here — it is what the one-shot
6
+ * renderer already puts in `EmittedEvent.path`, which is why streaming can reuse
7
+ * it as node identity.
8
+ *
9
+ * **JSON Pointers** (`/user/name`) address values in the surface data model,
10
+ * per RFC 6901.
11
+ */
12
+ export type PathSegment = {
13
+ kind: 'children';
14
+ index: number;
15
+ } | {
16
+ kind: 'slot';
17
+ name: string;
18
+ index: number;
19
+ };
20
+ /** Parse `$.slots.footer[0]` into segments. Throws on malformed input. */
21
+ export declare function parsePath(path: string): PathSegment[];
22
+ export declare function formatPath(segments: PathSegment[]): string;
23
+ /** `$.children[0]` + `{children,2}` → `$.children[0].children[2]`. */
24
+ export declare function childPath(parentPath: string, slot: string | null, index: number): string;
25
+ export declare function parsePointer(pointer: string): string[];
26
+ export declare function pointerGet(root: unknown, pointer: string): unknown;
27
+ /**
28
+ * Write `value` at `pointer`, creating intermediate containers as needed. An
29
+ * array is created when the next token looks like an index, an object otherwise.
30
+ * Mutates and returns `root` — except for the whole-document pointer `""`,
31
+ * where the caller must use the returned value.
32
+ */
33
+ export declare function pointerSet(root: Record<string, unknown>, pointer: string, value: unknown): unknown;
34
+ export declare function pointerRemove(root: Record<string, unknown>, pointer: string): void;
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Two addressing schemes, kept in one file because they are easy to confuse.
3
+ *
4
+ * **Spec paths** (`$.slots.footer[0].children[2]`) address nodes in the
5
+ * component tree. This grammar is not invented here — it is what the one-shot
6
+ * renderer already puts in `EmittedEvent.path`, which is why streaming can reuse
7
+ * it as node identity.
8
+ *
9
+ * **JSON Pointers** (`/user/name`) address values in the surface data model,
10
+ * per RFC 6901.
11
+ */
12
+ const SEGMENT_RE = /^\.(?:children\[(\d+)\]|slots\.([A-Za-z_][\w-]*)\[(\d+)\])/;
13
+ /** Parse `$.slots.footer[0]` into segments. Throws on malformed input. */
14
+ export function parsePath(path) {
15
+ if (typeof path !== 'string' || path.length === 0) {
16
+ throw new Error(`path: must be a non-empty string, got ${JSON.stringify(path)}`);
17
+ }
18
+ if (path[0] !== '$') {
19
+ throw new Error(`path "${path}": must start with "$"`);
20
+ }
21
+ const segments = [];
22
+ let rest = path.slice(1);
23
+ while (rest.length > 0) {
24
+ const m = SEGMENT_RE.exec(rest);
25
+ if (!m) {
26
+ throw new Error(`path "${path}": cannot parse at "${rest}" — expected ".children[N]" or ".slots.NAME[N]"`);
27
+ }
28
+ if (m[1] !== undefined) {
29
+ segments.push({ kind: 'children', index: Number(m[1]) });
30
+ }
31
+ else {
32
+ segments.push({ kind: 'slot', name: m[2], index: Number(m[3]) });
33
+ }
34
+ rest = rest.slice(m[0].length);
35
+ }
36
+ return segments;
37
+ }
38
+ export function formatPath(segments) {
39
+ let out = '$';
40
+ for (const seg of segments) {
41
+ out += seg.kind === 'children' ? `.children[${seg.index}]` : `.slots.${seg.name}[${seg.index}]`;
42
+ }
43
+ return out;
44
+ }
45
+ /** `$.children[0]` + `{children,2}` → `$.children[0].children[2]`. */
46
+ export function childPath(parentPath, slot, index) {
47
+ return slot === null || slot === undefined
48
+ ? `${parentPath}.children[${index}]`
49
+ : `${parentPath}.slots.${slot}[${index}]`;
50
+ }
51
+ // ─── RFC 6901 JSON Pointer ──────────────────────────────────────────────────
52
+ function unescapeToken(token) {
53
+ return token.replace(/~1/g, '/').replace(/~0/g, '~');
54
+ }
55
+ export function parsePointer(pointer) {
56
+ if (pointer === '' || pointer === '/')
57
+ return [];
58
+ if (pointer[0] !== '/') {
59
+ throw new Error(`pointer "${pointer}": must be empty or start with "/"`);
60
+ }
61
+ return pointer.slice(1).split('/').map(unescapeToken);
62
+ }
63
+ export function pointerGet(root, pointer) {
64
+ let cur = root;
65
+ for (const token of parsePointer(pointer)) {
66
+ if (cur === null || cur === undefined)
67
+ return undefined;
68
+ if (Array.isArray(cur)) {
69
+ const i = Number(token);
70
+ if (!Number.isInteger(i))
71
+ return undefined;
72
+ cur = cur[i];
73
+ }
74
+ else if (typeof cur === 'object') {
75
+ cur = cur[token];
76
+ }
77
+ else {
78
+ return undefined;
79
+ }
80
+ }
81
+ return cur;
82
+ }
83
+ /**
84
+ * Write `value` at `pointer`, creating intermediate containers as needed. An
85
+ * array is created when the next token looks like an index, an object otherwise.
86
+ * Mutates and returns `root` — except for the whole-document pointer `""`,
87
+ * where the caller must use the returned value.
88
+ */
89
+ export function pointerSet(root, pointer, value) {
90
+ const tokens = parsePointer(pointer);
91
+ if (tokens.length === 0)
92
+ return value;
93
+ let cur = root;
94
+ for (let i = 0; i < tokens.length - 1; i++) {
95
+ const token = tokens[i];
96
+ const container = cur;
97
+ const existing = Array.isArray(container)
98
+ ? container[Number(token)]
99
+ : container[token];
100
+ if (existing === undefined || existing === null || typeof existing !== 'object') {
101
+ const next = /^\d+$/.test(tokens[i + 1]) ? [] : {};
102
+ if (Array.isArray(container))
103
+ container[Number(token)] = next;
104
+ else
105
+ container[token] = next;
106
+ cur = next;
107
+ }
108
+ else {
109
+ cur = existing;
110
+ }
111
+ }
112
+ const last = tokens[tokens.length - 1];
113
+ if (Array.isArray(cur)) {
114
+ if (last === '-')
115
+ cur.push(value);
116
+ else
117
+ cur[Number(last)] = value;
118
+ }
119
+ else {
120
+ cur[last] = value;
121
+ }
122
+ return root;
123
+ }
124
+ export function pointerRemove(root, pointer) {
125
+ const tokens = parsePointer(pointer);
126
+ if (tokens.length === 0) {
127
+ for (const key of Object.keys(root))
128
+ delete root[key];
129
+ return;
130
+ }
131
+ let cur = root;
132
+ for (let i = 0; i < tokens.length - 1; i++) {
133
+ if (cur === null || typeof cur !== 'object')
134
+ return;
135
+ cur = Array.isArray(cur)
136
+ ? cur[Number(tokens[i])]
137
+ : cur[tokens[i]];
138
+ }
139
+ if (cur === null || typeof cur !== 'object')
140
+ return;
141
+ const last = tokens[tokens.length - 1];
142
+ if (Array.isArray(cur))
143
+ cur.splice(Number(last), 1);
144
+ else
145
+ delete cur[last];
146
+ }