@jxsuite/studio 2.0.1 → 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-799jpvhm.js → components-2bpqp4mq.js} +5 -7
- package/dist/chunks/{components-799jpvhm.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-8jxwts2p.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-gs6kqdt1.js → studio-adn0z1k3.js} +14 -8
- package/dist/chunks/{studio-gs6kqdt1.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-esrewxap.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-v7jkjqng.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-jm0z592w.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 +21080 -32585
- 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 +7 -0
- package/src/new-project/location-fields.ts +9 -1
- package/src/new-project/new-project-modal.ts +221 -245
- 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 -53
- 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 +30 -1
- 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 +7 -1
- 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-qr3drkkw.js +0 -531
- package/dist/chunks/extension-sections-qr3drkkw.js.map +0 -12
- package/dist/chunks/files-j8a1t06k.js +0 -50
- package/dist/chunks/files-j8a1t06k.js.map +0 -9
- package/dist/chunks/git-panel-xtq5z81x.js +0 -28
- package/dist/chunks/git-panel-xtq5z81x.js.map +0 -9
- package/dist/chunks/layers-panel-ancn2wpq.js +0 -26
- package/dist/chunks/layers-panel-ancn2wpq.js.map +0 -9
- package/dist/chunks/settings-modal-17ttr96g.js +0 -29
- package/dist/chunks/settings-modal-17ttr96g.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-0xgs7xrs.js +0 -429
- package/dist/chunks/studio-0xgs7xrs.js.map +0 -13
- package/dist/chunks/studio-4d8hzcz5.js +0 -3427
- package/dist/chunks/studio-4d8hzcz5.js.map +0 -26
- package/dist/chunks/studio-4k0m4fmp.js.map +0 -13
- package/dist/chunks/studio-9smfzqhc.js +0 -19
- package/dist/chunks/studio-9smfzqhc.js.map +0 -10
- package/dist/chunks/studio-jm0z592w.js.map +0 -115
- package/dist/chunks/studio-m2t4mdg5.js +0 -1854
- package/dist/chunks/studio-m2t4mdg5.js.map +0 -18
- package/dist/chunks/studio-n4p11dfy.js +0 -853
- package/dist/chunks/studio-n4p11dfy.js.map +0 -12
- package/dist/chunks/studio-qkvt37c0.js.map +0 -9
- package/dist/chunks/studio-sjh1wt1a.js +0 -3744
- package/dist/chunks/studio-sjh1wt1a.js.map +0 -22
- package/dist/chunks/studio-v7jkjqng.js.map +0 -46
- 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-yfcstdzy.js +0 -399
- package/dist/chunks/studio-yfcstdzy.js.map +0 -12
- package/dist/chunks/studio-zp7jncs8.js +0 -469
- package/dist/chunks/studio-zp7jncs8.js.map +0 -14
- 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-8jxwts2p.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-esrewxap.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
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/ui/field-row.ts", "../src/ui/schema-form.ts", "../src/services/context-resolver.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/// <reference lib=\"dom\" />\n/**\n * Field-row.js — Universal field row layout for all Studio panels.\n *\n * Renders the consistent pattern: indicator dot + label + widget slot. Used by style panel,\n * attributes panel, frontmatter panel, signals panel, etc.\n */\n\nimport { html, nothing } from \"lit-html\";\nimport { classMap } from \"lit-html/directives/class-map.js\";\n\n/**\n * Render a universal field row with indicator dot, label, and widget.\n *\n * @param {{\n * prop: string;\n * label: string;\n * hasValue: boolean;\n * onClear?: () => void;\n * widget: unknown;\n * labelExtra?: unknown;\n * span?: number;\n * warning?: boolean;\n * }} opts\n * @returns {import(\"lit-html\").TemplateResult}\n */\nexport function renderFieldRow({\n prop,\n label,\n hasValue,\n onClear,\n widget,\n labelExtra,\n span,\n warning,\n}: {\n prop: string;\n label: string;\n hasValue: boolean;\n onClear?: () => void;\n widget: unknown;\n /** Rendered after the label inside the label cell (e.g. the dynamic-slot mode button). */\n labelExtra?: unknown;\n span?: number;\n warning?: boolean;\n}) {\n return html`\n <div\n class=${classMap({ \"style-row\": true, \"style-row--warning\": Boolean(warning) })}\n data-prop=${prop}\n style=${span === 2 ? \"grid-column: 1 / -1\" : \"\"}\n >\n <div class=\"style-row-label\">\n ${\n hasValue && onClear\n ? html`<span\n class=\"set-dot\"\n title=\"Clear ${prop}\"\n @click=${(e: Event) => {\n e.stopPropagation();\n onClear();\n }}\n ></span>`\n : nothing\n }\n <sp-field-label size=\"s\" title=${prop}>${label}</sp-field-label>\n ${labelExtra ?? nothing}\n </div>\n ${widget}\n </div>\n `;\n}\n",
|
|
6
|
-
"/// <reference lib=\"dom\" />\n/**\n * Schema-form — reusable JSON-Schema → form rendering engine, extracted from the signals panel.\n *\n * Maps schema property types to Spectrum controls (enum → picker, boolean → checkbox,\n * number/integer → number-field, `json-schema` format → multiline JSON editor, array-of-objects →\n * multi-row inline form, other array/object → JSON text field, default → textfield). Hosts commit\n * edits through a single `onChange(patch)` callback; dynamic enum choices and `$ref` bindings\n * resolve through a {@link SchemaFormContext}. Custom controls register by name via\n * {@link registerFormControl} and are consulted first for `ui` overrides.\n */\n\nimport { html, nothing } from \"lit-html\";\nimport { ifDefined } from \"lit-html/directives/if-defined.js\";\nimport { live } from \"lit-html/directives/live.js\";\nimport { styleMap } from \"lit-html/directives/style-map.js\";\nimport { isRef } from \"@jxsuite/schema/guards\";\nimport { renderFieldRow } from \"./field-row\";\nimport type { TemplateResult } from \"lit-html\";\n\n/** A (possibly nested) JSON Schema node, covering both object and property level keys. */\nexport interface JsonSchema {\n type?: string;\n properties?: Record<string, JsonSchema>;\n required?: string[];\n description?: string;\n enum?: unknown;\n default?: unknown;\n format?: string;\n minimum?: number;\n maximum?: number;\n examples?: string[];\n name?: string;\n items?: JsonSchema;\n}\n\n/** Host-provided context threaded to every control. */\nexport interface SchemaFormContext {\n /** Resolve a `#/$context/…` pointer (or legacy sentinel) against the host's project config. */\n resolvePointer: (pointer: string, scope?: Record<string, unknown>) => unknown;\n /** Route params available for `$ref` bindings (e.g. from the document path). */\n params?: string[] | undefined;\n /** Unique prefix for per-field ephemeral UI state (e.g. the binding control's custom mode). */\n fieldKeyPrefix?: string | undefined;\n /**\n * Commit hook for the \"secret\" control: stores the VALUE in the platform's secret store (never\n * project.json) and returns the derived env-var NAME, which the control persists to the field\n * instead of the value.\n */\n commitSecret?: ((key: string, value: string) => string | Promise<string>) | undefined;\n}\n\n/** Arguments passed to a registered form control. */\nexport interface SchemaFormControlArgs {\n key: string;\n schema: JsonSchema;\n value: unknown;\n onChange: (next: unknown) => void;\n ctx: SchemaFormContext;\n rerender?: (() => void) | undefined;\n}\n\nexport type SchemaFormControl = (args: SchemaFormControlArgs) => TemplateResult;\n\n/** Options for {@link renderForm}. */\nexport interface RenderFormOptions {\n onChange: (patch: Record<string, unknown>) => void;\n context?: SchemaFormContext | undefined;\n /**\n * Per-field overrides from `$studio.settings.entry.ui`: a registered control name, and/or an\n * `enum` source (choice list or `{ \"$ref\": \"#/$context/<pointer>\" }`) layered over the field\n * schema — fragments stay valid JSON Schema while descriptors add dynamic choices.\n */\n ui?: Record<string, { control?: string; enum?: unknown }> | undefined;\n rerender?: (() => void) | undefined;\n}\n\n// ─── Control registry ────────────────────────────────────────────────────────\n\nconst controlRegistry = new Map<string, SchemaFormControl>();\n\n/** Register (or replace) a named form control. */\nexport function registerFormControl(name: string, control: SchemaFormControl): void {\n controlRegistry.set(name, control);\n}\n\n/** Look up a registered form control by name. */\nexport function getFormControl(name: string): SchemaFormControl | undefined {\n return controlRegistry.get(name);\n}\n\n/** Inert context used when a host renders a form without one. */\nconst NULL_CONTEXT: SchemaFormContext = {\n resolvePointer: () => {\n // Nothing to resolve against without a host context\n },\n};\n\n// ─── Enum resolution ─────────────────────────────────────────────────────────\n\n/**\n * Resolve a schema enum definition to concrete choices. Plain arrays pass through; `$ref` objects\n * and sentinel strings resolve through the context's pointer resolver, applying object →\n * `Object.keys` and string[] → itself.\n *\n * @param {unknown} enumDef\n * @param {SchemaFormContext | undefined} ctx\n * @param {Record<string, unknown>} [scope] - Scope for `{@param}` substitution (the form value)\n * @returns {string[] | undefined}\n */\nexport function resolveFormEnum(\n enumDef: unknown,\n ctx?: SchemaFormContext,\n scope?: Record<string, unknown>,\n): string[] | undefined {\n if (Array.isArray(enumDef)) {\n return enumDef as string[];\n }\n let pointer: string | undefined;\n if (enumDef && typeof enumDef === \"object\") {\n const ref = (enumDef as Record<string, unknown>).$ref;\n if (typeof ref === \"string\") {\n pointer = ref;\n }\n } else if (typeof enumDef === \"string\") {\n // Legacy sentinel strings (e.g. \"$contentTypes\") resolve through the host's pointer resolver\n pointer = enumDef;\n }\n if (pointer === undefined || !ctx) {\n return undefined;\n }\n const resolved = ctx.resolvePointer(pointer, scope);\n if (Array.isArray(resolved)) {\n return resolved.map(String);\n }\n if (resolved && typeof resolved === \"object\") {\n return Object.keys(resolved);\n }\n return undefined;\n}\n\n// ─── Field helpers ───────────────────────────────────────────────────────────\n\n/** Parse a numeric field value, returning NaN for blank input (so callers can treat it as unset). */\nexport function parseNumericField(raw: string, integer: boolean): number {\n if (raw.trim() === \"\") {\n return Number.NaN;\n }\n return integer ? Math.trunc(Number(raw)) : Number(raw);\n}\n\n/** Plain textfield editing a `{ $ref }` value directly — the fallback when no binding control. */\nfunction refTextField(key: string, refVal: string, onChange: (next: unknown) => void) {\n return html`<sp-textfield\n size=\"s\"\n label=${key}\n placeholder=${key}\n .value=${live(refVal)}\n @change=${(e: Event) => {\n const v = (e.target as HTMLInputElement).value.trim();\n onChange(v ? { $ref: v } : undefined);\n }}\n ></sp-textfield>`;\n}\n\n/**\n * Render a single inline field within an array-of-objects row. Dispatches by schema type: enum →\n * picker, boolean → switch, number → number-field, else → textfield.\n *\n * @param {string} key\n * @param {JsonSchema} schema\n * @param {unknown} value\n * @param {(val: unknown) => void} onChange\n * @param {SchemaFormContext | undefined} ctx\n * @param {Record<string, unknown>} [scope] - Scope for dependent enum refs (the parent form value)\n */\nexport function renderInlineField(\n key: string,\n schema: JsonSchema,\n value: unknown,\n onChange: (val: unknown) => void,\n ctx?: SchemaFormContext,\n scope?: Record<string, unknown>,\n) {\n if (isRef(value)) {\n return refTextField(key, value.$ref, onChange);\n }\n const enumValues = resolveFormEnum(schema.enum, ctx, scope);\n\n if (enumValues) {\n return html`<sp-picker\n size=\"s\"\n label=${key}\n value=${value !== undefined ? String(value) : \"__none__\"}\n @change=${(e: Event) =>\n onChange(\n (e.target as HTMLInputElement).value === \"__none__\"\n ? undefined\n : (e.target as HTMLInputElement).value,\n )}\n >\n <sp-menu-item value=\"__none__\">—</sp-menu-item>\n ${enumValues.map((v: string) => html`<sp-menu-item value=${v}>${v}</sp-menu-item>`)}\n </sp-picker>`;\n }\n if (schema.type === \"boolean\") {\n return html`<sp-switch\n size=\"s\"\n ?checked=${Boolean(value)}\n @change=${(e: Event) => onChange((e.target as HTMLInputElement).checked)}\n >${key}</sp-switch\n >`;\n }\n if (schema.type === \"integer\" || schema.type === \"number\") {\n return html`<sp-number-field\n size=\"s\"\n label=${key}\n .value=${value !== undefined ? value : nothing}\n step=${schema.type === \"integer\" ? \"1\" : nothing}\n @change=${(e: Event) => {\n const parsed = parseNumericField(\n (e.target as HTMLInputElement).value,\n schema.type === \"integer\",\n );\n onChange(Number.isNaN(parsed) ? undefined : parsed);\n }}\n ></sp-number-field>`;\n }\n return html`<sp-textfield\n size=\"s\"\n label=${key}\n placeholder=${key}\n .value=${value ?? \"\"}\n @input=${(e: Event) => onChange((e.target as HTMLInputElement).value || undefined)}\n ></sp-textfield>`;\n}\n\n/** Render a debounced multiline JSON text field for array/object schema properties. */\nfunction renderJsonTextField(currentValue: unknown, ps: JsonSchema, commit: (v: unknown) => void) {\n /** @type {ReturnType<typeof setTimeout> | undefined} */\n let debounce: ReturnType<typeof setTimeout> | undefined;\n return html`<sp-textfield\n multiline\n size=\"s\"\n style=\"min-height:40px\"\n .value=${currentValue !== undefined ? JSON.stringify(currentValue, null, 2) : \"\"}\n placeholder=${ps.default !== undefined ? JSON.stringify(ps.default) : nothing}\n @input=${(e: Event) => {\n clearTimeout(debounce);\n debounce = setTimeout(() => {\n try {\n commit(JSON.parse((e.target as HTMLInputElement).value) as unknown);\n } catch {}\n }, 500);\n }}\n ></sp-textfield>`;\n}\n\n// ─── Per-property control dispatch ───────────────────────────────────────────\n\n/** Render the widget for one schema property, honoring registered-control overrides. */\nfunction renderPropertyControl(\n prop: string,\n ps: JsonSchema,\n value: Record<string, unknown>,\n required: Set<string>,\n opts: RenderFormOptions,\n ctx: SchemaFormContext,\n): TemplateResult {\n const currentValue = value[prop];\n const commit = (next: unknown) => opts.onChange({ [prop]: next });\n const controlArgs: SchemaFormControlArgs = {\n ctx,\n key: prop,\n onChange: commit,\n rerender: opts.rerender,\n schema: ps,\n value: currentValue,\n };\n\n // Explicit ui override → consult the control registry first\n const overrideName = opts.ui?.[prop]?.control;\n if (overrideName) {\n const custom = controlRegistry.get(overrideName);\n if (custom) {\n return custom(controlArgs);\n }\n }\n\n if (\n isRef(currentValue) &&\n ps.format !== \"json-schema\" &&\n ps.type !== \"object\" &&\n ps.type !== \"array\"\n ) {\n const binding = controlRegistry.get(\"binding\");\n if (binding) {\n return binding(controlArgs);\n }\n return refTextField(prop, currentValue.$ref, commit);\n }\n\n const enumValues = resolveFormEnum(opts.ui?.[prop]?.enum ?? ps.enum, ctx, value);\n if (enumValues) {\n return html`\n <sp-picker\n size=\"s\"\n value=${\n currentValue !== undefined\n ? String(currentValue)\n : ps.default !== undefined\n ? String(ps.default)\n : \"__none__\"\n }\n @change=${(e: Event) =>\n commit(\n (e.target as HTMLInputElement).value === \"__none__\"\n ? undefined\n : (e.target as HTMLInputElement).value,\n )}\n >\n ${!required.has(prop) ? html`<sp-menu-item value=\"__none__\">—</sp-menu-item>` : nothing}\n ${enumValues.map((val: string) => html`<sp-menu-item value=${val}>${val}</sp-menu-item>`)}\n </sp-picker>\n `;\n }\n if (ps.type === \"boolean\") {\n return html`<sp-checkbox\n ?checked=${currentValue ?? ps.default ?? false}\n @change=${(e: Event) => commit((e.target as HTMLInputElement).checked)}\n ></sp-checkbox>`;\n }\n if (ps.type === \"integer\" || ps.type === \"number\") {\n /** @type {ReturnType<typeof setTimeout> | undefined} */\n let debounce: ReturnType<typeof setTimeout> | undefined;\n return html`<sp-number-field\n size=\"s\"\n min=${ifDefined(ps.minimum)}\n max=${ifDefined(ps.maximum)}\n step=${ps.type === \"integer\" ? \"1\" : nothing}\n .value=${currentValue !== undefined ? currentValue : nothing}\n placeholder=${ps.default != null ? String(ps.default) : nothing}\n @change=${(e: Event) => {\n clearTimeout(debounce);\n debounce = setTimeout(() => {\n const parsed = parseNumericField(\n (e.target as HTMLInputElement).value,\n ps.type === \"integer\",\n );\n commit(Number.isNaN(parsed) ? undefined : parsed);\n }, 400);\n }}\n ></sp-number-field>`;\n }\n if (ps.format === \"json-schema\") {\n const hasValue =\n currentValue && typeof currentValue === \"object\" && Object.keys(currentValue).length > 0;\n const cv = currentValue as Record<string, unknown>;\n const isSchemaRef = hasValue && cv.$ref;\n /** @type {ReturnType<typeof setTimeout> | undefined} */\n let debounce: ReturnType<typeof setTimeout> | undefined;\n return html`\n <div class=\"schema-param-editor\">\n ${\n hasValue && !isSchemaRef && cv.properties\n ? html`\n <div style=\"display:flex;flex-wrap:wrap;gap:3px;margin-bottom:4px\">\n ${Object.entries(cv.properties as Record<string, Record<string, unknown>>).map(\n ([k, v]) => html`\n <span\n style=\"background:var(--bg);padding:1px 6px;border-radius:var(--radius);font-size:10px;color:var(--fg-dim)\"\n >${k}: ${v.type ?? \"any\"}</span\n >\n `,\n )}\n </div>\n `\n : nothing\n }\n <sp-textfield\n multiline\n size=\"s\"\n style=${styleMap({\n fontFamily: \"monospace\",\n fontSize: \"11px\",\n minHeight: hasValue ? \"80px\" : \"40px\",\n })}\n .value=${currentValue !== undefined ? JSON.stringify(currentValue, null, 2) : \"\"}\n placeholder=${ps.description ?? \"JSON Schema defining the data shape…\"}\n @input=${(e: Event) => {\n clearTimeout(debounce);\n debounce = setTimeout(() => {\n try {\n commit(JSON.parse((e.target as HTMLInputElement).value) as unknown);\n } catch {}\n }, 500);\n }}\n ></sp-textfield>\n </div>\n `;\n }\n if (ps.type === \"array\" && ps.items?.type === \"object\" && ps.items?.properties) {\n // Array of objects with defined schema → multi-row inline form\n const rows: Record<string, unknown>[] = Array.isArray(currentValue)\n ? (currentValue as Record<string, unknown>[])\n : [];\n const itemProps = ps.items.properties;\n return html`\n <div class=\"array-object-field\">\n ${rows.map(\n (row: Record<string, unknown>, idx: number) => html`\n <div\n class=\"array-object-row\"\n style=\"display:flex;gap:4px;align-items:center;margin-bottom:4px\"\n >\n ${Object.entries(itemProps).map(([propKey, propSchema]) =>\n renderInlineField(\n propKey,\n propSchema,\n row[propKey],\n (val) => {\n const updated = [...rows];\n updated[idx] = { ...updated[idx], [propKey]: val };\n commit(updated);\n },\n ctx,\n value,\n ),\n )}\n <sp-action-button\n quiet\n size=\"s\"\n @click=${() => {\n const updated = rows.filter((_: unknown, i: number) => i !== idx);\n commit(updated.length > 0 ? updated : undefined);\n opts.rerender?.();\n }}\n >\n <sp-icon-delete slot=\"icon\"></sp-icon-delete>\n </sp-action-button>\n </div>\n `,\n )}\n <sp-action-button\n quiet\n size=\"s\"\n @click=${(e: Event) => {\n e.stopPropagation();\n const newRow: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(itemProps)) {\n if (v.default !== undefined) {\n newRow[k] = v.default;\n }\n }\n commit([...rows, newRow]);\n opts.rerender?.();\n }}\n >+ Add</sp-action-button\n >\n </div>\n `;\n }\n if (ps.type === \"array\" || ps.type === \"object\") {\n return renderJsonTextField(currentValue, ps, commit) as TemplateResult;\n }\n\n /** @type {ReturnType<typeof setTimeout> | undefined} */\n let debounce: ReturnType<typeof setTimeout> | undefined;\n const params = ctx.params ?? [];\n const ph = ps.default !== undefined ? String(ps.default) : (ps.examples?.[0] ?? \"\");\n return html`<div style=\"display:flex;gap:4px;align-items:center\">\n <sp-textfield\n size=\"s\"\n style=\"flex:1\"\n .value=${currentValue ?? \"\"}\n placeholder=${ph || nothing}\n title=${ps.description || nothing}\n @input=${(e: Event) => {\n clearTimeout(debounce);\n debounce = setTimeout(() => commit((e.target as HTMLInputElement).value || undefined), 400);\n }}\n ></sp-textfield>\n ${\n params.length > 0\n ? html`<sp-action-button\n quiet\n size=\"s\"\n title=\"Bind to route param\"\n @click=${() => {\n commit({ $ref: `#/$params/${params[0]}` });\n opts.rerender?.();\n }}\n ><sp-icon-link slot=\"icon\"></sp-icon-link\n ></sp-action-button>`\n : nothing\n }\n </div>`;\n}\n\n// ─── Form rendering ──────────────────────────────────────────────────────────\n\n/**\n * Render form field rows for a JSON Schema's `properties`, committing edits through `opts.onChange`\n * as single-key patches (`undefined` values mean \"unset the key\").\n *\n * @param {JsonSchema} schema\n * @param {Record<string, unknown>} value - The record being edited\n * @param {RenderFormOptions} opts\n * @returns {TemplateResult}\n */\nexport function renderForm(\n schema: JsonSchema,\n value: Record<string, unknown>,\n opts: RenderFormOptions,\n): TemplateResult {\n const required = new Set(schema.required);\n const ctx = opts.context ?? NULL_CONTEXT;\n\n const propertyFields = Object.entries(schema.properties ?? {}).map(([prop, ps]) => {\n const labelText = prop + (required.has(prop) ? \" *\" : \"\");\n return renderFieldRow({\n hasValue: false,\n label: labelText,\n prop: ps.name || prop,\n widget: renderPropertyControl(prop, ps, value, required, opts, ctx),\n });\n });\n\n return html`${propertyFields}`;\n}\n",
|
|
7
|
-
"/**\n * Context resolver — generic `#/$context/<pointer>` resolution over the project config\n * (specs/extensions.md §9.1).\n *\n * Pointers walk the project config segment by segment. `{@param}` segments substitute values from a\n * caller-provided scope (e.g. the form's current value record), and the `$formats` virtual root\n * resolves to the registered format names instead of a project.json key.\n */\n\n/** Options for {@link resolveContextPointer}. */\nexport interface ResolveContextOptions {\n /** The project configuration object the pointer walks over. */\n projectConfig: Record<string, unknown>;\n /** Scope record supplying `{@param}` substitutions (e.g. the enclosing form value). */\n scope?: Record<string, unknown> | undefined;\n /** Registered formats backing the `$formats` virtual root. */\n formats?: { name: string }[] | undefined;\n}\n\n/** Matches a `{@param}` pointer segment, capturing the param name. */\nconst PARAM_SEGMENT = /^\\{@(\\w+)\\}$/;\n\n/**\n * Resolve a `#/$context/<seg>/<seg>…` pointer.\n *\n * - `{@param}` segments substitute from `opts.scope`; an unresolvable param yields `undefined`.\n * - The `$formats` virtual root returns the format names from `opts.formats`.\n * - Every other pointer is a plain JSON-pointer walk over `opts.projectConfig` — no key is\n * special-cased, so both legacy (`contentTypes`) and newer (`content`) sections resolve alike.\n *\n * @param {string} pointer\n * @param {ResolveContextOptions} opts\n * @returns {unknown} The resolved value, or `undefined` when the pointer does not resolve.\n */\nexport function resolveContextPointer(pointer: string, opts: ResolveContextOptions): unknown {\n if (!pointer.startsWith(\"#/$context/\")) {\n return undefined;\n }\n\n const segments: string[] = [];\n for (const raw of pointer.slice(\"#/$context/\".length).split(\"/\")) {\n const match = raw.match(PARAM_SEGMENT);\n if (match) {\n const value = opts.scope?.[match[1]!];\n if (typeof value !== \"string\" && typeof value !== \"number\") {\n return undefined;\n }\n const substituted = String(value);\n if (!substituted) {\n return undefined;\n }\n segments.push(substituted);\n } else {\n segments.push(raw);\n }\n }\n\n if (segments[0] === \"$formats\") {\n if (segments.length !== 1) {\n return undefined;\n }\n return (opts.formats ?? []).map((format) => format.name);\n }\n\n let node: unknown = opts.projectConfig;\n for (const segment of segments) {\n if (node === null || typeof node !== \"object\") {\n return undefined;\n }\n node = (node as Record<string, unknown>)[segment];\n }\n return node;\n}\n"
|
|
8
|
-
],
|
|
9
|
-
"mappings": "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",
|
|
10
|
-
"debugId": "C2BB6E7E97CDF54564756E2164756E21",
|
|
11
|
-
"names": []
|
|
12
|
-
}
|
|
@@ -1,469 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
errorMessage,
|
|
3
|
-
openModal,
|
|
4
|
-
showConfirmDialog,
|
|
5
|
-
statusMessage
|
|
6
|
-
} from "./studio-0xgs7xrs.js";
|
|
7
|
-
import {
|
|
8
|
-
html
|
|
9
|
-
} from "./studio-5x5774ak.js";
|
|
10
|
-
import {
|
|
11
|
-
getPlatform
|
|
12
|
-
} from "./studio-9smfzqhc.js";
|
|
13
|
-
|
|
14
|
-
// src/version.ts
|
|
15
|
-
var APP_NAME = "Jx Studio";
|
|
16
|
-
var VERSION = "2.0.1";
|
|
17
|
-
var BUILD_DATE = "2026-07-31T19:36:38.230Z";
|
|
18
|
-
var GIT_COMMIT = "7472825";
|
|
19
|
-
var LINKS = {
|
|
20
|
-
github: "https://github.com/jxsuite/jx",
|
|
21
|
-
docs: "https://github.com/jxsuite/jx#readme",
|
|
22
|
-
license: "https://github.com/jxsuite/jx/blob/main/LICENSE"
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
// src/ui/progress-modal.ts
|
|
26
|
-
function card(body) {
|
|
27
|
-
return html`
|
|
28
|
-
<sp-underlay open></sp-underlay>
|
|
29
|
-
<div
|
|
30
|
-
class="progress-modal"
|
|
31
|
-
role="dialog"
|
|
32
|
-
aria-live="polite"
|
|
33
|
-
style="position:fixed;inset:0;margin:auto;width:min(420px,calc(100vw - 48px));max-height:calc(100vh - 96px);height:max-content;background:var(--bg-panel,#1e1e1e);border:1px solid var(--border,#3a3a3a);border-radius:var(--spectrum-corner-radius-200,8px);padding:24px;display:flex;flex-direction:column;gap:16px;box-shadow:0 8px 32px rgba(0,0,0,.4)"
|
|
34
|
-
>
|
|
35
|
-
${body}
|
|
36
|
-
</div>
|
|
37
|
-
`;
|
|
38
|
-
}
|
|
39
|
-
function runningView(title, status) {
|
|
40
|
-
return card(html`
|
|
41
|
-
<div style="display:flex;align-items:center;gap:14px">
|
|
42
|
-
<sp-progress-circle indeterminate size="m" aria-label=${title}></sp-progress-circle>
|
|
43
|
-
<div style="display:flex;flex-direction:column;gap:2px">
|
|
44
|
-
<strong style="font-size:var(--spectrum-font-size-100, 14px)">${title}</strong>
|
|
45
|
-
${status ? html`<span
|
|
46
|
-
style="font-size:var(--spectrum-font-size-75, 12px);color:var(--fg-dim,#aaa)"
|
|
47
|
-
>${status}</span
|
|
48
|
-
>` : ""}
|
|
49
|
-
</div>
|
|
50
|
-
</div>
|
|
51
|
-
`);
|
|
52
|
-
}
|
|
53
|
-
function errorView(title, message, onClose) {
|
|
54
|
-
return card(html`
|
|
55
|
-
<div style="display:flex;flex-direction:column;gap:8px">
|
|
56
|
-
<strong style="font-size:var(--spectrum-font-size-100, 14px);color:var(--danger,#e34850)"
|
|
57
|
-
>${title} failed</strong
|
|
58
|
-
>
|
|
59
|
-
<pre
|
|
60
|
-
style="font-size:var(--spectrum-font-size-50, 11px);white-space:pre-wrap;overflow:auto;max-height:240px;margin:0;color:var(--fg-dim,#aaa)"
|
|
61
|
-
>
|
|
62
|
-
${message}
|
|
63
|
-
</pre>
|
|
64
|
-
</div>
|
|
65
|
-
<div style="display:flex;justify-content:flex-end">
|
|
66
|
-
<sp-button size="s" @click=${onClose}>Close</sp-button>
|
|
67
|
-
</div>
|
|
68
|
-
`);
|
|
69
|
-
}
|
|
70
|
-
function showProgressModal(opts) {
|
|
71
|
-
const modal = openModal(runningView(opts.title, opts.status ?? ""));
|
|
72
|
-
let closed = false;
|
|
73
|
-
const close = () => {
|
|
74
|
-
if (closed) {
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
closed = true;
|
|
78
|
-
modal.close();
|
|
79
|
-
};
|
|
80
|
-
return {
|
|
81
|
-
done: close,
|
|
82
|
-
fail(message) {
|
|
83
|
-
if (!closed) {
|
|
84
|
-
modal.update(errorView(opts.title, message || "Unknown error", close));
|
|
85
|
-
}
|
|
86
|
-
},
|
|
87
|
-
setStatus(text) {
|
|
88
|
-
if (!closed) {
|
|
89
|
-
modal.update(runningView(opts.title, text));
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// src/packages/semver.ts
|
|
96
|
-
function stripRange(range) {
|
|
97
|
-
const base = range.replace(/^[\^~>=<v\s]+/, "").trim();
|
|
98
|
-
return base.split(/\s+/)[0] ?? "";
|
|
99
|
-
}
|
|
100
|
-
function isComparable(spec) {
|
|
101
|
-
if (spec.includes(":")) {
|
|
102
|
-
return false;
|
|
103
|
-
}
|
|
104
|
-
return /^\d+\.\d+/.test(stripRange(spec));
|
|
105
|
-
}
|
|
106
|
-
function parts(version) {
|
|
107
|
-
const core = stripRange(version).split(/[-+]/)[0] ?? "";
|
|
108
|
-
const [major = 0, minor = 0, patch = 0] = core.split(".").map((n) => Math.trunc(Number(n)) || 0);
|
|
109
|
-
return [major, minor, patch];
|
|
110
|
-
}
|
|
111
|
-
function compareSemver(a, b) {
|
|
112
|
-
const pa = parts(a);
|
|
113
|
-
const pb = parts(b);
|
|
114
|
-
for (let i = 0;i < 3; i++) {
|
|
115
|
-
const da = pa[i] ?? 0;
|
|
116
|
-
const db = pb[i] ?? 0;
|
|
117
|
-
if (da !== db) {
|
|
118
|
-
return da < db ? -1 : 1;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
return 0;
|
|
122
|
-
}
|
|
123
|
-
function isUpgrade(current, latest) {
|
|
124
|
-
if (!isComparable(current) || !isComparable(latest)) {
|
|
125
|
-
return false;
|
|
126
|
-
}
|
|
127
|
-
return compareSemver(latest, current) > 0;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// src/packages/jxsuite-update.ts
|
|
131
|
-
var JXSUITE_PREFIX = "@jxsuite/";
|
|
132
|
-
async function checkJxsuiteUpdate() {
|
|
133
|
-
const target = VERSION;
|
|
134
|
-
if (!isComparable(target)) {
|
|
135
|
-
return null;
|
|
136
|
-
}
|
|
137
|
-
const platform = getPlatform();
|
|
138
|
-
let pkgs;
|
|
139
|
-
try {
|
|
140
|
-
pkgs = await platform.listPackages();
|
|
141
|
-
} catch {
|
|
142
|
-
return null;
|
|
143
|
-
}
|
|
144
|
-
const outdated = [];
|
|
145
|
-
for (const p of pkgs) {
|
|
146
|
-
if (!p.name.startsWith(JXSUITE_PREFIX) || !isComparable(p.version)) {
|
|
147
|
-
continue;
|
|
148
|
-
}
|
|
149
|
-
if (isUpgrade(p.version, target)) {
|
|
150
|
-
outdated.push({ current: p.version, dev: Boolean(p.dev), name: p.name });
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
return outdated.length > 0 ? { outdated, target } : null;
|
|
154
|
-
}
|
|
155
|
-
function dismissKey(root, target) {
|
|
156
|
-
return `jx:jxsuite-update-dismissed:${root}:${target}`;
|
|
157
|
-
}
|
|
158
|
-
function isDismissed(root, target) {
|
|
159
|
-
try {
|
|
160
|
-
return localStorage.getItem(dismissKey(root, target)) === "1";
|
|
161
|
-
} catch {
|
|
162
|
-
return false;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
function setDismissed(root, target) {
|
|
166
|
-
try {
|
|
167
|
-
localStorage.setItem(dismissKey(root, target), "1");
|
|
168
|
-
} catch {}
|
|
169
|
-
}
|
|
170
|
-
async function applyJxsuiteUpdate(outdated, target) {
|
|
171
|
-
const platform = getPlatform();
|
|
172
|
-
if (!platform.setPackageVersions) {
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
const progress = showProgressModal({
|
|
176
|
-
status: "Updating @jxsuite packages…",
|
|
177
|
-
title: "Updating dependencies"
|
|
178
|
-
});
|
|
179
|
-
try {
|
|
180
|
-
const result = await platform.setPackageVersions(outdated.map((p) => ({ dev: p.dev, name: p.name, version: `^${target}` })));
|
|
181
|
-
if (result.ok) {
|
|
182
|
-
progress.done();
|
|
183
|
-
statusMessage(`Updated ${outdated.length} @jxsuite package(s) to ${target}`);
|
|
184
|
-
} else {
|
|
185
|
-
progress.fail(result.log ?? "Update failed");
|
|
186
|
-
}
|
|
187
|
-
} catch (error) {
|
|
188
|
-
progress.fail(error instanceof Error ? error.message : String(error));
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
async function maybePromptJxsuiteUpdate(projectRoot) {
|
|
192
|
-
const platform = getPlatform();
|
|
193
|
-
if (!platform.setPackageVersions) {
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
const check = await checkJxsuiteUpdate();
|
|
197
|
-
if (!check || isDismissed(projectRoot, check.target)) {
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
const list = check.outdated.map((p) => `${p.name} ${p.current} → ^${check.target}`).join(`
|
|
201
|
-
`);
|
|
202
|
-
const confirmed = await showConfirmDialog("Update @jxsuite packages?", html`This project uses older @jxsuite packages. Update them to match Studio ${check.target}?
|
|
203
|
-
<br /><br /><span
|
|
204
|
-
style="font-size:var(--spectrum-font-size-75, 12px);color:var(--fg-dim);white-space:pre-line"
|
|
205
|
-
>${list}</span
|
|
206
|
-
>`, { cancelLabel: "Not now", confirmLabel: "Update" });
|
|
207
|
-
if (!confirmed) {
|
|
208
|
-
setDismissed(projectRoot, check.target);
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
await applyJxsuiteUpdate(check.outdated, check.target);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// src/packages/pull-package-sync.ts
|
|
215
|
-
var PKG_PATHS = ["package.json", "bun.lock", "bun.lockb"];
|
|
216
|
-
var UNTRACKED_STATUSES = new Set(["??", "U"]);
|
|
217
|
-
var MAX_CONFLICT_SCAN = 25;
|
|
218
|
-
var JXSUITE_PREFIX2 = "@jxsuite/";
|
|
219
|
-
function isRecord(value) {
|
|
220
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
221
|
-
}
|
|
222
|
-
function sortKeys(value) {
|
|
223
|
-
if (Array.isArray(value)) {
|
|
224
|
-
return value.map((entry) => sortKeys(entry));
|
|
225
|
-
}
|
|
226
|
-
if (isRecord(value)) {
|
|
227
|
-
const out = {};
|
|
228
|
-
for (const key of Object.keys(value).toSorted()) {
|
|
229
|
-
out[key] = sortKeys(value[key]);
|
|
230
|
-
}
|
|
231
|
-
return out;
|
|
232
|
-
}
|
|
233
|
-
return value;
|
|
234
|
-
}
|
|
235
|
-
function maskJxsuiteVersions(pkg) {
|
|
236
|
-
const out = { ...pkg };
|
|
237
|
-
for (const section of ["dependencies", "devDependencies"]) {
|
|
238
|
-
const deps = out[section];
|
|
239
|
-
if (!isRecord(deps)) {
|
|
240
|
-
continue;
|
|
241
|
-
}
|
|
242
|
-
const masked = { ...deps };
|
|
243
|
-
for (const name of Object.keys(masked)) {
|
|
244
|
-
if (name.startsWith(JXSUITE_PREFIX2)) {
|
|
245
|
-
masked[name] = "*";
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
out[section] = masked;
|
|
249
|
-
}
|
|
250
|
-
return out;
|
|
251
|
-
}
|
|
252
|
-
function isAutomatedPackageDiff(headText, workingText) {
|
|
253
|
-
if (headText === null || workingText === null) {
|
|
254
|
-
return false;
|
|
255
|
-
}
|
|
256
|
-
let head;
|
|
257
|
-
let working;
|
|
258
|
-
try {
|
|
259
|
-
head = JSON.parse(headText);
|
|
260
|
-
working = JSON.parse(workingText);
|
|
261
|
-
} catch {
|
|
262
|
-
return false;
|
|
263
|
-
}
|
|
264
|
-
if (!isRecord(head) || !isRecord(working)) {
|
|
265
|
-
return false;
|
|
266
|
-
}
|
|
267
|
-
return JSON.stringify(sortKeys(maskJxsuiteVersions(head))) === JSON.stringify(sortKeys(maskJxsuiteVersions(working)));
|
|
268
|
-
}
|
|
269
|
-
async function tryShow(path, ref) {
|
|
270
|
-
try {
|
|
271
|
-
return await getPlatform().gitShow({ path, ref });
|
|
272
|
-
} catch {
|
|
273
|
-
return null;
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
async function tryRead(path) {
|
|
277
|
-
try {
|
|
278
|
-
return await getPlatform().readFile(path);
|
|
279
|
-
} catch {
|
|
280
|
-
return null;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
async function planPackageDiscard(status) {
|
|
284
|
-
const discard = [];
|
|
285
|
-
const removeUntracked = [];
|
|
286
|
-
let automated = true;
|
|
287
|
-
for (const path of PKG_PATHS) {
|
|
288
|
-
const entries = status.files.filter((f) => f.path === path);
|
|
289
|
-
if (entries.length === 0) {
|
|
290
|
-
continue;
|
|
291
|
-
}
|
|
292
|
-
const upstream = await tryShow(path, "@{u}");
|
|
293
|
-
if (entries.every((f) => UNTRACKED_STATUSES.has(f.status))) {
|
|
294
|
-
if (upstream !== null) {
|
|
295
|
-
removeUntracked.push(path);
|
|
296
|
-
}
|
|
297
|
-
continue;
|
|
298
|
-
}
|
|
299
|
-
const head = await tryShow(path, "HEAD");
|
|
300
|
-
if (upstream === null || upstream === head) {
|
|
301
|
-
continue;
|
|
302
|
-
}
|
|
303
|
-
discard.push(path);
|
|
304
|
-
if (path === "package.json") {
|
|
305
|
-
automated &&= isAutomatedPackageDiff(head, await tryRead(path));
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
return { automated, discard, removeUntracked };
|
|
309
|
-
}
|
|
310
|
-
function planIsEmpty(plan) {
|
|
311
|
-
return plan.discard.length === 0 && plan.removeUntracked.length === 0;
|
|
312
|
-
}
|
|
313
|
-
async function otherFilesConflict(status) {
|
|
314
|
-
const paths = [
|
|
315
|
-
...new Set(status.files.filter((f) => !PKG_PATHS.includes(f.path)).map((f) => f.path))
|
|
316
|
-
];
|
|
317
|
-
if (paths.length > MAX_CONFLICT_SCAN) {
|
|
318
|
-
return true;
|
|
319
|
-
}
|
|
320
|
-
for (const path of paths) {
|
|
321
|
-
const upstream = await tryShow(path, "@{u}");
|
|
322
|
-
if (upstream !== null && upstream !== await tryShow(path, "HEAD")) {
|
|
323
|
-
return true;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
return false;
|
|
327
|
-
}
|
|
328
|
-
async function applyDiscard(plan) {
|
|
329
|
-
const platform = getPlatform();
|
|
330
|
-
if (plan.discard.length > 0) {
|
|
331
|
-
await platform.gitUnstage(plan.discard);
|
|
332
|
-
await platform.gitDiscard(plan.discard);
|
|
333
|
-
}
|
|
334
|
-
for (const path of plan.removeUntracked) {
|
|
335
|
-
await platform.deleteFile(path);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
async function syncPackagesAfterPull() {
|
|
339
|
-
const platform = getPlatform();
|
|
340
|
-
let check = null;
|
|
341
|
-
try {
|
|
342
|
-
check = await checkJxsuiteUpdate();
|
|
343
|
-
} catch {
|
|
344
|
-
check = null;
|
|
345
|
-
}
|
|
346
|
-
if (check && platform.setPackageVersions) {
|
|
347
|
-
await applyJxsuiteUpdate(check.outdated, check.target);
|
|
348
|
-
return;
|
|
349
|
-
}
|
|
350
|
-
if (!platform.installDependencies) {
|
|
351
|
-
return;
|
|
352
|
-
}
|
|
353
|
-
const progress = showProgressModal({
|
|
354
|
-
status: "Running bun install…",
|
|
355
|
-
title: "Syncing dependencies"
|
|
356
|
-
});
|
|
357
|
-
try {
|
|
358
|
-
const result = await platform.installDependencies();
|
|
359
|
-
if (result.ok) {
|
|
360
|
-
progress.done();
|
|
361
|
-
} else {
|
|
362
|
-
progress.fail(result.log ?? "bun install failed");
|
|
363
|
-
}
|
|
364
|
-
} catch (error) {
|
|
365
|
-
progress.fail(errorMessage(error));
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
async function discardPullAndSync(plan) {
|
|
369
|
-
const platform = getPlatform();
|
|
370
|
-
try {
|
|
371
|
-
await applyDiscard(plan);
|
|
372
|
-
} catch (error) {
|
|
373
|
-
throw new Error(`Could not reset local package files: ${errorMessage(error)}`, {
|
|
374
|
-
cause: error
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
try {
|
|
378
|
-
await platform.gitPull();
|
|
379
|
-
} catch (error) {
|
|
380
|
-
await syncPackagesAfterPull();
|
|
381
|
-
throw error;
|
|
382
|
-
}
|
|
383
|
-
statusMessage("Local package updates were superseded by pulled changes");
|
|
384
|
-
await syncPackagesAfterPull();
|
|
385
|
-
}
|
|
386
|
-
async function recoverAfterFailedPull(original) {
|
|
387
|
-
const platform = getPlatform();
|
|
388
|
-
let status;
|
|
389
|
-
try {
|
|
390
|
-
status = await platform.gitStatus();
|
|
391
|
-
} catch {
|
|
392
|
-
throw original;
|
|
393
|
-
}
|
|
394
|
-
if (!(status.behind > 0)) {
|
|
395
|
-
throw original;
|
|
396
|
-
}
|
|
397
|
-
const plan = await planPackageDiscard(status);
|
|
398
|
-
if (planIsEmpty(plan) || await otherFilesConflict(status)) {
|
|
399
|
-
throw original;
|
|
400
|
-
}
|
|
401
|
-
if (!plan.automated) {
|
|
402
|
-
const confirmed = await showConfirmDialog("Discard local package changes?", "package.json / bun.lock have local edits that conflict with incoming changes. Discard them, pull, and re-sync packages?", { confirmLabel: "Discard and pull", destructive: true });
|
|
403
|
-
if (!confirmed) {
|
|
404
|
-
throw original;
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
await discardPullAndSync(plan);
|
|
408
|
-
}
|
|
409
|
-
async function snapshotPackageFiles() {
|
|
410
|
-
let present;
|
|
411
|
-
try {
|
|
412
|
-
const entries = await getPlatform().listDirectory("");
|
|
413
|
-
present = new Set(entries.filter((e) => e.type === "file").map((e) => e.name));
|
|
414
|
-
} catch {
|
|
415
|
-
present = new Set(PKG_PATHS);
|
|
416
|
-
}
|
|
417
|
-
return Promise.all(PKG_PATHS.map((path) => present.has(path) ? tryRead(path) : Promise.resolve(null)));
|
|
418
|
-
}
|
|
419
|
-
async function pullWithPackageSync() {
|
|
420
|
-
const platform = getPlatform();
|
|
421
|
-
const before = await snapshotPackageFiles();
|
|
422
|
-
let status = null;
|
|
423
|
-
try {
|
|
424
|
-
await platform.gitFetch();
|
|
425
|
-
status = await platform.gitStatus();
|
|
426
|
-
} catch {
|
|
427
|
-
status = null;
|
|
428
|
-
}
|
|
429
|
-
if (status && status.behind > 0) {
|
|
430
|
-
const plan = await planPackageDiscard(status);
|
|
431
|
-
if (!planIsEmpty(plan) && plan.automated) {
|
|
432
|
-
await discardPullAndSync(plan);
|
|
433
|
-
return;
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
try {
|
|
437
|
-
await platform.gitPull();
|
|
438
|
-
} catch (error) {
|
|
439
|
-
await recoverAfterFailedPull(error);
|
|
440
|
-
return;
|
|
441
|
-
}
|
|
442
|
-
const after = await snapshotPackageFiles();
|
|
443
|
-
if (before.some((content, i) => content !== after[i])) {
|
|
444
|
-
await syncPackagesAfterPull();
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
async function autoSyncProjectOnOpen() {
|
|
448
|
-
const platform = getPlatform();
|
|
449
|
-
let status;
|
|
450
|
-
try {
|
|
451
|
-
status = await platform.gitStatus();
|
|
452
|
-
} catch {
|
|
453
|
-
return;
|
|
454
|
-
}
|
|
455
|
-
if (!status?.isRepo || (status.remotes?.length ?? 0) === 0) {
|
|
456
|
-
return;
|
|
457
|
-
}
|
|
458
|
-
statusMessage("Syncing project…");
|
|
459
|
-
try {
|
|
460
|
-
await pullWithPackageSync();
|
|
461
|
-
} catch (error) {
|
|
462
|
-
statusMessage(`Sync skipped: ${errorMessage(error)}`);
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
export { showProgressModal, APP_NAME, VERSION, BUILD_DATE, GIT_COMMIT, LINKS, stripRange, isComparable, isUpgrade, maybePromptJxsuiteUpdate, pullWithPackageSync, autoSyncProjectOnOpen };
|
|
467
|
-
|
|
468
|
-
//# debugId=88C48B6EB01A9FE764756E2164756E21
|
|
469
|
-
//# sourceMappingURL=studio-zp7jncs8.js.map
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/version.ts", "../src/ui/progress-modal.ts", "../src/packages/semver.ts", "../src/packages/jxsuite-update.ts", "../src/packages/pull-package-sync.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/**\n * Version.ts — build-time metadata for the About screen.\n *\n * The constants below are replaced at bundle time by scripts/build.ts via Bun's `define`. They're\n * read through `typeof` guards so the module stays safe under `bun test`, where the defines are\n * absent and the fallbacks apply.\n */\n\ndeclare const __JX_VERSION__: string;\ndeclare const __JX_BUILD_DATE__: string;\ndeclare const __JX_GIT_COMMIT__: string;\n\nexport const APP_NAME = \"Jx Studio\";\n\n/*\n * The `typeof` guards are deliberate: the identifiers are `declare const` placeholders that\n * only exist after Bun's build-time `define` substitution. Under `bun test` they're never\n * bound, so a direct `=== undefined` comparison would throw a ReferenceError.\n */\n\n// oxlint-disable-next-line unicorn/no-typeof-undefined -- guards undeclared build-time define\nexport const VERSION = typeof __JX_VERSION__ === \"undefined\" ? \"dev\" : __JX_VERSION__;\n\n// oxlint-disable-next-line unicorn/no-typeof-undefined -- guards undeclared build-time define\nexport const BUILD_DATE = typeof __JX_BUILD_DATE__ === \"undefined\" ? \"\" : __JX_BUILD_DATE__;\n\n// oxlint-disable-next-line unicorn/no-typeof-undefined -- guards undeclared build-time define\nexport const GIT_COMMIT = typeof __JX_GIT_COMMIT__ === \"undefined\" ? \"unknown\" : __JX_GIT_COMMIT__;\n\nexport const LINKS = {\n github: \"https://github.com/jxsuite/jx\",\n docs: \"https://github.com/jxsuite/jx#readme\",\n license: \"https://github.com/jxsuite/jx/blob/main/LICENSE\",\n} as const;\n",
|
|
6
|
-
"/// <reference lib=\"dom\" />\n/**\n * A blocking progress modal for long-running package operations (bun install / dependency updates).\n * Shows an indeterminate spinner with a status line; on failure it swaps to an error view with the\n * captured log and a Close button. Built on the persistent-modal layer helper.\n */\n\nimport { html } from \"lit-html\";\nimport type { TemplateResult } from \"lit-html\";\nimport { openModal } from \"./layers\";\n\nexport interface ProgressModalHandle {\n /** Update the status line shown under the title. */\n setStatus: (text: string) => void;\n /** Replace the spinner with an error view (log shown) that the user dismisses. */\n fail: (message: string) => void;\n /** Close the modal (success path). */\n done: () => void;\n}\n\nfunction card(body: TemplateResult): TemplateResult {\n return html`\n <sp-underlay open></sp-underlay>\n <div\n class=\"progress-modal\"\n role=\"dialog\"\n aria-live=\"polite\"\n style=\"position:fixed;inset:0;margin:auto;width:min(420px,calc(100vw - 48px));max-height:calc(100vh - 96px);height:max-content;background:var(--bg-panel,#1e1e1e);border:1px solid var(--border,#3a3a3a);border-radius:var(--spectrum-corner-radius-200,8px);padding:24px;display:flex;flex-direction:column;gap:16px;box-shadow:0 8px 32px rgba(0,0,0,.4)\"\n >\n ${body}\n </div>\n `;\n}\n\nfunction runningView(title: string, status: string): TemplateResult {\n return card(html`\n <div style=\"display:flex;align-items:center;gap:14px\">\n <sp-progress-circle indeterminate size=\"m\" aria-label=${title}></sp-progress-circle>\n <div style=\"display:flex;flex-direction:column;gap:2px\">\n <strong style=\"font-size:var(--spectrum-font-size-100, 14px)\">${title}</strong>\n ${\n status\n ? html`<span\n style=\"font-size:var(--spectrum-font-size-75, 12px);color:var(--fg-dim,#aaa)\"\n >${status}</span\n >`\n : \"\"\n }\n </div>\n </div>\n `);\n}\n\nfunction errorView(title: string, message: string, onClose: () => void): TemplateResult {\n return card(html`\n <div style=\"display:flex;flex-direction:column;gap:8px\">\n <strong style=\"font-size:var(--spectrum-font-size-100, 14px);color:var(--danger,#e34850)\"\n >${title} failed</strong\n >\n <pre\n style=\"font-size:var(--spectrum-font-size-50, 11px);white-space:pre-wrap;overflow:auto;max-height:240px;margin:0;color:var(--fg-dim,#aaa)\"\n >\n ${message}\n </pre>\n </div>\n <div style=\"display:flex;justify-content:flex-end\">\n <sp-button size=\"s\" @click=${onClose}>Close</sp-button>\n </div>\n `);\n}\n\nexport function showProgressModal(opts: { title: string; status?: string }): ProgressModalHandle {\n const modal = openModal(runningView(opts.title, opts.status ?? \"\"));\n let closed = false;\n\n const close = () => {\n if (closed) {\n return;\n }\n closed = true;\n modal.close();\n };\n\n return {\n done: close,\n fail(message: string) {\n if (!closed) {\n modal.update(errorView(opts.title, message || \"Unknown error\", close));\n }\n },\n setStatus(text: string) {\n if (!closed) {\n modal.update(runningView(opts.title, text));\n }\n },\n };\n}\n",
|
|
7
|
-
"/**\n * Minimal semver helpers for comparing dependency versions in the UI. Deliberately tiny — we only\n * need range stripping and ordering of `x.y.z` triples, not full semver range satisfaction, so we\n * avoid pulling in a dependency.\n */\n\n/** Strip a range prefix to its base version: \"^0.19.0\" → \"0.19.0\", \"~1.2.3\" → \"1.2.3\". */\nexport function stripRange(range: string): string {\n const base = range.replace(/^[\\^~>=<v\\s]+/, \"\").trim();\n return base.split(/\\s+/)[0] ?? \"\";\n}\n\n/**\n * Whether a spec is a comparable registry semver (a plain `x.y.z` range), as opposed to\n * `workspace:`, `file:`, `link:`, a git/URL spec, or a wildcard like `*`/`latest`.\n */\nexport function isComparable(spec: string): boolean {\n if (spec.includes(\":\")) {\n return false;\n }\n return /^\\d+\\.\\d+/.test(stripRange(spec));\n}\n\n/** Parse a version into numeric [major, minor, patch], ignoring any pre-release/build suffix. */\nfunction parts(version: string): [number, number, number] {\n const core = stripRange(version).split(/[-+]/)[0] ?? \"\";\n const [major = 0, minor = 0, patch = 0] = core.split(\".\").map((n) => Math.trunc(Number(n)) || 0);\n return [major, minor, patch];\n}\n\n/**\n * Compare two versions (range prefixes tolerated). Returns -1 if a < b, 1 if a > b, 0 if equal.\n * Pre-release/build metadata is ignored.\n */\nexport function compareSemver(a: string, b: string): number {\n const pa = parts(a);\n const pb = parts(b);\n for (let i = 0; i < 3; i++) {\n const da = pa[i] ?? 0;\n const db = pb[i] ?? 0;\n if (da !== db) {\n return da < db ? -1 : 1;\n }\n }\n return 0;\n}\n\n/** Whether `latest` is strictly newer than the base version of `current` (both comparable). */\nexport function isUpgrade(current: string, latest: string): boolean {\n if (!isComparable(current) || !isComparable(latest)) {\n return false;\n }\n return compareSemver(latest, current) > 0;\n}\n",
|
|
8
|
-
"/// <reference lib=\"dom\" />\n/**\n * On project open, compare the project's `@jxsuite/*` dependency ranges to the version this Studio\n * build embeds (`VERSION`). If the project is behind, prompt the user to bump them to match and —\n * on confirm — rewrite the ranges and reinstall. The target is the embedded version (not npm\n * latest) so a project always lines up with the runtime/compiler the running app actually uses.\n */\n\nimport { html } from \"lit-html\";\nimport { getPlatform } from \"../platform\";\nimport { VERSION } from \"../version\";\nimport { showConfirmDialog } from \"../ui/layers\";\nimport { showProgressModal } from \"../ui/progress-modal\";\nimport { statusMessage } from \"../panels/statusbar\";\nimport { isComparable, isUpgrade } from \"./semver\";\nimport type { PackageInfo } from \"../types\";\n\nconst JXSUITE_PREFIX = \"@jxsuite/\";\n\nexport interface JxsuiteUpdate {\n name: string;\n current: string;\n dev: boolean;\n}\n\n/**\n * Compare the project's @jxsuite/* deps to the embedded version. Returns the packages behind the\n * target plus the target version, or null when there's nothing to do (dev build, no project, or all\n * already current/ahead).\n */\nexport async function checkJxsuiteUpdate(): Promise<{\n target: string;\n outdated: JxsuiteUpdate[];\n} | null> {\n const target = VERSION;\n if (!isComparable(target)) {\n return null; // \"dev\" / non-semver build — no reliable target\n }\n const platform = getPlatform();\n let pkgs: PackageInfo[];\n try {\n pkgs = await platform.listPackages();\n } catch {\n return null;\n }\n const outdated: JxsuiteUpdate[] = [];\n for (const p of pkgs) {\n if (!p.name.startsWith(JXSUITE_PREFIX) || !isComparable(p.version)) {\n continue;\n }\n if (isUpgrade(p.version, target)) {\n outdated.push({ current: p.version, dev: Boolean(p.dev), name: p.name });\n }\n }\n return outdated.length > 0 ? { outdated, target } : null;\n}\n\nfunction dismissKey(root: string, target: string): string {\n return `jx:jxsuite-update-dismissed:${root}:${target}`;\n}\n\nfunction isDismissed(root: string, target: string): boolean {\n try {\n return localStorage.getItem(dismissKey(root, target)) === \"1\";\n } catch {\n return false;\n }\n}\n\nfunction setDismissed(root: string, target: string): void {\n try {\n localStorage.setItem(dismissKey(root, target), \"1\");\n } catch {\n /* Ignore storage errors */\n }\n}\n\n/** Apply a set of @jxsuite bumps to `^target` and reinstall, behind a progress modal. */\nexport async function applyJxsuiteUpdate(outdated: JxsuiteUpdate[], target: string): Promise<void> {\n const platform = getPlatform();\n if (!platform.setPackageVersions) {\n return;\n }\n const progress = showProgressModal({\n status: \"Updating @jxsuite packages…\",\n title: \"Updating dependencies\",\n });\n try {\n const result = await platform.setPackageVersions(\n outdated.map((p) => ({ dev: p.dev, name: p.name, version: `^${target}` })),\n );\n if (result.ok) {\n progress.done();\n statusMessage(`Updated ${outdated.length} @jxsuite package(s) to ${target}`);\n } else {\n progress.fail(result.log ?? \"Update failed\");\n }\n } catch (error) {\n progress.fail(error instanceof Error ? error.message : String(error));\n }\n}\n\n/**\n * Prompt to update @jxsuite packages on open. Skips when there's nothing to do or the user already\n * declined this exact target for this project (remembered in localStorage).\n */\nexport async function maybePromptJxsuiteUpdate(projectRoot: string): Promise<void> {\n const platform = getPlatform();\n if (!platform.setPackageVersions) {\n return;\n }\n const check = await checkJxsuiteUpdate();\n if (!check || isDismissed(projectRoot, check.target)) {\n return;\n }\n const list = check.outdated.map((p) => `${p.name} ${p.current} → ^${check.target}`).join(\"\\n\");\n const confirmed = await showConfirmDialog(\n \"Update @jxsuite packages?\",\n html`This project uses older @jxsuite packages. Update them to match Studio ${check.target}?\n <br /><br /><span\n style=\"font-size:var(--spectrum-font-size-75, 12px);color:var(--fg-dim);white-space:pre-line\"\n >${list}</span\n >`,\n { cancelLabel: \"Not now\", confirmLabel: \"Update\" },\n );\n if (!confirmed) {\n setDismissed(projectRoot, check.target);\n return;\n }\n await applyJxsuiteUpdate(check.outdated, check.target);\n}\n",
|
|
9
|
-
"/// <reference lib=\"dom\" />\n/**\n * Pull orchestration that keeps project sync from being blocked by Studio's own automated package\n * updates. The on-open @jxsuite update rewrites package.json and bun.lock without committing, so a\n * teammate pushing the same update makes a later `git pull` refuse to merge. Since those local\n * changes are machine-generated and reproducible, we discard them, pull, and re-run the package\n * sync (re-apply the update if the pulled project is still behind, or `bun install` if the pull\n * brought it). Detection is state-based (git status + content comparison against `@{u}`), never git\n * stderr parsing, so it works identically across backends and locales.\n */\n\nimport { errorMessage } from \"@jxsuite/schema/parse\";\nimport { getPlatform } from \"../platform\";\nimport { showConfirmDialog } from \"../ui/layers\";\nimport { showProgressModal } from \"../ui/progress-modal\";\nimport { statusMessage } from \"../panels/statusbar\";\nimport { applyJxsuiteUpdate, checkJxsuiteUpdate } from \"./jxsuite-update\";\nimport type { GitStatusResult } from \"../types\";\n\nconst PKG_PATHS = [\"package.json\", \"bun.lock\", \"bun.lockb\"];\n\n/** Untracked markers across backends: desktop porcelain v1 emits \"??\", server porcelain v2 \"U\". */\nconst UNTRACKED_STATUSES = new Set([\"??\", \"U\"]);\n\n/** Above this many dirty files, skip the per-file upstream comparison and leave the error as-is. */\nconst MAX_CONFLICT_SCAN = 25;\n\nconst JXSUITE_PREFIX = \"@jxsuite/\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction sortKeys(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map((entry) => sortKeys(entry));\n }\n if (isRecord(value)) {\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(value).toSorted()) {\n out[key] = sortKeys(value[key]);\n }\n return out;\n }\n return value;\n}\n\n/** Replace every @jxsuite/* version in dependencies/devDependencies so they compare equal. */\nfunction maskJxsuiteVersions(pkg: Record<string, unknown>): Record<string, unknown> {\n const out = { ...pkg };\n for (const section of [\"dependencies\", \"devDependencies\"]) {\n const deps = out[section];\n if (!isRecord(deps)) {\n continue;\n }\n const masked = { ...deps };\n for (const name of Object.keys(masked)) {\n if (name.startsWith(JXSUITE_PREFIX)) {\n masked[name] = \"*\";\n }\n }\n out[section] = masked;\n }\n return out;\n}\n\n/**\n * True when the working package.json differs from the HEAD copy only in the version strings of\n * jxsuite-scoped entries — i.e. exactly what Studio's automated update writes. Added/removed deps\n * or any other edit means a human touched the file.\n */\nexport function isAutomatedPackageDiff(\n headText: string | null,\n workingText: string | null,\n): boolean {\n if (headText === null || workingText === null) {\n return false;\n }\n let head: unknown;\n let working: unknown;\n try {\n head = JSON.parse(headText);\n working = JSON.parse(workingText);\n } catch {\n return false;\n }\n if (!isRecord(head) || !isRecord(working)) {\n return false;\n }\n return (\n JSON.stringify(sortKeys(maskJxsuiteVersions(head))) ===\n JSON.stringify(sortKeys(maskJxsuiteVersions(working)))\n );\n}\n\nasync function tryShow(path: string, ref: string): Promise<string | null> {\n try {\n return await getPlatform().gitShow({ path, ref });\n } catch {\n return null;\n }\n}\n\nasync function tryRead(path: string): Promise<string | null> {\n try {\n return await getPlatform().readFile(path);\n } catch {\n return null;\n }\n}\n\nexport interface PackagePullPlan {\n /** Tracked dirty package files whose upstream (@{u}) content differs from HEAD. */\n discard: string[];\n /** Untracked package files that exist at @{u} (\"untracked would be overwritten\" case). */\n removeUntracked: string[];\n /** Whether the package.json working copy diverges from HEAD only by automated @jxsuite bumps. */\n automated: boolean;\n}\n\n/**\n * Decide which local package files stand in the way of a merge. Only files the upstream actually\n * changed can block the pull, so files whose @{u} content matches HEAD are left alone.\n */\nexport async function planPackageDiscard(status: GitStatusResult): Promise<PackagePullPlan> {\n const discard: string[] = [];\n const removeUntracked: string[] = [];\n let automated = true;\n for (const path of PKG_PATHS) {\n const entries = status.files.filter((f) => f.path === path);\n if (entries.length === 0) {\n continue;\n }\n const upstream = await tryShow(path, \"@{u}\");\n if (entries.every((f) => UNTRACKED_STATUSES.has(f.status))) {\n if (upstream !== null) {\n removeUntracked.push(path);\n }\n continue;\n }\n const head = await tryShow(path, \"HEAD\");\n if (upstream === null || upstream === head) {\n continue;\n }\n discard.push(path);\n if (path === \"package.json\") {\n automated &&= isAutomatedPackageDiff(head, await tryRead(path));\n }\n }\n return { automated, discard, removeUntracked };\n}\n\nfunction planIsEmpty(plan: PackagePullPlan): boolean {\n return plan.discard.length === 0 && plan.removeUntracked.length === 0;\n}\n\n/** True when a dirty non-package file also differs upstream — recovery can't unblock that pull. */\nasync function otherFilesConflict(status: GitStatusResult): Promise<boolean> {\n const paths = [\n ...new Set(status.files.filter((f) => !PKG_PATHS.includes(f.path)).map((f) => f.path)),\n ];\n if (paths.length > MAX_CONFLICT_SCAN) {\n return true;\n }\n for (const path of paths) {\n const upstream = await tryShow(path, \"@{u}\");\n if (upstream !== null && upstream !== (await tryShow(path, \"HEAD\"))) {\n return true;\n }\n }\n return false;\n}\n\nasync function applyDiscard(plan: PackagePullPlan): Promise<void> {\n const platform = getPlatform();\n if (plan.discard.length > 0) {\n // Unstage unconditionally: desktop porcelain v1 doesn't report a staged flag.\n // Restoring an unstaged tracked file is a no-op.\n await platform.gitUnstage(plan.discard);\n await platform.gitDiscard(plan.discard);\n }\n for (const path of plan.removeUntracked) {\n await platform.deleteFile(path);\n }\n}\n\n/**\n * Bring packages back in line after a pull that touched (or followed a discard of) package files:\n * re-apply the @jxsuite update if the pulled project is still behind, otherwise `bun install` so\n * node_modules matches the pulled lockfile. Never throws — a successful pull must not turn into an\n * error banner; failures surface through the progress modal.\n */\nasync function syncPackagesAfterPull(): Promise<void> {\n const platform = getPlatform();\n let check: Awaited<ReturnType<typeof checkJxsuiteUpdate>> = null;\n try {\n check = await checkJxsuiteUpdate();\n } catch {\n check = null;\n }\n if (check && platform.setPackageVersions) {\n // No re-prompt: the discarded local changes came from an update the user already accepted.\n await applyJxsuiteUpdate(check.outdated, check.target);\n return;\n }\n if (!platform.installDependencies) {\n return;\n }\n const progress = showProgressModal({\n status: \"Running bun install…\",\n title: \"Syncing dependencies\",\n });\n try {\n const result = await platform.installDependencies();\n if (result.ok) {\n progress.done();\n } else {\n progress.fail(result.log ?? \"bun install failed\");\n }\n } catch (error) {\n progress.fail(errorMessage(error));\n }\n}\n\n/**\n * Discard per plan, pull, and re-sync. A discard is always followed by a package re-sync — even\n * when the pull fails — so the project is never stranded without the update it had before.\n */\nasync function discardPullAndSync(plan: PackagePullPlan): Promise<void> {\n const platform = getPlatform();\n try {\n await applyDiscard(plan);\n } catch (error) {\n throw new Error(`Could not reset local package files: ${errorMessage(error)}`, {\n cause: error,\n });\n }\n try {\n await platform.gitPull();\n } catch (error) {\n await syncPackagesAfterPull();\n throw error;\n }\n statusMessage(\"Local package updates were superseded by pulled changes\");\n await syncPackagesAfterPull();\n}\n\nasync function recoverAfterFailedPull(original: unknown): Promise<void> {\n const platform = getPlatform();\n let status: GitStatusResult;\n try {\n status = await platform.gitStatus();\n } catch {\n throw original;\n }\n if (!(status.behind > 0)) {\n throw original;\n }\n const plan = await planPackageDiscard(status);\n if (planIsEmpty(plan) || (await otherFilesConflict(status))) {\n throw original;\n }\n if (!plan.automated) {\n const confirmed = await showConfirmDialog(\n \"Discard local package changes?\",\n \"package.json / bun.lock have local edits that conflict with incoming changes. Discard them, pull, and re-sync packages?\",\n { confirmLabel: \"Discard and pull\", destructive: true },\n );\n if (!confirmed) {\n throw original;\n }\n }\n await discardPullAndSync(plan);\n}\n\n/**\n * Snapshot the package files (aligned to PKG_PATHS). Lists the root once and reads only the files\n * that exist, so absent lockfiles (cloud projects don't commit one) never trigger a console 404\n * from a blind read. Listing failure falls back to probing all paths.\n */\n/**\n * Snapshot the package files (aligned to PKG_PATHS). Lists the root once and reads only the files\n * that exist, so absent lockfiles (cloud projects don't commit one) never trigger a console 404\n * from a blind read. Listing failure falls back to probing all paths.\n */\nasync function snapshotPackageFiles(): Promise<(string | null)[]> {\n let present: Set<string>;\n try {\n const entries = await getPlatform().listDirectory(\"\");\n present = new Set(entries.filter((e) => e.type === \"file\").map((e) => e.name));\n } catch {\n present = new Set(PKG_PATHS);\n }\n return Promise.all(\n PKG_PATHS.map((path) => (present.has(path) ? tryRead(path) : Promise.resolve(null))),\n );\n}\n\n/**\n * Pull with automatic recovery from conflicts caused by Studio's own package updates. Throws only\n * when the pull genuinely fails for reasons recovery can't (or shouldn't) fix.\n */\nexport async function pullWithPackageSync(): Promise<void> {\n const platform = getPlatform();\n const before = await snapshotPackageFiles();\n\n // Preemptive: fetch so `behind` is current, then reset automated package edits that would\n // Block the merge — manual package.json edits fall through to the plain pull + confirm path.\n let status: GitStatusResult | null = null;\n try {\n await platform.gitFetch();\n status = await platform.gitStatus();\n } catch {\n status = null; // Offline or status failure — the plain pull will report the real error\n }\n if (status && status.behind > 0) {\n const plan = await planPackageDiscard(status);\n if (!planIsEmpty(plan) && plan.automated) {\n await discardPullAndSync(plan);\n return;\n }\n }\n\n try {\n await platform.gitPull();\n } catch (error) {\n await recoverAfterFailedPull(error);\n return;\n }\n const after = await snapshotPackageFiles();\n if (before.some((content, i) => content !== after[i])) {\n await syncPackagesAfterPull();\n }\n}\n\n/**\n * Pull remote changes as soon as a project opens, ahead of the install check and update prompt, so\n * a session starts from the current remote state. Never throws and never blocks the open — failures\n * (offline, no upstream, unrelated conflicts) surface as a status message only.\n */\nexport async function autoSyncProjectOnOpen(): Promise<void> {\n const platform = getPlatform();\n let status: GitStatusResult;\n try {\n status = await platform.gitStatus();\n } catch {\n return;\n }\n if (!status?.isRepo || (status.remotes?.length ?? 0) === 0) {\n return;\n }\n statusMessage(\"Syncing project…\");\n try {\n await pullWithPackageSync();\n } catch (error) {\n statusMessage(`Sync skipped: ${errorMessage(error)}`);\n }\n}\n"
|
|
10
|
-
],
|
|
11
|
-
"mappings": "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",
|
|
12
|
-
"debugId": "88C48B6EB01A9FE764756E2164756E21",
|
|
13
|
-
"names": []
|
|
14
|
-
}
|