@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/site-context.ts
CHANGED
|
@@ -8,11 +8,12 @@
|
|
|
8
8
|
* @docs framework/site/i18n
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import { isNonNullObject, isString } from "@jxsuite/schema/guards";
|
|
11
12
|
import { projectState } from "./store";
|
|
12
13
|
import { getPlatform } from "./platform";
|
|
13
14
|
import { commitProjectConfig } from "./tabs/project-config";
|
|
14
15
|
|
|
15
|
-
import { resolveI18n } from "@jxsuite/schema/locale";
|
|
16
|
+
import { canonicalizeLocale, localeOfPath, resolveI18n } from "@jxsuite/schema/locale";
|
|
16
17
|
import type { ResolvedI18n } from "@jxsuite/schema/locale";
|
|
17
18
|
import type {
|
|
18
19
|
JxElement,
|
|
@@ -21,6 +22,7 @@ import type {
|
|
|
21
22
|
JxStyle,
|
|
22
23
|
ProjectConfig,
|
|
23
24
|
} from "@jxsuite/schema/types";
|
|
25
|
+
import type { ExtensionsInfo } from "./types";
|
|
24
26
|
|
|
25
27
|
/**
|
|
26
28
|
* Merge site $media with document $media. Document keys win on conflict.
|
|
@@ -57,10 +59,8 @@ export function getEffectiveStyle(docStyle?: JxStyle) {
|
|
|
57
59
|
}
|
|
58
60
|
const merged = { ...siteStyle };
|
|
59
61
|
for (const [k, v] of Object.entries(docStyle)) {
|
|
60
|
-
merged[k]
|
|
61
|
-
|
|
62
|
-
? { ...(merged[k] as JxStyle), ...(v as JxStyle) }
|
|
63
|
-
: v;
|
|
62
|
+
const base = merged[k];
|
|
63
|
+
merged[k] = isNonNullObject(v) && isNonNullObject(base) ? { ...base, ...v } : v;
|
|
64
64
|
}
|
|
65
65
|
return merged;
|
|
66
66
|
}
|
|
@@ -72,15 +72,35 @@ export function getEffectiveStyle(docStyle?: JxStyle) {
|
|
|
72
72
|
* undefined)
|
|
73
73
|
* @returns {Record<string, string>}
|
|
74
74
|
*/
|
|
75
|
-
export function getEffectiveImports(
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
75
|
+
export function getEffectiveImports(
|
|
76
|
+
docImports?: Record<string, string>,
|
|
77
|
+
extensions: readonly ExtensionsInfo[] = [],
|
|
78
|
+
) {
|
|
79
|
+
/* The enabled extensions' manifest classes come last in the order the build resolves a bare
|
|
80
|
+
`$prototype` in (spec.md §12.5: the document's `imports`, then the project's, then the
|
|
81
|
+
extension registry), so they are the base the other two are spread over. Without them a
|
|
82
|
+
layout's `{ "$prototype": "ContentEntry" }` named a class the build knows and the canvas did
|
|
83
|
+
not, and the canvas warned of an unknown prototype and drew the layout with no data. The
|
|
84
|
+
first extension to declare a name keeps it, as the registry's `byName` answers. */
|
|
85
|
+
return {
|
|
86
|
+
...extensionClassPaths(extensions),
|
|
87
|
+
...projectState?.projectConfig?.imports,
|
|
88
|
+
...docImports,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* The enabled extensions' manifest classes, by name, as descriptor paths: the last step of the
|
|
94
|
+
* build's bare-`$prototype` resolution (spec.md §12.5). The first extension to declare a name keeps
|
|
95
|
+
* it, as the registry's `byName` answers.
|
|
96
|
+
*/
|
|
97
|
+
export function extensionClassPaths(extensions: readonly ExtensionsInfo[]) {
|
|
98
|
+
const classes = extensions.flatMap((extension) =>
|
|
99
|
+
(extension.classes ?? [])
|
|
100
|
+
.filter((cls) => cls.path.endsWith(".class.json"))
|
|
101
|
+
.map((cls): [string, string] => [cls.name, cls.path]),
|
|
102
|
+
);
|
|
103
|
+
return Object.fromEntries(classes.toReversed());
|
|
84
104
|
}
|
|
85
105
|
|
|
86
106
|
/**
|
|
@@ -101,7 +121,8 @@ export function getEffectiveElements(docElements?: (JxElement | string)[]) {
|
|
|
101
121
|
const seen = new Set<string>();
|
|
102
122
|
const merged: (JxElement | string)[] = [];
|
|
103
123
|
for (const entry of [...siteElements, ...docElements]) {
|
|
104
|
-
|
|
124
|
+
// A null entry in hand-edited JSON has no key, and is skipped rather than thrown on.
|
|
125
|
+
const key = isString(entry) ? entry : isNonNullObject(entry) ? entry.$ref : undefined;
|
|
105
126
|
if (key && !seen.has(key)) {
|
|
106
127
|
seen.add(key);
|
|
107
128
|
merged.push(entry);
|
|
@@ -127,8 +148,9 @@ export function getEffectiveHead(docHead?: JxHeadEntry[]) {
|
|
|
127
148
|
const seen = new Set<string>();
|
|
128
149
|
const merged: JxHeadEntry[] = [];
|
|
129
150
|
for (const entry of [...siteHead, ...docHead]) {
|
|
130
|
-
|
|
131
|
-
|
|
151
|
+
// A null entry in hand-edited JSON is keyed by its serialisation, like any entry without a URL.
|
|
152
|
+
const attributes = isNonNullObject(entry) ? entry.attributes : undefined;
|
|
153
|
+
const key = String(attributes?.href || attributes?.src || "") || JSON.stringify(entry);
|
|
132
154
|
if (!seen.has(key)) {
|
|
133
155
|
seen.add(key);
|
|
134
156
|
merged.push(entry);
|
|
@@ -158,6 +180,39 @@ export function getEffectiveLocales(): ResolvedI18n | null {
|
|
|
158
180
|
return config ? resolveI18n(config).i18n : null;
|
|
159
181
|
}
|
|
160
182
|
|
|
183
|
+
/**
|
|
184
|
+
* The language a pane renders in (studio.md §20.2), the one answer the context bar's Language
|
|
185
|
+
* segment, every artboard's `render` and the live push all read.
|
|
186
|
+
*
|
|
187
|
+
* The author's choice while the project declares it, else the document's own: the locale its path
|
|
188
|
+
* sits under (`site-architecture.md` §13.3 puts a translation in its own directory, so
|
|
189
|
+
* `pages/ar/about.json` and `content/exhibitions/ar/x.md` are Arabic), else the default locale,
|
|
190
|
+
* which is what an unprefixed page renders as. Null for a project that declares no locales.
|
|
191
|
+
*
|
|
192
|
+
* A stored choice the project no longer declares answers as if none were made, the counterpart of
|
|
193
|
+
* `i18n.switchLocale` refusing one on the way in; the stored value is left alone, so a locale that
|
|
194
|
+
* is declared again comes back. Answering with the document's own language when nothing is chosen
|
|
195
|
+
* is what makes an Arabic translation mirror as soon as it is opened: before, the artboard drew it
|
|
196
|
+
* left to right until the author picked Arabic from a control already showing Arabic.
|
|
197
|
+
*
|
|
198
|
+
* @param previewLocale - The pane's choice (`session.ui.previewLocale`), or null.
|
|
199
|
+
* @param documentPath - The project-relative path of the document being drawn.
|
|
200
|
+
*/
|
|
201
|
+
export function getEffectiveRenderLocale(
|
|
202
|
+
previewLocale: string | null | undefined,
|
|
203
|
+
documentPath: string | null | undefined,
|
|
204
|
+
): string | null {
|
|
205
|
+
const i18n = getEffectiveLocales();
|
|
206
|
+
if (i18n === null) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
const chosen = canonicalizeLocale(previewLocale);
|
|
210
|
+
if (chosen !== null && i18n.locales.includes(chosen)) {
|
|
211
|
+
return chosen;
|
|
212
|
+
}
|
|
213
|
+
return localeOfPath(documentPath ?? "", i18n) ?? i18n.defaultLocale;
|
|
214
|
+
}
|
|
215
|
+
|
|
161
216
|
// ─── Layout resolution ──────────────────────────────────────────────────────
|
|
162
217
|
|
|
163
218
|
const layoutCache = new Map<string, JxMutableNode>();
|
|
@@ -189,13 +244,16 @@ export function getEffectiveLayoutPath(docLayout: string | false | undefined) {
|
|
|
189
244
|
*/
|
|
190
245
|
export async function resolveLayoutDoc(layoutPath: string) {
|
|
191
246
|
const normalized = layoutPath.replace(/^\.\//, "");
|
|
192
|
-
|
|
193
|
-
|
|
247
|
+
const cached = layoutCache.get(normalized);
|
|
248
|
+
if (cached !== undefined) {
|
|
249
|
+
return structuredClone(cached);
|
|
194
250
|
}
|
|
195
251
|
|
|
196
252
|
try {
|
|
197
253
|
const platform = getPlatform();
|
|
198
254
|
const content = await platform.readFile(normalized);
|
|
255
|
+
/* SAFETY: a `$layout` target is a Jx document file, which is a JSON element object; the slot
|
|
256
|
+
walk that consumes it checks `children` is an array before reading any of it. */
|
|
199
257
|
const doc = JSON.parse(content) as JxMutableNode;
|
|
200
258
|
layoutCache.set(normalized, doc);
|
|
201
259
|
return structuredClone(doc);
|
|
@@ -220,8 +278,8 @@ export function distributePageIntoLayout(layoutDoc: JxMutableNode, pageDoc: JxMu
|
|
|
220
278
|
const defaults: (JxMutableNode | string)[] = [];
|
|
221
279
|
|
|
222
280
|
for (const child of children) {
|
|
223
|
-
const slotName =
|
|
224
|
-
if (
|
|
281
|
+
const slotName = isString(child) ? undefined : child.attributes?.slot;
|
|
282
|
+
if (!isString(child) && isString(slotName) && slotName) {
|
|
225
283
|
if (!named.has(slotName)) {
|
|
226
284
|
named.set(slotName, []);
|
|
227
285
|
}
|
|
@@ -254,18 +312,15 @@ function fillSlots(
|
|
|
254
312
|
named: Map<string, JxMutableNode[]>,
|
|
255
313
|
defaults: (JxMutableNode | string)[],
|
|
256
314
|
) {
|
|
257
|
-
if (!node || typeof node !== "object") {
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
260
315
|
if (!Array.isArray(node.children)) {
|
|
261
316
|
return;
|
|
262
317
|
}
|
|
263
318
|
|
|
264
319
|
const newChildren: (JxMutableNode | string)[] = [];
|
|
265
320
|
for (const child of node.children) {
|
|
266
|
-
if (child &&
|
|
321
|
+
if (isNonNullObject(child) && child.tagName === "slot") {
|
|
267
322
|
const slotName = child.attributes?.name;
|
|
268
|
-
if (
|
|
323
|
+
if (isString(slotName) && slotName && named.has(slotName)) {
|
|
269
324
|
newChildren.push(...named.get(slotName)!);
|
|
270
325
|
named.delete(slotName);
|
|
271
326
|
} else if (!slotName && defaults.length > 0) {
|
|
@@ -274,15 +329,26 @@ function fillSlots(
|
|
|
274
329
|
newChildren.push(...child.children);
|
|
275
330
|
}
|
|
276
331
|
} else {
|
|
277
|
-
|
|
332
|
+
/* Only an element has slots to fill. A null child (hand-edited JSON) used to reach the
|
|
333
|
+
`!node` guard this function opened with; it now stops here, with the same outcome. */
|
|
334
|
+
if (isNonNullObject(child)) {
|
|
278
335
|
fillSlots(child, named, defaults);
|
|
279
336
|
}
|
|
280
337
|
newChildren.push(child);
|
|
281
338
|
}
|
|
282
339
|
}
|
|
283
|
-
node.children = newChildren
|
|
340
|
+
node.children = newChildren;
|
|
284
341
|
}
|
|
285
342
|
|
|
343
|
+
/**
|
|
344
|
+
* A `project.json` patch: each key's new value, or `undefined` to remove the key.
|
|
345
|
+
*
|
|
346
|
+
* `Partial<ProjectConfig>` cannot say the second half under `exactOptionalPropertyTypes` — its
|
|
347
|
+
* `url` is `string` when present, never `undefined` — so clearing a setting had to be spelled as a
|
|
348
|
+
* double cast at every call site that wanted to.
|
|
349
|
+
*/
|
|
350
|
+
export type ProjectConfigPatch = { [K in keyof ProjectConfig]?: ProjectConfig[K] | undefined };
|
|
351
|
+
|
|
286
352
|
/**
|
|
287
353
|
* Merge a partial patch into the project's configuration and persist it.
|
|
288
354
|
*
|
|
@@ -297,12 +363,15 @@ function fillSlots(
|
|
|
297
363
|
* Problem, because the eight other sites reach this through `void updateSiteConfig(...)` and used
|
|
298
364
|
* to drop it on the floor.
|
|
299
365
|
*
|
|
300
|
-
* @param {
|
|
301
|
-
*
|
|
366
|
+
* @param {ProjectConfigPatch} patch - Fields to merge into the current projectConfig; a value of
|
|
367
|
+
* `undefined` clears the key.
|
|
302
368
|
* @throws {unknown} The platform's rejection, when the write fails.
|
|
303
369
|
*/
|
|
304
|
-
export async function updateSiteConfig(patch:
|
|
305
|
-
|
|
370
|
+
export async function updateSiteConfig(patch: ProjectConfigPatch) {
|
|
371
|
+
/* SAFETY: `commitProjectConfig` spreads the patch over the current config and serialises the
|
|
372
|
+
result with JSON.stringify, so an `undefined` member reaches disk as an absent key and the
|
|
373
|
+
written file is a ProjectConfig; every other member already has its ProjectConfig type. */
|
|
374
|
+
const result = await commitProjectConfig(patch as Partial<ProjectConfig>);
|
|
306
375
|
if (!result.ok) {
|
|
307
376
|
throw result.error;
|
|
308
377
|
}
|
package/src/state.ts
CHANGED
|
@@ -12,7 +12,15 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import type { ProjectState } from "./types";
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
displayTagName,
|
|
17
|
+
isBoolean,
|
|
18
|
+
isMappedArray,
|
|
19
|
+
isNonNullObject,
|
|
20
|
+
isNumber,
|
|
21
|
+
isRef,
|
|
22
|
+
isString,
|
|
23
|
+
} from "@jxsuite/schema/guards";
|
|
16
24
|
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
17
25
|
|
|
18
26
|
export type JxPath = (string | number)[];
|
|
@@ -20,23 +28,10 @@ export type JxPath = (string | number)[];
|
|
|
20
28
|
// ─── Path utilities ───────────────────────────────────────────────────────────
|
|
21
29
|
|
|
22
30
|
/**
|
|
23
|
-
* Walk the document tree and return the node at the given path
|
|
24
|
-
*
|
|
25
|
-
* @param {JxMutableNode} doc
|
|
26
|
-
* @param {JxPath} path
|
|
27
|
-
* @returns {JxMutableNode}
|
|
31
|
+
* Walk the document tree and return the node at the given path, or `undefined` when a step falls
|
|
32
|
+
* off the tree (a path gone stale since it was taken). One walk, shared with the document ops.
|
|
28
33
|
*/
|
|
29
|
-
export
|
|
30
|
-
let node = doc;
|
|
31
|
-
for (const key of path) {
|
|
32
|
-
if (node == null) {
|
|
33
|
-
return undefined as unknown as JxMutableNode;
|
|
34
|
-
}
|
|
35
|
-
// Paths address nodes by construction; non-node leaves surface as undefined above.
|
|
36
|
-
node = node[key] as JxMutableNode;
|
|
37
|
-
}
|
|
38
|
-
return node;
|
|
39
|
-
}
|
|
34
|
+
export { getNodeAtPath } from "@jxsuite/schema/doc-ops";
|
|
40
35
|
|
|
41
36
|
/**
|
|
42
37
|
* The node's children when they are a static array (the edit-mode invariant); an empty array for
|
|
@@ -56,45 +51,62 @@ export function childList(node: JxMutableNode | null | undefined): (JxMutableNod
|
|
|
56
51
|
* `$switch` cases. Runs once when a document is loaded into a tab so every in-studio doc — and its
|
|
57
52
|
* history checkpoints — uses the member form before any mutation.
|
|
58
53
|
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
54
|
+
* The rewrite is the editor's invariant, not the file's: `onBare` hears every repeater it moved,
|
|
55
|
+
* with the JSON Pointer of the node holding it (in the NORMALIZED document's coordinates), so a
|
|
56
|
+
* save can put the authored form back (`tabs/bare-repeaters.ts`).
|
|
57
|
+
*
|
|
58
|
+
* @param {T} node
|
|
59
|
+
* @param {BareRepeaterVisitor} [onBare]
|
|
60
|
+
* @param {string} [pointer] - The node's JSON Pointer, `""` for the root.
|
|
61
|
+
* @returns {T} The same node (mutated)
|
|
61
62
|
*/
|
|
62
|
-
export function normalizeArrayChildren(node:
|
|
63
|
-
if (!node
|
|
63
|
+
export function normalizeArrayChildren<T>(node: T, onBare?: BareRepeaterVisitor, pointer = ""): T {
|
|
64
|
+
if (!isNonNullObject(node)) {
|
|
64
65
|
return node;
|
|
65
66
|
}
|
|
66
67
|
if (Array.isArray(node)) {
|
|
67
|
-
for (const child of node) {
|
|
68
|
-
normalizeArrayChildren(child);
|
|
68
|
+
for (const [i, child] of node.entries()) {
|
|
69
|
+
normalizeArrayChildren(child, onBare, `${pointer}/${i}`);
|
|
69
70
|
}
|
|
70
71
|
return node;
|
|
71
72
|
}
|
|
73
|
+
/* SAFETY: A non-array object reached from a document root, a children array, a repeater `map` or
|
|
74
|
+
a `$switch` case is a node definition, and JxMutableNode is the editor's open node shape. */
|
|
72
75
|
const n = node as JxMutableNode;
|
|
73
76
|
const { children } = n;
|
|
74
|
-
if (
|
|
75
|
-
children
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
) {
|
|
80
|
-
n.children = [children as JxMutableNode];
|
|
77
|
+
if (isMappedArray(children)) {
|
|
78
|
+
// SAFETY: A legacy whole-children repeater is the same repeater node that becomes the member.
|
|
79
|
+
const repeater = children as JxMutableNode;
|
|
80
|
+
onBare?.(pointer, repeater);
|
|
81
|
+
n.children = [repeater];
|
|
81
82
|
}
|
|
82
83
|
if (Array.isArray(n.children)) {
|
|
83
|
-
for (const child of n.children) {
|
|
84
|
-
normalizeArrayChildren(child);
|
|
84
|
+
for (const [i, child] of n.children.entries()) {
|
|
85
|
+
normalizeArrayChildren(child, onBare, `${pointer}/children/${i}`);
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
|
-
if (n.$prototype === "Array" && n.map
|
|
88
|
-
normalizeArrayChildren(n.map);
|
|
88
|
+
if (n.$prototype === "Array" && isNonNullObject(n.map)) {
|
|
89
|
+
normalizeArrayChildren(n.map, onBare, `${pointer}/map`);
|
|
89
90
|
}
|
|
90
|
-
if (n.cases
|
|
91
|
-
for (const caseDef of Object.
|
|
92
|
-
normalizeArrayChildren(caseDef);
|
|
91
|
+
if (isNonNullObject(n.cases)) {
|
|
92
|
+
for (const [key, caseDef] of Object.entries(n.cases)) {
|
|
93
|
+
normalizeArrayChildren(caseDef, onBare, `${pointer}/cases/${pointerToken(key)}`);
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
96
|
return node;
|
|
96
97
|
}
|
|
97
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Hears each legacy whole-children repeater {@link normalizeArrayChildren} rewrites: the JSON
|
|
101
|
+
* Pointer of the node holding it, and the repeater.
|
|
102
|
+
*/
|
|
103
|
+
export type BareRepeaterVisitor = (pointer: string, repeater: JxMutableNode) => void;
|
|
104
|
+
|
|
105
|
+
/** One JSON Pointer reference token (RFC 6901 §4). */
|
|
106
|
+
export function pointerToken(segment: string | number): string {
|
|
107
|
+
return String(segment).replaceAll("~", "~0").replaceAll("/", "~1");
|
|
108
|
+
}
|
|
109
|
+
|
|
98
110
|
/**
|
|
99
111
|
* Return the path to the parent element (strips trailing 'children' + index).
|
|
100
112
|
*
|
|
@@ -209,7 +221,7 @@ function collectRows(
|
|
|
209
221
|
skipSelf: boolean,
|
|
210
222
|
): void {
|
|
211
223
|
// Text node children: bare primitives get a "text" row
|
|
212
|
-
if (
|
|
224
|
+
if (isString(doc) || isNumber(doc) || isBoolean(doc)) {
|
|
213
225
|
if (!skipSelf) {
|
|
214
226
|
out.push({ depth, node: doc, nodeType: "text", path });
|
|
215
227
|
}
|
|
@@ -220,13 +232,13 @@ function collectRows(
|
|
|
220
232
|
// Recurse into its single template at `[...path, "map"]`. This is reached both when the array is
|
|
221
233
|
// A member of a children array (path `[…, "children", i]`) and the legacy whole-children form
|
|
222
234
|
// (path `[…, "children"]`).
|
|
223
|
-
if (
|
|
235
|
+
if (doc.$prototype === "Array") {
|
|
224
236
|
if (!skipSelf) {
|
|
225
237
|
out.push({ depth, node: doc, nodeType: "map", path });
|
|
226
238
|
}
|
|
227
|
-
const mapDef =
|
|
228
|
-
if (mapDef
|
|
229
|
-
collectRows(mapDef
|
|
239
|
+
const mapDef = doc.map;
|
|
240
|
+
if (isNonNullObject(mapDef)) {
|
|
241
|
+
collectRows(mapDef, [...path, "map"], depth + 1, out, false);
|
|
230
242
|
}
|
|
231
243
|
return;
|
|
232
244
|
}
|
|
@@ -247,36 +259,33 @@ function collectRows(
|
|
|
247
259
|
const childPath = [...path, "children", i];
|
|
248
260
|
collectRows(children[i]!, childPath, depth + 1, out, false);
|
|
249
261
|
}
|
|
250
|
-
} else if (
|
|
251
|
-
children &&
|
|
252
|
-
typeof children === "object" &&
|
|
253
|
-
(children as JxMutableNode).$prototype === "Array"
|
|
254
|
-
) {
|
|
262
|
+
} else if (isMappedArray(children)) {
|
|
255
263
|
// Legacy whole-children repeater: the array occupies the children slot itself.
|
|
264
|
+
// SAFETY: The repeater in the children slot is the same repeater node a children member is.
|
|
256
265
|
collectRows(children as JxMutableNode, [...path, "children"], depth + 1, out, false);
|
|
257
266
|
}
|
|
258
267
|
|
|
259
268
|
// $switch — emit each case as a virtual child
|
|
260
|
-
if (doc.$switch && doc.cases
|
|
269
|
+
if (doc.$switch && isNonNullObject(doc.cases)) {
|
|
261
270
|
for (const [caseName, caseDef] of Object.entries(doc.cases)) {
|
|
262
271
|
const casePath = [...path, "cases", caseName];
|
|
263
|
-
if (caseDef &&
|
|
272
|
+
if (isNonNullObject(caseDef) && caseDef.$ref) {
|
|
264
273
|
out.push({
|
|
265
274
|
depth: depth + 1,
|
|
266
|
-
node: caseDef
|
|
275
|
+
node: caseDef,
|
|
267
276
|
nodeType: "case-ref",
|
|
268
277
|
path: casePath,
|
|
269
278
|
});
|
|
270
|
-
} else if (caseDef
|
|
279
|
+
} else if (isNonNullObject(caseDef)) {
|
|
271
280
|
out.push({
|
|
272
281
|
depth: depth + 1,
|
|
273
|
-
node: caseDef
|
|
282
|
+
node: caseDef,
|
|
274
283
|
nodeType: "case",
|
|
275
284
|
path: casePath,
|
|
276
285
|
});
|
|
277
286
|
// Recurse into case children — skipSelf, because the "case" row above already stands in for
|
|
278
287
|
// The case node itself (with its own nodeType).
|
|
279
|
-
collectRows(caseDef
|
|
288
|
+
collectRows(caseDef, casePath, depth + 2, out, true);
|
|
280
289
|
}
|
|
281
290
|
}
|
|
282
291
|
}
|
|
@@ -285,10 +294,10 @@ function collectRows(
|
|
|
285
294
|
/**
|
|
286
295
|
* Get a display label for a node (for layers + overlays).
|
|
287
296
|
*
|
|
288
|
-
* @param {JxMutableNode | null} node
|
|
297
|
+
* @param {JxMutableNode | null | undefined} node
|
|
289
298
|
* @returns {string}
|
|
290
299
|
*/
|
|
291
|
-
export function nodeLabel(node: JxMutableNode | null) {
|
|
300
|
+
export function nodeLabel(node: JxMutableNode | null | undefined) {
|
|
292
301
|
if (!node) {
|
|
293
302
|
return "?";
|
|
294
303
|
}
|
|
@@ -306,14 +315,14 @@ export function nodeLabel(node: JxMutableNode | null) {
|
|
|
306
315
|
}
|
|
307
316
|
if (node.tagName === "slot") {
|
|
308
317
|
const name = node.attributes?.name;
|
|
309
|
-
return
|
|
318
|
+
return isString(name) && name.trim() ? `slot: ${name.trim()}` : "slot";
|
|
310
319
|
}
|
|
311
320
|
/* `displayTagName`, because a tag may be CHOSEN rather than written: this label reached the
|
|
312
321
|
Outline row, the Inspector's header and the jump bar, and a raw read rendered `[object Object]`
|
|
313
322
|
in all three. `a|div` is the honest answer — one element, tag decided at creation. */
|
|
314
323
|
const tag = displayTagName(node.tagName) || "div";
|
|
315
324
|
const suffix = node.$switch ? " ⇆" : "";
|
|
316
|
-
if (
|
|
325
|
+
if (isString(node.textContent) && node.textContent.length > 0) {
|
|
317
326
|
return `${tag} — ${node.textContent.slice(0, 24)}${suffix}`;
|
|
318
327
|
}
|
|
319
328
|
return tag + suffix;
|
|
@@ -340,5 +349,7 @@ export function setProjectState(ps: ProjectState | null) {
|
|
|
340
349
|
* @returns {ProjectState}
|
|
341
350
|
*/
|
|
342
351
|
export function requireProjectState() {
|
|
352
|
+
/* SAFETY: The contract above restricts callers to paths reached after `setProjectState` installed
|
|
353
|
+
a project (a project command, a panel that only mounts with one open); nothing here checks it. */
|
|
343
354
|
return projectState as ProjectState;
|
|
344
355
|
}
|
package/src/store.ts
CHANGED
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
|
|
10
10
|
// ─── Re-exports from state.js ────────────────────────────────────────────────
|
|
11
11
|
|
|
12
|
+
import { isFunction, isNonNullObject } from "@jxsuite/schema/guards";
|
|
12
13
|
import { INPUT_DEBOUNCE } from "./ui/timing";
|
|
13
14
|
import type { JxPath } from "./state";
|
|
14
|
-
import type { Tab } from "./tabs/tab";
|
|
15
|
+
import type { Tab, TabUi } from "./tabs/tab";
|
|
15
16
|
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
16
17
|
|
|
17
18
|
export {
|
|
@@ -36,18 +37,38 @@ export {
|
|
|
36
37
|
each of which meant "the pane I am acting on" and got "the pane that happens to be focused". A
|
|
37
38
|
stage belongs to a pane (`canvas/canvas-surface.ts`), a pane's cell is built by
|
|
38
39
|
`panels/pane-grid.ts`, and every one of those readers now takes its surface. */
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
export let
|
|
43
|
-
export let
|
|
40
|
+
|
|
41
|
+
/* Null until `initShellRefs()`, which `studio.ts` calls at boot right after mounting the shell
|
|
42
|
+
document; a render asked for before that (a test, or a command run ahead of the shell) reads null. */
|
|
43
|
+
export let activityBar: HTMLElement | null = null;
|
|
44
|
+
export let leftPanel: HTMLElement | null = null;
|
|
45
|
+
export let rightPanel: HTMLElement | null = null;
|
|
46
|
+
export let toolbarEl: HTMLElement | null = null;
|
|
47
|
+
export let statusbarEl: HTMLElement | null = null;
|
|
48
|
+
|
|
49
|
+
/** The shell region whose `id` is given, or null when the mounted shell has none. */
|
|
50
|
+
function shellRef(id: string): HTMLElement | null {
|
|
51
|
+
const element = document.querySelector(`#${id}`);
|
|
52
|
+
return element instanceof HTMLElement ? element : null;
|
|
53
|
+
}
|
|
44
54
|
|
|
45
55
|
export function initShellRefs() {
|
|
46
|
-
activityBar =
|
|
47
|
-
leftPanel =
|
|
48
|
-
rightPanel =
|
|
49
|
-
toolbarEl =
|
|
50
|
-
statusbarEl =
|
|
56
|
+
activityBar = shellRef("activity-bar");
|
|
57
|
+
leftPanel = shellRef("left-panel");
|
|
58
|
+
rightPanel = shellRef("right-panel");
|
|
59
|
+
toolbarEl = shellRef("toolbar");
|
|
60
|
+
statusbarEl = shellRef("statusbar");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* A shell region for a caller that cannot work without it. Reading one before `initShellRefs()` has
|
|
65
|
+
* found it is a boot-order bug, so it throws a TypeError that names the region.
|
|
66
|
+
*/
|
|
67
|
+
export function requireShellRef(ref: HTMLElement | null, id: string): HTMLElement {
|
|
68
|
+
if (!ref) {
|
|
69
|
+
throw new TypeError(`#${id} is not in the shell yet; initShellRefs() has not found it`);
|
|
70
|
+
}
|
|
71
|
+
return ref;
|
|
51
72
|
}
|
|
52
73
|
|
|
53
74
|
// ─── Shared constants ────────────────────────────────────────────────────────
|
|
@@ -130,6 +151,11 @@ export { stripEventHandlers } from "./utils/strip-events";
|
|
|
130
151
|
|
|
131
152
|
const _renderers = new Map<string, () => void>();
|
|
132
153
|
|
|
154
|
+
/** Whether a renderer's return value is a thenable — an `async` renderer that is still painting. */
|
|
155
|
+
function isThenable(value: unknown): value is PromiseLike<unknown> {
|
|
156
|
+
return (isNonNullObject(value) || isFunction(value)) && "then" in value && isFunction(value.then);
|
|
157
|
+
}
|
|
158
|
+
|
|
133
159
|
/**
|
|
134
160
|
* How many registered renderers are mid-paint right now.
|
|
135
161
|
*
|
|
@@ -154,9 +180,9 @@ function runRenderer(name: string, fn: () => void) {
|
|
|
154
180
|
};
|
|
155
181
|
let pending: PromiseLike<unknown> | null = null;
|
|
156
182
|
try {
|
|
157
|
-
const result = fn()
|
|
158
|
-
if (
|
|
159
|
-
pending = result
|
|
183
|
+
const result = fn();
|
|
184
|
+
if (isThenable(result)) {
|
|
185
|
+
pending = result;
|
|
160
186
|
}
|
|
161
187
|
} catch (error) {
|
|
162
188
|
console.error(`Renderer "${name}" failed:`, error);
|
|
@@ -165,7 +191,7 @@ function runRenderer(name: string, fn: () => void) {
|
|
|
165
191
|
done();
|
|
166
192
|
return;
|
|
167
193
|
}
|
|
168
|
-
pending.then(done, (error
|
|
194
|
+
pending.then(done, (error) => {
|
|
169
195
|
console.error(`Renderer "${name}" failed:`, error);
|
|
170
196
|
done();
|
|
171
197
|
});
|
|
@@ -232,8 +258,8 @@ export function updateSession(
|
|
|
232
258
|
selection?: JxPath[];
|
|
233
259
|
hover?: JxPath | null;
|
|
234
260
|
clipboard?: JxMutableNode | null;
|
|
235
|
-
ui?:
|
|
236
|
-
canvas?:
|
|
261
|
+
ui?: Partial<TabUi>;
|
|
262
|
+
canvas?: Partial<Tab["session"]["canvas"]>;
|
|
237
263
|
},
|
|
238
264
|
) {
|
|
239
265
|
if (tab) {
|
|
@@ -241,20 +267,16 @@ export function updateSession(
|
|
|
241
267
|
tab.session.selection = patch.selection;
|
|
242
268
|
}
|
|
243
269
|
if (patch.hover !== undefined) {
|
|
244
|
-
tab.session.hover = patch.hover
|
|
270
|
+
tab.session.hover = patch.hover;
|
|
245
271
|
}
|
|
246
272
|
if (patch.clipboard !== undefined) {
|
|
247
|
-
tab.session.clipboard = patch.clipboard
|
|
273
|
+
tab.session.clipboard = patch.clipboard;
|
|
248
274
|
}
|
|
249
275
|
if (patch.ui) {
|
|
250
|
-
|
|
251
|
-
(tab.session.ui as unknown as Record<string, unknown>)[k] = v;
|
|
252
|
-
}
|
|
276
|
+
Object.assign(tab.session.ui, patch.ui);
|
|
253
277
|
}
|
|
254
278
|
if (patch.canvas) {
|
|
255
|
-
|
|
256
|
-
(tab.session.canvas as unknown as Record<string, unknown>)[k] = v;
|
|
257
|
-
}
|
|
279
|
+
Object.assign(tab.session.canvas, patch.canvas);
|
|
258
280
|
}
|
|
259
281
|
}
|
|
260
282
|
}
|
|
@@ -263,12 +285,12 @@ export function updateSession(
|
|
|
263
285
|
* Update a single UI field on `tab`.
|
|
264
286
|
*
|
|
265
287
|
* @param {Tab | null} tab — the tab this field belongs to. `null` is a no-op.
|
|
266
|
-
* @param {
|
|
267
|
-
* @param {
|
|
288
|
+
* @param {K} field
|
|
289
|
+
* @param {TabUi[K]} value
|
|
268
290
|
*/
|
|
269
|
-
export function updateUi(tab: Tab | null, field:
|
|
291
|
+
export function updateUi<K extends keyof TabUi>(tab: Tab | null, field: K, value: TabUi[K]) {
|
|
270
292
|
if (tab) {
|
|
271
|
-
|
|
293
|
+
tab.session.ui[field] = value;
|
|
272
294
|
}
|
|
273
295
|
}
|
|
274
296
|
|
|
@@ -276,12 +298,10 @@ export function updateUi(tab: Tab | null, field: string, value: unknown) {
|
|
|
276
298
|
* Update `tab`'s canvas async state (status, scope, error).
|
|
277
299
|
*
|
|
278
300
|
* @param {Tab | null} tab — the tab whose stage produced this state. `null` is a no-op.
|
|
279
|
-
* @param {
|
|
301
|
+
* @param {Partial<Tab["session"]["canvas"]>} patch
|
|
280
302
|
*/
|
|
281
|
-
export function updateCanvas(tab: Tab | null, patch:
|
|
303
|
+
export function updateCanvas(tab: Tab | null, patch: Partial<Tab["session"]["canvas"]>) {
|
|
282
304
|
if (tab) {
|
|
283
|
-
|
|
284
|
-
(tab.session.canvas as Record<string, unknown>)[k] = v;
|
|
285
|
-
}
|
|
305
|
+
Object.assign(tab.session.canvas, patch);
|
|
286
306
|
}
|
|
287
307
|
}
|