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