@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,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clock — the one seam every _relative_ time in Studio reads "now" through.
|
|
3
|
+
*
|
|
4
|
+
* Four surfaces render a duration rather than an instant: the Source Control panel's commit ages
|
|
5
|
+
* and "last refreshed", the Start pane's "last opened", the chat session list's row times, and the
|
|
6
|
+
* recents list those two read from. Each of them called `Date.now()` inline, which had two costs:
|
|
7
|
+
*
|
|
8
|
+
* 1. **They were untestable.** A formatter that reads the wall clock can only be asserted against an
|
|
9
|
+
* offset from the real present, so "yesterday" and "over a year ago" were never covered.
|
|
10
|
+
* 2. **They drift.** Two captures of the same state minutes apart legitimately read `01:59 PM` and
|
|
11
|
+
* `02:04 PM` (UX-REDESIGN-PLAN §13.4 measured exactly that on the git-panel shot).
|
|
12
|
+
*
|
|
13
|
+
* This is deliberately NOT a global `Date.now` override. Monaco, every `setTimeout`, the collab
|
|
14
|
+
* clock and the transaction log all read the real clock and must keep reading it — pinning time for
|
|
15
|
+
* the whole realm hangs the editor. Four imports, four honest readers.
|
|
16
|
+
*
|
|
17
|
+
* `pinClock` is also what makes session restore's "last opened" honest: the value written is the
|
|
18
|
+
* value the formatter reads back.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/** Epoch milliseconds the clock is pinned to, or `null` while it follows the real clock. */
|
|
22
|
+
let _pinned: number | null = null;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The current time in epoch milliseconds — pinned when {@link pinClock} has been called, otherwise
|
|
26
|
+
* the wall clock.
|
|
27
|
+
*
|
|
28
|
+
* Frozen rather than offset while pinned: a shot, a test and a bug report all want the SAME answer
|
|
29
|
+
* on the tenth read as on the first, and a ticking pin reintroduces exactly the drift it exists to
|
|
30
|
+
* remove.
|
|
31
|
+
*/
|
|
32
|
+
export function now(): number {
|
|
33
|
+
return _pinned ?? Date.now();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Pin the clock to a fixed instant. Accepts epoch milliseconds, a `Date`, or anything `Date` parses
|
|
38
|
+
* (the `2026-01-15T09:30:00Z` an `open.clock` field carries).
|
|
39
|
+
*
|
|
40
|
+
* @returns The pinned instant, in epoch milliseconds.
|
|
41
|
+
* @throws {TypeError} When the value cannot be read as a time — a silently-ignored pin would
|
|
42
|
+
* photograph the wall clock and the capture would be accepted.
|
|
43
|
+
*/
|
|
44
|
+
export function pinClock(at: number | string | Date): number {
|
|
45
|
+
const ms = at instanceof Date ? at.getTime() : typeof at === "number" ? at : Date.parse(at);
|
|
46
|
+
if (!Number.isFinite(ms)) {
|
|
47
|
+
throw new TypeError(`clock: cannot pin to ${JSON.stringify(at)}`);
|
|
48
|
+
}
|
|
49
|
+
_pinned = ms;
|
|
50
|
+
return ms;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Release the pin; {@link now} follows the wall clock again. */
|
|
54
|
+
export function unpinClock(): void {
|
|
55
|
+
_pinned = null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Whether the clock is currently pinned. Read by `probe.state()` and by the tests. */
|
|
59
|
+
export function isClockPinned(): boolean {
|
|
60
|
+
return _pinned !== null;
|
|
61
|
+
}
|
|
@@ -12,11 +12,13 @@
|
|
|
12
12
|
import { createChatState, createProxyStreamingClient, createToolRegistry } from "@jxsuite/ai";
|
|
13
13
|
import type { ProjectConfig } from "@jxsuite/schema/types";
|
|
14
14
|
import { getPlatform } from "../platform";
|
|
15
|
-
import { activeTab,
|
|
15
|
+
import { activeTab, workspace } from "../workspace/workspace";
|
|
16
16
|
import { toRaw } from "../reactivity";
|
|
17
|
-
import { projectState
|
|
17
|
+
import { projectState } from "../store";
|
|
18
|
+
import { adoptProjectConfig } from "../tabs/project-config";
|
|
18
19
|
import type { Tab } from "../tabs/tab";
|
|
19
20
|
import { componentRegistry } from "../files/components";
|
|
21
|
+
import { activeRegistry } from "../commands/active-registry";
|
|
20
22
|
import { registerAiTools } from "./ai-tools";
|
|
21
23
|
import { registerProjectTools } from "./ai-project-tools";
|
|
22
24
|
import { createGatedToolRegistry } from "./gated-registry";
|
|
@@ -104,11 +106,12 @@ export function createDocumentAssistant() {
|
|
|
104
106
|
sessionStore.moveSession("", root, sessionId);
|
|
105
107
|
}
|
|
106
108
|
},
|
|
107
|
-
onProjectConfigWritten: (config: ProjectConfig) => {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
onProjectConfigWritten: async (config: ProjectConfig) => {
|
|
110
|
+
/* Into the configuration document, not beside it. This used to assign a fresh object to
|
|
111
|
+
`projectState.projectConfig`, leaving the document holding the previous configuration —
|
|
112
|
+
and the next settings commit wrote that stale document back over the assistant's file.
|
|
113
|
+
`adoptProjectConfig` is the one door for a config that reached disk another way. */
|
|
114
|
+
await adoptProjectConfig(config);
|
|
112
115
|
/* An `extensions` edit changes what the generated entry documents compose, and the backends
|
|
113
116
|
regenerate them from project.json on demand — so without this the editor and the assistant
|
|
114
117
|
both keep judging by the PREVIOUS project's schemas until the window reopens. */
|
|
@@ -125,12 +128,37 @@ export function createDocumentAssistant() {
|
|
|
125
128
|
"no-project": "no project to be open (it bootstraps one)",
|
|
126
129
|
project: "an open project",
|
|
127
130
|
document: "an open document (use open_document first)",
|
|
131
|
+
"document-tree":
|
|
132
|
+
"an open document whose element tree the canvas is editing — Project Settings and the " +
|
|
133
|
+
"grid editors are documents, but not trees to restructure",
|
|
128
134
|
} as const;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* The HUMAN's own gate, read rather than reimplemented.
|
|
138
|
+
*
|
|
139
|
+
* `Command.aiTool` promises "the human's gate and the agent's gate stay one predicate", and the
|
|
140
|
+
* only way to keep that promise is for the agent to ask the same object: this is the
|
|
141
|
+
* `CommandContext` `selection.delete` and the movers are evaluated against. Recomputing
|
|
142
|
+
* `editor.kind` here would make two predicates that agree today and drift the first time either
|
|
143
|
+
* is edited. Falls back to permissive when no registry is installed — the assistant runs in tests
|
|
144
|
+
* that never build one, and refusing everything there would be a second wrong answer.
|
|
145
|
+
*/
|
|
146
|
+
const treeEditable = () => {
|
|
147
|
+
const registry = activeRegistry();
|
|
148
|
+
// `=== "canvas"`, the human's exact test — not a looser cousin of it. Being more permissive for
|
|
149
|
+
// The agent than for the person is the divergence this is here to remove.
|
|
150
|
+
return registry ? registry.context().editor.kind === "canvas" : true;
|
|
151
|
+
};
|
|
129
152
|
const availability = new Map<string, ToolAvailability>(
|
|
130
153
|
AI_TOOL_TIERS.map((t) => [
|
|
131
154
|
t.name,
|
|
132
155
|
{
|
|
133
|
-
when: () =>
|
|
156
|
+
when: () =>
|
|
157
|
+
tierActive(t.tier, {
|
|
158
|
+
hasDocument: Boolean(activeTab.value),
|
|
159
|
+
hasProject: Boolean(workspace.projectRoot),
|
|
160
|
+
treeEditable: treeEditable(),
|
|
161
|
+
}),
|
|
134
162
|
requires: TIER_REQUIREMENTS[t.tier],
|
|
135
163
|
},
|
|
136
164
|
]),
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
2
|
+
/**
|
|
3
|
+
* Idle.ts — "settled" is a predicate, and it can fail.
|
|
4
|
+
*
|
|
5
|
+
* One question — _has Studio finished reacting?_ — asked of the five subsystems that can still be
|
|
6
|
+
* mid-flight, over two consecutive animation frames (spec studio.md §13.5, plan §13.4).
|
|
7
|
+
*
|
|
8
|
+
* **The rejection is the point.** The thing this replaces is 115 `wait: {ms}` steps totalling 73
|
|
9
|
+
* seconds, and a sleep cannot fail: a subsystem that was slow that day got answered with `+500 ms`
|
|
10
|
+
* and the wrong state was photographed, committed and accepted. {@link NotIdleError} carries a
|
|
11
|
+
* `blockedBy` array naming every outstanding item — `["canvas[page-1]: gen 7 unacked", "platform: 1
|
|
12
|
+
* in-flight (gitStatus)"]` — so the slow subsystem identifies itself.
|
|
13
|
+
*
|
|
14
|
+
* Nothing here polls a subsystem it does not own. Each source is a function the owning module
|
|
15
|
+
* already had to write for its own reasons:
|
|
16
|
+
*
|
|
17
|
+
* 1. `store.rendersInFlight()` — renderers mid-paint.
|
|
18
|
+
* 2. `panel-scheduler.pendingSchedulers()` — panels with a frame queued or a render withheld.
|
|
19
|
+
* 3. `iframe-host.canvasIdleBlockers()` — per host: unacked generations and patches, plus the frame's
|
|
20
|
+
* own cross-realm report of fonts, running animations and pending image retries.
|
|
21
|
+
* 4. `platform.platformInFlight()` — unsettled PAL calls, counted at the one seam every adapter and
|
|
22
|
+
* all thirty-odd `git*`/fs/fetch methods pass through.
|
|
23
|
+
* 5. `layers.overlayIdleBlockers()` — overlays still in transition. Only the SETTLING window counts: a
|
|
24
|
+
* resting toast is not a blocker, which is what lets `toastsAreHeld()` hold one open for a
|
|
25
|
+
* capture without `probeIdle()` waiting forever alongside it (plan §13.7's named exception).
|
|
26
|
+
* 6. `activity-panel.activityIdleBlockers()` — operations still RUNNING in the Activity tab. Not a
|
|
27
|
+
* duplicate of `platform`: an activity spans a whole operation (an install, a deploy, a clone)
|
|
28
|
+
* across many PAL calls, so the gaps between them look quiet at the seam while the operation is
|
|
29
|
+
* plainly mid-flight. A finished entry never blocks — the list stays on screen forever.
|
|
30
|
+
*
|
|
31
|
+
* The consumers are the `packages/studio:verify` skill, the screenshot runner and P4.2's Activity
|
|
32
|
+
* tracker (this is a read-only projection of the same in-flight set that dock renders).
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
import { rendersInFlight } from "../store";
|
|
36
|
+
import { activityIdleBlockers } from "../panels/activity-panel";
|
|
37
|
+
import { pendingSchedulers } from "../panels/panel-scheduler";
|
|
38
|
+
import { canvasIdleBlockers } from "../canvas/iframe-host";
|
|
39
|
+
import { platformInFlight } from "../platform";
|
|
40
|
+
import { overlayIdleBlockers } from "../ui/layers";
|
|
41
|
+
|
|
42
|
+
/** One subsystem that can be outstanding, and its account of why. */
|
|
43
|
+
export interface IdleSource {
|
|
44
|
+
/** Stable name — `render`, `panels`, `canvas`, `platform`, `overlay`. */
|
|
45
|
+
readonly name: string;
|
|
46
|
+
/** Empty when quiet; otherwise one human-readable line per outstanding item. */
|
|
47
|
+
blockers: () => readonly string[];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Consecutive quiet animation frames required before Studio counts as settled. */
|
|
51
|
+
export const QUIET_FRAMES = 2;
|
|
52
|
+
|
|
53
|
+
/** How long {@link probeIdle} waits before rejecting with what is still outstanding. */
|
|
54
|
+
export const DEFAULT_IDLE_TIMEOUT_MS = 10_000;
|
|
55
|
+
|
|
56
|
+
/** Thrown when Studio did not settle in time — `blockedBy` is the answer, not the message. */
|
|
57
|
+
export class NotIdleError extends Error {
|
|
58
|
+
readonly blockedBy: readonly string[];
|
|
59
|
+
|
|
60
|
+
constructor(blockedBy: readonly string[], timeoutMs: number) {
|
|
61
|
+
super(
|
|
62
|
+
blockedBy.length === 0
|
|
63
|
+
? `Studio did not report ${QUIET_FRAMES} consecutive quiet frames within ${timeoutMs}ms`
|
|
64
|
+
: `Studio was not idle after ${timeoutMs}ms — blocked by ${blockedBy.join("; ")}`,
|
|
65
|
+
);
|
|
66
|
+
this.name = "NotIdleError";
|
|
67
|
+
this.blockedBy = blockedBy;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The six live sources.
|
|
73
|
+
*
|
|
74
|
+
* Built per call rather than held in a module constant so a test can substitute one without
|
|
75
|
+
* unpicking the others, and so a second window's hosts are never read through the first window's
|
|
76
|
+
* closure.
|
|
77
|
+
*/
|
|
78
|
+
export function defaultIdleSources(): IdleSource[] {
|
|
79
|
+
return [
|
|
80
|
+
{
|
|
81
|
+
blockers: () => {
|
|
82
|
+
const count = rendersInFlight();
|
|
83
|
+
return count > 0 ? [`render: ${count} renderer(s) mid-paint`] : [];
|
|
84
|
+
},
|
|
85
|
+
name: "render",
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
blockers: () => pendingSchedulers().map((panel) => `panels: ${panel}`),
|
|
89
|
+
name: "panels",
|
|
90
|
+
},
|
|
91
|
+
{ blockers: canvasIdleBlockers, name: "canvas" },
|
|
92
|
+
{
|
|
93
|
+
blockers: () => {
|
|
94
|
+
const calls = platformInFlight();
|
|
95
|
+
if (calls.length === 0) {
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
return [`platform: ${calls.length} in-flight (${[...new Set(calls)].join(", ")})`];
|
|
99
|
+
},
|
|
100
|
+
name: "platform",
|
|
101
|
+
},
|
|
102
|
+
{ blockers: overlayIdleBlockers, name: "overlay" },
|
|
103
|
+
{ blockers: activityIdleBlockers, name: "activity" },
|
|
104
|
+
];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Everything outstanding right now, across every source. Empty means this instant is quiet. */
|
|
108
|
+
export function idleBlockers(sources: readonly IdleSource[] = defaultIdleSources()): string[] {
|
|
109
|
+
const blockers: string[] = [];
|
|
110
|
+
for (const source of sources) {
|
|
111
|
+
blockers.push(...source.blockers());
|
|
112
|
+
}
|
|
113
|
+
return blockers;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface IdleOptions {
|
|
117
|
+
timeoutMs?: number;
|
|
118
|
+
/** Consecutive quiet frames required. Defaults to {@link QUIET_FRAMES}. */
|
|
119
|
+
frames?: number;
|
|
120
|
+
/** Substitute the quiescence sources — what a test states, and what a second window would pass. */
|
|
121
|
+
sources?: readonly IdleSource[];
|
|
122
|
+
/** Frame scheduler, injectable so the loop is testable without a real compositor. */
|
|
123
|
+
raf?: (callback: () => void) => void;
|
|
124
|
+
/** Clock, injectable for the same reason. */
|
|
125
|
+
now?: () => number;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Resolve once every source has been quiet for `frames` consecutive animation frames.
|
|
130
|
+
*
|
|
131
|
+
* Rejects with {@link NotIdleError} on timeout. A single quiet frame is not enough: a render commits
|
|
132
|
+
* its DOM in one frame and its layout/animation consequences in the next, which is exactly the
|
|
133
|
+
* window a one-frame check photographs.
|
|
134
|
+
*/
|
|
135
|
+
export function probeIdle(options: IdleOptions = {}): Promise<void> {
|
|
136
|
+
const {
|
|
137
|
+
frames = QUIET_FRAMES,
|
|
138
|
+
now = () => Date.now(),
|
|
139
|
+
raf = (callback: () => void) => {
|
|
140
|
+
requestAnimationFrame(() => callback());
|
|
141
|
+
},
|
|
142
|
+
sources = defaultIdleSources(),
|
|
143
|
+
timeoutMs = DEFAULT_IDLE_TIMEOUT_MS,
|
|
144
|
+
} = options;
|
|
145
|
+
|
|
146
|
+
return new Promise<void>((resolve, reject) => {
|
|
147
|
+
const deadline = now() + timeoutMs;
|
|
148
|
+
let quiet = 0;
|
|
149
|
+
let settled = false;
|
|
150
|
+
// The last non-empty account, so a timeout that lands on a momentarily-quiet frame still names
|
|
151
|
+
// What kept it from reaching `frames` — "not idle, blocked by nothing" helps nobody.
|
|
152
|
+
let lastBlockers: readonly string[] = [];
|
|
153
|
+
|
|
154
|
+
const tick = () => {
|
|
155
|
+
if (settled) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const blockers = idleBlockers(sources);
|
|
159
|
+
if (blockers.length > 0) {
|
|
160
|
+
lastBlockers = blockers;
|
|
161
|
+
quiet = 0;
|
|
162
|
+
} else {
|
|
163
|
+
quiet += 1;
|
|
164
|
+
if (quiet >= frames) {
|
|
165
|
+
settled = true;
|
|
166
|
+
resolve();
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (now() >= deadline) {
|
|
171
|
+
settled = true;
|
|
172
|
+
reject(new NotIdleError(blockers.length > 0 ? blockers : lastBlockers, timeoutMs));
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
raf(tick);
|
|
176
|
+
};
|
|
177
|
+
raf(tick);
|
|
178
|
+
});
|
|
179
|
+
}
|
|
@@ -10,6 +10,15 @@
|
|
|
10
10
|
import type { ImportProgressEvent, ImportSiteOptions } from "../types";
|
|
11
11
|
import type { ProjectConfig } from "@jxsuite/schema/types";
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* The `phase` of the one progress line this client emits itself rather than forwarding.
|
|
15
|
+
*
|
|
16
|
+
* Exported so a caller can recognize it without matching a bare string: the import log renders
|
|
17
|
+
* every phase verbatim, but a warning also needs to outlive the log, which vanishes the moment a
|
|
18
|
+
* successful import hands off to the new project.
|
|
19
|
+
*/
|
|
20
|
+
export const IMPORT_WARNING_PHASE = "warning";
|
|
21
|
+
|
|
13
22
|
interface StreamLine {
|
|
14
23
|
type: string;
|
|
15
24
|
phase?: string;
|
|
@@ -77,6 +86,13 @@ export async function streamImport(
|
|
|
77
86
|
const decoder = new TextDecoder();
|
|
78
87
|
let buffer = "";
|
|
79
88
|
let result: { root: string; config: ProjectConfig } | null = null;
|
|
89
|
+
/*
|
|
90
|
+
* Lines the parser could not read. Tolerating one is right — an import that ran for two minutes
|
|
91
|
+
* should not die on a garbled progress line — but doing it *silently* is not: the import then
|
|
92
|
+
* finishes looking clean while the user never sees the pages it skipped. Counted here and
|
|
93
|
+
* surfaced once at the end, so the tolerance stays visible instead of becoming a hiding place.
|
|
94
|
+
*/
|
|
95
|
+
let unreadable = 0;
|
|
80
96
|
|
|
81
97
|
const handleLine = (line: string) => {
|
|
82
98
|
const trimmed = line.trim();
|
|
@@ -87,6 +103,7 @@ export async function streamImport(
|
|
|
87
103
|
try {
|
|
88
104
|
parsed = JSON.parse(trimmed) as StreamLine;
|
|
89
105
|
} catch {
|
|
106
|
+
unreadable += 1;
|
|
90
107
|
return; // Tolerate a mangled line rather than killing the whole import.
|
|
91
108
|
}
|
|
92
109
|
if (parsed.type === "progress") {
|
|
@@ -127,6 +144,15 @@ export async function streamImport(
|
|
|
127
144
|
}
|
|
128
145
|
}
|
|
129
146
|
|
|
147
|
+
if (unreadable > 0) {
|
|
148
|
+
onProgress({
|
|
149
|
+
message:
|
|
150
|
+
`${unreadable} progress line${unreadable === 1 ? "" : "s"} could not be read and ` +
|
|
151
|
+
`${unreadable === 1 ? "was" : "were"} skipped — the import may be missing steps.`,
|
|
152
|
+
phase: IMPORT_WARNING_PHASE,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
130
156
|
if (!result) {
|
|
131
157
|
throw new Error("Import stream ended without a result");
|
|
132
158
|
}
|