@jxsuite/studio 2.0.0 → 2.1.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/canvas.html +21 -0
- package/dist/chunks/Overlay.dev-qfjzkms8.js +23 -0
- package/dist/chunks/{Overlay.dev-cszx7yn5.js.map → Overlay.dev-qfjzkms8.js.map} +1 -1
- package/dist/chunks/{adapter-z8fkmbmv.js → adapter-qfnesn5v.js} +2 -2
- package/dist/chunks/{cf-settings-mmyv436d.js → cf-settings-73sh5z4p.js} +3 -3
- package/dist/chunks/{components-0hzentwq.js → components-2bpqp4mq.js} +5 -7
- package/dist/chunks/{components-0hzentwq.js.map → components-2bpqp4mq.js.map} +1 -1
- package/dist/chunks/content-source-34gnkbnn.js +38 -0
- package/dist/chunks/content-source-34gnkbnn.js.map +9 -0
- package/dist/chunks/convert-to-repeater-t8kxre5s.js +258 -0
- package/dist/chunks/convert-to-repeater-t8kxre5s.js.map +10 -0
- package/dist/chunks/extension-sections-6mqydz35.js +301 -0
- package/dist/chunks/extension-sections-6mqydz35.js.map +11 -0
- package/dist/chunks/files-8kn321h1.js +70 -0
- package/dist/chunks/files-8kn321h1.js.map +9 -0
- package/dist/chunks/{format-host-2c188n41.js → format-host-mkwsmt8d.js} +3 -3
- package/dist/chunks/git-panel-tjbr191d.js +51 -0
- package/dist/chunks/git-panel-tjbr191d.js.map +9 -0
- package/dist/chunks/{index-baeg2x3y.js → index-7pxchcce.js} +4 -3
- package/dist/chunks/{index-baeg2x3y.js.map → index-7pxchcce.js.map} +3 -3
- package/dist/chunks/{jx-validate-qx8degj7.js → jx-validate-v6qgknrs.js} +3 -3
- package/dist/chunks/layers-panel-87pb25km.js +58 -0
- package/dist/chunks/layers-panel-87pb25km.js.map +9 -0
- package/dist/chunks/{monaco-setup-zjdp9zdw.js → monaco-setup-e0yh25j4.js} +4 -75
- package/dist/chunks/{monaco-setup-zjdp9zdw.js.map → monaco-setup-e0yh25j4.js.map} +3 -4
- package/dist/chunks/publish-panel-m0fcgdrt.js +21 -0
- package/dist/chunks/publish-panel-m0fcgdrt.js.map +9 -0
- package/dist/chunks/quick-search-rhs6cbsb.js +53 -0
- package/dist/chunks/quick-search-rhs6cbsb.js.map +9 -0
- package/dist/chunks/right-panel-zpdxd98t.js +37 -0
- package/dist/chunks/right-panel-zpdxd98t.js.map +9 -0
- package/dist/chunks/section-registry-zmckaxf4.js +30 -0
- package/dist/chunks/section-registry-zmckaxf4.js.map +9 -0
- package/dist/chunks/sp-overlay.dev-9ran0sfq.js +18 -0
- package/dist/chunks/sp-overlay.dev-9ran0sfq.js.map +9 -0
- package/dist/chunks/sp-popover.dev-rebmdncr.js +9 -0
- package/dist/chunks/sp-popover.dev-rebmdncr.js.map +9 -0
- package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js +15 -0
- package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js.map +9 -0
- package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js +15 -0
- package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js.map +9 -0
- package/dist/chunks/{sp-tray.dev-pb2fsd65.js → sp-tray.dev-ey59vfh7.js} +10 -8
- package/dist/chunks/{sp-tray.dev-pb2fsd65.js.map → sp-tray.dev-ey59vfh7.js.map} +2 -2
- package/dist/chunks/{studio-9qr6fq7p.js → studio-0rqqhrdy.js} +10 -378
- package/dist/chunks/{studio-9qr6fq7p.js.map → studio-0rqqhrdy.js.map} +4 -14
- package/dist/chunks/{studio-5x6tqqec.js → studio-2sj1jj3v.js} +10 -8
- package/dist/chunks/{studio-5x6tqqec.js.map → studio-2sj1jj3v.js.map} +2 -2
- package/dist/chunks/{studio-h3fw0wn8.js → studio-3fk1ac9z.js} +6 -4
- package/dist/chunks/{studio-h3fw0wn8.js.map → studio-3fk1ac9z.js.map} +2 -2
- package/dist/chunks/studio-41exgzhq.js +6690 -0
- package/dist/chunks/studio-41exgzhq.js.map +38 -0
- package/dist/chunks/{studio-7v2bpweq.js → studio-4mqb9a0j.js} +6 -4
- package/dist/chunks/{studio-7v2bpweq.js.map → studio-4mqb9a0j.js.map} +2 -2
- package/dist/chunks/studio-50k77cca.js +1787 -0
- package/dist/chunks/studio-50k77cca.js.map +18 -0
- package/dist/chunks/{studio-56v3zwk6.js → studio-6a0h7sne.js} +10 -8
- package/dist/chunks/{studio-56v3zwk6.js.map → studio-6a0h7sne.js.map} +2 -2
- package/dist/chunks/studio-6f0am8f2.js +53 -0
- package/dist/chunks/studio-6f0am8f2.js.map +10 -0
- package/dist/chunks/studio-6nmjc5qk.js +7002 -0
- package/dist/chunks/studio-6nmjc5qk.js.map +32 -0
- package/dist/chunks/studio-7afd21nw.js +67 -0
- package/dist/chunks/studio-7afd21nw.js.map +10 -0
- package/dist/chunks/{studio-xze4zrs1.js → studio-7bmdvzne.js} +2 -2
- package/dist/chunks/studio-7bmdvzne.js.map +10 -0
- package/dist/chunks/studio-8jpzqk5s.js +128 -0
- package/dist/chunks/studio-8jpzqk5s.js.map +10 -0
- package/dist/chunks/studio-94m77tgk.js +1482 -0
- package/dist/chunks/studio-94m77tgk.js.map +13 -0
- package/dist/chunks/studio-9je6w5sq.js +1000 -0
- package/dist/chunks/studio-9je6w5sq.js.map +16 -0
- package/dist/chunks/{studio-w7c6kvk7.js → studio-a7pzveq1.js} +2 -2
- package/dist/chunks/{studio-97qcgvdn.js → studio-adn0z1k3.js} +14 -8
- package/dist/chunks/{studio-97qcgvdn.js.map → studio-adn0z1k3.js.map} +3 -3
- package/dist/chunks/{studio-kr88ryr7.js → studio-bsxxx3x2.js} +17 -15
- package/dist/chunks/{studio-kr88ryr7.js.map → studio-bsxxx3x2.js.map} +7 -6
- package/dist/chunks/studio-bw5dz6km.js +608 -0
- package/dist/chunks/studio-bw5dz6km.js.map +21 -0
- package/dist/chunks/studio-c6s5getc.js +4232 -0
- package/dist/chunks/studio-c6s5getc.js.map +39 -0
- package/dist/chunks/studio-cjm7fdjf.js +451 -0
- package/dist/chunks/studio-cjm7fdjf.js.map +14 -0
- package/dist/chunks/{studio-cx91mnh8.js → studio-ckwz4d3x.js} +53 -53
- package/dist/chunks/{studio-cx91mnh8.js.map → studio-ckwz4d3x.js.map} +5 -5
- package/dist/chunks/studio-dg7zyt5x.js +28 -0
- package/dist/chunks/studio-dg7zyt5x.js.map +10 -0
- package/dist/chunks/studio-dzcyvvvz.js +166 -0
- package/dist/chunks/studio-dzcyvvvz.js.map +10 -0
- package/dist/chunks/{studio-7kqe41sa.js → studio-evkr5d3b.js} +15 -7
- package/dist/chunks/{studio-7kqe41sa.js.map → studio-evkr5d3b.js.map} +5 -4
- package/dist/chunks/studio-f12h6177.js +411 -0
- package/dist/chunks/studio-f12h6177.js.map +13 -0
- package/dist/chunks/studio-hbp1s8m9.js +1817 -0
- package/dist/chunks/studio-hbp1s8m9.js.map +14 -0
- package/dist/chunks/studio-k2sxjph5.js +15295 -0
- package/dist/chunks/studio-k2sxjph5.js.map +235 -0
- package/dist/chunks/studio-myje51t3.js +385 -0
- package/dist/chunks/studio-myje51t3.js.map +12 -0
- package/dist/chunks/studio-na6rwzhw.js +353 -0
- package/dist/chunks/studio-na6rwzhw.js.map +11 -0
- package/dist/chunks/{studio-4k0m4fmp.js → studio-p471gg5n.js} +126 -3
- package/dist/chunks/studio-p471gg5n.js.map +14 -0
- package/dist/chunks/{studio-9bjwf0d4.js → studio-rgwcpast.js} +5 -46
- package/dist/chunks/{studio-9bjwf0d4.js.map → studio-rgwcpast.js.map} +4 -5
- package/dist/chunks/{studio-hhj92gcr.js → studio-s519zc99.js} +3 -3
- package/dist/chunks/studio-sas7mt3k.js +75 -0
- package/dist/chunks/studio-sas7mt3k.js.map +10 -0
- package/dist/chunks/studio-t5wqwzdh.js +74 -0
- package/dist/chunks/studio-t5wqwzdh.js.map +10 -0
- package/dist/chunks/{studio-9qpspwfn.js → studio-temv5bw4.js} +5 -5
- package/dist/chunks/{studio-9qpspwfn.js.map → studio-temv5bw4.js.map} +1 -1
- package/dist/chunks/{studio-qkvt37c0.js → studio-tr20m8g8.js} +669 -18
- package/dist/chunks/studio-tr20m8g8.js.map +9 -0
- package/dist/chunks/{studio-ygzav7z5.js → studio-v96qfnww.js} +5514 -4291
- package/dist/chunks/studio-v96qfnww.js.map +54 -0
- package/dist/chunks/studio-vcetc91k.js +659 -0
- package/dist/chunks/studio-vcetc91k.js.map +10 -0
- package/dist/chunks/{studio-n9zmpxjg.js → studio-vmymjefp.js} +2972 -4937
- package/dist/chunks/studio-vmymjefp.js.map +98 -0
- package/dist/chunks/{studio-bghqfmea.js → studio-wwseqyw0.js} +2 -2
- package/dist/chunks/studio-x9hmy5kr.js +390 -0
- package/dist/chunks/studio-x9hmy5kr.js.map +10 -0
- package/dist/chunks/studio-xa0ce0n7.js +335 -0
- package/dist/chunks/studio-xa0ce0n7.js.map +10 -0
- package/dist/chunks/studio-xm3dbxvn.js +378 -0
- package/dist/chunks/studio-xm3dbxvn.js.map +19 -0
- package/dist/chunks/{studio-nqw433kv.js → studio-xmvbhg31.js} +2 -2
- package/dist/chunks/studio-zv37yrfa.js +1054 -0
- package/dist/chunks/studio-zv37yrfa.js.map +13 -0
- package/dist/chunks/{ws-client-q7hkz3j9.js → ws-client-654ts66j.js} +6 -4
- package/dist/chunks/ws-client-654ts66j.js.map +11 -0
- package/dist/iframe-entry.js +668 -230
- package/dist/studio.js +23711 -35185
- package/index.html +35 -4685
- package/package.json +17 -15
- package/src/about/about-modal.ts +42 -11
- package/src/browse/library-commands.ts +240 -0
- package/src/browse/library-layouts.ts +369 -0
- package/src/browse/library-model.ts +396 -0
- package/src/browse/library-pane.ts +1049 -0
- package/src/browse/library-preview.ts +252 -0
- package/src/browse/library-source.ts +150 -0
- package/src/canvas/canvas-helpers.ts +33 -9
- package/src/canvas/canvas-live-render.ts +45 -29
- package/src/canvas/canvas-patcher.ts +151 -31
- package/src/canvas/canvas-perf.ts +46 -7
- package/src/canvas/canvas-render.ts +1092 -220
- package/src/canvas/canvas-surface.ts +240 -0
- package/src/canvas/canvas-utils.ts +1166 -124
- package/src/canvas/iframe-drop.ts +2 -1
- package/src/canvas/iframe-entry.ts +241 -4
- package/src/canvas/iframe-host.ts +1226 -143
- package/src/canvas/iframe-inline-edit.ts +31 -0
- package/src/canvas/iframe-interaction.ts +76 -16
- package/src/canvas/iframe-keys.ts +107 -45
- package/src/canvas/iframe-overlay.ts +38 -1
- package/src/canvas/iframe-protocol.ts +137 -2
- package/src/canvas/iframe-render.ts +70 -2
- package/src/canvas/iframe-slash.ts +6 -0
- package/src/canvas/path-mapping.ts +56 -6
- package/src/canvas/surface-registry.ts +292 -0
- package/src/collab/collab-commands.ts +244 -0
- package/src/collab/collab-session.ts +198 -32
- package/src/collab/collab-state.ts +28 -2
- package/src/collab/presence-chips.ts +100 -9
- package/src/commands/active-registry.ts +42 -0
- package/src/commands/app-commands.ts +176 -0
- package/src/commands/budget.ts +158 -0
- package/src/commands/command-args.ts +253 -0
- package/src/commands/context.ts +387 -0
- package/src/commands/defaults.ts +580 -0
- package/src/commands/keymap.ts +571 -0
- package/src/commands/levels.ts +345 -0
- package/src/commands/live-context.ts +193 -0
- package/src/commands/reference.ts +227 -0
- package/src/commands/registry.ts +293 -0
- package/src/component-props.ts +3 -2
- package/src/content/draft-state.ts +106 -0
- package/src/content/entry-commands.ts +282 -0
- package/src/content/entry-editor.ts +327 -0
- package/src/content/entry-fields.ts +116 -0
- package/src/content/entry-model.ts +175 -0
- package/src/editor/canvas-context-menu.ts +17 -11
- package/src/editor/canvas-slash-bridge.ts +11 -4
- package/src/editor/context-menu.ts +804 -204
- package/src/editor/convert-to-component.ts +31 -10
- package/src/editor/convert-to-repeater.ts +3 -2
- package/src/editor/inline-edit-apply.ts +5 -5
- package/src/editor/inline-edit.ts +86 -50
- package/src/editor/insert-zone-action.ts +1 -1
- package/src/editor/shortcuts.ts +1043 -329
- package/src/editor/slash-menu.ts +1 -0
- package/src/files/elements.ts +166 -0
- package/src/files/file-ops.ts +178 -31
- package/src/files/files.ts +898 -268
- package/src/files/fs-events.ts +21 -0
- package/src/files/media-meta.ts +203 -0
- package/src/files/media-paths.ts +141 -0
- package/src/files/media-upload.ts +7 -3
- package/src/files/media-usage.ts +189 -0
- package/src/github/github-auth.ts +235 -33
- package/src/github/github-publish.ts +80 -21
- package/src/grid/grid-controller.ts +152 -12
- package/src/grid/grid-layout.ts +225 -20
- package/src/grid/grid-open.ts +120 -0
- package/src/grid/grid-panel.ts +554 -39
- package/src/grid/grid-source.ts +27 -1
- package/src/grid/redirects-grid.ts +599 -0
- package/src/grid/redirects.ts +398 -0
- package/src/grid/sources/content-source.ts +108 -2
- package/src/i18n/i18n-commands.ts +322 -0
- package/src/new-project/add-repo-modal.ts +8 -10
- package/src/new-project/import-tab.ts +34 -9
- package/src/new-project/location-fields.ts +9 -1
- package/src/new-project/new-project-modal.ts +270 -262
- package/src/packages/jxsuite-update.ts +97 -48
- package/src/packages/pull-package-sync.ts +18 -9
- package/src/page-params.ts +2 -1
- package/src/panels/activity-bar.ts +152 -91
- package/src/panels/activity-panel.ts +481 -0
- package/src/panels/ai-chat/chat-markdown.ts +8 -3
- package/src/panels/ai-chat/chat-view.ts +245 -18
- package/src/panels/ai-chat/composer.ts +31 -5
- package/src/panels/ai-chat/sessions-view.ts +17 -10
- package/src/panels/ai-panel.ts +279 -120
- package/src/panels/block-action-bar.ts +1115 -224
- package/src/panels/bottom-dock.ts +337 -0
- package/src/panels/canvas-dnd-bridge.ts +37 -8
- package/src/panels/chat-panel.ts +29 -12
- package/src/panels/data-explorer.ts +254 -112
- package/src/panels/data-grid.ts +10 -4
- package/src/panels/dnd.ts +28 -51
- package/src/panels/editors.ts +434 -107
- package/src/panels/elements-panel.ts +66 -2
- package/src/panels/empty-state.ts +112 -0
- package/src/panels/events-panel.ts +596 -82
- package/src/panels/formula-workspace.ts +408 -218
- package/src/panels/frontmatter-fields.ts +51 -10
- package/src/panels/frontmatter-panel.ts +357 -79
- package/src/panels/git-panel.ts +375 -164
- package/src/panels/head-panel.ts +791 -85
- package/src/panels/i18n-panel.ts +592 -0
- package/src/panels/imports-panel.ts +95 -85
- package/src/panels/jump-bar.ts +584 -0
- package/src/panels/layers-panel.ts +1106 -328
- package/src/panels/left-panel.ts +109 -204
- package/src/panels/navigator-panels.ts +131 -0
- package/src/panels/overlays.ts +7 -2
- package/src/panels/pane-context.ts +1477 -0
- package/src/panels/pane-grid.ts +406 -0
- package/src/panels/panel-registry.ts +340 -0
- package/src/panels/panel-scheduler.ts +75 -0
- package/src/panels/problems-panel.ts +234 -0
- package/src/panels/properties-panel.ts +946 -1139
- package/src/panels/provenance.ts +258 -0
- package/src/panels/quick-search.ts +791 -122
- package/src/panels/right-panel.ts +228 -102
- package/src/panels/seo-modal.ts +395 -0
- package/src/panels/settings-pane.ts +203 -0
- package/src/panels/signals-panel.ts +354 -137
- package/src/panels/statement-editor.ts +41 -25
- package/src/panels/statusbar.ts +342 -106
- package/src/panels/style-panel.ts +974 -463
- package/src/panels/style-utils.ts +3 -3
- package/src/panels/stylebook-doc.ts +4 -2
- package/src/panels/stylebook-layers-panel.ts +3 -2
- package/src/panels/stylebook-panel.ts +51 -26
- package/src/panels/tab-strip.ts +1058 -78
- package/src/panels/target-line.ts +274 -0
- package/src/panels/toolbar.ts +631 -484
- package/src/panels/welcome-screen.ts +301 -198
- package/src/platform-errors.ts +26 -3
- package/src/platform.ts +96 -2
- package/src/platforms/cloud.ts +71 -8
- package/src/platforms/devserver.ts +92 -29
- package/src/publish/deploy-checklist.ts +383 -0
- package/src/publish/pages-service.ts +10 -1
- package/src/publish/publish-commands.ts +218 -0
- package/src/publish/publish-panel.ts +110 -16
- package/src/recent-projects.ts +3 -2
- package/src/services/a11y-report.ts +505 -0
- package/src/services/ai-models.ts +75 -2
- package/src/services/ai-project-tools.ts +29 -10
- package/src/services/ai-system-prompt.ts +53 -14
- package/src/services/ai-tools.ts +39 -3
- package/src/services/ai-writes.ts +154 -0
- package/src/services/announce.ts +97 -0
- package/src/services/automation.ts +424 -175
- package/src/services/cem-export.ts +9 -4
- package/src/services/clock.ts +61 -0
- package/src/services/document-assistant.ts +36 -8
- package/src/services/idle.ts +179 -0
- package/src/services/import-client.ts +26 -0
- package/src/services/monaco-buffer.ts +627 -0
- package/src/services/monaco-lazy.ts +36 -0
- package/src/services/notify.ts +271 -0
- package/src/services/profile.ts +155 -0
- package/src/services/references.ts +0 -0
- package/src/services/token-lint.ts +3 -2
- package/src/services/tool-executor.ts +53 -7
- package/src/services/trusted-types.ts +123 -0
- package/src/settings/contexts-section.ts +427 -0
- package/src/settings/contributed-section.ts +149 -11
- package/src/settings/css-vars-editor.ts +306 -349
- package/src/settings/defs-editor.ts +93 -34
- package/src/settings/dependencies-editor.ts +7 -7
- package/src/settings/extension-sections.ts +37 -5
- package/src/settings/general-settings.ts +204 -121
- package/src/settings/locales-section.ts +347 -0
- package/src/settings/preferences-accounts.ts +140 -0
- package/src/settings/preferences-dialog.ts +620 -0
- package/src/settings/preferences-keymap.ts +270 -0
- package/src/settings/project-sections.ts +260 -0
- package/src/settings/section-registry.ts +169 -0
- package/src/settings/settings-document.ts +385 -0
- package/src/shell.ts +1549 -0
- package/src/site-context.ts +45 -20
- package/src/state.ts +14 -275
- package/src/store.ts +88 -43
- package/src/studio.ts +790 -346
- package/src/style/live-preview.ts +36 -0
- package/src/style/project-styles.ts +349 -0
- package/src/style/token-ref.ts +123 -0
- package/src/tabs/patch-ops.ts +16 -4
- package/src/tabs/project-config.ts +416 -0
- package/src/tabs/selection.ts +323 -0
- package/src/tabs/tab.ts +182 -47
- package/src/tabs/transact.ts +209 -28
- package/src/types.ts +68 -13
- package/src/ui/ai-credentials-form.ts +39 -35
- package/src/ui/ai-managed-connect.ts +113 -0
- package/src/ui/dynamic-slot.ts +224 -81
- package/src/ui/expression-editor.ts +71 -63
- package/src/ui/field-input.ts +4 -6
- package/src/ui/field-row.ts +215 -38
- package/src/ui/form-controls.ts +194 -7
- package/src/ui/layers.ts +492 -69
- package/src/ui/media-picker.ts +115 -25
- package/src/ui/panel-resize.ts +109 -91
- package/src/ui/progress-modal.ts +131 -50
- package/src/ui/regions.ts +462 -0
- package/src/ui/schema-form.ts +229 -45
- package/src/ui/spectrum.ts +24 -8
- package/src/ui/timing.ts +49 -0
- package/src/ui/value-selector.ts +20 -0
- package/src/ui/value-source.ts +348 -0
- package/src/ui/virtual-window.ts +400 -0
- package/src/utils/edit-display.ts +3 -2
- package/src/utils/inherited-style.ts +67 -37
- package/src/view.ts +64 -78
- package/src/workspace/pane-derive.ts +1258 -0
- package/src/workspace/session.ts +317 -0
- package/src/workspace/workspace.ts +1345 -23
- package/styles/canvas.css +653 -0
- package/styles/forced-colors.css +106 -0
- package/styles/inspector.css +1454 -0
- package/styles/overlays.css +2704 -0
- package/styles/panels.css +1701 -0
- package/styles/shell.css +1423 -0
- package/styles/tokens.css +151 -0
- package/dist/chunks/Overlay.dev-cszx7yn5.js +0 -22
- package/dist/chunks/extension-sections-qct0gt8f.js +0 -531
- package/dist/chunks/extension-sections-qct0gt8f.js.map +0 -12
- package/dist/chunks/files-02zn5y24.js +0 -50
- package/dist/chunks/files-02zn5y24.js.map +0 -9
- package/dist/chunks/git-panel-mbb0y0hz.js +0 -28
- package/dist/chunks/git-panel-mbb0y0hz.js.map +0 -9
- package/dist/chunks/layers-panel-9qekmqk1.js +0 -26
- package/dist/chunks/layers-panel-9qekmqk1.js.map +0 -9
- package/dist/chunks/settings-modal-gj0hrah4.js +0 -29
- package/dist/chunks/settings-modal-gj0hrah4.js.map +0 -9
- package/dist/chunks/sp-overlay.dev-earn5as8.js +0 -17
- package/dist/chunks/sp-overlay.dev-earn5as8.js.map +0 -9
- package/dist/chunks/sp-popover.dev-frxtfejn.js +0 -8
- package/dist/chunks/sp-popover.dev-frxtfejn.js.map +0 -9
- package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js +0 -14
- package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js.map +0 -9
- package/dist/chunks/sp-tooltip.dev-a9fywesm.js +0 -21
- package/dist/chunks/sp-tooltip.dev-a9fywesm.js.map +0 -10
- package/dist/chunks/studio-4k0m4fmp.js.map +0 -13
- package/dist/chunks/studio-568nx4t5.js +0 -469
- package/dist/chunks/studio-568nx4t5.js.map +0 -14
- package/dist/chunks/studio-9smfzqhc.js +0 -19
- package/dist/chunks/studio-9smfzqhc.js.map +0 -10
- package/dist/chunks/studio-asvf0j9e.js +0 -429
- package/dist/chunks/studio-asvf0j9e.js.map +0 -13
- package/dist/chunks/studio-d77qm3pk.js +0 -3427
- package/dist/chunks/studio-d77qm3pk.js.map +0 -26
- package/dist/chunks/studio-j6gqyjf4.js +0 -1854
- package/dist/chunks/studio-j6gqyjf4.js.map +0 -18
- package/dist/chunks/studio-n9zmpxjg.js.map +0 -115
- package/dist/chunks/studio-qkvt37c0.js.map +0 -9
- package/dist/chunks/studio-rq0vxb19.js +0 -3744
- package/dist/chunks/studio-rq0vxb19.js.map +0 -22
- package/dist/chunks/studio-wd6ewdvd.js +0 -853
- package/dist/chunks/studio-wd6ewdvd.js.map +0 -12
- package/dist/chunks/studio-xq0t7n5t.js +0 -140
- package/dist/chunks/studio-xq0t7n5t.js.map +0 -10
- package/dist/chunks/studio-xze4zrs1.js.map +0 -10
- package/dist/chunks/studio-ygzav7z5.js.map +0 -46
- package/dist/chunks/studio-zmy7241e.js +0 -399
- package/dist/chunks/studio-zmy7241e.js.map +0 -12
- package/dist/chunks/ws-client-q7hkz3j9.js.map +0 -11
- package/src/browse/browse-modal.ts +0 -69
- package/src/browse/browse.ts +0 -904
- package/src/canvas/canvas-diff.ts +0 -216
- package/src/canvas/nested-site-style.ts +0 -58
- package/src/new-project/design-fields.ts +0 -264
- package/src/new-project/templates.ts +0 -61
- package/src/panels/tab-bar.ts +0 -548
- package/src/settings/settings-modal.ts +0 -203
- /package/dist/chunks/{adapter-z8fkmbmv.js.map → adapter-qfnesn5v.js.map} +0 -0
- /package/dist/chunks/{cf-settings-mmyv436d.js.map → cf-settings-73sh5z4p.js.map} +0 -0
- /package/dist/chunks/{format-host-2c188n41.js.map → format-host-mkwsmt8d.js.map} +0 -0
- /package/dist/chunks/{jx-validate-qx8degj7.js.map → jx-validate-v6qgknrs.js.map} +0 -0
- /package/dist/chunks/{studio-w7c6kvk7.js.map → studio-a7pzveq1.js.map} +0 -0
- /package/dist/chunks/{studio-hhj92gcr.js.map → studio-s519zc99.js.map} +0 -0
- /package/dist/chunks/{studio-bghqfmea.js.map → studio-wwseqyw0.js.map} +0 -0
- /package/dist/chunks/{studio-nqw433kv.js.map → studio-xmvbhg31.js.map} +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/services/data-service.ts", "../src/grid/csv-codec.ts", "../src/grid/sources/csv-file-source.ts", "../src/grid/sources/connector-source.ts", "../src/browse/library-model.ts", "../src/browse/library-source.ts", "../src/grid/grid-open.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * Data-service — thin PAL wrapper over the optional data-surface members\n * (dataConnections/dataConnectionTest/dataPush/dataRows/row CRUD/listSecrets/setSecrets).\n *\n * Every helper degrades cleanly when the platform omits the member family (older backends, cloud\n * without DB reach): list-shaped calls resolve null/empty, action-shaped calls resolve an error\n * result instead of throwing. Secret VALUES only ever flow INTO setSecrets — reads are names-only\n * (specs/extensions.md §13).\n */\n\nimport { getPlatform } from \"../platform\";\nimport type {\n DataConnectionsResponse,\n DataConnectionTestResult,\n DataPushResult,\n DataRowDelete,\n DataRowInsert,\n DataRowsQuery,\n DataRowsResult,\n DataRowUpdate,\n SecretsSetRequest,\n SecretsSetResponse,\n StudioPlatform,\n} from \"../types\";\n\n/** The registered platform, or null before registration (early boot, bare tests). */\nfunction platformOrNull(): StudioPlatform | null {\n try {\n return getPlatform();\n } catch {\n return null;\n }\n}\n\n/** True when the platform serves the data grid (the family's gating member is dataRows). */\nexport function dataSurfaceAvailable(): boolean {\n return typeof platformOrNull()?.dataRows === \"function\";\n}\n\n/** True when the platform can store secret values (backs the \"secret\" form control). */\nexport function secretsAvailable(): boolean {\n return typeof platformOrNull()?.setSecrets === \"function\";\n}\n\n/** Connections with configured state and table names; null when the backend lacks the route. */\nexport async function fetchConnections(): Promise<DataConnectionsResponse | null> {\n const platform = platformOrNull();\n if (typeof platform?.dataConnections !== \"function\") {\n return null;\n }\n return platform.dataConnections();\n}\n\n/** Probe one connection; degrades to an error result instead of throwing. */\nexport async function testConnection(connection: string): Promise<DataConnectionTestResult> {\n const platform = platformOrNull();\n if (typeof platform?.dataConnectionTest !== \"function\") {\n return { error: \"Connection tests are not supported by this backend\", ok: false };\n }\n try {\n return await platform.dataConnectionTest(connection);\n } catch (error) {\n return { error: error instanceof Error ? error.message : String(error), ok: false };\n }\n}\n\n/** Push table schemas (dryRun compiles the plan only); degrades to an error result. */\nexport async function pushSchema(opts?: {\n connection?: string;\n dryRun?: boolean;\n}): Promise<DataPushResult> {\n const platform = platformOrNull();\n if (typeof platform?.dataPush !== \"function\") {\n return { applied: false, errors: [\"Schema push is not supported by this backend\"], plan: [] };\n }\n try {\n return await platform.dataPush(opts);\n } catch (error) {\n return {\n applied: false,\n errors: [error instanceof Error ? error.message : String(error)],\n plan: [],\n };\n }\n}\n\n/** A required data member, throwing a uniform degradation error when absent. */\nfunction requireMember<K extends keyof StudioPlatform>(name: K): NonNullable<StudioPlatform[K]> {\n const platform = platformOrNull();\n const member = platform?.[name];\n if (member === undefined || member === null) {\n throw new Error(`The ${String(name)} surface is not supported by this backend`);\n }\n return member as NonNullable<StudioPlatform[K]>;\n}\n\n/** Page a table's rows (grid callers handle errors per load). */\nexport function fetchRows(query: DataRowsQuery): Promise<DataRowsResult> {\n return requireMember(\"dataRows\")(query);\n}\n\nexport function insertRow(req: DataRowInsert): Promise<{ row: Record<string, unknown> }> {\n return requireMember(\"dataInsertRow\")(req);\n}\n\nexport function updateRow(req: DataRowUpdate): Promise<{ row: Record<string, unknown> }> {\n return requireMember(\"dataUpdateRow\")(req);\n}\n\nexport function deleteRow(req: DataRowDelete): Promise<{ ok: boolean }> {\n return requireMember(\"dataDeleteRow\")(req);\n}\n\n/** Configured secret env-var NAMES; null when the backend has no secrets surface. */\nexport async function listSecretNames(): Promise<string[] | null> {\n const platform = platformOrNull();\n if (typeof platform?.listSecrets !== \"function\") {\n return null;\n }\n return platform.listSecrets();\n}\n\n/** Write/remove secrets through the platform store (values flow in, names come back). */\nexport function saveSecrets(req: SecretsSetRequest): Promise<SecretsSetResponse> {\n return requireMember(\"setSecrets\")(req);\n}\n\n/**\n * Derive the env-var NAME a secret-marked field stores its value under: CONSTANT_CASE of the entry\n * key (falling back to the section key) plus the field key minus its `Env` suffix — e.g. connection\n * \"main\" field \"urlEnv\" → \"MAIN_URL\"; section \"auth\" field \"secretEnv\" → \"AUTH_SECRET\". The NAME\n * goes into project.json; the VALUE goes to setSecrets.\n *\n * @param {string} sectionKey\n * @param {string | null} entryKey - The map-layout entry (connection) name, when any\n * @param {string} fieldKey\n * @returns {string}\n */\nexport function deriveSecretEnvName(\n sectionKey: string,\n entryKey: string | null,\n fieldKey: string,\n): string {\n const constant = (raw: string) =>\n raw\n .replaceAll(/([a-z0-9])([A-Z])/g, \"$1_$2\")\n .replaceAll(/[^A-Za-z0-9]+/g, \"_\")\n .replaceAll(/^_+|_+$/g, \"\")\n .toUpperCase();\n const parts = [entryKey ?? sectionKey, fieldKey.replace(/Env$/, \"\")]\n .map((part) => constant(part))\n .filter(Boolean);\n const name = parts.join(\"_\") || \"SECRET\";\n return /^\\d/.test(name) ? `JX_${name}` : name;\n}\n",
|
|
6
|
+
"/**\n * Positional CSV codec for the grid editor.\n *\n * RFC 4180 parse/serialize that keeps what the parser extension's object-row loader discards:\n * column order, duplicate/empty headers, untrimmed whitespace, the file's dominant EOL, and whether\n * it ended with a newline. Values stay raw strings — typing lives in schema-columns. Serialization\n * is canonical (quotes only where required), so an edited file is re-emitted minimally quoted;\n * untouched files are never rewritten.\n */\n\nexport interface CsvDocument {\n headers: string[];\n rows: string[][];\n eol: \"\\n\" | \"\\r\\n\";\n trailingNewline: boolean;\n}\n\n/** Split CSV text into records of raw fields, honoring quotes across commas and newlines. */\nfunction splitRecords(text: string): string[][] {\n const records: string[][] = [];\n let fields: string[] = [];\n let field = \"\";\n let inQuotes = false;\n let fieldStarted = false;\n\n const endField = () => {\n fields.push(field);\n field = \"\";\n fieldStarted = false;\n };\n const endRecord = () => {\n endField();\n // A completely empty line is structure, not data — skip it (common trailing-blank case).\n if (fields.length === 1 && fields[0] === \"\") {\n fields = [];\n return;\n }\n records.push(fields);\n fields = [];\n };\n\n for (let i = 0; i < text.length; i++) {\n const ch = text[i];\n if (inQuotes) {\n if (ch === '\"') {\n if (text[i + 1] === '\"') {\n field += '\"';\n i += 1;\n } else {\n inQuotes = false;\n }\n } else {\n field += ch;\n }\n continue;\n }\n if (ch === '\"' && !fieldStarted) {\n inQuotes = true;\n fieldStarted = true;\n } else if (ch === '\"') {\n // Quote inside an unquoted field — keep it literal (lenient, matches common parsers).\n field += ch;\n } else if (ch === \",\") {\n endField();\n } else if (ch === \"\\n\") {\n endRecord();\n } else if (ch === \"\\r\") {\n if (text[i + 1] === \"\\n\") {\n i += 1;\n }\n endRecord();\n } else {\n field += ch;\n fieldStarted = true;\n }\n }\n if (field !== \"\" || fields.length > 0) {\n endRecord();\n }\n return records;\n}\n\n/**\n * Parse CSV text into headers + positional rows. Rows are padded to the header width; when a data\n * row is wider than the header row, headers are padded with \"\" so no column is lost.\n */\nexport function parseCsv(text: string): CsvDocument {\n const crlf = (text.match(/\\r\\n/g) ?? []).length;\n const bareLf = (text.match(/(?<!\\r)\\n/g) ?? []).length;\n const eol: CsvDocument[\"eol\"] = crlf > bareLf ? \"\\r\\n\" : \"\\n\";\n const trailingNewline = text.endsWith(\"\\n\");\n\n const records = splitRecords(text);\n const headers = records[0] ?? [];\n const rows = records.slice(1);\n const width = Math.max(headers.length, ...rows.map((r) => r.length), 0);\n while (headers.length < width) {\n headers.push(\"\");\n }\n for (const row of rows) {\n while (row.length < width) {\n row.push(\"\");\n }\n }\n return { eol, headers, rows, trailingNewline };\n}\n\n/** Quote a field iff it contains a delimiter, quote, or newline; double embedded quotes. */\nfunction encodeField(value: string): string {\n if (/[\",\\n\\r]/.test(value)) {\n return `\"${value.replaceAll('\"', '\"\"')}\"`;\n }\n return value;\n}\n\n/** Serialize back to CSV text, preserving the document's EOL flavor and trailing-newline flag. */\nexport function serializeCsv(doc: CsvDocument): string {\n const lines = [doc.headers, ...doc.rows].map((fields) =>\n fields.map((field) => encodeField(field)).join(\",\"),\n );\n return lines.join(doc.eol) + (doc.trailingNewline ? doc.eol : \"\");\n}\n",
|
|
7
|
+
"/**\n * CSV file grid source — one `.csv` project file edited as a grid.\n *\n * The file loads once into a positional string matrix (csv-codec). Columns are typed by the\n * matching content-type schema when the CSV backs a collection (same resolver as the head panel),\n * otherwise inferred by sampling values. Commit is atomic whole-file: pending edits are applied to\n * the matrix, the document is re-serialized, and a save-time staleness check (file text vs. the\n * load-time text) aborts the entire commit rather than clobber an external change. Only edited\n * cells are canonicalized — untouched cells keep their raw file text.\n */\nimport { getPlatform } from \"../../platform\";\nimport { projectState } from \"../../store\";\nimport { findContentTypeSchema } from \"../../utils/studio-utils\";\nimport { isRecentLocal, markLocalMutation } from \"../../files/fs-events\";\nimport { parseCsv, serializeCsv } from \"../csv-codec\";\nimport {\n cellToText,\n coerceCellInput,\n columnsFromSchema,\n inferColumnsFromRows,\n} from \"../schema-columns\";\nimport type { CsvDocument } from \"../csv-codec\";\nimport type {\n CommitResult,\n GridCellValue,\n GridColumn,\n GridEditBatch,\n GridRow,\n GridRowsResult,\n GridSource,\n} from \"../grid-source\";\n\n/** Candidate identity columns, in the parser extension's fallback order. */\nconst ID_FIELDS = [\"id\", \"sku\", \"slug\", \"Slug\"];\n\ninterface CsvModel {\n doc: CsvDocument;\n /** Unique field name per column position (duplicate/empty headers get positional names). */\n fields: string[];\n columns: GridColumn[];\n /** Map of rowKey → matrix row index. */\n keyToIndex: Map<string, number>;\n /** Matrix row index → rowKey. */\n keys: string[];\n /** File text at load time — the whole-file staleness fingerprint. */\n loadText: string;\n}\n\n/** Unique grid field names for CSV headers (duplicates/empties fall back to positional names). */\nexport function fieldNamesForHeaders(headers: string[]): string[] {\n const used = new Set<string>();\n return headers.map((header, i) => {\n let name = header.trim() === \"\" ? `column${i + 1}` : header;\n if (used.has(name)) {\n name = `${name}__${i + 1}`;\n }\n used.add(name);\n return name;\n });\n}\n\n/** Pick the identity column: first id-chain field whose values are all unique and non-empty. */\nfunction pickIdField(fields: string[], doc: CsvDocument): string | null {\n for (const candidate of ID_FIELDS) {\n const idx = fields.indexOf(candidate);\n if (idx === -1) {\n continue;\n }\n const values = doc.rows.map((row) => row[idx] ?? \"\");\n if (values.every((v) => v !== \"\") && new Set(values).size === values.length) {\n return candidate;\n }\n }\n return null;\n}\n\nfunction buildModel(text: string, path: string): CsvModel {\n const doc = parseCsv(text);\n const fields = fieldNamesForHeaders(doc.headers);\n const idField = pickIdField(fields, doc);\n const idIndex = idField ? fields.indexOf(idField) : -1;\n const keys = doc.rows.map((row, i) => (idIndex === -1 ? String(i) : row[idIndex]!));\n const keyToIndex = new Map(keys.map((key, i) => [key, i]));\n\n // Typed columns when this CSV is a collection source; sniffed kinds otherwise.\n const contentType = findContentTypeSchema(path, projectState?.projectConfig);\n const schemaProps = contentType?.schema?.properties ?? {};\n const sampleRows = doc.rows.slice(0, 50).map((row) => {\n const cells: Record<string, GridCellValue> = {};\n for (const [i, field] of fields.entries()) {\n cells[field] = row[i] ?? \"\";\n }\n return cells;\n });\n const inferred = new Map(inferColumnsFromRows(sampleRows).map((c) => [c.field, c]));\n const typed = new Map(\n columnsFromSchema(contentType?.schema, { idField: idField ?? undefined }).map((c) => [\n c.field,\n c,\n ]),\n );\n\n const columns = fields.map((field, i): GridColumn => {\n const fromSchema = field in schemaProps ? typed.get(field) : undefined;\n const column = fromSchema ??\n inferred.get(field) ?? {\n editable: true,\n field,\n kind: \"string\" as const,\n title: doc.headers[i] || field,\n };\n return { ...column, pk: field === idField, title: doc.headers[i]?.trim() || column.title };\n });\n\n return { columns, doc, fields, keys, keyToIndex, loadText: text };\n}\n\n/** Typed cell values for one matrix row. */\nfunction rowCells(model: CsvModel, rowIndex: number): Record<string, GridCellValue> {\n const cells: Record<string, GridCellValue> = {};\n const row = model.doc.rows[rowIndex] ?? [];\n for (const [i, field] of model.fields.entries()) {\n const column = model.columns[i]!;\n const raw = row[i] ?? \"\";\n cells[field] =\n column.kind === \"string\" || column.kind === \"text\" || column.kind === \"readonly\"\n ? raw\n : coerceCellInput(raw, column);\n }\n return cells;\n}\n\n/** Apply a batch to a copy of the matrix (cells, then inserts, then deletes). */\nfunction applyBatch(model: CsvModel, batch: GridEditBatch): CsvDocument {\n const rows = model.doc.rows.map((row) => [...row]);\n const colFor = (field: string) => model.fields.indexOf(field);\n\n for (const cell of batch.cells) {\n const rowIndex = model.keyToIndex.get(cell.rowKey);\n const colIndex = colFor(cell.field);\n if (rowIndex === undefined || colIndex === -1) {\n continue;\n }\n rows[rowIndex]![colIndex] = cellToText(cell.value);\n }\n for (const insert of batch.inserts) {\n const row = model.fields.map((field) => cellToText(insert.cells[field] ?? null));\n rows.push(row);\n }\n const dropIndexes = batch.deletes\n .map((del) => model.keyToIndex.get(del.rowKey))\n .filter((i): i is number => i !== undefined)\n .toSorted((a, b) => b - a);\n for (const index of dropIndexes) {\n rows.splice(index, 1);\n }\n return { ...model.doc, rows };\n}\n\n/** All batch items resolved with one shared outcome (whole-file commits are atomic). */\nfunction uniformResult(\n batch: GridEditBatch,\n outcome: { ok: boolean; error?: string; stale?: boolean },\n): CommitResult {\n return {\n cells: batch.cells.map((c) => ({ field: c.field, rowKey: c.rowKey, ...outcome })),\n deletes: batch.deletes.map((d) => ({ rowKey: d.rowKey, ...outcome })),\n inserts: batch.inserts.map((i) => ({\n error: outcome.error,\n ok: outcome.ok,\n tempKey: i.tempKey,\n })),\n };\n}\n\n/** Create the grid source for one CSV file. The tab id is the file path. */\nexport function createCsvFileSource(path: string): GridSource {\n let loadPromise: Promise<CsvModel> | null = null;\n\n const load = (force = false): Promise<CsvModel> => {\n if (!force && loadPromise) {\n return loadPromise;\n }\n loadPromise = getPlatform()\n .readFile(path)\n .then((text) => buildModel(text, path));\n return loadPromise;\n };\n\n return {\n backingPaths: () => new Map([[path, \"*\"]]),\n capabilities: { delete: true, insert: true, remotePaging: false, remoteSort: false },\n\n async columns(): Promise<GridColumn[]> {\n const current = await load();\n return current.columns;\n },\n\n async commit(batch: GridEditBatch): Promise<CommitResult> {\n const current = await load();\n const platform = getPlatform();\n\n // Whole-file staleness: abort if the file changed under us (and it wasn't our own write).\n let onDisk: string | null = null;\n try {\n onDisk = await platform.readFile(path);\n } catch {\n onDisk = null; // Deleted underneath — treat as stale.\n }\n if (onDisk !== current.loadText && !isRecentLocal(path)) {\n return uniformResult(batch, {\n error: \"File changed on disk — refresh to reload\",\n ok: false,\n stale: true,\n });\n }\n\n const nextDoc = applyBatch(current, batch);\n const text = serializeCsv(nextDoc);\n markLocalMutation(path);\n await platform.writeFile(path, text);\n loadPromise = Promise.resolve(buildModel(text, path));\n return uniformResult(batch, { ok: true });\n },\n\n id: path,\n label: path.split(\"/\").pop() ?? path,\n\n async refresh(): Promise<void> {\n await load(true);\n },\n\n async rows(): Promise<GridRowsResult> {\n const current = await load();\n const rows: GridRow[] = current.doc.rows.map((_, i) => ({\n cells: rowCells(current, i),\n key: current.keys[i]!,\n }));\n return { rows, total: rows.length };\n },\n\n async serializeForSource(batch: GridEditBatch): Promise<string> {\n const current = await load();\n return serializeCsv(applyBatch(current, batch));\n },\n };\n}\n",
|
|
8
|
+
"/**\n * Connector-table grid source — SQL rows through the platform data surface.\n *\n * Columns come from backend introspection (DataColumnMeta); the primary key and the\n * created_at/updated_at system columns are read-only (matching the old modal grid's rules). Paging\n * and ordering are remote — rows(query) maps straight onto DataRowsQuery — so the grid shows a\n * pager instead of loading whole tables. Commit flushes the batch as per-row API calls: one\n * dataUpdateRow per edited row (fields merged), dataInsertRow per new row, dataDeleteRow per\n * deletion. The server is authoritative — there are no file fingerprints; conflicts surface as\n * per-row API errors.\n */\nimport { deleteRow, fetchRows, insertRow, updateRow } from \"../../services/data-service\";\nimport { makeGridTabId } from \"../grid-source\";\nimport type { DataColumnMeta, DataRowsQuery } from \"../../types\";\nimport type {\n CommitResult,\n GridCellValue,\n GridColumn,\n GridColumnKind,\n GridEditBatch,\n GridQuery,\n GridRow,\n GridRowsResult,\n GridSource,\n} from \"../grid-source\";\n\n/** Page size when the query does not specify one (matches the old modal grid). */\nexport const DATA_PAGE_SIZE = 50;\n\n/** SQL type → column kind (best-effort across sqlite/postgres type names). */\nexport function kindForSqlType(type: string): GridColumnKind {\n const t = type.toLowerCase();\n if (/(int|real|floa|doub|num|dec)/.test(t)) {\n return \"number\";\n }\n if (t.includes(\"bool\")) {\n return \"boolean\";\n }\n if (/(timestamp|datetime|date)/.test(t)) {\n return \"date\";\n }\n return \"string\";\n}\n\n/** System-managed columns are display-only (same rule as the old modal grid). */\nfunction editableColumn(column: DataColumnMeta): boolean {\n return !column.pk && column.name !== \"created_at\" && column.name !== \"updated_at\";\n}\n\n/** DB value → grid cell value (JSON-ish values surface as text). */\nfunction toCellValue(value: unknown): GridCellValue {\n if (value === null || value === undefined) {\n return null;\n }\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return value;\n }\n return JSON.stringify(value);\n}\n\n/** Create the grid source for one connector table. */\nexport function createConnectorSource(connection: string | undefined, table: string): GridSource {\n let columnsMeta: DataColumnMeta[] = [];\n let pkName = \"id\";\n /** Map of rowKey → the pk value as the backend returned it (numeric pks stay numeric). */\n const pkValues = new Map<string, string | number>();\n\n const applyMeta = (columns: DataColumnMeta[]) => {\n if (columns.length > 0) {\n columnsMeta = columns;\n pkName = columns.find((c) => c.pk)?.name ?? \"id\";\n }\n };\n\n const toQuery = (query?: GridQuery): DataRowsQuery => ({\n table,\n ...(connection ? { connection } : {}),\n limit: query?.limit ?? DATA_PAGE_SIZE,\n offset: query?.offset ?? 0,\n ...(query?.orderBy ? { dir: query.dir ?? \"asc\", orderBy: query.orderBy } : {}),\n });\n\n const rowKeyOf = (row: Record<string, unknown>, index: number): string => {\n const pk = row[pkName];\n if (typeof pk === \"string\" || typeof pk === \"number\") {\n pkValues.set(String(pk), pk);\n return String(pk);\n }\n return `row-${index}`;\n };\n\n return {\n capabilities: { delete: true, insert: true, remotePaging: true, remoteSort: true },\n\n async columns(): Promise<GridColumn[]> {\n if (columnsMeta.length === 0) {\n const result = await fetchRows(toQuery({ limit: 1, offset: 0 }));\n applyMeta(result.columns);\n }\n return columnsMeta.map((meta): GridColumn => {\n const kind = editableColumn(meta) ? kindForSqlType(meta.type) : \"readonly\";\n return {\n editable: kind !== \"readonly\",\n field: meta.name,\n kind,\n pk: meta.pk === true,\n title: meta.name,\n widthHint: meta.pk ? 80 : undefined,\n };\n });\n },\n\n async commit(batch: GridEditBatch): Promise<CommitResult> {\n const result: CommitResult = { cells: [], deletes: [], inserts: [] };\n\n // Cell edits merge into one dataUpdateRow per row.\n const byRow = new Map<string, { field: string; value: GridCellValue }[]>();\n for (const cell of batch.cells) {\n const list = byRow.get(cell.rowKey) ?? [];\n list.push({ field: cell.field, value: cell.value });\n byRow.set(cell.rowKey, list);\n }\n for (const [rowKey, patches] of byRow) {\n const pk = pkValues.get(rowKey);\n const outcome = (ok: boolean, error?: string) => {\n for (const patch of patches) {\n result.cells.push({ error, field: patch.field, ok, rowKey });\n }\n };\n if (pk === undefined) {\n outcome(false, \"Row has no primary key — refresh the grid\");\n continue;\n }\n try {\n const set: Record<string, unknown> = {};\n for (const patch of patches) {\n set[patch.field] = patch.value;\n }\n await updateRow({ pk, set, table, ...(connection ? { connection } : {}) });\n outcome(true);\n } catch (error) {\n outcome(false, error instanceof Error ? error.message : String(error));\n }\n }\n\n for (const insert of batch.inserts) {\n try {\n const values: Record<string, unknown> = {};\n for (const [field, value] of Object.entries(insert.cells)) {\n if (value !== null) {\n values[field] = value;\n }\n }\n const { row } = await insertRow({ table, values, ...(connection ? { connection } : {}) });\n const pk = row[pkName];\n const newKey = typeof pk === \"string\" || typeof pk === \"number\" ? String(pk) : undefined;\n if (newKey !== undefined && (typeof pk === \"string\" || typeof pk === \"number\")) {\n pkValues.set(newKey, pk);\n }\n result.inserts.push({ newKey, ok: true, tempKey: insert.tempKey });\n } catch (error) {\n result.inserts.push({\n error: error instanceof Error ? error.message : String(error),\n ok: false,\n tempKey: insert.tempKey,\n });\n }\n }\n\n for (const del of batch.deletes) {\n const pk = pkValues.get(del.rowKey);\n if (pk === undefined) {\n result.deletes.push({\n error: \"Row has no primary key — refresh the grid\",\n ok: false,\n rowKey: del.rowKey,\n });\n continue;\n }\n try {\n await deleteRow({ pk, table, ...(connection ? { connection } : {}) });\n result.deletes.push({ ok: true, rowKey: del.rowKey });\n } catch (error) {\n result.deletes.push({\n error: error instanceof Error ? error.message : String(error),\n ok: false,\n rowKey: del.rowKey,\n });\n }\n }\n\n return result;\n },\n\n id: makeGridTabId({ connection: connection ?? \"default\", kind: \"data\", table }),\n label: table,\n\n async refresh(): Promise<void> {\n columnsMeta = [];\n pkValues.clear();\n },\n\n async rows(query?: GridQuery): Promise<GridRowsResult> {\n const result = await fetchRows(toQuery(query));\n applyMeta(result.columns);\n const rows: GridRow[] = result.rows.map((row, index) => {\n const key = rowKeyOf(row, index);\n const cells: Record<string, GridCellValue> = {};\n for (const meta of columnsMeta) {\n cells[meta.name] = toCellValue(row[meta.name]);\n }\n return { cells, key };\n });\n return { rows, total: result.total };\n },\n };\n}\n",
|
|
9
|
+
"/**\n * The Library's data model — what a project contains, and how a scan can fail.\n *\n * Two facts the Manage view it replaces could not state:\n *\n * 1. **A scan has failures.** `collectFiles` swallowed every `listDirectory` rejection in an empty\n * catch block, so a project directory the platform could not read simply contributed nothing. A\n * 500 from the dev server and an empty `content/` produced the identical file list and the\n * identical sentence — \"No files found\" — which is the lie §16 exists to end.\n * {@link scanLibrary} returns {@link LibraryScan.failures} beside the files; the pane raises\n * them as Problems with a Retry and refuses to call an incomplete listing empty.\n * 2. **A category has a directory.** The Manage view filtered by category and uploaded to whatever\n * directory the active filter happened to name, which for \"All\" was nothing at all — the upload\n * landed wherever `uploadAssets` defaulted. {@link uploadDirForCategory} still answers, but the\n * pane never uploads to an unnamed destination: it asks.\n *\n * Everything here is pure over its inputs (the scan takes the platform as an argument) so the\n * 300-page acceptance case can be measured without a DOM.\n */\n\nimport { MEDIA_EXTENSIONS, extensionOf } from \"../files/media-upload\";\nimport { projectState } from \"../store\";\nimport { errorMessage } from \"@jxsuite/schema/parse\";\nimport { resolveI18n, servedLocaleOfPath } from \"@jxsuite/schema/locale\";\nimport type { ResolvedI18n } from \"@jxsuite/schema/locale\";\nimport type { ContentSectionEntry, DirEntry, StudioPlatform } from \"../types\";\n\n// ─── Files ───────────────────────────────────────────────────────────────────\n\n/** One row of the Library, whichever layout is drawing it. */\nexport interface LibraryFile {\n name: string;\n path: string;\n /** The content type name for a content file; the extension otherwise. */\n type: string;\n category: string;\n ext: string;\n /** Bytes, when the platform reported them. */\n size?: number | undefined;\n /** ISO timestamp, when the platform reported one. Drives the Calendar layout. */\n modified?: string | undefined;\n /**\n * The locale this file is **served as**, from `@jxsuite/schema/locale`'s `servedLocaleOfPath` —\n * the canonical tag, never the spelling on disk.\n *\n * The path answers it wherever there is a locale directory. Where there is not, `routing` does:\n * under `prefix-except-default` an unprefixed page IS the default locale's copy, and a facet that\n * could filter to French and Arabic but never to English cannot answer the question it is most\n * often asked. That reading stops at `pages/` — an unlocalized collection expands under every\n * locale's route, so calling its entries the default language would be a claim about content that\n * is in none.\n */\n locale?: string | undefined;\n}\n\n/** A directory the scan could not read. Its presence means the listing is INCOMPLETE, not empty. */\nexport interface ScanFailure {\n dir: string;\n error: string;\n}\n\n/** The result of one pass over the project's directories. */\nexport interface LibraryScan {\n files: LibraryFile[];\n failures: ScanFailure[];\n}\n\n// ─── Categories ──────────────────────────────────────────────────────────────\n\n/** A Library category: what it is called, and the directory an upload into it lands in. */\nexport interface LibraryCategory {\n key: string;\n label: string;\n /** Absent for \"All\" — which is why \"All\" has no upload destination and must ask for one. */\n dir?: string;\n}\n\nexport const LIBRARY_CATEGORIES: readonly LibraryCategory[] = [\n { key: \"all\", label: \"All\" },\n { dir: \"pages\", key: \"pages\", label: \"Pages\" },\n { dir: \"layouts\", key: \"layouts\", label: \"Layouts\" },\n { dir: \"components\", key: \"components\", label: \"Components\" },\n { dir: \"content\", key: \"content\", label: \"Content\" },\n { dir: \"public\", key: \"media\", label: \"Media\" },\n];\n\n/** The category keys, for a command's `enum` — so `library.setCategory` refuses an unknown one. */\nexport const LIBRARY_CATEGORY_KEYS: readonly string[] = LIBRARY_CATEGORIES.map((c) => c.key);\n\n/** The category with this key, or undefined. */\nexport function libraryCategory(key: string): LibraryCategory | undefined {\n return LIBRARY_CATEGORIES.find((c) => c.key === key);\n}\n\n/**\n * The directory a drop on the Library targets while `key` is the active category.\n *\n * `undefined` for \"All\" and for any category without one, and the caller MUST treat that as \"ask\",\n * never as \"use the default\": an upload that lands somewhere the author did not choose is the same\n * class of surprise as a rename that silently rewrites files.\n */\nexport function uploadDirForCategory(key: string): string | undefined {\n return libraryCategory(key)?.dir;\n}\n\n/** Map a file path to a display category. Media files override by extension. */\nexport function categoryFor(dir: string, ext: string): string {\n if (ext && MEDIA_EXTENSIONS.has(ext)) {\n return \"Media\";\n }\n if (dir.startsWith(\"pages\")) {\n return \"Pages\";\n }\n if (dir.startsWith(\"layouts\")) {\n return \"Layouts\";\n }\n if (dir.startsWith(\"components\")) {\n return \"Components\";\n }\n if (dir.startsWith(\"content\")) {\n return \"Content\";\n }\n if (dir.startsWith(\"public\")) {\n return \"Media\";\n }\n if (dir.startsWith(\"data\")) {\n return \"Content\";\n }\n if (dir.startsWith(\"styles\")) {\n return \"Components\";\n }\n return \"Other\";\n}\n\n/**\n * The content type a path belongs to, from the project's `content` section — capitalized, or null.\n *\n * @param {string} filePath\n * @returns {string | null}\n */\nexport function contentTypeFor(filePath: string): string | null {\n const content = (projectState?.projectConfig?.content ?? {}) as Record<\n string,\n ContentSectionEntry\n >;\n for (const [name, entry] of Object.entries(content)) {\n if (!entry.source) {\n continue;\n }\n const prefix = entry.source.replace(/^\\.\\//, \"\").replace(/\\/$/, \"\");\n if (filePath.startsWith(`${prefix}/`) || filePath === prefix) {\n return name.charAt(0).toUpperCase() + name.slice(1);\n }\n }\n return null;\n}\n\n// ─── The scan ────────────────────────────────────────────────────────────────\n\n/** Directory names never worth walking — a `node_modules` scan is minutes, not milliseconds. */\nconst SKIP_DIRS = new Set([\"node_modules\", \".git\", \".jx\", \"dist\", \"build\", \".cache\"]);\n\n/**\n * Walk one directory tree, collecting files and recording — never swallowing — what it could not\n * read. A failure at depth is reported against the directory that failed, not the root, so the\n * Problem names the path the author can act on.\n */\nasync function walk(\n dir: string,\n platform: Pick<StudioPlatform, \"listDirectory\">,\n out: LibraryFile[],\n failures: ScanFailure[],\n i18n: ResolvedI18n | null,\n): Promise<void> {\n let entries: DirEntry[];\n try {\n entries = await platform.listDirectory(dir);\n } catch (error) {\n failures.push({ dir, error: errorMessage(error) });\n return;\n }\n const subdirectories: string[] = [];\n for (const entry of entries) {\n if (entry.type === \"directory\") {\n if (!SKIP_DIRS.has(entry.name)) {\n subdirectories.push(entry.path);\n }\n continue;\n }\n const ext = extensionOf(entry.name);\n const category = categoryFor(entry.path, ext);\n out.push({\n category,\n ext,\n locale: servedLocaleOfPath(entry.path, i18n) ?? undefined,\n modified: entry.modified,\n name: entry.name,\n path: entry.path,\n size: entry.size,\n type: category === \"Content\" ? (contentTypeFor(entry.path) ?? ext ?? \"file\") : ext || \"file\",\n });\n }\n // Siblings in parallel, depth serialized per branch: the platform counts every call as in-flight,\n // So `probe.idle()` already knows the scan is running without the Library declaring a source.\n await Promise.all(subdirectories.map((sub) => walk(sub, platform, out, failures, i18n)));\n}\n\n/**\n * Scan the project's declared directories.\n *\n * Never rejects: a scan that half-worked is a real, useful answer that the caller must be able to\n * render honestly, and an exception would throw the good half away with the bad.\n */\nexport async function scanLibrary(\n dirs: readonly string[],\n platform: Pick<StudioPlatform, \"listDirectory\">,\n): Promise<LibraryScan> {\n const files: LibraryFile[] = [];\n const failures: ScanFailure[] = [];\n // Resolved ONCE for the whole walk. `resolveI18n` canonicalizes every declared tag through\n // `Intl.Locale`, and a project with 300 pages would otherwise pay for that per file.\n const { i18n } = resolveI18n(projectState?.projectConfig ?? {});\n await Promise.all(dirs.map((dir) => walk(dir, platform, files, failures, i18n)));\n files.sort((a, b) => a.path.localeCompare(b.path));\n return { failures, files };\n}\n\n// ─── Filtering ───────────────────────────────────────────────────────────────\n\nexport interface LibraryFilter {\n category: string;\n query: string;\n /** A canonical tag, or \"\" for every language. Never a label — the labels are not unique. */\n locale?: string;\n}\n\n/**\n * Category, then text over name and path, then language. Returns the input array unchanged when\n * nothing filters.\n */\nexport function filterLibrary(\n files: readonly LibraryFile[],\n filter: LibraryFilter,\n): readonly LibraryFile[] {\n let result = files;\n const category = libraryCategory(filter.category);\n if (category && category.key !== \"all\") {\n result = result.filter((f) => f.category === category.label);\n }\n const query = filter.query.trim().toLowerCase();\n if (query) {\n result = result.filter(\n (f) => f.name.toLowerCase().includes(query) || f.path.toLowerCase().includes(query),\n );\n }\n const locale = filter.locale?.trim();\n if (locale) {\n result = result.filter((f) => f.locale === locale);\n }\n return result;\n}\n\n// ─── Layouts ─────────────────────────────────────────────────────────────────\n\nexport const LIBRARY_LAYOUTS = [\"table\", \"cards\", \"media\", \"calendar\", \"board\"] as const;\n\nexport type LibraryLayout = (typeof LIBRARY_LAYOUTS)[number];\n\nexport const LIBRARY_LAYOUT_LABELS: Readonly<Record<LibraryLayout, string>> = {\n board: \"Board\",\n calendar: \"Calendar\",\n cards: \"Cards\",\n media: \"Media\",\n table: \"Table\",\n};\n\n/** Whether a string names a layout — the guard behind `library.setLayout`'s argument. */\nexport function isLibraryLayout(value: string): value is LibraryLayout {\n return (LIBRARY_LAYOUTS as readonly string[]).includes(value);\n}\n\n/** Layouts that draw a live preview per item. Table and Board draw text, and stay cheap. */\nexport const PREVIEW_LAYOUTS: ReadonlySet<LibraryLayout> = new Set<LibraryLayout>([\n \"cards\",\n \"media\",\n]);\n\n// ─── Derived axes (Calendar and Board) ───────────────────────────────────────\n\n/** `YYYY-MM-DD` at the head of a filename — the dated-post convention, used when there is no mtime. */\nconst DATE_PREFIX = /^(\\d{4}-\\d{2}-\\d{2})/;\n\n/**\n * The day a file belongs to, as `YYYY-MM-DD`, or null when nothing states one.\n *\n * The filename prefix wins over the filesystem's mtime: a dated post's date is authored content,\n * and mtime is a fact about the last save. A file with neither is not placed on the calendar at all\n * rather than being parked on today — the Calendar says how many it could not date.\n */\nexport function libraryDate(file: LibraryFile): string | null {\n const prefix = DATE_PREFIX.exec(file.name);\n if (prefix) {\n return prefix[1]!;\n }\n if (file.modified) {\n const parsed = new Date(file.modified);\n if (!Number.isNaN(parsed.getTime())) {\n return parsed.toISOString().slice(0, 10);\n }\n }\n return null;\n}\n\n/**\n * The locales this project DECLARES, canonical and in declaration order — the value space of the\n * Library's language facet and of `library.setLocale`'s `enum`.\n *\n * Read at call time rather than cached: `projectState` is a plain binding replaced wholesale on a\n * project switch, so a cached list would describe the project before last.\n */\nexport function projectLocales(): readonly string[] {\n return resolveI18n(projectState?.projectConfig ?? {}).i18n?.locales ?? [];\n}\n\n/**\n * The locales actually PRESENT among these files, in the project's declaration order.\n *\n * Ordered by the project and not by the scan for the reason {@link groupByCategory} orders its\n * columns by {@link LIBRARY_CATEGORIES}: a facet whose options reshuffle when a file is added is a\n * facet nobody can build muscle memory for. Declaration order also puts the default locale first,\n * because {@link resolveI18n} guarantees it is `locales[0]`.\n *\n * Only declared tags can appear — `localeOfPath` matches nothing else — so filtering the\n * declaration through the presence set loses no file.\n */\nexport function libraryLocales(files: readonly LibraryFile[]): string[] {\n const present = new Set<string>();\n for (const file of files) {\n if (file.locale) {\n present.add(file.locale);\n }\n }\n return projectLocales().filter((tag) => present.has(tag));\n}\n\n/** Calendar buckets, newest day first, plus the files no date could be derived for. */\nexport function groupByDate(files: readonly LibraryFile[]): {\n days: { date: string; files: LibraryFile[] }[];\n undated: LibraryFile[];\n} {\n const byDay = new Map<string, LibraryFile[]>();\n const undated: LibraryFile[] = [];\n for (const file of files) {\n const date = libraryDate(file);\n if (date === null) {\n undated.push(file);\n continue;\n }\n const bucket = byDay.get(date);\n if (bucket) {\n bucket.push(file);\n } else {\n byDay.set(date, [file]);\n }\n }\n const days = [...byDay.entries()]\n .map(([date, dayFiles]) => ({ date, files: dayFiles }))\n .toSorted((a, b) => b.date.localeCompare(a.date));\n return { days, undated };\n}\n\n/** Board columns — one per category present, in the Library's own category order, then the rest. */\nexport function groupByCategory(\n files: readonly LibraryFile[],\n): { group: string; files: LibraryFile[] }[] {\n const byGroup = new Map<string, LibraryFile[]>();\n for (const file of files) {\n const bucket = byGroup.get(file.category);\n if (bucket) {\n bucket.push(file);\n } else {\n byGroup.set(file.category, [file]);\n }\n }\n const order = LIBRARY_CATEGORIES.map((c) => c.label);\n return [...byGroup.entries()]\n .map(([group, groupFiles]) => ({ files: groupFiles, group }))\n .toSorted((a, b) => {\n const ai = order.indexOf(a.group);\n const bi = order.indexOf(b.group);\n if (ai === bi) {\n return a.group.localeCompare(b.group);\n }\n return (ai === -1 ? order.length : ai) - (bi === -1 ? order.length : bi);\n });\n}\n",
|
|
10
|
+
"/**\n * The Library as a {@link GridSource}.\n *\n * The Library is one more source over the same contract the CSV, collection, pages and connector\n * grids already use, which is what makes Table a real grid rather than a fifth hand-written table:\n * columns come from {@link libraryColumns}, rows are the scan, and every layout — Cards, Media,\n * Calendar, Board — draws the SAME rows through a different arrangement. A layout switch never\n * re-reads the project.\n *\n * It is a **read-only** source, and says so rather than pretending. Renaming, duplicating and\n * deleting a file are real operations with real consequences (a rename rewrites references; a\n * delete needs the reference count in its confirmation), and they belong to the commands that\n * already do that work correctly. A grid cell that silently renamed a file on blur would bypass\n * both. {@link LibrarySource.commit} therefore refuses, naming the surface that can.\n */\n\nimport { getPlatform } from \"../platform\";\nimport { projectState } from \"../store\";\nimport { makeGridTabId } from \"../grid/grid-source\";\nimport { scanLibrary } from \"./library-model\";\nimport type { LibraryFile, LibraryScan, ScanFailure } from \"./library-model\";\nimport type {\n CommitResult,\n GridColumn,\n GridEditBatch,\n GridRow,\n GridRowsResult,\n GridSource,\n} from \"../grid/grid-source\";\n\n/** Why a cell edit is refused — printed by the grid, so the author is told where to go instead. */\nexport const LIBRARY_READ_ONLY =\n \"The Library lists files; it does not edit them. Rename, duplicate or delete from the file's \" +\n \"context menu, or open the file to edit it.\";\n\n/** The Table layout's columns. `path` is the row key and is never editable. */\nexport function libraryColumns(): GridColumn[] {\n return [\n { editable: false, field: \"name\", kind: \"string\", pk: true, title: \"Name\", widthHint: 260 },\n { editable: false, field: \"category\", kind: \"string\", title: \"Category\", widthHint: 120 },\n { editable: false, field: \"locale\", kind: \"string\", title: \"Locale\", widthHint: 90 },\n { editable: false, field: \"type\", kind: \"string\", title: \"Type\", widthHint: 120 },\n { editable: false, field: \"size\", kind: \"number\", title: \"Size\", widthHint: 90 },\n { editable: false, field: \"modified\", kind: \"date\", title: \"Modified\", widthHint: 160 },\n { editable: false, field: \"path\", kind: \"readonly\", title: \"Path\", widthHint: 320 },\n ];\n}\n\n/** One scanned file as a grid row. */\nexport function libraryRow(file: LibraryFile): GridRow {\n return {\n cells: {\n category: file.category,\n // Null, not \"\": the platform reported no locale directory for this file, and a grid cell\n // Distinguishes \"no value\" from \"the empty string\" everywhere else in this contract.\n locale: file.locale ?? null,\n modified: file.modified ?? null,\n name: file.name,\n path: file.path,\n size: file.size ?? null,\n type: file.type,\n },\n key: file.path,\n };\n}\n\n/**\n * A Library source, plus the two questions a grid source cannot ask but the Library must answer:\n * what the scan could not read, and the files behind the rows (the non-table layouts want the typed\n * record, not a cell bag).\n */\nexport interface LibrarySource extends GridSource {\n /** The scanned files, in path order. Empty before the first {@link GridSource.rows} call. */\n files: () => readonly LibraryFile[];\n /** Directories the last scan could not read. NON-EMPTY MEANS THE LISTING IS INCOMPLETE. */\n failures: () => readonly ScanFailure[];\n /** Whether a scan has completed at least once — \"not loaded yet\" is not \"empty\". */\n scanned: () => boolean;\n}\n\n/** The Library's tab id. One Library per window; category and layout are view state, not identity. */\nexport function libraryTabId(): string {\n return makeGridTabId({ kind: \"library\" });\n}\n\n/**\n * Build the Library source. The scan is lazy: nothing is read until the first `rows()`.\n *\n * @param {() => readonly string[]} [dirs] Project directories to scan, injectable for tests and for\n * the perf measurement; defaults to the open project's own list.\n */\nexport function createLibrarySource(dirs?: () => readonly string[]): LibrarySource {\n let scan: LibraryScan | null = null;\n let inFlight: Promise<LibraryScan> | null = null;\n\n const projectDirs = dirs ?? (() => (projectState?.projectDirs ?? []) as readonly string[]);\n\n async function ensureScan(): Promise<LibraryScan> {\n if (scan) {\n return scan;\n }\n // Coalesce: five layouts and a command can all ask at once on the first paint, and the answer\n // Is one walk of the project, not six.\n inFlight ??= scanLibrary(projectDirs(), getPlatform()).then((result) => {\n scan = result;\n inFlight = null;\n return result;\n });\n return inFlight;\n }\n\n return {\n capabilities: { delete: false, insert: false, remotePaging: false, remoteSort: false },\n columns: () => Promise.resolve(libraryColumns()),\n commit(batch: GridEditBatch): Promise<CommitResult> {\n return Promise.resolve({\n cells: batch.cells.map((cell) => ({\n error: LIBRARY_READ_ONLY,\n field: cell.field,\n ok: false,\n rowKey: cell.rowKey,\n })),\n deletes: batch.deletes.map((row) => ({\n error: LIBRARY_READ_ONLY,\n ok: false,\n rowKey: row.rowKey,\n })),\n inserts: batch.inserts.map((row) => ({\n error: LIBRARY_READ_ONLY,\n ok: false,\n tempKey: row.tempKey,\n })),\n });\n },\n failures: () => scan?.failures ?? [],\n files: () => scan?.files ?? [],\n id: libraryTabId(),\n label: \"Library\",\n async refresh() {\n scan = null;\n inFlight = null;\n await ensureScan();\n },\n async rows(): Promise<GridRowsResult> {\n const result = await ensureScan();\n return { rows: result.files.map((file) => libraryRow(file)), total: result.files.length };\n },\n scanned: () => scan !== null,\n };\n}\n",
|
|
11
|
+
"/**\n * Grid tab openers — create (or activate) the tab + controller pair for a grid surface.\n *\n * CSV files open as REAL file tabs (id = path) whose default canvas mode is \"grid\" with a Monaco\n * \"source\" alternate; collection/pages/connector grids (later phases) open as virtual tabs with\n * `grid://` ids. All openers dedupe by tab id.\n */\nimport { html } from \"lit-html\";\nimport { activateTab, openTab, workspace } from \"../workspace/workspace\";\nimport { formatForPath, loadFormats } from \"../format/format-host\";\nimport { openModal } from \"../ui/layers\";\nimport { dataSurfaceAvailable, fetchConnections } from \"../services/data-service\";\nimport { createGridController } from \"./grid-controller\";\nimport { createCsvFileSource } from \"./sources/csv-file-source\";\nimport {\n collectionDirs,\n createCollectionSource,\n createPagesSource,\n} from \"./sources/content-source\";\nimport { createConnectorSource } from \"./sources/connector-source\";\nimport { makeGridTabId } from \"./grid-source\";\nimport { libraryTabId } from \"../browse/library-source\";\nimport { argsSchema, optionalStringArg, stringArg, stringProperty } from \"../commands/command-args\";\nimport type { GridSource } from \"./grid-source\";\nimport type { Tab } from \"../tabs/tab\";\nimport type { AnyCommand, CommandRegistry } from \"../commands/registry\";\n\n/** Placeholder document for grid tabs — the grid never reads it; save routes to the controller. */\nconst GRID_STUB_DOCUMENT = { children: [], tagName: \"div\" };\n\n/** Open (or activate) a `.csv` file as a grid tab. */\nexport async function openCsvGridTab(path: string): Promise<Tab> {\n const existing = workspace.tabs.get(path);\n if (existing) {\n activateTab(path);\n return existing;\n }\n\n // Best effort: the format name labels the tab's source mode; the grid works without it.\n try {\n await loadFormats();\n } catch {\n // Format registry unavailable (e.g. no dev server) — grid mode still works.\n }\n\n const source = createCsvFileSource(path);\n const tab = openTab({\n capabilities: { modes: [\"grid\", \"source\"] },\n document: structuredClone(GRID_STUB_DOCUMENT),\n documentPath: path,\n id: path,\n sourceFormat: formatForPath(path)?.name ?? null,\n });\n const controller = createGridController(tab, source);\n void controller.load();\n return tab;\n}\n\n/**\n * Open a virtual grid tab for a source (collections now; more kinds later). Callers dedupe by the\n * same `makeGridTabId` id before constructing the source.\n */\nfunction openVirtualGridTab(source: GridSource): Tab {\n const tab = openTab({\n capabilities: { modes: [\"grid\"] },\n document: structuredClone(GRID_STUB_DOCUMENT),\n documentPath: null,\n id: source.id,\n });\n const controller = createGridController(tab, source);\n void controller.load();\n return tab;\n}\n\n/** Open (or activate) the grid tab for a content collection. */\nexport function openCollectionGrid(typeName: string): Tab {\n const id = makeGridTabId({ kind: \"collection\", name: typeName });\n const existing = workspace.tabs.get(id);\n if (existing) {\n activateTab(id);\n return existing;\n }\n return openVirtualGridTab(createCollectionSource(typeName));\n}\n\n/**\n * Open (or activate) the Library.\n *\n * A real tab, in the primary pane, with `manage` as its only mode — `commands/context.ts` maps that\n * to the `library` editor kind, so the status bar and the pane context bar can name what is on\n * screen. It is opened here rather than in `browse/` because this is the module that knows how a\n * virtual tab is made; the pane itself resolves its own source and its own view state.\n *\n * Idempotent by construction, which is what lets a shot say \"the Library is open\" without caring\n * whether an earlier step opened it.\n */\nexport function openLibraryTab(): Tab {\n const id = libraryTabId();\n const existing = workspace.tabs.get(id);\n if (existing) {\n activateTab(id);\n return existing;\n }\n return openTab({\n capabilities: { modes: [\"manage\"] },\n document: structuredClone(GRID_STUB_DOCUMENT),\n documentPath: null,\n id,\n });\n}\n\n/** Open (or activate) the pages metadata grid. */\nexport function openPagesGrid(): Tab {\n const id = makeGridTabId({ kind: \"pages\" });\n const existing = workspace.tabs.get(id);\n if (existing) {\n activateTab(id);\n return existing;\n }\n return openVirtualGridTab(createPagesSource());\n}\n\n/** Open (or activate) the grid tab for a connector table. */\nexport function openConnectorGrid(connection: string | undefined, table: string): Tab {\n const id = makeGridTabId({ connection: connection ?? \"default\", kind: \"data\", table });\n const existing = workspace.tabs.get(id);\n if (existing) {\n activateTab(id);\n return existing;\n }\n return openVirtualGridTab(createConnectorSource(connection, table));\n}\n\n/**\n * Source picker — one dialog listing every grid-able source: pages, content collections, and (when\n * the platform serves the data surface) each connection's tables.\n */\nexport async function openGridSourcePicker(): Promise<void> {\n const collections = collectionDirs();\n let connections: { name: string; tables: string[] }[] = [];\n if (dataSurfaceAvailable()) {\n const response = await fetchConnections().catch(() => null);\n connections = response?.connections ?? [];\n }\n\n const handle = openModal(\n html`<sp-dialog-wrapper\n open\n dismissable\n underlay\n headline=\"Open Grid\"\n @close=${() => handle.close()}\n >\n <sp-menu class=\"jx-grid-picker\">\n <sp-menu-group>\n <span slot=\"header\">Project</span>\n <sp-menu-item\n @click=${() => {\n handle.close();\n openPagesGrid();\n }}\n >Pages</sp-menu-item\n >\n ${collections.map(\n ({ name }) =>\n html`<sp-menu-item\n @click=${() => {\n handle.close();\n openCollectionGrid(name);\n }}\n >Collection: ${name}</sp-menu-item\n >`,\n )}\n </sp-menu-group>\n ${connections.map(\n (conn) =>\n html`<sp-menu-group>\n <span slot=\"header\">Data · ${conn.name}</span>\n ${\n conn.tables.length === 0\n ? html`<sp-menu-item disabled>No tables — push a schema first</sp-menu-item>`\n : conn.tables.map(\n (table) =>\n html`<sp-menu-item\n @click=${() => {\n handle.close();\n openConnectorGrid(conn.name, table);\n }}\n >${table}</sp-menu-item\n >`,\n )\n }\n </sp-menu-group>`,\n )}\n </sp-menu>\n </sp-dialog-wrapper>`,\n { label: \"Open Grid\" },\n );\n}\n\n// ─── Commands ─────────────────────────────────────────────────────────────────\n\n/**\n * The grid openers, as commands.\n *\n * `collection.editInGrid` used to be a press on the file tree's context-menu row, matched by the\n * item's rendered label (\"Edit Collection in Grid\") through an XPath — so the shot that used it\n * also had to open the menu first, and renaming the row broke both steps. Naming the COLLECTION\n * instead of the control is what plan §13's R1 asks for: the menu row and the command are the same\n * action, and only one of them is addressable.\n *\n * Both refuse a source the project does not declare. `data.openGrid` is additionally gated on the\n * platform serving the data routes (`capability.dataRows`), so on a build without them the command\n * is visible-but-disabled with a reason rather than opening a tab that can never load.\n *\n * @returns {AnyCommand[]}\n */\nexport function gridCommands(): AnyCommand[] {\n return [\n {\n args: argsSchema({\n name: stringProperty(\"The content collection's name, as project.json declares it.\"),\n }),\n category: \"Project\",\n id: \"collection.editInGrid\",\n level: \"project\",\n menus: [\"context/file\", \"palette\"],\n group: \"5_data\",\n requires: \"a project that declares content collections\",\n when: (ctx) => ctx.project.open,\n aiTool: {\n description: \"Open a content collection's entries as an editable grid in a new tab.\",\n name: \"open_collection_grid\",\n },\n run: (_commandCtx, args) => {\n const name = stringArg(\"collection.editInGrid\", args, \"name\");\n const declared = collectionDirs().map((c) => c.name);\n if (!declared.includes(name)) {\n throw new RangeError(\n `command \"collection.editInGrid\" argument \"name\": \"${name}\" is not a content ` +\n `collection this project declares — it declares: ` +\n `${declared.length > 0 ? declared.join(\", \") : \"none\"}`,\n );\n }\n openCollectionGrid(name);\n },\n title: \"Edit Collection in Grid\",\n },\n {\n args: {\n additionalProperties: false,\n properties: {\n connection: stringProperty(\n 'The connection name from project.json. Defaults to \"default\".',\n ),\n table: stringProperty(\"The table to open.\"),\n },\n required: [\"table\"],\n type: \"object\",\n },\n category: \"Project\",\n id: \"data.openGrid\",\n level: \"project\",\n menus: [\"palette\"],\n group: \"5_data\",\n requires: \"a platform that serves the data routes\",\n when: (ctx) => ctx.project.open,\n enablement: (ctx) => ctx.capability.dataRows,\n aiTool: {\n description: \"Open a connector table as an editable grid in a new tab.\",\n name: \"open_data_grid\",\n },\n run: (_commandCtx, args) => {\n const table = stringArg(\"data.openGrid\", args, \"table\");\n openConnectorGrid(optionalStringArg(\"data.openGrid\", args, \"connection\"), table);\n },\n title: \"Open Data Grid\",\n },\n ];\n}\n\n/**\n * Register the grid openers.\n *\n * @param {CommandRegistry} registry\n */\nexport function registerGridCommands(registry: CommandRegistry): void {\n registry.registerAll(gridCommands());\n}\n"
|
|
12
|
+
],
|
|
13
|
+
"mappings": "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",
|
|
14
|
+
"debugId": "B5A73986FCDCB07464756E2164756E21",
|
|
15
|
+
"names": []
|
|
16
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getPlatform,
|
|
3
3
|
hasPlatform
|
|
4
|
-
} from "./studio-
|
|
4
|
+
} from "./studio-sas7mt3k.js";
|
|
5
5
|
|
|
6
6
|
// src/services/settings-store.ts
|
|
7
7
|
var PERSISTED_SETTINGS_KEYS = [
|
|
@@ -107,4 +107,4 @@ function setCfAccountId(accountId) {
|
|
|
107
107
|
export { hydrateSettings, persistSettings, getCfToken, setCfToken, getCfAccountId, setCfAccountId };
|
|
108
108
|
|
|
109
109
|
//# debugId=521A72F1905394A564756E2164756E21
|
|
110
|
-
//# sourceMappingURL=studio-
|
|
110
|
+
//# sourceMappingURL=studio-a7pzveq1.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getPlatform
|
|
3
|
-
} from "./studio-
|
|
3
|
+
} from "./studio-sas7mt3k.js";
|
|
4
4
|
import {
|
|
5
5
|
__require
|
|
6
6
|
} from "./studio-md4gps17.js";
|
|
@@ -23,7 +23,7 @@ async function applyPendingSchemas() {
|
|
|
23
23
|
}
|
|
24
24
|
_pendingSchemasDirty = false;
|
|
25
25
|
try {
|
|
26
|
-
const { applyProjectSchemas } = await import("./monaco-setup-
|
|
26
|
+
const { applyProjectSchemas } = await import("./monaco-setup-e0yh25j4.js");
|
|
27
27
|
applyProjectSchemas(_pendingSchemas);
|
|
28
28
|
} catch {}
|
|
29
29
|
}
|
|
@@ -34,7 +34,7 @@ function loadMonaco() {
|
|
|
34
34
|
_loading ??= (async () => {
|
|
35
35
|
const [monaco] = await Promise.all([
|
|
36
36
|
import("./editor.api-bgqm8zdh.js"),
|
|
37
|
-
import("./monaco-setup-
|
|
37
|
+
import("./monaco-setup-e0yh25j4.js")
|
|
38
38
|
]);
|
|
39
39
|
_monaco = monaco;
|
|
40
40
|
await applyPendingSchemas();
|
|
@@ -45,6 +45,12 @@ function loadMonaco() {
|
|
|
45
45
|
function loadedMonaco() {
|
|
46
46
|
return _monaco;
|
|
47
47
|
}
|
|
48
|
+
function mountStillWanted(container, existing, stillTargeted) {
|
|
49
|
+
if (!container?.isConnected || existing) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
return stillTargeted();
|
|
53
|
+
}
|
|
48
54
|
|
|
49
55
|
// src/format/format-host.ts
|
|
50
56
|
var _formats = [];
|
|
@@ -102,11 +108,11 @@ async function shareProjectSchemas(platform) {
|
|
|
102
108
|
schemas = await platform.fetchProjectSchemas?.() ?? null;
|
|
103
109
|
} catch {}
|
|
104
110
|
setProjectSchemasForMonaco(schemas);
|
|
105
|
-
await import("./jx-validate-
|
|
111
|
+
await import("./jx-validate-v6qgknrs.js").then(({ applyProjectSchemas }) => applyProjectSchemas(schemas)).catch(() => false);
|
|
106
112
|
}
|
|
107
113
|
function refreshExtensionUi(platform) {
|
|
108
114
|
shareProjectSchemas(platform);
|
|
109
|
-
import("./extension-sections-
|
|
115
|
+
import("./extension-sections-6mqydz35.js").then(({ syncExtensionSettingsSections }) => syncExtensionSettingsSections()).catch(() => {});
|
|
110
116
|
}
|
|
111
117
|
function getFormats() {
|
|
112
118
|
return _formats;
|
|
@@ -218,7 +224,7 @@ function splitFormatDocument(format, doc) {
|
|
|
218
224
|
};
|
|
219
225
|
}
|
|
220
226
|
|
|
221
|
-
export { loadMonaco, loadedMonaco, loadFormats, refreshFormats, setFormats, loadExtensions, getExtensions, setExtensions, refreshExtensionUi, getFormats, formatByExtension, formatByName, noFormatError, formatForPath, documentExtensions, defaultContentFormat, formatParse, formatSerialize, splitFormatDocument };
|
|
227
|
+
export { loadMonaco, loadedMonaco, mountStillWanted, loadFormats, refreshFormats, setFormats, loadExtensions, getExtensions, setExtensions, refreshExtensionUi, getFormats, formatByExtension, formatByName, noFormatError, formatForPath, documentExtensions, defaultContentFormat, formatParse, formatSerialize, splitFormatDocument };
|
|
222
228
|
|
|
223
|
-
//# debugId=
|
|
224
|
-
//# sourceMappingURL=studio-
|
|
229
|
+
//# debugId=64F2ED66D12C3F6C64756E2164756E21
|
|
230
|
+
//# sourceMappingURL=studio-adn0z1k3.js.map
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/services/monaco-lazy.ts", "../src/format/format-host.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * Lazy Monaco.\n *\n * Monaco is 12.6 MB of the studio bundle — two thirds of it — and most sessions never open a code\n * view. It used to be pulled in by a static `import * as monaco` in three modules plus a\n * side-effect `import \"./services/monaco-setup.js\"` from `studio.ts`, so every cold start\n * downloaded, parsed and evaluated the editor, its TypeScript/JSON/JavaScript language\n * contributions, and a `flattenSchema` pass over a 497 KB schema before first paint.\n *\n * Loading is deferred to the first code surface that actually needs it: source mode, the function\n * editor, the formula workspace. `loadMonaco()` is memoized, so concurrent callers share one import\n * and the language contributions register exactly once.\n *\n * Two accessors, deliberately:\n *\n * - {@link loadMonaco} for code that MOUNTS an editor. Those call sites are lit `ref()` DOM-attach\n * callbacks or already-async paths, so awaiting is free.\n * - {@link loadedMonaco} for code that can only run once an editor exists (setting markers on a\n * model, comparing a live editor's model URI). Returning the already-resolved namespace\n * synchronously keeps those paths sync — no async ripple through the render tree for a module\n * that is provably present.\n */\n\nimport type * as monacoNs from \"monaco-editor\";\n\nexport type Monaco = typeof monacoNs;\n\nlet _monaco: Monaco | null = null;\nlet _loading: Promise<Monaco> | null = null;\n\n/**\n * The active project's generated entry schemas, held until Monaco exists to receive them.\n *\n * These arrive at project activation — long before anyone opens a code view — and applying them\n * used to mean `import(\"./monaco-setup\")` right then. A dynamic import that EXECUTES at startup\n * defers evaluation by a tick but still fetches: Monaco went over the wire on every cold load,\n * which is precisely what the lazy path exists to avoid. So the schemas wait here instead, and the\n * loader applies whatever is pending once an editor actually needs one.\n */\nlet _pendingSchemas: { project?: unknown; document?: unknown } | null = null;\nlet _pendingSchemasDirty = false;\n\n/**\n * Record the active project's schemas for Monaco's JSON diagnostics.\n *\n * Applied immediately when Monaco is already loaded, otherwise on the next {@link loadMonaco}. Only\n * the LATEST set matters — reactivation and `project.json` writes both call this — so it overwrites\n * rather than queues.\n */\nexport function setProjectSchemasForMonaco(\n schemas: { project?: unknown; document?: unknown } | null,\n): void {\n _pendingSchemas = schemas;\n _pendingSchemasDirty = true;\n if (_monaco) {\n void applyPendingSchemas();\n }\n}\n\n/** Push any pending schemas into Monaco's JSON diagnostics. No-op when nothing changed. */\nasync function applyPendingSchemas(): Promise<void> {\n if (!_pendingSchemasDirty) {\n return;\n }\n _pendingSchemasDirty = false;\n try {\n const { applyProjectSchemas } = await import(\"./monaco-setup.js\");\n applyProjectSchemas(_pendingSchemas);\n } catch {\n // Editor degradation: the bundled core schemas stay in force.\n }\n}\n\n/**\n * Load Monaco and its Jx configuration (workers, JSON schemas, TS/JS contributions). Memoized.\n *\n * The `monaco-setup` import is what registers the language contributions and the worker factory, so\n * it must resolve before an editor is created — hence both imports awaited here rather than left to\n * whichever module happens to be evaluated first.\n */\nexport function loadMonaco(): Promise<Monaco> {\n if (_monaco) {\n return Promise.resolve(_monaco);\n }\n // Not `async`: an async function wraps the memo in a fresh promise per call, so concurrent callers\n // Could not observe that they share one in-flight load. Returning `_loading` itself makes the\n // Load-once guarantee visible (and testable) rather than merely true.\n _loading ??= (async () => {\n const [monaco] = await Promise.all([\n import(\"monaco-editor/esm/vs/editor/editor.api.js\"),\n import(\"./monaco-setup.js\"),\n ]);\n _monaco = monaco as unknown as Monaco;\n // The project's schemas may have arrived long before now; register them before the first editor\n // Mounts so its very first validation pass uses the right rules.\n await applyPendingSchemas();\n return _monaco;\n })();\n return _loading;\n}\n\n/**\n * The loaded Monaco namespace, or null when no code surface has opened yet.\n *\n * For call sites reachable ONLY with a live editor in hand — they cannot observe null in practice,\n * but they must not force the module to load either.\n */\nexport function loadedMonaco(): Monaco | null {\n return _monaco;\n}\n\n/** Whether Monaco has been loaded (tests, and the odd diagnostic). */\nexport function isMonacoLoaded(): boolean {\n return _monaco !== null;\n}\n\n/** Reset the memo (tests only). */\nexport function resetMonacoLazy(): void {\n _monaco = null;\n _loading = null;\n _pendingSchemas = null;\n _pendingSchemasDirty = false;\n}\n",
|
|
5
|
+
"/**\n * Lazy Monaco.\n *\n * Monaco is 12.6 MB of the studio bundle — two thirds of it — and most sessions never open a code\n * view. It used to be pulled in by a static `import * as monaco` in three modules plus a\n * side-effect `import \"./services/monaco-setup.js\"` from `studio.ts`, so every cold start\n * downloaded, parsed and evaluated the editor, its TypeScript/JSON/JavaScript language\n * contributions, and a `flattenSchema` pass over a 497 KB schema before first paint.\n *\n * Loading is deferred to the first code surface that actually needs it: source mode, the function\n * editor, the formula workspace. `loadMonaco()` is memoized, so concurrent callers share one import\n * and the language contributions register exactly once.\n *\n * Two accessors, deliberately:\n *\n * - {@link loadMonaco} for code that MOUNTS an editor. Those call sites are lit `ref()` DOM-attach\n * callbacks or already-async paths, so awaiting is free.\n * - {@link loadedMonaco} for code that can only run once an editor exists (setting markers on a\n * model, comparing a live editor's model URI). Returning the already-resolved namespace\n * synchronously keeps those paths sync — no async ripple through the render tree for a module\n * that is provably present.\n */\n\nimport type * as monacoNs from \"monaco-editor\";\n\nexport type Monaco = typeof monacoNs;\n\nlet _monaco: Monaco | null = null;\nlet _loading: Promise<Monaco> | null = null;\n\n/**\n * The active project's generated entry schemas, held until Monaco exists to receive them.\n *\n * These arrive at project activation — long before anyone opens a code view — and applying them\n * used to mean `import(\"./monaco-setup\")` right then. A dynamic import that EXECUTES at startup\n * defers evaluation by a tick but still fetches: Monaco went over the wire on every cold load,\n * which is precisely what the lazy path exists to avoid. So the schemas wait here instead, and the\n * loader applies whatever is pending once an editor actually needs one.\n */\nlet _pendingSchemas: { project?: unknown; document?: unknown } | null = null;\nlet _pendingSchemasDirty = false;\n\n/**\n * Record the active project's schemas for Monaco's JSON diagnostics.\n *\n * Applied immediately when Monaco is already loaded, otherwise on the next {@link loadMonaco}. Only\n * the LATEST set matters — reactivation and `project.json` writes both call this — so it overwrites\n * rather than queues.\n */\nexport function setProjectSchemasForMonaco(\n schemas: { project?: unknown; document?: unknown } | null,\n): void {\n _pendingSchemas = schemas;\n _pendingSchemasDirty = true;\n if (_monaco) {\n void applyPendingSchemas();\n }\n}\n\n/** Push any pending schemas into Monaco's JSON diagnostics. No-op when nothing changed. */\nasync function applyPendingSchemas(): Promise<void> {\n if (!_pendingSchemasDirty) {\n return;\n }\n _pendingSchemasDirty = false;\n try {\n const { applyProjectSchemas } = await import(\"./monaco-setup.js\");\n applyProjectSchemas(_pendingSchemas);\n } catch {\n // Editor degradation: the bundled core schemas stay in force.\n }\n}\n\n/**\n * Load Monaco and its Jx configuration (workers, JSON schemas, TS/JS contributions). Memoized.\n *\n * The `monaco-setup` import is what registers the language contributions and the worker factory, so\n * it must resolve before an editor is created — hence both imports awaited here rather than left to\n * whichever module happens to be evaluated first.\n */\nexport function loadMonaco(): Promise<Monaco> {\n if (_monaco) {\n return Promise.resolve(_monaco);\n }\n // Not `async`: an async function wraps the memo in a fresh promise per call, so concurrent callers\n // Could not observe that they share one in-flight load. Returning `_loading` itself makes the\n // Load-once guarantee visible (and testable) rather than merely true.\n _loading ??= (async () => {\n const [monaco] = await Promise.all([\n import(\"monaco-editor/esm/vs/editor/editor.api.js\"),\n import(\"./monaco-setup.js\"),\n ]);\n _monaco = monaco as unknown as Monaco;\n // The project's schemas may have arrived long before now; register them before the first editor\n // Mounts so its very first validation pass uses the right rules.\n await applyPendingSchemas();\n return _monaco;\n })();\n return _loading;\n}\n\n/**\n * The loaded Monaco namespace, or null when no code surface has opened yet.\n *\n * For call sites reachable ONLY with a live editor in hand — they cannot observe null in practice,\n * but they must not force the module to load either.\n */\nexport function loadedMonaco(): Monaco | null {\n return _monaco;\n}\n\n/**\n * Whether the mount started before {@link loadMonaco} is still the one the app wants.\n *\n * **The question you owe on the far side of the load, which is why it lives beside the load.** A\n * cold `loadMonaco()` is a 12.6 MB dynamic import; the user has hundreds of milliseconds inside it\n * to close the surface, retarget it, or leave the mode — and a second render has the same window to\n * start a mount of its own. Both surfaces need it and each had its own spelling of it, so the\n * source view simply did without: `renderCanvasImpl` assigns `surface.prevCanvasMode` BEFORE it\n * reaches the mount, so a second synchronous `renderCanvas()` during the load sees `modeChanged ===\n * false` and a null `view.monacoEditor`, skips the fast path and mounts again. The second mount\n * then calls `createModel` with a URI the first already registered, which real Monaco throws on\n * (\"ERR: Another model with the same URI\"), and `store.ts`'s `render()`/`renderOnly()` coalesce\n * nothing.\n *\n * Returning false means creating NOTHING — no model, no editor, no `automaticLayout` observer. That\n * is strictly better than creating and disposing: there is no window in which a doomed editor is\n * attached to anything, and no URI briefly claimed by a model nobody holds.\n *\n * @param {Element | null | undefined} container Where the editor was going to be created.\n * @param {unknown} existing The surface's editor handle (`view.monacoEditor` /\n * `view.functionEditor`). Non-null means another mount already won this race.\n * @param {() => boolean} stillTargeted Whether the app still wants exactly THIS mount — the same\n * tab, the same mode, the same editing target. Lazy: the two cheap clauses above answer first.\n * @returns {boolean}\n */\nexport function mountStillWanted(\n container: Element | null | undefined,\n existing: unknown,\n stillTargeted: () => boolean,\n): boolean {\n if (!container?.isConnected || existing) {\n return false;\n }\n return stillTargeted();\n}\n\n/** Whether Monaco has been loaded (tests, and the odd diagnostic). */\nexport function isMonacoLoaded(): boolean {\n return _monaco !== null;\n}\n\n/** Reset the memo (tests only). */\nexport function resetMonacoLazy(): void {\n _monaco = null;\n _loading = null;\n _pendingSchemas = null;\n _pendingSchemasDirty = false;\n}\n",
|
|
6
6
|
"/**\n * Format-host — the studio's view of the project's format registry.\n *\n * Format classes are auto-discovered server-side from the project imports map\n * (specs/extensions.md); the studio introspects them via the PAL (`listFormats`) and invokes\n * parse/serialize capabilities via `formatAction` (POST /__studio/format in the dev server, RPC on\n * desktop). The studio itself holds zero format knowledge — `.json` is the single native built-in.\n */\n\nimport { setProjectSchemasForMonaco } from \"../services/monaco-lazy\";\nimport { getPlatform } from \"../platform\";\nimport type { ExtensionsInfo } from \"../types\";\nimport type { JxMutableNode } from \"@jxsuite/schema/types\";\n\nexport interface StudioFormatHints {\n icon?: string;\n modes?: string[];\n documentMode?: {\n default?: \"content\" | \"component\";\n componentWhen?: { frontmatterKey?: string; matches?: string };\n };\n newFileTemplate?: string;\n elements?: {\n block?: string[];\n inline?: string[];\n void?: string[];\n textOnly?: string[];\n nesting?: Record<\n string,\n {\n block?: boolean;\n inline?: boolean;\n directive?: boolean;\n only?: string[];\n }\n >;\n };\n [key: string]: unknown;\n}\n\nexport interface StudioFormat {\n name: string;\n extensions: string[];\n mediaType: string | null;\n documentKinds: string[];\n exportTarget: boolean;\n remote: boolean;\n studio: StudioFormatHints | null;\n capabilities: Record<string, { identifier: string; timing: string[] }>;\n}\n\nlet _formats: StudioFormat[] = [];\nlet _loaded: Promise<StudioFormat[]> | null = null;\n\n/** Load (and cache) the project's format registry from the platform. */\nexport function loadFormats(): Promise<StudioFormat[]> {\n if (!_loaded) {\n _loaded = (async () => {\n try {\n const platform = getPlatform() as {\n listFormats?: () => Promise<StudioFormat[]>;\n };\n _formats = (await platform.listFormats?.()) ?? [];\n } catch {\n _formats = [];\n }\n return _formats;\n })();\n }\n return _loaded;\n}\n\n/** Invalidate the cached registry and extensions payload (call on project switch). */\nexport function refreshFormats() {\n _loaded = null;\n _formats = [];\n _extensionsLoaded = null;\n _extensions = [];\n}\n\n/** Seed the registry directly (tests and hosts that preload format metadata). */\nexport function setFormats(formats: StudioFormat[]) {\n _formats = formats;\n _loaded = Promise.resolve(formats);\n}\n\n// ─── Extensions payload (specs/extensions.md §9/§9.1) ────────────────────────\n\nlet _extensions: ExtensionsInfo[] = [];\nlet _extensionsLoaded: Promise<ExtensionsInfo[]> | null = null;\n\n/**\n * Load (and cache) the project's enabled extensions with their project-section contributions.\n * Backed by the platform's optional `listExtensions` member; platforms without it (or failures)\n * degrade to an empty list, hiding descriptor-contributed settings sections.\n */\nexport function loadExtensions(): Promise<ExtensionsInfo[]> {\n if (!_extensionsLoaded) {\n _extensionsLoaded = (async () => {\n try {\n const platform = getPlatform() as {\n listExtensions?: () => Promise<ExtensionsInfo[]>;\n };\n _extensions = (await platform.listExtensions?.()) ?? [];\n } catch {\n _extensions = [];\n }\n return _extensions;\n })();\n }\n return _extensionsLoaded;\n}\n\n/** The last-loaded extensions payload (synchronous access for render paths). */\nexport function getExtensions(): ExtensionsInfo[] {\n return _extensions;\n}\n\n/** Seed the extensions payload directly (tests and hosts that preload it). */\nexport function setExtensions(extensions: ExtensionsInfo[]) {\n _extensions = extensions;\n _extensionsLoaded = Promise.resolve(extensions);\n}\n\n/**\n * Fetch the active project's entry documents ONCE and hand the same payload to every consumer.\n *\n * The backends regenerate entry documents that are missing or older than `project.json` and write\n * them to disk (extensions.md §5.2), so a second concurrent fetch is not a harmless duplicate — it\n * races the first on the same two files. One fetch also guarantees Monaco's diagnostics and the AI\n * assistant's gate judge a document by the SAME schema; when they disagree the model ships work its\n * own tool call called clean and the editor immediately paints red.\n *\n * @param {object} platform - The studio platform (only `fetchProjectSchemas` is consulted)\n * @returns {Promise<void>} Resolves once both consumers have been updated\n */\nasync function shareProjectSchemas(platform: {\n fetchProjectSchemas?: () => Promise<{ project?: unknown; document?: unknown }>;\n}): Promise<void> {\n let schemas: { project?: unknown; document?: unknown } | null = null;\n try {\n schemas = (await platform.fetchProjectSchemas?.()) ?? null;\n } catch {\n // Editor degradation: both consumers keep the bundled core schemas.\n }\n // Monaco's copy is HELD, not applied: this runs at project activation, and importing monaco-setup\n // Here would fetch the whole editor on every cold load for a code view most sessions never open.\n // `services/monaco-lazy` registers them when an editor is actually created.\n setProjectSchemasForMonaco(schemas);\n await import(\"../services/jx-validate\")\n .then(({ applyProjectSchemas }) => applyProjectSchemas(schemas))\n .catch(() => false);\n}\n\n/**\n * Fire-and-forget refresh of the extension-facing editor surface after project (re)activation, a\n * `project.json` write, or an `extensions` change: the per-project schemas behind Monaco's\n * diagnostics and the AI assistant's validation gate, plus the descriptor-contributed settings\n * sections. Every module loads lazily — monaco is heavy and the settings registry pulls DOM\n * templates — and all of them degrade silently (core schemas, built-in sections only).\n *\n * @param {object} platform - The studio platform (only `fetchProjectSchemas` is consulted here)\n */\nexport function refreshExtensionUi(platform: {\n fetchProjectSchemas?: () => Promise<{ project?: unknown; document?: unknown }>;\n}): void {\n void shareProjectSchemas(platform);\n void import(\"../settings/extension-sections\")\n .then(({ syncExtensionSettingsSections }) => syncExtensionSettingsSections())\n .catch(() => {\n // Contributed sections also refresh on the next settings-modal open.\n });\n}\n\n/** The last-loaded registry (synchronous access for render paths). */\nexport function getFormats(): StudioFormat[] {\n return _formats;\n}\n\n/** Look up the format claiming a file extension (\".md\" or \"md\"), optionally by capability. */\nexport function formatByExtension(ext: string, capability?: string): StudioFormat | undefined {\n const norm = ext.startsWith(\".\") ? ext.toLowerCase() : `.${ext.toLowerCase()}`;\n return _formats.find(\n (f) => f.extensions.includes(norm) && (!capability || f.capabilities[capability]),\n );\n}\n\n/** Look up a format by its import name. */\nexport function formatByName(name: string | null | undefined): StudioFormat | undefined {\n if (!name) {\n return undefined;\n }\n return _formats.find((f) => f.name === name);\n}\n\n/** Error for opening a non-JSON file when no imported format class claims its extension. */\nexport function noFormatError(path: string): Error {\n return new Error(\n `No format class imported for \"${path}\" — add one to project.json imports ` +\n `(e.g. \"Markdown\": \"@jxsuite/parser/Markdown.class.json\") and make sure the ` +\n `project's dependencies are installed`,\n );\n}\n\n/** The format claiming a file path's extension, if any. */\nexport function formatForPath(path: string | null | undefined): StudioFormat | undefined {\n if (!path) {\n return undefined;\n }\n const dot = path.lastIndexOf(\".\");\n if (dot === -1) {\n return undefined;\n }\n return formatByExtension(path.slice(dot));\n}\n\n/** Registered extensions, optionally filtered by document kind. Never includes \".json\". */\nexport function documentExtensions(kind?: string): string[] {\n const exts = new Set<string>();\n for (const f of _formats) {\n if (kind && !f.documentKinds.includes(kind)) {\n continue;\n }\n for (const e of f.extensions) {\n exts.add(e);\n }\n }\n exts.delete(\".json\");\n return [...exts];\n}\n\n/** The default format for new content documents (first content-kind serializer). */\nexport function defaultContentFormat(): StudioFormat | undefined {\n return _formats.find((f) => f.capabilities.serialize && f.documentKinds.includes(\"content\"));\n}\n\nasync function formatAction(payload: Record<string, unknown>): Promise<unknown> {\n const platform = getPlatform() as {\n formatAction?: (payload: Record<string, unknown>) => Promise<unknown>;\n };\n if (!platform.formatAction) {\n throw new Error(\"Platform does not support format actions\");\n }\n return platform.formatAction(payload);\n}\n\n/** Parse source text into a Jx document via the named format's parse capability. */\nexport async function formatParse(\n name: string,\n source: string,\n options?: Record<string, unknown>,\n): Promise<JxMutableNode> {\n return (await formatAction({\n action: \"parse\",\n format: name,\n options,\n source,\n })) as JxMutableNode;\n}\n\n/** Serialize a Jx document to source text via the named format's serialize capability. */\nexport async function formatSerialize(\n name: string,\n doc: Record<string, unknown>,\n options?: Record<string, unknown>,\n): Promise<string> {\n return (await formatAction({\n action: \"serialize\",\n doc,\n format: name,\n options,\n })) as string;\n}\n\n/**\n * Split a parsed format document into { document, frontmatter, mode } per the format's\n * `$studio.documentMode` hints. Component documents (e.g. a frontmatter `tagName` with a hyphen)\n * keep their full shape; content documents separate frontmatter metadata from the body children.\n */\nexport function splitFormatDocument(format: StudioFormat | undefined, doc: JxMutableNode) {\n const hints = format?.studio?.documentMode;\n const componentWhen = hints?.componentWhen;\n if (componentWhen?.frontmatterKey) {\n const value = doc[componentWhen.frontmatterKey];\n const pattern = componentWhen.matches ? new RegExp(componentWhen.matches) : /./;\n if (typeof value === \"string\" && pattern.test(value)) {\n return {\n document: doc,\n frontmatter: {} as Record<string, unknown>,\n mode: \"component\",\n };\n }\n }\n if (hints?.default === \"component\") {\n return {\n document: doc,\n frontmatter: {} as Record<string, unknown>,\n mode: \"component\",\n };\n }\n\n // Content document — children form the root-level body; other keys are frontmatter\n const children = (doc.children as unknown[]) ?? [];\n if (children.length === 0) {\n children.push({ children: [], tagName: \"p\" });\n }\n\n const documentKeys = new Set([\"state\", \"imports\"]);\n const contentDoc: Record<string, unknown> = { children };\n const frontmatter: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(doc)) {\n if (key === \"children\") {\n continue;\n }\n if (documentKeys.has(key)) {\n contentDoc[key] = value;\n } else {\n frontmatter[key] = value;\n }\n }\n\n return {\n document: contentDoc as JxMutableNode,\n frontmatter,\n mode: \"content\",\n };\n}\n"
|
|
7
7
|
],
|
|
8
|
-
"mappings": ";;;;;;;;AA2BA,IAAI,UAAyB;AAC7B,IAAI,WAAmC;AAWvC,IAAI,kBAAoE;AACxE,IAAI,uBAAuB;AASpB,SAAS,0BAA0B,CACxC,SACM;AAAA,EACN,kBAAkB;AAAA,EAClB,uBAAuB;AAAA,EACvB,IAAI,SAAS;AAAA,IACN,oBAAoB;AAAA,EAC3B;AAAA;AAIF,eAAe,mBAAmB,GAAkB;AAAA,EAClD,IAAI,CAAC,sBAAsB;AAAA,IACzB;AAAA,EACF;AAAA,EACA,uBAAuB;AAAA,EACvB,IAAI;AAAA,IACF,QAAQ,wBAAwB,MAAa;AAAA,IAC7C,oBAAoB,eAAe;AAAA,IACnC,MAAM;AAAA;AAYH,SAAS,UAAU,GAAoB;AAAA,EAC5C,IAAI,SAAS;AAAA,IACX,OAAO,QAAQ,QAAQ,OAAO;AAAA,EAChC;AAAA,EAIA,cAAc,YAAY;AAAA,IACxB,OAAO,UAAU,MAAM,QAAQ,IAAI;AAAA,MAC1B;AAAA,MACA;AAAA,IACT,CAAC;AAAA,IACD,UAAU;AAAA,IAGV,MAAM,oBAAoB;AAAA,IAC1B,OAAO;AAAA,KACN;AAAA,EACH,OAAO;AAAA;AASF,SAAS,YAAY,GAAkB;AAAA,EAC5C,OAAO;AAAA;;;
|
|
9
|
-
"debugId": "
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "64F2ED66D12C3F6C64756E2164756E21",
|
|
10
10
|
"names": []
|
|
11
11
|
}
|
|
@@ -501,19 +501,20 @@ var isSafari = once(function isSafari2() {
|
|
|
501
501
|
return userAgent.includes("AppleWebKit") && !userAgent.includes("Chrome");
|
|
502
502
|
});
|
|
503
503
|
|
|
504
|
+
// ../../node_modules/@atlaskit/pragmatic-drag-and-drop/dist/esm/util/changing-window/is-from-another-window.js
|
|
505
|
+
function isNodeLike(target) {
|
|
506
|
+
return "nodeName" in target;
|
|
507
|
+
}
|
|
508
|
+
function isFromAnotherWindow(eventTarget) {
|
|
509
|
+
return isNodeLike(eventTarget) && eventTarget.ownerDocument !== document;
|
|
510
|
+
}
|
|
511
|
+
|
|
504
512
|
// ../../node_modules/@atlaskit/pragmatic-drag-and-drop/dist/esm/util/changing-window/count-events-for-safari.js
|
|
505
513
|
var import_bind_event_listener2 = __toESM(require_dist(), 1);
|
|
506
514
|
var symbols = {
|
|
507
515
|
isLeavingWindow: Symbol("leaving"),
|
|
508
516
|
isEnteringWindow: Symbol("entering")
|
|
509
517
|
};
|
|
510
|
-
function isLeavingWindowInSafari(_ref2) {
|
|
511
|
-
var dragLeave = _ref2.dragLeave;
|
|
512
|
-
if (!isSafari()) {
|
|
513
|
-
return false;
|
|
514
|
-
}
|
|
515
|
-
return dragLeave.hasOwnProperty(symbols.isLeavingWindow);
|
|
516
|
-
}
|
|
517
518
|
(function fixSafari() {
|
|
518
519
|
if (typeof window === "undefined") {
|
|
519
520
|
return;
|
|
@@ -567,12 +568,13 @@ function isLeavingWindowInSafari(_ref2) {
|
|
|
567
568
|
});
|
|
568
569
|
})();
|
|
569
570
|
|
|
570
|
-
// ../../node_modules/@atlaskit/pragmatic-drag-and-drop/dist/esm/util/changing-window/is-
|
|
571
|
-
function
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
571
|
+
// ../../node_modules/@atlaskit/pragmatic-drag-and-drop/dist/esm/util/changing-window/is-leaving-window-in-safari.js
|
|
572
|
+
function isLeavingWindowInSafari(_ref) {
|
|
573
|
+
var dragLeave = _ref.dragLeave;
|
|
574
|
+
if (!isSafari()) {
|
|
575
|
+
return false;
|
|
576
|
+
}
|
|
577
|
+
return dragLeave.hasOwnProperty(symbols.isLeavingWindow);
|
|
576
578
|
}
|
|
577
579
|
|
|
578
580
|
// ../../node_modules/@atlaskit/pragmatic-drag-and-drop/dist/esm/util/changing-window/is-leaving-window.js
|
|
@@ -1643,5 +1645,5 @@ function draggable(args) {
|
|
|
1643
1645
|
}
|
|
1644
1646
|
export { _defineProperty, combine, dropTargetForElements, monitorForElements, draggable };
|
|
1645
1647
|
|
|
1646
|
-
//# debugId=
|
|
1647
|
-
//# sourceMappingURL=studio-
|
|
1648
|
+
//# debugId=B98852195E240EEB64756E2164756E21
|
|
1649
|
+
//# sourceMappingURL=studio-bsxxx3x2.js.map
|