@jxsuite/studio 6.1.1 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/chunks/2020-5wtzce5g.js +4 -0
- package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
- package/dist/chunks/adapter-5tphg7xe.js +4 -0
- package/dist/chunks/add-new-flow-psym14sn.js +4 -0
- package/dist/chunks/cf-account-picker-haqazq5r.js +4 -0
- package/dist/chunks/cf-settings-h2wrh6hq.js +4 -0
- package/dist/chunks/color-area-6rbra5dy.js +4 -0
- package/dist/chunks/color-field-gy56c94g.js +4 -0
- package/dist/chunks/color-m7r1vk54.js +4 -0
- package/dist/chunks/color-slider-sqqdyf6c.js +4 -0
- package/dist/chunks/combobox-72h32ejk.js +4 -0
- package/dist/chunks/components-r22xca09.js +4 -0
- package/dist/chunks/content-source-mmppmcyg.js +4 -0
- package/dist/chunks/convert-to-repeater-he70fc2b.js +4 -0
- package/dist/chunks/dialog-c4x05vyx.js +4 -0
- package/dist/chunks/editor-ccd9jwsa.js +4 -0
- package/dist/chunks/entry-commands-6qxz9e8p.js +4 -0
- package/dist/chunks/extension-sections-0egb88dm.js +4 -0
- package/dist/chunks/file-ops-qnab36ek.js +4 -0
- package/dist/chunks/files-rcn56qvm.js +4 -0
- package/dist/chunks/format-host-yxz0kjjs.js +4 -0
- package/dist/chunks/fs-events-d1qxq4z4.js +4 -0
- package/dist/chunks/grid-open-4z1g062t.js +4 -0
- package/dist/chunks/grid-view-qg1b5eqx.js +51 -0
- package/dist/chunks/icons-63bjtbs7.js +4 -0
- package/dist/chunks/iframe-entry-2zggzajv.js +5 -0
- package/dist/chunks/iframe-entry-76j8vwwx.js +5 -0
- package/dist/chunks/iframe-entry-99nr5zfb.js +5 -0
- package/dist/chunks/iframe-entry-pkgmcgp0.js +5 -0
- package/dist/chunks/iframe-host-ssv7kyj0.js +4 -0
- package/dist/chunks/{index-2veqmnhr.js → index-32eqzv1k.js} +3 -3
- package/dist/chunks/index-f0jn7nnp.js +4 -0
- package/dist/chunks/{javascript-8nbvs12s.js → javascript-pjp734q4.js} +3 -3
- package/dist/chunks/jsonMode-njkvsa02.js +13 -0
- package/dist/chunks/jx-validate-ttasrbh7.js +4 -0
- package/dist/chunks/layers-bgyr11tr.js +4 -0
- package/dist/chunks/layers-panel-7ez66zeq.js +4 -0
- package/dist/chunks/listbox-c421cf8c.js +4 -0
- package/dist/chunks/lit-html-v9gh687x.js +4 -0
- package/dist/chunks/media-library-sq468wts.js +4 -0
- package/dist/chunks/media-picker-shfe59pt.js +4 -0
- package/dist/chunks/menu-bdpzbfvs.js +4 -0
- package/dist/chunks/monaco-binding-vq1hgnn0.js +4 -0
- package/dist/chunks/monaco-buffer-3afgwvbp.js +4 -0
- package/dist/chunks/monaco-setup-xrd2cbkp.js +4 -0
- package/dist/chunks/notify-kzrjr3fv.js +4 -0
- package/dist/chunks/number-field-y62xq0ty.js +4 -0
- package/dist/chunks/parse-v77xtwv7.js +4 -0
- package/dist/chunks/platform-7v4rtd7m.js +4 -0
- package/dist/chunks/popover-b89sfej7.js +4 -0
- package/dist/chunks/publish-panel-2z9gw8ee.js +4 -0
- package/dist/chunks/publish-quick-qx2455cj.js +4 -0
- package/dist/chunks/publish-workspace-wrc1dgwx.js +4 -0
- package/dist/chunks/quick-search-n0t0eqxb.js +4 -0
- package/dist/chunks/references-9547rg5s.js +4 -0
- package/dist/chunks/right-panel-wsgnr9pn.js +4 -0
- package/dist/chunks/select-rzds841e.js +4 -0
- package/dist/chunks/source-control-kwktr9y6.js +4 -0
- package/dist/chunks/split-c9zfdgxf.js +4 -0
- package/dist/chunks/studio-03ct6yfv.js +9 -0
- package/dist/chunks/studio-07rcfje3.js +5 -0
- package/dist/chunks/studio-3e54qh39.js +7 -0
- package/dist/chunks/studio-3exxhz5g.js +5 -0
- package/dist/chunks/studio-3q40e3rj.js +5 -0
- package/dist/chunks/studio-3qeh9t0h.js +6 -0
- package/dist/chunks/studio-3qqjeep5.js +6 -0
- package/dist/chunks/studio-43sd2mam.js +4 -0
- package/dist/chunks/studio-4hp8pkyt.js +5 -0
- package/dist/chunks/studio-58xg6j2q.js +9 -0
- package/dist/chunks/studio-5g0rprdt.js +7 -0
- package/dist/chunks/studio-6m380wp7.js +5 -0
- package/dist/chunks/studio-80jyh1xh.js +4 -0
- package/dist/chunks/studio-83mk4bgg.js +9 -0
- package/dist/chunks/{studio-kggey1jt.js → studio-881z1xrx.js} +4 -4
- package/dist/chunks/studio-8m0y2qe7.js +5 -0
- package/dist/chunks/studio-8tr6cfrc.js +5 -0
- package/dist/chunks/studio-8vcvfs7r.js +6 -0
- package/dist/chunks/studio-9tmebf0s.js +5 -0
- package/dist/chunks/studio-a2bvaptz.js +5 -0
- package/dist/chunks/studio-b7y5mr30.js +5 -0
- package/dist/chunks/studio-bavb31r0.js +5 -0
- package/dist/chunks/studio-bbe4c90a.js +5 -0
- package/dist/chunks/studio-c05wdnt3.js +5 -0
- package/dist/chunks/studio-ccv2svc6.js +5 -0
- package/dist/chunks/studio-d5grtb9e.js +16 -0
- package/dist/chunks/studio-df0baea9.js +5 -0
- package/dist/chunks/studio-dgk4dqtx.js +7 -0
- package/dist/chunks/studio-e1g64q43.js +5 -0
- package/dist/chunks/studio-ed1hp6zf.js +6 -0
- package/dist/chunks/studio-ed3xx40h.js +7 -0
- package/dist/chunks/studio-f14e1zdj.js +5 -0
- package/dist/chunks/studio-fbhxxc5f.js +5 -0
- package/dist/chunks/studio-fyh0jc96.js +5 -0
- package/dist/chunks/studio-gcxk20n7.js +5 -0
- package/dist/chunks/studio-jaaz8ce9.js +5 -0
- package/dist/chunks/{studio-8grwxtqk.js → studio-jcnsdaep.js} +4 -4
- package/dist/chunks/studio-jsgf2q5k.js +7 -0
- package/dist/chunks/{studio-1q1sh2ax.js → studio-k3xxbagr.js} +3 -3
- package/dist/chunks/studio-k7evxqh4.js +5 -0
- package/dist/chunks/studio-kt3pjkwd.js +5 -0
- package/dist/chunks/studio-m8g16bgz.js +5 -0
- package/dist/chunks/studio-mn0476ag.js +5 -0
- package/dist/chunks/studio-mx1smyq0.js +5 -0
- package/dist/chunks/studio-n0c5h6mf.js +5 -0
- package/dist/chunks/{studio-rv11kfwa.js → studio-nh6d342n.js} +7 -7
- package/dist/chunks/studio-nqxqf8p2.js +4 -0
- package/dist/chunks/studio-p4nrkvqr.js +5 -0
- package/dist/chunks/{studio-h46vtzk8.js → studio-pbxa5fpc.js} +4 -4
- package/dist/chunks/studio-pgmvdv7z.js +7 -0
- package/dist/chunks/studio-ph84avkf.js +5 -0
- package/dist/chunks/{studio-wszjyh0j.js → studio-q0mvbaq6.js} +4 -4
- package/dist/chunks/studio-q0tccd43.js +5 -0
- package/dist/chunks/studio-q7rtx6zq.js +14 -0
- package/dist/chunks/{studio-pre0skq6.js → studio-qgh13jtz.js} +4 -4
- package/dist/chunks/studio-qmn1xc24.js +5 -0
- package/dist/chunks/studio-qwdqwkj0.js +5 -0
- package/dist/chunks/{studio-t6b6qe31.js → studio-r5qy30vx.js} +4 -4
- package/dist/chunks/studio-rj9eamf8.js +5 -0
- package/dist/chunks/studio-rptgsk96.js +5 -0
- package/dist/chunks/studio-rthyg42z.js +928 -0
- package/dist/chunks/studio-s19tp1xr.js +5 -0
- package/dist/chunks/studio-s32578pn.js +5 -0
- package/dist/chunks/studio-svb7yyve.js +5 -0
- package/dist/chunks/studio-syreb644.js +5 -0
- package/dist/chunks/studio-tf9jryb1.js +10 -0
- package/dist/chunks/studio-tfkznv39.js +5 -0
- package/dist/chunks/studio-tft6r105.js +5 -0
- package/dist/chunks/studio-txf2kysx.js +5 -0
- package/dist/chunks/studio-v8867ddv.js +12 -0
- package/dist/chunks/studio-vxq7fcvv.js +5 -0
- package/dist/chunks/studio-w4rz9hdk.js +5 -0
- package/dist/chunks/studio-wbcjbhy1.js +9 -0
- package/dist/chunks/studio-wc649wss.js +5 -0
- package/dist/chunks/studio-wys23mxz.js +5 -0
- package/dist/chunks/studio-x1x167jh.js +5 -0
- package/dist/chunks/studio-x9hsze61.js +5 -0
- package/dist/chunks/studio-y0n7yxea.js +9 -0
- package/dist/chunks/studio-y3ahhdpx.js +5 -0
- package/dist/chunks/studio-z97c48fk.js +5 -0
- package/dist/chunks/studio-zat62m0c.js +5 -0
- package/dist/chunks/studio-zcd2e7yz.js +5 -0
- package/dist/chunks/studio-zz9qe3rw.js +64 -0
- package/dist/chunks/swatch-group-ewh24n1f.js +4 -0
- package/dist/chunks/tabs-f5cw3tgp.js +4 -0
- package/dist/chunks/textfield-wewc8rq2.js +4 -0
- package/dist/chunks/toast-1gv0h53h.js +4 -0
- package/dist/chunks/toast-host-1yg5ar8d.js +4 -0
- package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
- package/dist/chunks/tooltip-yypz28gq.js +4 -0
- package/dist/chunks/tree-9xa4hm7n.js +4 -0
- package/dist/chunks/tsMode-epyfz1hv.js +14 -0
- package/dist/chunks/workspace-dz7nxfhv.js +4 -0
- package/dist/chunks/workspace-home-xsd7hkjw.js +4 -0
- package/dist/chunks/ws-client-bv552sfx.js +4 -0
- package/dist/iframe-entry.js +20 -16
- package/dist/manifest.json +77 -63
- package/dist/studio.js +106 -107
- package/dist/workers/ts.worker.js +3 -3
- package/package.json +17 -16
- package/src/about/about-modal.ts +4 -3
- package/src/account/action-flow.ts +45 -38
- package/src/account-status.ts +7 -2
- package/src/browse/component-examples.ts +272 -0
- package/src/browse/library-commands.ts +64 -104
- package/src/browse/library-layouts.ts +270 -53
- package/src/browse/library-model.ts +194 -134
- package/src/browse/library-pane.ts +748 -440
- package/src/browse/library-preview.ts +161 -26
- package/src/browse/library-source.ts +308 -41
- package/src/browse/preview-root.ts +78 -0
- package/src/browse/preview-style.ts +155 -0
- package/src/canvas/asset-refs.ts +40 -10
- package/src/canvas/asset-resolve.ts +19 -23
- package/src/canvas/canvas-helpers.ts +7 -6
- package/src/canvas/canvas-live-render.ts +260 -77
- package/src/canvas/canvas-origin.ts +37 -12
- package/src/canvas/canvas-page-context.ts +112 -0
- package/src/canvas/canvas-patcher.ts +30 -30
- package/src/canvas/canvas-perf.ts +11 -5
- package/src/canvas/canvas-render.ts +175 -148
- package/src/canvas/canvas-surface.ts +5 -3
- package/src/canvas/canvas-utils.ts +147 -61
- package/src/canvas/dialog-path.ts +9 -4
- package/src/canvas/dialog-state.ts +1 -2
- package/src/canvas/diff-marks.ts +9 -16
- package/src/canvas/diff-toolbar.ts +8 -7
- package/src/canvas/edit-width-drag.ts +4 -1
- package/src/canvas/edit-width.ts +1 -3
- package/src/canvas/iframe-channel.ts +27 -13
- package/src/canvas/iframe-drop.ts +120 -12
- package/src/canvas/iframe-editable-root.ts +29 -16
- package/src/canvas/iframe-entry.ts +104 -75
- package/src/canvas/iframe-eval.ts +73 -49
- package/src/canvas/iframe-host.ts +269 -158
- package/src/canvas/iframe-inline-edit.ts +49 -30
- package/src/canvas/iframe-insert.ts +5 -4
- package/src/canvas/iframe-interaction.ts +30 -25
- package/src/canvas/iframe-keys.ts +11 -0
- package/src/canvas/iframe-overlay.ts +1 -1
- package/src/canvas/iframe-patch.ts +25 -21
- package/src/canvas/iframe-position.ts +12 -6
- package/src/canvas/iframe-protocol.ts +36 -21
- package/src/canvas/iframe-render.ts +84 -35
- package/src/canvas/iframe-slash.ts +24 -11
- package/src/canvas/iframe-subtree.ts +10 -3
- package/src/canvas/npm-modules.ts +22 -0
- package/src/canvas/path-mapping.ts +19 -12
- package/src/canvas/popover-path.ts +7 -3
- package/src/canvas/popover-state.ts +1 -2
- package/src/canvas/preview-navigate.ts +16 -0
- package/src/canvas/repeater-sources.ts +200 -0
- package/src/canvas/serialize-scope.ts +13 -5
- package/src/canvas/stage-scrollbar.ts +7 -2
- package/src/canvas/surface-registry.ts +27 -3
- package/src/collab/collab-commands.ts +7 -2
- package/src/collab/collab-session.ts +84 -45
- package/src/collab/collab-state.ts +4 -3
- package/src/collab/monaco-binding.ts +16 -13
- package/src/collab/monaco-cursors.ts +5 -2
- package/src/commands/app-commands.ts +16 -6
- package/src/commands/budget.ts +13 -11
- package/src/commands/command-args.ts +103 -71
- package/src/commands/context.ts +55 -28
- package/src/commands/defaults.ts +69 -45
- package/src/commands/keymap.ts +56 -43
- package/src/commands/levels.ts +14 -8
- package/src/commands/live-context.ts +9 -7
- package/src/commands/reference.ts +2 -1
- package/src/commands/registry.ts +22 -11
- package/src/commands/run-reported.ts +15 -10
- package/src/component-props.ts +46 -30
- package/src/content/collection-match.ts +11 -9
- package/src/content/collection-pages.ts +412 -0
- package/src/content/content-collections.ts +270 -0
- package/src/content/draft-state.ts +4 -3
- package/src/content/entry-commands.ts +54 -62
- package/src/content/entry-editor.ts +137 -32
- package/src/content/entry-fields.ts +25 -8
- package/src/content/entry-inspector.ts +225 -0
- package/src/content/entry-model.ts +38 -15
- package/src/content/entry-open.ts +80 -0
- package/src/content/entry-summaries.ts +440 -0
- package/src/content/file-record-ids.ts +80 -0
- package/src/content/file-records.ts +125 -0
- package/src/content/page-summaries.ts +129 -0
- package/src/content/record-entry.ts +201 -0
- package/src/content/writing-banner.ts +177 -0
- package/src/create/add-new-commands.ts +185 -0
- package/src/create/add-new-flow.ts +1116 -0
- package/src/create/add-new.ts +1014 -0
- package/src/create/element-name.ts +121 -0
- package/src/editor/canvas-context-menu.ts +1 -2
- package/src/editor/canvas-slash-bridge.ts +3 -6
- package/src/editor/content-slice.ts +16 -14
- package/src/editor/context-menu.ts +35 -22
- package/src/editor/convert-targets.ts +30 -35
- package/src/editor/convert-to-component.ts +78 -48
- package/src/editor/convert-to-repeater.ts +34 -22
- package/src/editor/editable-tags.ts +17 -2
- package/src/editor/file-drop-action.ts +29 -22
- package/src/editor/inline-edit-apply.ts +79 -17
- package/src/editor/inline-edit.ts +76 -50
- package/src/editor/inline-format.ts +59 -56
- package/src/editor/inline-link.ts +40 -15
- package/src/editor/insert-component.ts +91 -0
- package/src/editor/insert-zone-action.ts +14 -5
- package/src/editor/merge-tags.ts +58 -19
- package/src/editor/repeater-scope.ts +39 -28
- package/src/editor/shortcuts.ts +76 -42
- package/src/editor/slash-menu.ts +52 -14
- package/src/files/asset-versions.ts +4 -4
- package/src/files/components.ts +89 -20
- package/src/files/elements.ts +5 -6
- package/src/files/file-ops.ts +92 -41
- package/src/files/files.ts +248 -239
- package/src/files/fs-events.ts +18 -7
- package/src/files/media-meta.ts +97 -2
- package/src/files/media-paths.ts +3 -0
- package/src/files/media-types.ts +55 -0
- package/src/files/media-upload.ts +209 -52
- package/src/files/new-file-name.ts +156 -0
- package/src/files/serialize-document.ts +15 -5
- package/src/format/constraints.ts +1 -1
- package/src/format/convert-file.ts +27 -13
- package/src/format/format-choices.ts +2 -1
- package/src/format/format-host.ts +91 -50
- package/src/github/github-auth-status.ts +27 -3
- package/src/github/github-auth.ts +21 -11
- package/src/github/github-publish.ts +28 -23
- package/src/grid/cell-editors.ts +46 -31
- package/src/grid/cell-popovers.ts +5 -3
- package/src/grid/edit-buffer.ts +10 -9
- package/src/grid/grid-controller.ts +25 -23
- package/src/grid/grid-layout.ts +21 -5
- package/src/grid/grid-open.ts +3 -33
- package/src/grid/grid-panel.ts +65 -6
- package/src/grid/grid-reveal.ts +34 -0
- package/src/grid/grid-source.ts +9 -31
- package/src/grid/grid-view.ts +45 -23
- package/src/grid/redirects-grid.ts +14 -5
- package/src/grid/redirects.ts +16 -14
- package/src/grid/schema-columns.ts +25 -19
- package/src/grid/sources/connector-source.ts +47 -20
- package/src/grid/sources/content-source.ts +100 -31
- package/src/grid/sources/csv-file-source.ts +2 -2
- package/src/grid/tabulator-tables.d.ts +61 -34
- package/src/hosting/document.ts +2 -2
- package/src/hosting/stage.ts +7 -7
- package/src/i18n/i18n-commands.ts +3 -3
- package/src/media/media-commands.ts +181 -0
- package/src/media/media-library-model.ts +232 -0
- package/src/media/media-library.ts +1283 -0
- package/src/media/media-pane.ts +51 -20
- package/src/new-project/add-repo-modal.ts +20 -19
- package/src/new-project/import-tab.ts +10 -14
- package/src/new-project/location-fields.ts +2 -1
- package/src/new-project/new-project-modal.ts +12 -9
- package/src/packages/jxsuite-update.ts +4 -3
- package/src/packages/pull-package-sync.ts +26 -25
- package/src/page-params.ts +97 -68
- package/src/panels/activity-panel.ts +38 -14
- package/src/panels/ai-chat/attached-context.ts +13 -7
- package/src/panels/ai-chat/chat-markdown.ts +8 -8
- package/src/panels/ai-chat/chat-view.ts +80 -73
- package/src/panels/ai-chat/composer.ts +30 -33
- package/src/panels/ai-chat/sessions-view.ts +1 -2
- package/src/panels/ai-panel.ts +23 -20
- package/src/panels/block-action-bar.ts +57 -46
- package/src/panels/bottom-dock.ts +5 -3
- package/src/panels/canvas-dnd-bridge.ts +36 -26
- package/src/panels/chat-panel.ts +6 -6
- package/src/panels/collections-panel.ts +306 -0
- package/src/panels/component-preview.ts +35 -13
- package/src/panels/data-explorer.ts +63 -26
- package/src/panels/data-grid.ts +18 -11
- package/src/panels/dnd.ts +115 -138
- package/src/panels/editors.ts +52 -21
- package/src/panels/elements-panel.ts +19 -5
- package/src/panels/empty-state.ts +2 -2
- package/src/panels/events-panel.ts +84 -69
- package/src/panels/formula-workspace.ts +78 -54
- package/src/panels/frontmatter-fields.ts +33 -28
- package/src/panels/git-diff-open.ts +10 -6
- package/src/panels/head-panel.ts +488 -202
- package/src/panels/i18n-panel.ts +20 -12
- package/src/panels/imports-panel.ts +25 -47
- package/src/panels/jump-bar.ts +75 -31
- package/src/panels/layers-panel.ts +130 -101
- package/src/panels/left-panel.ts +25 -11
- package/src/panels/navigator-panels.ts +23 -11
- package/src/panels/pane-context.ts +140 -49
- package/src/panels/pane-grid.ts +55 -26
- package/src/panels/panel-registry.ts +36 -46
- package/src/panels/properties-panel.ts +182 -124
- package/src/panels/quick-search.ts +53 -31
- package/src/panels/right-panel.ts +201 -45
- package/src/panels/seo-modal.ts +54 -125
- package/src/panels/settings-menu.ts +63 -61
- package/src/panels/settings-pane.ts +268 -162
- package/src/panels/signals-panel.ts +156 -135
- package/src/panels/site-model.ts +367 -0
- package/src/panels/site-panel.ts +638 -0
- package/src/panels/statement-editor.ts +230 -140
- package/src/panels/style-panel.ts +253 -206
- package/src/panels/style-utils.ts +114 -51
- package/src/panels/stylebook-doc.ts +195 -60
- package/src/panels/stylebook-layers-panel.ts +48 -89
- package/src/panels/stylebook-panel.ts +60 -27
- package/src/panels/styles-panel.ts +327 -0
- package/src/panels/tab-drop.ts +27 -11
- package/src/panels/tab-strip.ts +143 -49
- package/src/platform-errors.ts +57 -43
- package/src/platform.ts +59 -31
- package/src/platforms/cloud.ts +373 -176
- package/src/platforms/default-platform.ts +14 -8
- package/src/platforms/devserver.ts +180 -142
- package/src/platforms/read-batcher.ts +16 -8
- package/src/project-list.ts +2 -1
- package/src/publish/deploy-checklist.ts +20 -9
- package/src/publish/pages-service.ts +66 -27
- package/src/publish/publish-changes.ts +491 -0
- package/src/publish/publish-commands.ts +88 -22
- package/src/publish/publish-ids.ts +49 -0
- package/src/publish/publish-panel.ts +10 -6
- package/src/publish/publish-quick.ts +148 -0
- package/src/publish/publish-workspace.ts +926 -0
- package/src/publish/source-control.ts +907 -0
- package/src/recent-projects.ts +15 -8
- package/src/resize-edges.ts +26 -36
- package/src/services/a11y-report.ts +26 -19
- package/src/services/agent-seed.ts +23 -11
- package/src/services/ai-ask.ts +9 -12
- package/src/services/ai-command-tools.ts +68 -62
- package/src/services/ai-import-tools.ts +80 -67
- package/src/services/ai-models.ts +17 -13
- package/src/services/ai-project-tools.ts +68 -32
- package/src/services/ai-session-store.ts +19 -10
- package/src/services/ai-system-prompt.ts +46 -20
- package/src/services/ai-tools.ts +71 -27
- package/src/services/ai-write-report.ts +20 -12
- package/src/services/ai-writes.ts +4 -4
- package/src/services/automation.ts +74 -51
- package/src/services/cem-export.ts +149 -58
- package/src/services/cf-settings.ts +4 -4
- package/src/services/clock.ts +6 -1
- package/src/services/code-services.ts +37 -31
- package/src/services/connection.ts +2 -2
- package/src/services/context-manager.ts +14 -10
- package/src/services/context-resolver.ts +20 -8
- package/src/services/data-service.ts +19 -15
- package/src/services/directory-picker.ts +20 -14
- package/src/services/document-assistant.ts +39 -19
- package/src/services/gated-registry.ts +10 -6
- package/src/services/harness/chat-reducer.ts +23 -1
- package/src/services/import-client.ts +91 -38
- package/src/services/import-seed.ts +8 -2
- package/src/services/jx-validate.ts +28 -31
- package/src/services/live-preview.ts +0 -0
- package/src/services/live-surfaces.ts +6 -3
- package/src/services/model-uri.ts +10 -2
- package/src/services/module-preloads.ts +12 -8
- package/src/services/monaco-buffer.ts +43 -24
- package/src/services/monaco-lazy.ts +7 -8
- package/src/services/monaco-setup.ts +23 -16
- package/src/services/notify.ts +44 -17
- package/src/services/popover-report.ts +25 -10
- package/src/services/preview-eval.ts +20 -8
- package/src/services/profile.ts +13 -6
- package/src/services/project-path.ts +13 -10
- package/src/services/references.ts +0 -0
- package/src/services/render-critic.ts +29 -9
- package/src/services/settings/definitions.ts +25 -14
- package/src/services/settings/kernel.ts +13 -4
- package/src/services/settings/write-queue.ts +9 -9
- package/src/services/token-lint.ts +12 -10
- package/src/services/tool-executor.ts +17 -5
- package/src/services/tool-outcomes.ts +44 -24
- package/src/services/trusted-types.ts +24 -7
- package/src/settings/contexts-section.ts +11 -8
- package/src/settings/contributed-section.ts +128 -70
- package/src/settings/css-vars-editor.ts +119 -32
- package/src/settings/defs-editor.ts +38 -35
- package/src/settings/developer-panels.ts +43 -0
- package/src/settings/extension-rows.ts +16 -8
- package/src/settings/extension-sections.ts +42 -14
- package/src/settings/extensions-section.ts +4 -1
- package/src/settings/general-settings.ts +101 -28
- package/src/settings/locales-section.ts +20 -12
- package/src/settings/preferences-dialog.ts +17 -7
- package/src/settings/preferences-keymap.ts +7 -5
- package/src/settings/preferences-sections.ts +11 -5
- package/src/settings/project-sections.ts +28 -11
- package/src/settings/schema-field-ui.ts +12 -1
- package/src/settings/section-registry.ts +116 -11
- package/src/settings/settings-dialog.ts +192 -0
- package/src/settings/settings-document.ts +186 -166
- package/src/shell/tree.ts +6 -5
- package/src/shell.ts +536 -477
- package/src/site-context.ts +101 -32
- package/src/state.ts +68 -57
- package/src/store.ts +54 -34
- package/src/studio.ts +219 -116
- package/src/style/live-preview.ts +1 -1
- package/src/style/project-styles.ts +40 -7
- package/src/style/stylebook-specimens.ts +89 -0
- package/src/style/stylebook-target.ts +26 -0
- package/src/style/tag-inheritance.ts +105 -0
- package/src/style/token-ref.ts +5 -4
- package/src/style/variables-focus.ts +61 -0
- package/src/style/variables-view.ts +235 -0
- package/src/surfaces/about.ts +18 -19
- package/src/surfaces/add-new.json +1482 -0
- package/src/surfaces/add-new.ts +325 -0
- package/src/surfaces/add-repo.ts +17 -19
- package/src/surfaces/ai-chat.ts +33 -38
- package/src/surfaces/ai-credentials-form.ts +6 -16
- package/src/surfaces/ai-managed-connect.ts +3 -4
- package/src/surfaces/ai-model-picker.ts +3 -5
- package/src/surfaces/block-action-bar.ts +22 -11
- package/src/surfaces/boot-failure.json +4 -3
- package/src/surfaces/boot-failure.ts +4 -5
- package/src/surfaces/bottom-dock.json +1 -1
- package/src/surfaces/bottom-dock.ts +9 -18
- package/src/surfaces/canvas-stage.json +30 -19
- package/src/surfaces/canvas-stage.ts +17 -16
- package/src/surfaces/cf-account-picker.ts +17 -18
- package/src/surfaces/collections-panel.json +615 -0
- package/src/surfaces/collections-panel.ts +168 -0
- package/src/surfaces/commandbar.json +241 -96
- package/src/surfaces/commandbar.ts +145 -105
- package/src/surfaces/convert-repeater.ts +17 -19
- package/src/surfaces/data-actions.ts +9 -7
- package/src/surfaces/dialog.ts +26 -28
- package/src/surfaces/diff-toolbar.ts +9 -7
- package/src/surfaces/empty-state.json +1 -1
- package/src/surfaces/empty-state.ts +7 -10
- package/src/surfaces/entry-editor.json +136 -0
- package/src/surfaces/entry-editor.ts +35 -11
- package/src/surfaces/entry-inspector.json +371 -0
- package/src/surfaces/entry-inspector.ts +143 -0
- package/src/surfaces/expression-editor.ts +11 -25
- package/src/surfaces/files-panel.ts +27 -14
- package/src/surfaces/formula-palette.ts +4 -5
- package/src/surfaces/github-auth.ts +16 -20
- package/src/surfaces/github-publish.ts +17 -22
- package/src/surfaces/grid-cell.ts +30 -31
- package/src/surfaces/grid-open.ts +10 -14
- package/src/surfaces/grid-panel.ts +13 -9
- package/src/surfaces/grid-replace.ts +13 -13
- package/src/surfaces/grid-views.ts +15 -18
- package/src/surfaces/inspector-dock.json +162 -14
- package/src/surfaces/inspector-dock.ts +59 -31
- package/src/surfaces/jump-bar.ts +5 -6
- package/src/surfaces/jxsuite-update.ts +16 -22
- package/src/surfaces/library-pane.json +670 -437
- package/src/surfaces/library-pane.ts +111 -77
- package/src/surfaces/logic-panel.ts +17 -30
- package/src/surfaces/logic-workspace.ts +13 -15
- package/src/surfaces/media-browser.json +62 -6
- package/src/surfaces/media-browser.ts +26 -11
- package/src/surfaces/media-field.json +1 -1
- package/src/surfaces/media-field.ts +4 -5
- package/src/surfaces/media-library.json +1586 -0
- package/src/surfaces/media-library.ts +282 -0
- package/src/surfaces/media-pane.ts +8 -7
- package/src/surfaces/media-pick-dialog.json +71 -0
- package/src/surfaces/media-pick-dialog.ts +132 -0
- package/src/surfaces/menu.ts +47 -23
- package/src/surfaces/navigator-dock.ts +11 -12
- package/src/surfaces/new-project.ts +27 -26
- package/src/surfaces/pane-context.json +144 -77
- package/src/surfaces/pane-context.ts +44 -25
- package/src/surfaces/pane-grid.ts +15 -10
- package/src/surfaces/panel-activity.ts +5 -6
- package/src/surfaces/panel-data.ts +3 -4
- package/src/surfaces/panel-deploy-checklist.json +12 -6
- package/src/surfaces/panel-deploy-checklist.ts +8 -7
- package/src/surfaces/panel-elements.ts +5 -7
- package/src/surfaces/panel-i18n.ts +5 -7
- package/src/surfaces/panel-imports.ts +6 -13
- package/src/surfaces/panel-outline.ts +25 -19
- package/src/surfaces/panel-page.json +72 -2
- package/src/surfaces/panel-page.ts +49 -25
- package/src/surfaces/panel-problems.ts +5 -7
- package/src/surfaces/panel-signals.json +1 -1
- package/src/surfaces/panel-signals.ts +25 -39
- package/src/surfaces/panel-stylebook-layers.json +71 -204
- package/src/surfaces/panel-stylebook-layers.ts +5 -29
- package/src/surfaces/preferences.json +120 -48
- package/src/surfaces/preferences.ts +29 -11
- package/src/surfaces/progress-modal.ts +15 -9
- package/src/surfaces/properties-panel.json +1 -1
- package/src/surfaces/properties-panel.ts +20 -42
- package/src/surfaces/publish-quick.json +428 -0
- package/src/surfaces/publish-quick.ts +165 -0
- package/src/surfaces/publish-workspace.json +2892 -0
- package/src/surfaces/publish-workspace.ts +391 -0
- package/src/surfaces/publish.ts +18 -18
- package/src/surfaces/push-plan.ts +7 -8
- package/src/surfaces/rail.json +1 -159
- package/src/surfaces/rail.ts +22 -79
- package/src/surfaces/reference-field.ts +11 -15
- package/src/surfaces/schema-builder.ts +16 -22
- package/src/surfaces/schema-form.json +10 -2
- package/src/surfaces/schema-form.ts +17 -25
- package/src/surfaces/secret-field.ts +9 -6
- package/src/surfaces/seo.json +1 -1
- package/src/surfaces/seo.ts +21 -15
- package/src/surfaces/settings-contexts.ts +9 -7
- package/src/surfaces/settings-contributed.json +5 -5
- package/src/surfaces/settings-contributed.ts +32 -12
- package/src/surfaces/settings-css-vars.json +44 -36
- package/src/surfaces/settings-css-vars.ts +82 -16
- package/src/surfaces/settings-defs.json +2 -2
- package/src/surfaces/settings-defs.ts +17 -21
- package/src/surfaces/settings-deploy.json +2 -15
- package/src/surfaces/settings-deploy.ts +9 -16
- package/src/surfaces/settings-dialog.json +51 -0
- package/src/surfaces/settings-dialog.ts +169 -0
- package/src/surfaces/settings-extensions.ts +5 -6
- package/src/surfaces/settings-head.ts +33 -39
- package/src/surfaces/settings-locales.ts +8 -20
- package/src/surfaces/settings-overview.json +3 -3
- package/src/surfaces/settings-overview.ts +14 -8
- package/src/surfaces/settings-packages.ts +8 -7
- package/src/surfaces/settings-pane.json +269 -46
- package/src/surfaces/settings-pane.ts +88 -36
- package/src/surfaces/settings-rawjson.ts +5 -6
- package/src/surfaces/shell.json +2 -1
- package/src/surfaces/shell.ts +1 -2
- package/src/surfaces/site-panel.json +1029 -0
- package/src/surfaces/site-panel.ts +233 -0
- package/src/surfaces/slash-menu.json +63 -21
- package/src/surfaces/slash-menu.ts +42 -9
- package/src/surfaces/statements.ts +13 -18
- package/src/surfaces/statusbar.ts +56 -29
- package/src/surfaces/style-panel.ts +18 -31
- package/src/surfaces/stylebook-chrome.ts +3 -5
- package/src/surfaces/styles-panel.json +735 -0
- package/src/surfaces/styles-panel.ts +195 -0
- package/src/surfaces/styles-variables.json +149 -0
- package/src/surfaces/styles-variables.ts +145 -0
- package/src/surfaces/tab-strip.json +4 -4
- package/src/surfaces/tab-strip.ts +14 -13
- package/src/surfaces/target-line.ts +6 -7
- package/src/surfaces/welcome.ts +6 -8
- package/src/surfaces/writing-banner.json +94 -0
- package/src/surfaces/writing-banner.ts +80 -0
- package/src/tabs/bare-repeaters.ts +101 -0
- package/src/tabs/patch-ops.ts +4 -3
- package/src/tabs/project-config.ts +32 -21
- package/src/tabs/selection.ts +36 -8
- package/src/tabs/tab.ts +99 -48
- package/src/tabs/transact.ts +98 -53
- package/src/types.ts +53 -43
- package/src/ui/ai-credentials-form.ts +10 -13
- package/src/ui/ai-model-picker.ts +3 -3
- package/src/ui/cf-account-picker.ts +7 -9
- package/src/ui/color-selector.ts +9 -5
- package/src/ui/dynamic-slot.ts +7 -8
- package/src/ui/expression-editor.ts +112 -105
- package/src/ui/form-controls.ts +104 -56
- package/src/ui/formula-catalog.ts +239 -230
- package/src/ui/formula-chips.ts +33 -18
- package/src/ui/layers.ts +57 -31
- package/src/ui/media-picker.ts +300 -47
- package/src/ui/popover-surface.ts +20 -12
- package/src/ui/progress-modal.ts +13 -8
- package/src/ui/regions.ts +14 -12
- package/src/ui/schema-form.ts +372 -97
- package/src/ui/surface.ts +71 -8
- package/src/ui/timing.ts +9 -0
- package/src/ui/value-source.ts +44 -31
- package/src/ui/virtual-window.ts +29 -3
- package/src/utils/base64.ts +6 -4
- package/src/utils/edit-display.ts +366 -111
- package/src/utils/element-selectors.ts +3 -2
- package/src/utils/google-fonts.ts +15 -14
- package/src/utils/inherited-style.ts +18 -20
- package/src/utils/link-target.ts +1 -1
- package/src/utils/local-day.ts +18 -0
- package/src/utils/preview-format.ts +25 -3
- package/src/utils/strip-events.ts +49 -22
- package/src/utils/studio-utils.ts +29 -14
- package/src/view.ts +2 -3
- package/src/workspace/pane-derive.ts +14 -16
- package/src/workspace/session.ts +81 -50
- package/src/workspace/tab-workspace.ts +137 -0
- package/src/workspace/workspace-back.ts +189 -0
- package/src/workspace/workspace-home.ts +133 -0
- package/src/workspace/workspace-ids.ts +129 -0
- package/src/workspace/workspace-switch.ts +372 -0
- package/src/workspace/workspace.ts +165 -47
- package/styles/shell-frame.css +30 -7
- package/styles/shell-frame.json +15 -3
- package/dist/chunks/2020-va2wwra4.js +0 -4
- package/dist/chunks/adapter-f93pafd7.js +0 -4
- package/dist/chunks/cf-account-picker-af1h381v.js +0 -4
- package/dist/chunks/cf-settings-125tdm0w.js +0 -4
- package/dist/chunks/color-area-jqhna8zy.js +0 -4
- package/dist/chunks/color-field-embq5ctg.js +0 -4
- package/dist/chunks/color-fpezvnkt.js +0 -4
- package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
- package/dist/chunks/combobox-773hdzyj.js +0 -4
- package/dist/chunks/components-ax2f1fnn.js +0 -4
- package/dist/chunks/content-source-108aqtk1.js +0 -4
- package/dist/chunks/convert-to-repeater-ry5rmppr.js +0 -4
- package/dist/chunks/dialog-mtm9fq5t.js +0 -4
- package/dist/chunks/editor-pfgdmkb0.js +0 -4
- package/dist/chunks/entry-commands-t0k1q0kx.js +0 -4
- package/dist/chunks/extension-sections-6mwh2hf8.js +0 -4
- package/dist/chunks/file-ops-meej5mqf.js +0 -4
- package/dist/chunks/files-44vp8a2s.js +0 -4
- package/dist/chunks/format-host-7q1petb9.js +0 -4
- package/dist/chunks/fs-events-h2mwnxaz.js +0 -4
- package/dist/chunks/git-panel-zngbymvd.js +0 -4
- package/dist/chunks/grid-view-sx9vynsp.js +0 -51
- package/dist/chunks/icons-p44xhjf0.js +0 -4
- package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
- package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
- package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
- package/dist/chunks/iframe-host-qk3ycq87.js +0 -4
- package/dist/chunks/index-wkyfjeqz.js +0 -4
- package/dist/chunks/jsonMode-s8kt9dsj.js +0 -13
- package/dist/chunks/jx-validate-psgd7vsx.js +0 -4
- package/dist/chunks/layers-panel-1kq2jyfk.js +0 -4
- package/dist/chunks/layers-xd92fg8d.js +0 -4
- package/dist/chunks/listbox-s8fkmnq8.js +0 -4
- package/dist/chunks/lit-html-ac4cwwr4.js +0 -4
- package/dist/chunks/media-picker-0svzkdyb.js +0 -4
- package/dist/chunks/menu-37d07z9m.js +0 -4
- package/dist/chunks/menu-5c55ea3d.js +0 -4
- package/dist/chunks/monaco-binding-z6r70pdt.js +0 -4
- package/dist/chunks/monaco-buffer-fz6gq5y7.js +0 -4
- package/dist/chunks/monaco-setup-q4axkgj7.js +0 -4
- package/dist/chunks/notify-0xgtn8q1.js +0 -4
- package/dist/chunks/number-field-gw7sq8rn.js +0 -4
- package/dist/chunks/parse-897fvqah.js +0 -4
- package/dist/chunks/platform-v1qctbe6.js +0 -4
- package/dist/chunks/popover-8htra4er.js +0 -4
- package/dist/chunks/publish-panel-ym1fmgq5.js +0 -4
- package/dist/chunks/quick-search-a54e6t5n.js +0 -4
- package/dist/chunks/references-gmqp82fs.js +0 -4
- package/dist/chunks/right-panel-v7t9awbk.js +0 -4
- package/dist/chunks/section-registry-vhyf3zsr.js +0 -4
- package/dist/chunks/select-n3v7gwas.js +0 -4
- package/dist/chunks/split-pff8f3ze.js +0 -4
- package/dist/chunks/studio-0bhx5hz6.js +0 -5
- package/dist/chunks/studio-0k1ddnyy.js +0 -6
- package/dist/chunks/studio-1b04pd0j.js +0 -64
- package/dist/chunks/studio-4dwbj6gb.js +0 -5
- package/dist/chunks/studio-4tanh828.js +0 -5
- package/dist/chunks/studio-55h4mstj.js +0 -4
- package/dist/chunks/studio-5tnvjkz4.js +0 -5
- package/dist/chunks/studio-60dqgb0c.js +0 -5
- package/dist/chunks/studio-61dp09qg.js +0 -9
- package/dist/chunks/studio-63epcrj2.js +0 -5
- package/dist/chunks/studio-74k29dy9.js +0 -5
- package/dist/chunks/studio-7vg6jcd3.js +0 -5
- package/dist/chunks/studio-7zx31knw.js +0 -9
- package/dist/chunks/studio-8bxk97km.js +0 -5
- package/dist/chunks/studio-933e30n4.js +0 -5
- package/dist/chunks/studio-98wnwhbg.js +0 -5
- package/dist/chunks/studio-9mccjwjh.js +0 -14
- package/dist/chunks/studio-a2ke1e4t.js +0 -5
- package/dist/chunks/studio-e3a2a6v3.js +0 -4
- package/dist/chunks/studio-e81q1vb9.js +0 -5
- package/dist/chunks/studio-epgrmqqm.js +0 -5
- package/dist/chunks/studio-ery42sqr.js +0 -4
- package/dist/chunks/studio-g1shz58g.js +0 -5
- package/dist/chunks/studio-gf0fz03c.js +0 -5
- package/dist/chunks/studio-gjtpe62q.js +0 -6
- package/dist/chunks/studio-gkskhg7m.js +0 -5
- package/dist/chunks/studio-gx4dnjzd.js +0 -5
- package/dist/chunks/studio-j03zga3y.js +0 -9
- package/dist/chunks/studio-jhpxeckz.js +0 -5
- package/dist/chunks/studio-k01r7ykp.js +0 -5
- package/dist/chunks/studio-kk7h30ne.js +0 -7
- package/dist/chunks/studio-kt1zqney.js +0 -5
- package/dist/chunks/studio-m3cwhvye.js +0 -5
- package/dist/chunks/studio-mcayt6hz.js +0 -5
- package/dist/chunks/studio-myjcghv3.js +0 -5
- package/dist/chunks/studio-n8bxwc3y.js +0 -4
- package/dist/chunks/studio-ngm8gvpb.js +0 -5
- package/dist/chunks/studio-nj5a01jy.js +0 -928
- package/dist/chunks/studio-pcgz8heb.js +0 -5
- package/dist/chunks/studio-qcsq0t15.js +0 -5
- package/dist/chunks/studio-qkstvve9.js +0 -5
- package/dist/chunks/studio-qv1pwd3c.js +0 -5
- package/dist/chunks/studio-rc6dvxjb.js +0 -7
- package/dist/chunks/studio-s8dmmz66.js +0 -5
- package/dist/chunks/studio-sp5xzbj4.js +0 -6
- package/dist/chunks/studio-szsjbj0g.js +0 -5
- package/dist/chunks/studio-t1xzawhr.js +0 -16
- package/dist/chunks/studio-tdcprbqb.js +0 -5
- package/dist/chunks/studio-vrmcjf9g.js +0 -7
- package/dist/chunks/studio-vyc0b4he.js +0 -10
- package/dist/chunks/studio-w0cgf6jg.js +0 -5
- package/dist/chunks/studio-w3hskzqk.js +0 -5
- package/dist/chunks/studio-xgrgcdyh.js +0 -9
- package/dist/chunks/studio-xz2yxfcb.js +0 -5
- package/dist/chunks/studio-y6n42tgs.js +0 -5
- package/dist/chunks/studio-yb560vxr.js +0 -5
- package/dist/chunks/studio-yn9f8vtx.js +0 -5
- package/dist/chunks/studio-yw05w8f0.js +0 -7
- package/dist/chunks/studio-z16sgavc.js +0 -5
- package/dist/chunks/studio-zey7zsdw.js +0 -12
- package/dist/chunks/studio-zyqn40w4.js +0 -5
- package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
- package/dist/chunks/tabs-jwthg40w.js +0 -4
- package/dist/chunks/textfield-spy3hc77.js +0 -4
- package/dist/chunks/toast-4d35zd64.js +0 -4
- package/dist/chunks/toast-host-8sjmfed3.js +0 -4
- package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
- package/dist/chunks/tree-h19v1jfz.js +0 -4
- package/dist/chunks/tsMode-2frah6h1.js +0 -14
- package/dist/chunks/workspace-zt81g1ms.js +0 -4
- package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
- package/src/panels/frontmatter-panel.ts +0 -701
- package/src/panels/git-panel.ts +0 -1120
- package/src/surfaces/doc-header.json +0 -776
- package/src/surfaces/doc-header.ts +0 -231
- package/src/surfaces/git-panel.json +0 -1880
- package/src/surfaces/git-panel.ts +0 -272
package/src/files/components.ts
CHANGED
|
@@ -4,7 +4,8 @@ import { getPlatform } from "../platform";
|
|
|
4
4
|
import { projectState } from "../store";
|
|
5
5
|
import type { ComponentMeta } from "../types";
|
|
6
6
|
import { componentMetaFrom } from "@jxsuite/schema/component-meta";
|
|
7
|
-
import
|
|
7
|
+
import { isNonNullObject, isString } from "@jxsuite/schema/guards";
|
|
8
|
+
import type { JsonValue, JxMutableNode } from "@jxsuite/schema/types";
|
|
8
9
|
|
|
9
10
|
/** A discovered component: project components carry a file path; package components may not. */
|
|
10
11
|
export interface ComponentEntry extends Omit<ComponentMeta, "path"> {
|
|
@@ -17,14 +18,39 @@ export interface ComponentEntry extends Omit<ComponentMeta, "path"> {
|
|
|
17
18
|
export let componentRegistry: ComponentEntry[] = [];
|
|
18
19
|
export let _componentRegistryLoaded = false;
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
/** Bumped by every load, so only the newest scan may write the registry. */
|
|
22
|
+
let _generation = 0;
|
|
23
|
+
/** The newest scan, which a superseded one waits on so its caller still sees a loaded registry. */
|
|
24
|
+
let _newest: Promise<void> = Promise.resolve();
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Scan the project's components into the registry.
|
|
28
|
+
*
|
|
29
|
+
* Scans can overlap (the project-open path and the Site panel each start one), and a scan bound to
|
|
30
|
+
* the project being closed may resolve after the next project's. So the newest scan wins: an older
|
|
31
|
+
* one discards what it read and resolves when the newest has written the registry.
|
|
32
|
+
*/
|
|
33
|
+
export function loadComponentRegistry(): Promise<void> {
|
|
34
|
+
_generation += 1;
|
|
35
|
+
const generation = _generation;
|
|
36
|
+
const scan = (async () => {
|
|
37
|
+
let found: ComponentEntry[] | null = null;
|
|
38
|
+
try {
|
|
39
|
+
found = await getPlatform().discoverComponents(projectState?.projectRoot || undefined);
|
|
40
|
+
} catch {
|
|
41
|
+
found = null;
|
|
42
|
+
}
|
|
43
|
+
if (generation !== _generation) {
|
|
44
|
+
await _newest;
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (found) {
|
|
48
|
+
componentRegistry = found;
|
|
49
|
+
}
|
|
26
50
|
_componentRegistryLoaded = true;
|
|
27
|
-
}
|
|
51
|
+
})();
|
|
52
|
+
_newest = scan;
|
|
53
|
+
return scan;
|
|
28
54
|
}
|
|
29
55
|
|
|
30
56
|
/**
|
|
@@ -40,15 +66,17 @@ export async function loadComponentRegistry() {
|
|
|
40
66
|
*
|
|
41
67
|
* @param {string | null} path - The saved document's project-relative path; `null` for an unsaved
|
|
42
68
|
* draft, which no scan would have seen either.
|
|
43
|
-
* @param {
|
|
69
|
+
* @param {JxMutableNode} doc - The saved document.
|
|
44
70
|
* @returns {boolean} Whether the registry changed, so a caller knows to repaint what reads it.
|
|
45
71
|
*/
|
|
46
|
-
export function noteComponentSaved(path: string | null, doc:
|
|
72
|
+
export function noteComponentSaved(path: string | null, doc: JxMutableNode): boolean {
|
|
47
73
|
if (!path) {
|
|
48
74
|
return false;
|
|
49
75
|
}
|
|
50
76
|
const index = componentRegistry.findIndex((c) => c.path === path);
|
|
51
|
-
|
|
77
|
+
/* SAFETY: a saved tab's document was parsed from JSON and has just been written back as JSON
|
|
78
|
+
(`serializeDocument`), so every value it holds is a JSON value — the model the extractor reads. */
|
|
79
|
+
const meta = componentMetaFrom(doc as JsonValue, path);
|
|
52
80
|
if (!meta) {
|
|
53
81
|
if (index === -1) {
|
|
54
82
|
return false;
|
|
@@ -56,6 +84,8 @@ export function noteComponentSaved(path: string | null, doc: unknown): boolean {
|
|
|
56
84
|
componentRegistry.splice(index, 1);
|
|
57
85
|
return true;
|
|
58
86
|
}
|
|
87
|
+
/* SAFETY: `componentMetaFrom` is the extractor every backend's `discoverComponents` scan runs to
|
|
88
|
+
Produce the registry's entries, so its output has the shape the registry already holds. */
|
|
59
89
|
const entry = meta as ComponentEntry;
|
|
60
90
|
if (index === -1) {
|
|
61
91
|
componentRegistry.push(entry);
|
|
@@ -84,7 +114,7 @@ export function buildComponentInstance(comp: ComponentEntry): JxMutableNode {
|
|
|
84
114
|
for (const child of structuredClone(slot.fallback ?? [])) {
|
|
85
115
|
if (!slot.name) {
|
|
86
116
|
children.push(child);
|
|
87
|
-
} else if (
|
|
117
|
+
} else if (isNonNullObject(child) && isString(child.tagName)) {
|
|
88
118
|
// Preserve an author-set slot attribute (slot forwarding inside fallback).
|
|
89
119
|
child.attributes = { slot: slot.name, ...child.attributes };
|
|
90
120
|
children.push(child);
|
|
@@ -94,26 +124,65 @@ export function buildComponentInstance(comp: ComponentEntry): JxMutableNode {
|
|
|
94
124
|
}
|
|
95
125
|
}
|
|
96
126
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
127
|
+
const instance: JxMutableNode = { $props, tagName: comp.tagName };
|
|
128
|
+
if (children.length > 0) {
|
|
129
|
+
instance.children = children;
|
|
130
|
+
}
|
|
131
|
+
return instance;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Walk `parts` the way a path resolver does: `.` stays, `..` climbs, the rest descend. A climb
|
|
136
|
+
* above the start is kept as a leading `..`, which is how a project-relative path names a file
|
|
137
|
+
* outside the project.
|
|
138
|
+
*/
|
|
139
|
+
function normalizeParts(parts: readonly string[]): string[] {
|
|
140
|
+
const out: string[] = [];
|
|
141
|
+
for (const part of parts) {
|
|
142
|
+
if (part === ".") {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (part === ".." && out.length > 0 && out.at(-1) !== "..") {
|
|
146
|
+
out.pop();
|
|
147
|
+
} else {
|
|
148
|
+
out.push(part);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return out;
|
|
102
152
|
}
|
|
103
153
|
|
|
104
154
|
/**
|
|
155
|
+
* The `$ref` a document at `fromDocPath` writes to reach `toCompPath`, both project-relative.
|
|
156
|
+
*
|
|
157
|
+
* A document can sit OUTSIDE the project: jxsuite.com's docs collection is `../../docs`, so an
|
|
158
|
+
* entry is `../../docs/extending/x.md`. Climbing from there back into the project needs the names
|
|
159
|
+
* of the folders the project sits in, which a project-relative path does not carry; counting its
|
|
160
|
+
* segments gave five `../` and a ref into a folder that does not exist, so every component a docs
|
|
161
|
+
* layout imports failed to register on the canvas. Such a path is resolved against `projectRoot`
|
|
162
|
+
* (the open project's, by default), the way the browser resolves the ref.
|
|
163
|
+
*
|
|
105
164
|
* @param {string | null} fromDocPath
|
|
106
165
|
* @param {string} toCompPath
|
|
166
|
+
* @param {string | null} [projectRoot]
|
|
107
167
|
*/
|
|
108
|
-
export function computeRelativePath(
|
|
168
|
+
export function computeRelativePath(
|
|
169
|
+
fromDocPath: string | null,
|
|
170
|
+
toCompPath: string,
|
|
171
|
+
projectRoot: string | null = projectState?.projectRoot ?? null,
|
|
172
|
+
) {
|
|
109
173
|
if (!fromDocPath) {
|
|
110
174
|
return `./${toCompPath}`;
|
|
111
175
|
}
|
|
112
176
|
const from = fromDocPath.replaceAll("\\", "/");
|
|
113
177
|
const to = toCompPath.replaceAll("\\", "/");
|
|
114
178
|
const fromDir = from.includes("/") ? from.slice(0, from.lastIndexOf("/")) : "";
|
|
115
|
-
|
|
116
|
-
|
|
179
|
+
let fromParts = normalizeParts(fromDir.split("/").filter(Boolean));
|
|
180
|
+
let toParts = normalizeParts(to.split("/").filter(Boolean));
|
|
181
|
+
if (fromParts[0] === ".." && projectRoot) {
|
|
182
|
+
const rootParts = projectRoot.replaceAll("\\", "/").split("/").filter(Boolean);
|
|
183
|
+
fromParts = normalizeParts([...rootParts, ...fromParts]);
|
|
184
|
+
toParts = normalizeParts([...rootParts, ...toParts]);
|
|
185
|
+
}
|
|
117
186
|
let common = 0;
|
|
118
187
|
while (
|
|
119
188
|
common < fromParts.length &&
|
package/src/files/elements.ts
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
* they must not differ on is WHICH entries the list should hold.
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
+
import { isNonNullObject, isString } from "@jxsuite/schema/guards";
|
|
23
24
|
import { computeRelativePath } from "./components";
|
|
24
25
|
import type { ComponentEntry } from "./components";
|
|
25
26
|
import type { JxElement } from "@jxsuite/schema/types";
|
|
@@ -29,9 +30,7 @@ export type ElementsEntry = string | JxElement | { $ref: string };
|
|
|
29
30
|
|
|
30
31
|
/** The `$ref` of an entry, when it has one. */
|
|
31
32
|
function refOf(entry: ElementsEntry): string | null {
|
|
32
|
-
return
|
|
33
|
-
? entry.$ref
|
|
34
|
-
: null;
|
|
33
|
+
return isNonNullObject(entry) && isString(entry.$ref) ? entry.$ref : null;
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
/**
|
|
@@ -81,7 +80,7 @@ export function hasElement(
|
|
|
81
80
|
const specifier = npmSpecifier(comp);
|
|
82
81
|
if (specifier) {
|
|
83
82
|
return elements.some(
|
|
84
|
-
(entry) =>
|
|
83
|
+
(entry) => isString(entry) && (entry === specifier || entry === comp.package),
|
|
85
84
|
);
|
|
86
85
|
}
|
|
87
86
|
if (!comp.path) {
|
|
@@ -132,7 +131,7 @@ export function disableElement(
|
|
|
132
131
|
if (specifier) {
|
|
133
132
|
// Both spellings: a component ticked off must not stay imported through the package entry.
|
|
134
133
|
return elements.filter(
|
|
135
|
-
(entry) => !(
|
|
134
|
+
(entry) => !(isString(entry) && (entry === specifier || entry === comp.package)),
|
|
136
135
|
);
|
|
137
136
|
}
|
|
138
137
|
if (!comp.path) {
|
|
@@ -151,7 +150,7 @@ export function removePackageElements(
|
|
|
151
150
|
pkg: string,
|
|
152
151
|
): ElementsEntry[] {
|
|
153
152
|
return elements.filter(
|
|
154
|
-
(entry) =>
|
|
153
|
+
(entry) => !isString(entry) || !(entry === pkg || entry.startsWith(`${pkg}/`)),
|
|
155
154
|
);
|
|
156
155
|
}
|
|
157
156
|
|
package/src/files/file-ops.ts
CHANGED
|
@@ -28,6 +28,8 @@ import { showConfirmDialog } from "../ui/layers";
|
|
|
28
28
|
import { locateDocument } from "../services/code-services";
|
|
29
29
|
import { errorMessage } from "@jxsuite/schema/parse";
|
|
30
30
|
import { notify } from "../services/notify";
|
|
31
|
+
import type { NotifyOptions } from "../services/notify";
|
|
32
|
+
import { isString } from "@jxsuite/schema/guards";
|
|
31
33
|
import { validateComponentSlots } from "../services/cem-export";
|
|
32
34
|
import { reportPopoverProblems } from "../services/popover-report";
|
|
33
35
|
import { getPlatform } from "../platform";
|
|
@@ -103,19 +105,68 @@ export async function parseSourceForPath(path: string, source: string) {
|
|
|
103
105
|
export const parseCollabSource: CollabParser = async (tab, text) => {
|
|
104
106
|
if (tab.documentPath && formatForPath(tab.documentPath)) {
|
|
105
107
|
const parsed = await parseSourceForPath(tab.documentPath, text);
|
|
106
|
-
|
|
108
|
+
// The peer's text is what this client saves against now, as `layout` is for a JSON file.
|
|
109
|
+
tab.doc.source = text;
|
|
110
|
+
return { document: parsed.document, frontmatter: parsed.frontmatter };
|
|
107
111
|
}
|
|
108
112
|
const parsed = parseJsonDocument(text);
|
|
109
113
|
tab.doc.layout = parsed.layout;
|
|
114
|
+
/* SAFETY: a co-edited path no format class claims is a `.json` Jx document (every other path
|
|
115
|
+
`ensureCollab` attaches to is a format file, handled above), and that file's schema makes its
|
|
116
|
+
Top-level object a node — the object `parseJsonDocument` already states it returns. */
|
|
110
117
|
return { document: parsed.document as JxMutableNode };
|
|
111
118
|
};
|
|
112
119
|
|
|
120
|
+
/** One `accept` group of a File System Access picker: media type → extensions, with a label. */
|
|
121
|
+
interface FilePickerAcceptType {
|
|
122
|
+
accept: Record<string, string[]>;
|
|
123
|
+
description: string;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* The File System Access pickers (WICG), which TypeScript's DOM lib does not declare. Only what
|
|
128
|
+
* this module passes and reads is spelled out.
|
|
129
|
+
*/
|
|
130
|
+
interface FilePickerWindow {
|
|
131
|
+
showOpenFilePicker: (options: {
|
|
132
|
+
types: FilePickerAcceptType[];
|
|
133
|
+
}) => Promise<FileSystemFileHandle[]>;
|
|
134
|
+
/* Export's single extension is `format.extensions[0]`, absent for a format that declares none —
|
|
135
|
+
So the save picker is typed with the value it is actually handed. */
|
|
136
|
+
showSaveFilePicker: (options: {
|
|
137
|
+
suggestedName?: string | undefined;
|
|
138
|
+
types: { accept: Record<string, (string | undefined)[]>; description: string }[];
|
|
139
|
+
}) => Promise<FileSystemFileHandle>;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** Whether this browser offers `showOpenFilePicker` (Chromium does; Firefox and Safari do not). */
|
|
143
|
+
function hasOpenFilePicker(
|
|
144
|
+
win: Window,
|
|
145
|
+
): win is Window & Pick<FilePickerWindow, "showOpenFilePicker"> {
|
|
146
|
+
return "showOpenFilePicker" in win;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** Whether this browser offers `showSaveFilePicker` (Chromium does; Firefox and Safari do not). */
|
|
150
|
+
function hasSaveFilePicker(
|
|
151
|
+
win: Window,
|
|
152
|
+
): win is Window & Pick<FilePickerWindow, "showSaveFilePicker"> {
|
|
153
|
+
return "showSaveFilePicker" in win;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** Attach the tab's file to a notification's options, when it has one. */
|
|
157
|
+
function atTabPath(tab: Tab, options: NotifyOptions): NotifyOptions {
|
|
158
|
+
if (tab.documentPath !== null) {
|
|
159
|
+
options.path = tab.documentPath;
|
|
160
|
+
}
|
|
161
|
+
return options;
|
|
162
|
+
}
|
|
163
|
+
|
|
113
164
|
/** Open a file via the File System Access API (or fallback input). */
|
|
114
165
|
export async function openFile() {
|
|
115
166
|
try {
|
|
116
167
|
await loadFormats();
|
|
117
168
|
const formats = getFormats();
|
|
118
|
-
const pickerTypes = [
|
|
169
|
+
const pickerTypes: FilePickerAcceptType[] = [
|
|
119
170
|
{
|
|
120
171
|
accept: { "application/json": [".json"] },
|
|
121
172
|
description: "Jx Component",
|
|
@@ -146,6 +197,7 @@ export async function openFile() {
|
|
|
146
197
|
fileHandle: handle,
|
|
147
198
|
frontmatter,
|
|
148
199
|
id: name,
|
|
200
|
+
source: text,
|
|
149
201
|
sourceFormat: format.name,
|
|
150
202
|
});
|
|
151
203
|
} else if (name.endsWith(".json")) {
|
|
@@ -160,12 +212,8 @@ export async function openFile() {
|
|
|
160
212
|
// Trail; it does not need a message that erases itself.
|
|
161
213
|
};
|
|
162
214
|
|
|
163
|
-
if (
|
|
164
|
-
const [handle] = await (
|
|
165
|
-
window as unknown as {
|
|
166
|
-
showOpenFilePicker: (options?: unknown) => Promise<FileSystemFileHandle[]>;
|
|
167
|
-
}
|
|
168
|
-
).showOpenFilePicker({ types: pickerTypes });
|
|
215
|
+
if (hasOpenFilePicker(window)) {
|
|
216
|
+
const [handle] = await window.showOpenFilePicker({ types: pickerTypes });
|
|
169
217
|
const file = await handle!.getFile();
|
|
170
218
|
await handleSource(handle!.name, await file.text(), handle!);
|
|
171
219
|
} else {
|
|
@@ -209,37 +257,38 @@ export async function openFile() {
|
|
|
209
257
|
* **By injection**, the idiom `setSurfaceTeardown` and `setDiffRepaint` already use. The one
|
|
210
258
|
* listener today is source control: a comparison is two texts read once, so it does not notice a
|
|
211
259
|
* save on its own, and the file an author is most likely to save is the one they are reviewing. A
|
|
212
|
-
* direct import would put `
|
|
213
|
-
* every suite that mocks the canvas host out from under
|
|
260
|
+
* direct import would put `publish/source-control.ts` and the comparison opener behind it into this
|
|
261
|
+
* module's graph, which is a load error for every suite that mocks the canvas host out from under
|
|
262
|
+
* it.
|
|
214
263
|
*
|
|
215
264
|
* The listener is handed the document as well as the path, for the second listener: the live chrome
|
|
216
265
|
* lane (`services/live-surfaces.ts`) re-mounts a saved surface from the document the tab just wrote
|
|
217
266
|
* rather than reading the file back, which is what keeps the shipped app from ever reading its
|
|
218
267
|
* chrome from disk.
|
|
219
268
|
*/
|
|
220
|
-
let _onDocumentSaved: (path: string | null, doc: JxMutableNode) => void = () => {};
|
|
269
|
+
let _onDocumentSaved: (path: string | null, doc: JxMutableNode, tab: Tab) => void = () => {};
|
|
221
270
|
|
|
222
271
|
/** Register the save listener. Called once, from the bootstrap. */
|
|
223
272
|
export function setDocumentSavedListener(
|
|
224
|
-
listener: (path: string | null, doc: JxMutableNode) => void,
|
|
273
|
+
listener: (path: string | null, doc: JxMutableNode, tab: Tab) => void,
|
|
225
274
|
): void {
|
|
226
275
|
_onDocumentSaved = listener;
|
|
227
276
|
}
|
|
228
277
|
|
|
229
278
|
function reportSaved(tab: Tab) {
|
|
230
279
|
const doc = tab.doc.document;
|
|
231
|
-
_onDocumentSaved(tab.documentPath, doc);
|
|
280
|
+
_onDocumentSaved(tab.documentPath, doc, tab);
|
|
232
281
|
const warning =
|
|
233
|
-
|
|
234
|
-
? validateComponentSlots(doc)
|
|
235
|
-
: null;
|
|
282
|
+
isString(doc.tagName) && doc.tagName.includes("-") ? validateComponentSlots(doc) : null;
|
|
236
283
|
if (warning) {
|
|
237
|
-
notify.warn(
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
284
|
+
notify.warn(
|
|
285
|
+
warning,
|
|
286
|
+
atTabPath(tab, {
|
|
287
|
+
key: `slots:${tab.documentPath ?? tab.id}`,
|
|
288
|
+
source: "Components",
|
|
289
|
+
tier: "problem",
|
|
290
|
+
}),
|
|
291
|
+
);
|
|
243
292
|
}
|
|
244
293
|
/* Popover correctness, beside the slot check and for the same reason it is here: a successful
|
|
245
294
|
save is the one chokepoint every edit passes through, whichever surface made it. A render-time
|
|
@@ -311,12 +360,11 @@ export async function saveFile(tab: Tab | null = activeTab.value): Promise<boole
|
|
|
311
360
|
notify.warn(
|
|
312
361
|
`You have read access to this session — changes to ${tab.documentPath ?? "this document"} ` +
|
|
313
362
|
`stay in your browser and cannot be saved.`,
|
|
314
|
-
{
|
|
363
|
+
atTabPath(tab, {
|
|
315
364
|
action: "file.save",
|
|
316
365
|
key: `save.readOnly:${tab.documentPath ?? tab.id}`,
|
|
317
|
-
...(tab.documentPath === null ? {} : { path: tab.documentPath }),
|
|
318
366
|
source: "Collaboration",
|
|
319
|
-
},
|
|
367
|
+
}),
|
|
320
368
|
);
|
|
321
369
|
return false;
|
|
322
370
|
}
|
|
@@ -327,11 +375,10 @@ export async function saveFile(tab: Tab | null = activeTab.value): Promise<boole
|
|
|
327
375
|
if (!hasSerializableDocument(tab)) {
|
|
328
376
|
notify.warn(
|
|
329
377
|
`${tab.documentPath ?? "This file"} is a media file, so there is no document for Save to write.`,
|
|
330
|
-
{
|
|
378
|
+
atTabPath(tab, {
|
|
331
379
|
key: `save.notADocument:${tab.documentPath ?? tab.id}`,
|
|
332
|
-
...(tab.documentPath === null ? {} : { path: tab.documentPath }),
|
|
333
380
|
source: "Save",
|
|
334
|
-
},
|
|
381
|
+
}),
|
|
335
382
|
);
|
|
336
383
|
return false;
|
|
337
384
|
}
|
|
@@ -355,6 +402,9 @@ export async function saveFile(tab: Tab | null = activeTab.value): Promise<boole
|
|
|
355
402
|
const platform = getPlatform();
|
|
356
403
|
await platform.writeFile(tab.documentPath, output);
|
|
357
404
|
tab.doc.dirty = false;
|
|
405
|
+
if (tab.doc.sourceFormat !== null) {
|
|
406
|
+
tab.doc.source = output;
|
|
407
|
+
}
|
|
358
408
|
/* Retract the unsaved bytes NOW rather than a debounce later. The write also reaches the
|
|
359
409
|
backend's filesystem watcher, and a live preview coalesces both into one reload only if
|
|
360
410
|
they arrive together — otherwise a save costs two. */
|
|
@@ -375,19 +425,24 @@ export async function saveFile(tab: Tab | null = activeTab.value): Promise<boole
|
|
|
375
425
|
await writable.write(output);
|
|
376
426
|
await writable.close();
|
|
377
427
|
tab.doc.dirty = false;
|
|
428
|
+
if (tab.doc.sourceFormat !== null) {
|
|
429
|
+
tab.doc.source = output;
|
|
430
|
+
}
|
|
378
431
|
reportSaved(tab);
|
|
379
432
|
return true;
|
|
380
433
|
}
|
|
381
434
|
notify.warn("This document has no save target — use Export.", { key: "save.noTarget" });
|
|
382
435
|
} catch (error) {
|
|
383
436
|
if (!(error instanceof Error && error.name === "AbortError")) {
|
|
384
|
-
notify.error(
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
437
|
+
notify.error(
|
|
438
|
+
`Could not save ${tab.documentPath ?? tab.id}.`,
|
|
439
|
+
atTabPath(tab, {
|
|
440
|
+
action: "file.save",
|
|
441
|
+
detail: errorMessage(error),
|
|
442
|
+
key: `save:${tab.documentPath ?? tab.id}`,
|
|
443
|
+
source: "Save",
|
|
444
|
+
}),
|
|
445
|
+
);
|
|
391
446
|
}
|
|
392
447
|
}
|
|
393
448
|
return false;
|
|
@@ -418,13 +473,9 @@ export async function exportFile() {
|
|
|
418
473
|
const description = format ? format.name : "Jx Component";
|
|
419
474
|
const fallbackName = format ? `content${ext}` : "component.json";
|
|
420
475
|
|
|
421
|
-
if (
|
|
476
|
+
if (hasSaveFilePicker(window)) {
|
|
422
477
|
const suggestedName = tab.documentPath ? tab.documentPath.split("/").pop() : fallbackName;
|
|
423
|
-
const handle = await (
|
|
424
|
-
window as unknown as {
|
|
425
|
-
showSaveFilePicker: (options?: unknown) => Promise<FileSystemFileHandle>;
|
|
426
|
-
}
|
|
427
|
-
).showSaveFilePicker({
|
|
478
|
+
const handle = await window.showSaveFilePicker({
|
|
428
479
|
suggestedName,
|
|
429
480
|
types: [{ accept: { [mimeType]: [ext] }, description }],
|
|
430
481
|
});
|