@volter/editor-core 0.5.57
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/BUNDLED_NOTICES +1527 -0
- package/LICENSE +686 -0
- package/LICENSE-APACHE +202 -0
- package/NOTICE +18 -0
- package/README.md +24 -0
- package/dist/build/chunk-JS4D4XZ3.js +175 -0
- package/dist/build/chunk-JS4D4XZ3.js.map +7 -0
- package/dist/build/vite-plugin-product-contributions.js +100 -0
- package/dist/build/vite-plugin-product-contributions.js.map +7 -0
- package/dist/build/vite-plugin-shared-react.js +25 -0
- package/dist/build/vite-plugin-shared-react.js.map +7 -0
- package/dist/build/vite-plugin-shared-three.js +86 -0
- package/dist/build/vite-plugin-shared-three.js.map +7 -0
- package/dist/server/chunk-KMJC7AGO.js +98 -0
- package/dist/server/chunk-KMJC7AGO.js.map +7 -0
- package/dist/server/chunk-PSILUMGS.js +46 -0
- package/dist/server/chunk-PSILUMGS.js.map +7 -0
- package/dist/server/frame-proxy.js +255 -0
- package/dist/server/frame-proxy.js.map +7 -0
- package/dist/server/open-browser.js +53 -0
- package/dist/server/open-browser.js.map +7 -0
- package/dist/server/process-shutdown.js +127 -0
- package/dist/server/process-shutdown.js.map +7 -0
- package/dist/server/session-registry.js +141 -0
- package/dist/server/session-registry.js.map +7 -0
- package/dist/server/spawn-opener.js +11 -0
- package/dist/server/spawn-opener.js.map +7 -0
- package/dist/server/worktree-identity.js +11 -0
- package/dist/server/worktree-identity.js.map +7 -0
- package/dist-server/packaged.mjs +88816 -0
- package/package.json +118 -0
- package/scripts/build-plugins.mjs +14 -0
- package/scripts/build-server.mjs +26 -0
- package/scripts/build-session.mjs +9 -0
- package/server/account-credentials.ts +60 -0
- package/server/account-service.ts +1434 -0
- package/server/adapter-region-includes.ts +47 -0
- package/server/asset-catalog-v2.ts +175 -0
- package/server/asset-history-snapshots.ts +196 -0
- package/server/asset-ledger-store.ts +195 -0
- package/server/asset-library-routes.ts +1595 -0
- package/server/blender-wasm-artifact.ts +430 -0
- package/server/boot-timings.ts +106 -0
- package/server/canonical-path.ts +50 -0
- package/server/checkout-workspace-preflight.ts +349 -0
- package/server/cloud-asset-catalog.ts +158 -0
- package/server/coding-inference-launch.ts +237 -0
- package/server/collaboration-account-client.ts +202 -0
- package/server/collaboration-attribution.ts +122 -0
- package/server/collaboration-session.ts +934 -0
- package/server/comfyui-bridge.ts +248 -0
- package/server/console-ledger.ts +499 -0
- package/server/creation-site-transform.ts +304 -0
- package/server/creation-site-write.ts +648 -0
- package/server/data-file-serialize.ts +158 -0
- package/server/editor-brand-html.ts +72 -0
- package/server/editor-control-socket.ts +366 -0
- package/server/editor-server-options.ts +190 -0
- package/server/editor-server.ts +1483 -0
- package/server/editor-sse.ts +352 -0
- package/server/engine-provenance.ts +169 -0
- package/server/engine-source-restart.ts +117 -0
- package/server/frame-bridge.ts +115 -0
- package/server/frame-proxy.ts +490 -0
- package/server/frame-workbench.ts +259 -0
- package/server/frontend-handoff.ts +229 -0
- package/server/game-globals-shadow.ts +113 -0
- package/server/gameplay-session-retention.ts +149 -0
- package/server/gameplay-sessions.ts +123 -0
- package/server/generation-jobs.ts +201 -0
- package/server/generation-reconciler.ts +137 -0
- package/server/generative-execution-context.ts +59 -0
- package/server/git-workflow.ts +612 -0
- package/server/harness-chat-caller.ts +36 -0
- package/server/harness-chat-service.ts +1681 -0
- package/server/idle-shutdown.ts +170 -0
- package/server/js-profiling-policy.ts +52 -0
- package/server/launcher-settings.ts +84 -0
- package/server/local-asset-catalog.ts +410 -0
- package/server/managed-account-defaults.ts +22 -0
- package/server/mock-control-plane.ts +540 -0
- package/server/model-import-conversion.ts +345 -0
- package/server/native-credential-store.ts +162 -0
- package/server/open-browser.ts +118 -0
- package/server/packaged.ts +1192 -0
- package/server/play-stall.ts +126 -0
- package/server/process-shutdown.ts +218 -0
- package/server/product-presets.ts +55 -0
- package/server/project-build-artifact.ts +95 -0
- package/server/project-components.ts +100 -0
- package/server/project-dependency-invalidation.ts +114 -0
- package/server/project-file-scan.ts +235 -0
- package/server/project-hmr-files.ts +215 -0
- package/server/project-install-roots.ts +210 -0
- package/server/project-kinds.ts +71 -0
- package/server/project-mcp-servers.ts +82 -0
- package/server/project-module-freshness.ts +109 -0
- package/server/project-module-instance.ts +375 -0
- package/server/project-optimize-deps-entries.ts +827 -0
- package/server/project-output-writer.ts +679 -0
- package/server/project-package-origin.ts +63 -0
- package/server/project-root-surface.ts +831 -0
- package/server/project-scratch-path.ts +47 -0
- package/server/project-script-hmr.ts +619 -0
- package/server/project-serving-plugins.ts +236 -0
- package/server/project-tools.ts +653 -0
- package/server/project-validation.ts +250 -0
- package/server/project-verbs.ts +127 -0
- package/server/project-view.ts +52 -0
- package/server/project-watch.ts +1134 -0
- package/server/project-work-coordinator.ts +288 -0
- package/server/provider-credentials.ts +331 -0
- package/server/recent-projects-store.ts +98 -0
- package/server/redact-secrets.ts +71 -0
- package/server/repository-presence.ts +267 -0
- package/server/routes/account.ts +357 -0
- package/server/routes/agents.ts +60 -0
- package/server/routes/assets.ts +154 -0
- package/server/routes/build.ts +13 -0
- package/server/routes/collaboration.ts +595 -0
- package/server/routes/configurations.ts +419 -0
- package/server/routes/context.ts +264 -0
- package/server/routes/control-plane.ts +1811 -0
- package/server/routes/logs.ts +272 -0
- package/server/routes/project-identity.ts +302 -0
- package/server/routes/project-open.ts +429 -0
- package/server/routes/project-source.ts +686 -0
- package/server/routes/project-state.ts +383 -0
- package/server/routes/relay.ts +1029 -0
- package/server/routes/route-helpers.ts +29 -0
- package/server/routes/served-modules.ts +138 -0
- package/server/routes/session-tabs.ts +196 -0
- package/server/routes/settings.ts +121 -0
- package/server/routes/share-control.ts +486 -0
- package/server/routes/themes.ts +116 -0
- package/server/routes/tools.ts +230 -0
- package/server/routes/worktrees.ts +595 -0
- package/server/scoped-game-css.ts +461 -0
- package/server/server-utils.ts +1194 -0
- package/server/session-product.ts +112 -0
- package/server/session-registry.ts +230 -0
- package/server/share-claims.ts +138 -0
- package/server/share-host.ts +526 -0
- package/server/share-session-gateway.ts +1362 -0
- package/server/share-tunnel.ts +123 -0
- package/server/spawn-opener.ts +74 -0
- package/server/support/play/log-format.ts +76 -0
- package/server/support/play/session-record.ts +199 -0
- package/server/support/project/build-discipline.ts +718 -0
- package/server/support/project/inspection-node.ts +119 -0
- package/server/support/project/log-naming.ts +54 -0
- package/server/support/project/provenance.ts +290 -0
- package/server/support/project/run-name.ts +18 -0
- package/server/support/project/session-journal.ts +830 -0
- package/server/support/project/shared.ts +327 -0
- package/server/tab-bootstrap.ts +62 -0
- package/server/tab-heartbeat.ts +477 -0
- package/server/tab-lifecycle.ts +550 -0
- package/server/tab-presence.ts +1508 -0
- package/server/team-agent-mirror.ts +95 -0
- package/server/twin-auth.ts +138 -0
- package/server/vendored-lock-recorder.ts +968 -0
- package/server/worktree-identity.ts +121 -0
- package/server/worktree-management.ts +398 -0
- package/server/worktree-retention.d.mts +13 -0
- package/server/worktree-retention.mjs +205 -0
- package/src/EditorContext.tsx +169 -0
- package/src/account.ts +333 -0
- package/src/action-registry.ts +532 -0
- package/src/active-product.ts +74 -0
- package/src/active-project.ts +155 -0
- package/src/adapter-editor-config.ts +25 -0
- package/src/adapter-observation.ts +49 -0
- package/src/animation/stage-transport.ts +379 -0
- package/src/animation/three-clips-subject.ts +172 -0
- package/src/api/asset-library-wire.ts +45 -0
- package/src/api/assets.ts +365 -0
- package/src/api/base.ts +10 -0
- package/src/api/build.ts +99 -0
- package/src/api/git-wire.ts +56 -0
- package/src/api/logs.ts +92 -0
- package/src/api/project-identity.ts +74 -0
- package/src/api/project-open.ts +355 -0
- package/src/api/project-source.ts +162 -0
- package/src/api/project-state.ts +107 -0
- package/src/api/relay.ts +268 -0
- package/src/api/settings.ts +36 -0
- package/src/api/themes.ts +45 -0
- package/src/api/worktrees.ts +257 -0
- package/src/asset-compare-core.ts +171 -0
- package/src/asset-compare.ts +294 -0
- package/src/asset-editor-context.tsx +100 -0
- package/src/asset-events.ts +97 -0
- package/src/asset-inspector-actions.ts +87 -0
- package/src/asset-preview-framing.ts +357 -0
- package/src/asset-preview.ts +2802 -0
- package/src/asset-selection-viewer-registry.ts +113 -0
- package/src/asset-selection.ts +133 -0
- package/src/asset-workflow/asset-capabilities.ts +344 -0
- package/src/asset-workflow/asset-import-jobs.ts +106 -0
- package/src/asset-workflow/asset-ledger-backend.ts +126 -0
- package/src/asset-workflow/asset-ledger.ts +156 -0
- package/src/asset-workflow/asset-materialization-report.ts +140 -0
- package/src/asset-workflow/asset-pack-manifest.ts +320 -0
- package/src/asset-workflow/asset-types.ts +142 -0
- package/src/asset-workflow/asset-workflow-quality.ts +61 -0
- package/src/asset-workflow/audio-preview-player.ts +193 -0
- package/src/asset-workflow/audio-waveform.ts +22 -0
- package/src/asset-workflow/cloud-asset-client.ts +263 -0
- package/src/asset-workflow/folder-preview.ts +345 -0
- package/src/asset-workflow/hosted-asset-materialization.ts +236 -0
- package/src/asset-workflow/image-view-scale.ts +32 -0
- package/src/asset-workflow/import-contract.ts +124 -0
- package/src/asset-workflow/ledger-write-lock.ts +244 -0
- package/src/asset-workflow/model-inspection.ts +818 -0
- package/src/asset-workflow/pixi-spritesheet.ts +197 -0
- package/src/asset-workflow/preview-resource-lifetime.ts +44 -0
- package/src/asset-workflow/project-asset-commands.ts +23 -0
- package/src/asset-workflow/project-asset-health.ts +139 -0
- package/src/asset-workflow/project-asset-operations.ts +154 -0
- package/src/asset-workflow/project-asset-roots.ts +68 -0
- package/src/asset-workflow/project-content.ts +288 -0
- package/src/asset-workflow/project-source-index.ts +550 -0
- package/src/asset-workflow/thumbnail-system.ts +256 -0
- package/src/authoring/active-adapter.ts +199 -0
- package/src/authoring/active-systems.ts +422 -0
- package/src/authoring/adapter-key.ts +18 -0
- package/src/authoring/authoring-asset-url.ts +27 -0
- package/src/authoring/bootstrap-state.ts +49 -0
- package/src/authoring/boundary-authoring-adapter.ts +184 -0
- package/src/authoring/breakpoint-state.ts +43 -0
- package/src/authoring/canvas-scene-guides.ts +76 -0
- package/src/authoring/component-instance-root.ts +171 -0
- package/src/authoring/composite-authoring-adapter.ts +2110 -0
- package/src/authoring/consumer-actions.ts +520 -0
- package/src/authoring/css-numeric-style.ts +97 -0
- package/src/authoring/design-time-layers.ts +849 -0
- package/src/authoring/design-time-mount-registry.ts +235 -0
- package/src/authoring/design-time-settle.ts +343 -0
- package/src/authoring/edit-mode-authoring.ts +619 -0
- package/src/authoring/eyedropper-session.ts +60 -0
- package/src/authoring/instance-source-menu-register.ts +13 -0
- package/src/authoring/instance-source-menu.ts +135 -0
- package/src/authoring/layered-pick.ts +183 -0
- package/src/authoring/live-gesture-lock.ts +50 -0
- package/src/authoring/live-object-transform.ts +62 -0
- package/src/authoring/mount-failure-report.ts +154 -0
- package/src/authoring/mounted-root-subjects.ts +144 -0
- package/src/authoring/no-authoring-adapter.ts +55 -0
- package/src/authoring/null-inspection-subjects.tsx +75 -0
- package/src/authoring/object3d-document-persistence.ts +106 -0
- package/src/authoring/object3d-document-session-registry.ts +120 -0
- package/src/authoring/object3d-document-session.ts +1326 -0
- package/src/authoring/object3d-gesture-controller.ts +113 -0
- package/src/authoring/panel-authoring.ts +121 -0
- package/src/authoring/prefab-instance-inspector-section.tsx +237 -0
- package/src/authoring/prefab-instance-section-model.ts +55 -0
- package/src/authoring/project-authoring-session.ts +105 -0
- package/src/authoring/provenance.ts +99 -0
- package/src/authoring/quarks-particle-systems.ts +19 -0
- package/src/authoring/react-canvas-navigation.ts +255 -0
- package/src/authoring/react-design-canvas-style.ts +20 -0
- package/src/authoring/react-story-board.ts +937 -0
- package/src/authoring/selection-scope.ts +195 -0
- package/src/authoring/shell-document-ops.ts +169 -0
- package/src/authoring/shell-object3d-document-write-policy.ts +108 -0
- package/src/authoring/shell-viewport-policy.ts +48 -0
- package/src/authoring/source-object3d-authoring-adapter.ts +526 -0
- package/src/authoring/stories-scope.ts +35 -0
- package/src/authoring/story-board-chrome-fit.ts +107 -0
- package/src/authoring/story-board-presentation.ts +111 -0
- package/src/authoring/three-projection-core.ts +226 -0
- package/src/authoring/viewport-pick-context.ts +40 -0
- package/src/authoring/viewport-raycast.ts +240 -0
- package/src/authoring/viewport-tool-context.ts +73 -0
- package/src/authoring/world-canvas-viewport-state.ts +35 -0
- package/src/authoring/world-hidden-viewport.ts +152 -0
- package/src/authoring/world-pan-state.ts +198 -0
- package/src/authoring/world-session-state.ts +101 -0
- package/src/authoring/write-pipe.ts +173 -0
- package/src/availability-tick.ts +66 -0
- package/src/bitmap-label.ts +120 -0
- package/src/blender-tab-metrics.ts +161 -0
- package/src/board-open-actions.ts +20 -0
- package/src/boot-routing.ts +391 -0
- package/src/build-identity.ts +15 -0
- package/src/bytes-codec.ts +62 -0
- package/src/camera-authoring.ts +175 -0
- package/src/cancellation-reason.ts +58 -0
- package/src/canvas-preview-frames.ts +482 -0
- package/src/capture-camera-pose.ts +77 -0
- package/src/chrome-registry.ts +159 -0
- package/src/chrome-slot-registry.ts +91 -0
- package/src/collaboration-client.ts +264 -0
- package/src/collaboration-presence.ts +41 -0
- package/src/command-dispatch.ts +19 -0
- package/src/command-listener.ts +2743 -0
- package/src/command-registry.ts +70 -0
- package/src/component-board-registry.ts +205 -0
- package/src/component-states-registry.ts +200 -0
- package/src/components/AgentPresentationNotice.tsx +75 -0
- package/src/components/AlignToolbar.tsx +204 -0
- package/src/components/AppRoot.tsx +394 -0
- package/src/components/ApplicationMenus.tsx +415 -0
- package/src/components/AssetBrowser.tsx +2843 -0
- package/src/components/AssetEditorShell.tsx +216 -0
- package/src/components/AssetInspectorToolSection.tsx +124 -0
- package/src/components/BoardRulers.tsx +354 -0
- package/src/components/CameraInfo.tsx +81 -0
- package/src/components/CanvasSceneViewport.tsx +556 -0
- package/src/components/CapabilityCoverageSection.tsx +185 -0
- package/src/components/CenterDocuments.tsx +22 -0
- package/src/components/ChromeSlot.tsx +20 -0
- package/src/components/CodeView.tsx +470 -0
- package/src/components/CollaborationHeaderControl.css +74 -0
- package/src/components/CompactInspectorCard.tsx +190 -0
- package/src/components/CompactInspectorShell.tsx +39 -0
- package/src/components/ConsolePanel.css +55 -0
- package/src/components/ConsolePanel.tsx +270 -0
- package/src/components/DefaultEditorLayout.tsx +106 -0
- package/src/components/DocumentHeaderStrip.tsx +96 -0
- package/src/components/DocumentShelfRail.tsx +45 -0
- package/src/components/DocumentThumbnail.tsx +345 -0
- package/src/components/EditorLeaseGuard.tsx +372 -0
- package/src/components/ErrorBanner.tsx +123 -0
- package/src/components/FolderPreviewTile.tsx +159 -0
- package/src/components/GameHierarchy.tsx +3842 -0
- package/src/components/GameplaySessionTimeline.tsx +295 -0
- package/src/components/InspectionProjection.tsx +968 -0
- package/src/components/Inspector.tsx +233 -0
- package/src/components/InspectorCanvasPreview.tsx +35 -0
- package/src/components/InspectorFieldsSection.tsx +290 -0
- package/src/components/InspectorObjectPreview.tsx +57 -0
- package/src/components/InspectorStoriesSection.tsx +92 -0
- package/src/components/InspectorToolSection.tsx +96 -0
- package/src/components/InspectorTransformSection.tsx +245 -0
- package/src/components/LightExplorerPanel.tsx +433 -0
- package/src/components/MediaProperties.tsx +145 -0
- package/src/components/NonThreeAuthoringBootstrap.tsx +19 -0
- package/src/components/Object3DDocumentToolbar.css +100 -0
- package/src/components/Object3DDocumentToolbar.tsx +454 -0
- package/src/components/Object3DDocumentViewport.tsx +58 -0
- package/src/components/ProjectHeader.css +617 -0
- package/src/components/ProjectHeader.tsx +328 -0
- package/src/components/ProjectLayout.tsx +249 -0
- package/src/components/ReactCanvasControls.tsx +284 -0
- package/src/components/RootSelectionOverlay.tsx +3162 -0
- package/src/components/RootTextEditor.tsx +79 -0
- package/src/components/SaveStatus.tsx +70 -0
- package/src/components/StageHost.tsx +1954 -0
- package/src/components/StageOverlays.tsx +21 -0
- package/src/components/StartupErrorScreen.tsx +76 -0
- package/src/components/StartupLoadingScreen.tsx +65 -0
- package/src/components/StatsOverlay.tsx +78 -0
- package/src/components/SurfaceStateOverlay.tsx +24 -0
- package/src/components/ToolContributionSurfaces.tsx +65 -0
- package/src/components/ToolHost.tsx +370 -0
- package/src/components/ToolObject3DPreview.tsx +39 -0
- package/src/components/Toolbar.tsx +595 -0
- package/src/components/TransientHint.tsx +44 -0
- package/src/components/TransportStrip.tsx +174 -0
- package/src/components/VersionControlSection.tsx +470 -0
- package/src/components/VgaiLogo.css +83 -0
- package/src/components/VgaiLogo.tsx +35 -0
- package/src/components/ViewportControlsHint.tsx +60 -0
- package/src/components/ViewportFurniture.tsx +401 -0
- package/src/components/ViewportOverlay.tsx +145 -0
- package/src/components/ViewportOverlaysMenu.tsx +153 -0
- package/src/components/ViewportShadingMenu.tsx +300 -0
- package/src/components/ViewportViewMenu.tsx +101 -0
- package/src/components/WorkspaceDocumentSurface.tsx +204 -0
- package/src/components/WorkspaceUtilitySurface.tsx +22 -0
- package/src/components/WorktreeSwitcher.css +239 -0
- package/src/components/WorktreeSwitcher.tsx +890 -0
- package/src/components/account-documents.tsx +1162 -0
- package/src/components/asset-documents.tsx +812 -0
- package/src/components/asset-editor-persistence.ts +216 -0
- package/src/components/asset-selection-section.tsx +535 -0
- package/src/components/asset-thumbnails.tsx +312 -0
- package/src/components/asset-viewers/AudioViewer.tsx +201 -0
- package/src/components/asset-viewers/EntityModelDocument.tsx +122 -0
- package/src/components/asset-viewers/EnvironmentAssetDocument.tsx +440 -0
- package/src/components/asset-viewers/GenericJsonViewer.tsx +102 -0
- package/src/components/asset-viewers/ImageViewer.tsx +300 -0
- package/src/components/asset-viewers/JsonAssetDocument.tsx +93 -0
- package/src/components/asset-viewers/LiveModuleDocument.tsx +417 -0
- package/src/components/asset-viewers/LutAssetDocument.tsx +444 -0
- package/src/components/asset-viewers/ModelAssetDocument.tsx +105 -0
- package/src/components/asset-viewers/Object3DPreview.tsx +359 -0
- package/src/components/asset-viewers/OnlineAssetDetail.tsx +421 -0
- package/src/components/asset-viewers/PasteboardModuleDocument.tsx +67 -0
- package/src/components/asset-viewers/QuarksAssetDocument.tsx +526 -0
- package/src/components/asset-viewers/ShaderAssetDocument.tsx +743 -0
- package/src/components/asset-viewers/SourceAssetViewer.tsx +281 -0
- package/src/components/asset-viewers/SpritesheetSpriteView.tsx +102 -0
- package/src/components/asset-viewers/VideoViewer.tsx +101 -0
- package/src/components/asset-viewers/shader-source.ts +144 -0
- package/src/components/asset-workflow.css +731 -0
- package/src/components/board-guides.ts +150 -0
- package/src/components/compact-inspector.css +539 -0
- package/src/components/core-utilities.tsx +90 -0
- package/src/components/editor-notifications.css +40 -0
- package/src/components/engine-workspace.css +274 -0
- package/src/components/inspector-preview-section.tsx +238 -0
- package/src/components/inspector-property-grouping.ts +64 -0
- package/src/components/inspector-revert-label.ts +20 -0
- package/src/components/inspector-selection.ts +42 -0
- package/src/components/inspector-stories-gating.ts +171 -0
- package/src/components/inspector-transform-subject.ts +11 -0
- package/src/components/inspector-transform.ts +75 -0
- package/src/components/kind-documents.tsx +500 -0
- package/src/components/palette-action-publisher.tsx +140 -0
- package/src/components/primitives/DraftColorInput.tsx +74 -0
- package/src/components/product-shell.css +1829 -0
- package/src/components/project-tool-documents.tsx +410 -0
- package/src/components/scene-documents.tsx +223 -0
- package/src/components/stage-keyboard.tsx +37 -0
- package/src/components/stage-overlay-set.tsx +107 -0
- package/src/components/stage-presence-markers.ts +478 -0
- package/src/components/standard-viewport-dressing.ts +417 -0
- package/src/components/status-contributions.tsx +403 -0
- package/src/components/tool-documents.tsx +309 -0
- package/src/components/tool-schema-form.tsx +262 -0
- package/src/components/use-after-paint.ts +41 -0
- package/src/components/use-project-image-assets.ts +86 -0
- package/src/components/viewport-header-controls.css +90 -0
- package/src/components/viewport-surface-status.tsx +55 -0
- package/src/components/workspace-history.ts +32 -0
- package/src/components/workspace-static-panel-registry.tsx +152 -0
- package/src/components/workspace-surfaces.css +621 -0
- package/src/components/world-documents.tsx +586 -0
- package/src/components/world-overlay-gestures.ts +1694 -0
- package/src/composite-screenshot.ts +1641 -0
- package/src/console-sync.ts +131 -0
- package/src/constraint-helper.ts +338 -0
- package/src/content-entry-source-registry.ts +184 -0
- package/src/coverage/authoring-seam-evidence.ts +300 -0
- package/src/coverage/canvas-reveal.ts +192 -0
- package/src/coverage/design-time-surfaces.ts +101 -0
- package/src/coverage/live-seam-evidence.ts +11 -0
- package/src/coverage/ontology-invariants.ts +466 -0
- package/src/coverage/session-vitals.ts +501 -0
- package/src/coverage/system-seam-evidence.ts +72 -0
- package/src/crash-null-boundary.ts +36 -0
- package/src/creation-site-edit.ts +1479 -0
- package/src/creation-site-registry.ts +160 -0
- package/src/delegate-harness-registry.ts +143 -0
- package/src/document-context-registry.ts +177 -0
- package/src/document-open-registry.ts +200 -0
- package/src/document-preview-source.ts +20 -0
- package/src/document-renderer-session.ts +138 -0
- package/src/editor-api.ts +46 -0
- package/src/editor-chrome-capture.ts +139 -0
- package/src/editor-commands.ts +164 -0
- package/src/editor-console.ts +563 -0
- package/src/editor-current-view.ts +82 -0
- package/src/editor-document-probe.ts +881 -0
- package/src/editor-git-client.ts +115 -0
- package/src/editor-host-door.ts +462 -0
- package/src/editor-hotkeys.ts +842 -0
- package/src/editor-lease-view.ts +39 -0
- package/src/editor-lease.ts +415 -0
- package/src/editor-mode.ts +19 -0
- package/src/editor-notifications.ts +140 -0
- package/src/editor-presence.ts +563 -0
- package/src/editor-presentation-activity.ts +50 -0
- package/src/editor-presentation-notice.ts +42 -0
- package/src/editor-runtime.tsx +145 -0
- package/src/editor-server-response.ts +86 -0
- package/src/editor-session-attribution.ts +75 -0
- package/src/editor-session-mode.ts +54 -0
- package/src/editor-shell-store.ts +1304 -0
- package/src/editor-state-facets.ts +74 -0
- package/src/editor-styles.css +33 -0
- package/src/editor-view-presentation.ts +810 -0
- package/src/editor-viewport.ts +5302 -0
- package/src/entity-lod.ts +31 -0
- package/src/entity-object.ts +91 -0
- package/src/files/file-provider.ts +62 -0
- package/src/files/project-files.ts +264 -0
- package/src/finders/index.ts +136 -0
- package/src/finders/scenes-from-entrypoint-selection.ts +387 -0
- package/src/frame/bridge.tsx +1408 -0
- package/src/frame/product.ts +77 -0
- package/src/gameplay-dom-recording.ts +319 -0
- package/src/gameplay-export-state.ts +14 -0
- package/src/gameplay-replay.ts +417 -0
- package/src/gameplay-session-time.ts +9 -0
- package/src/gameplay-sessions.ts +204 -0
- package/src/harness-chat-types.ts +253 -0
- package/src/hierarchy-component-marks.ts +298 -0
- package/src/hierarchy-drop.ts +91 -0
- package/src/hierarchy-expansion-state.ts +80 -0
- package/src/hierarchy-header-slot.ts +52 -0
- package/src/hierarchy-internals.ts +197 -0
- package/src/hierarchy-kind-icon.ts +217 -0
- package/src/hierarchy-mark-reader.ts +73 -0
- package/src/hierarchy-menu-registry.ts +67 -0
- package/src/hierarchy-node-rows.ts +307 -0
- package/src/hierarchy-panel-view.ts +280 -0
- package/src/hierarchy-projection.ts +76 -0
- package/src/hierarchy-row-cache.ts +243 -0
- package/src/hierarchy-row-model.ts +308 -0
- package/src/hierarchy-rows.ts +11 -0
- package/src/hierarchy-walk.ts +86 -0
- package/src/history/editor-session.ts +25 -0
- package/src/history/history-commands.ts +147 -0
- package/src/history/history-delegate.ts +163 -0
- package/src/history/history-limit-notices.ts +43 -0
- package/src/history/history-service.ts +1173 -0
- package/src/history/persistence-coordinator.ts +35 -0
- package/src/history/project-file-history.ts +386 -0
- package/src/history/project-root-history-backends.ts +139 -0
- package/src/history/resource-registry.ts +209 -0
- package/src/history/snapshot-store.ts +103 -0
- package/src/history/source-history-backend.ts +546 -0
- package/src/history/types.ts +124 -0
- package/src/hmr-registration-group.ts +67 -0
- package/src/hmr-stable-react-context.ts +23 -0
- package/src/hotkeys.ts +188 -0
- package/src/inference-diagnostics.ts +69 -0
- package/src/initial-project.ts +80 -0
- package/src/inspection/active-subject.ts +578 -0
- package/src/inspection/active-surface.ts +142 -0
- package/src/inspection/compose.ts +1064 -0
- package/src/inspection/display.ts +170 -0
- package/src/inspection/document-subject.ts +109 -0
- package/src/inspection/game-subject.ts +85 -0
- package/src/inspection/model.ts +542 -0
- package/src/inspection/null-subject.ts +115 -0
- package/src/inspection/serialize.ts +357 -0
- package/src/inspection/use-active-inspection.ts +180 -0
- package/src/inspector-presentation.ts +201 -0
- package/src/inspector-section-registry.ts +221 -0
- package/src/instance-source-actions.ts +163 -0
- package/src/instanced-presentation.ts +164 -0
- package/src/js-heap.ts +71 -0
- package/src/key-actions.ts +91 -0
- package/src/keymap-presets.ts +401 -0
- package/src/layout-policy.ts +31 -0
- package/src/learn-links.ts +73 -0
- package/src/light-explorer-model.ts +134 -0
- package/src/live-canvas-frame.ts +55 -0
- package/src/live-document.ts +279 -0
- package/src/live-module-source.ts +230 -0
- package/src/live-session-registry.ts +220 -0
- package/src/live-transition.ts +633 -0
- package/src/manifest-project.ts +107 -0
- package/src/model-thumbnail.ts +523 -0
- package/src/native-selection-style.ts +202 -0
- package/src/object3d-document-write-policy.ts +137 -0
- package/src/packaged-runtime.ts +108 -0
- package/src/palettes/maya.palette.json +57 -0
- package/src/palettes/substance.palette.json +57 -0
- package/src/pasteboard-module.ts +81 -0
- package/src/performance-profiler.ts +367 -0
- package/src/performance-sources.ts +69 -0
- package/src/play-boot-phase.ts +145 -0
- package/src/presentation-surface.ts +248 -0
- package/src/project-adapter.ts +1143 -0
- package/src/project-asset-refresh.ts +26 -0
- package/src/project-declaration-refresh.ts +31 -0
- package/src/project-local-state.ts +118 -0
- package/src/project-manager.ts +243 -0
- package/src/project-module-changes.ts +163 -0
- package/src/project-module-split.ts +266 -0
- package/src/project-provenance.ts +115 -0
- package/src/project-ready.ts +42 -0
- package/src/project-session-reset.ts +67 -0
- package/src/project-shape.ts +68 -0
- package/src/project-tool-discovery.ts +66 -0
- package/src/project-tools.ts +107 -0
- package/src/project-work-types.ts +149 -0
- package/src/projection/three.ts +898 -0
- package/src/projection/types.ts +44 -0
- package/src/readiness.ts +113 -0
- package/src/reflection-probe-helper.ts +142 -0
- package/src/reported-play-state.ts +90 -0
- package/src/resolve-relative-specifier.ts +33 -0
- package/src/scene-document-plan.ts +315 -0
- package/src/scene-framing.ts +315 -0
- package/src/scene-live-open.ts +210 -0
- package/src/scene-view-fog.ts +89 -0
- package/src/scoped-game-css.ts +152 -0
- package/src/session-orphan-record.ts +193 -0
- package/src/session-tombstone.ts +126 -0
- package/src/settings/settings-provider.ts +82 -0
- package/src/settings-store.ts +345 -0
- package/src/shared-view-restore.ts +42 -0
- package/src/shell-store-door.ts +45 -0
- package/src/source-conflict.ts +122 -0
- package/src/spatial-handle-visuals.ts +332 -0
- package/src/stage-context.ts +341 -0
- package/src/stage-store-registry.ts +63 -0
- package/src/stale-chunk-recovery.ts +34 -0
- package/src/state-report-deferral.ts +73 -0
- package/src/storage/host-files-storage.ts +97 -0
- package/src/storage/http-storage.ts +174 -0
- package/src/storage/index.ts +75 -0
- package/src/storage/mem-storage.ts +149 -0
- package/src/storage/path-lock.ts +44 -0
- package/src/storage/paths.ts +26 -0
- package/src/storage/types.ts +116 -0
- package/src/stories/StoryComponentThumbnail.tsx +184 -0
- package/src/stories/StoryPreviewMount.tsx +306 -0
- package/src/stories/component-content-source.tsx +106 -0
- package/src/stories/component-states-source.ts +78 -0
- package/src/stories/compose-project-stories.ts +255 -0
- package/src/stories/pixi-story-model.ts +30 -0
- package/src/stories/prefabs-finder.ts +54 -0
- package/src/stories/prefabs-from-stories.ts +182 -0
- package/src/stories/project-story-discovery.ts +78 -0
- package/src/stories/project-story-regions.ts +24 -0
- package/src/stories/story-actions.ts +54 -0
- package/src/stories/story-capture-command.ts +124 -0
- package/src/stories/story-capture.ts +584 -0
- package/src/stories/story-declared-medium.ts +126 -0
- package/src/stories/story-discovery.ts +176 -0
- package/src/stories/story-document-openers.ts +36 -0
- package/src/stories/story-dom-runtime.ts +78 -0
- package/src/stories/story-grouping.ts +111 -0
- package/src/stories/story-lane.ts +88 -0
- package/src/stories/story-mount-turn.ts +27 -0
- package/src/stories/story-opener.ts +260 -0
- package/src/stories/story-pixi-preview.ts +408 -0
- package/src/stories/story-presentation.ts +215 -0
- package/src/stories/story-registry.ts +517 -0
- package/src/stories/story-three-preview.ts +807 -0
- package/src/stories/three-story-model.ts +96 -0
- package/src/story-three-preview-runtime.ts +56 -0
- package/src/surface-keyboard.ts +112 -0
- package/src/surface-state.ts +124 -0
- package/src/tab-bootstrap.js +628 -0
- package/src/tab-census.ts +198 -0
- package/src/tab-lifecycle-client.ts +196 -0
- package/src/theme-library.ts +844 -0
- package/src/theme-preference.ts +378 -0
- package/src/theme.css +3437 -0
- package/src/three-viewport/bone-selection-highlight.ts +119 -0
- package/src/three-viewport/camera-fit.ts +41 -0
- package/src/three-viewport/interactive-renderer.ts +132 -0
- package/src/three-viewport/selection-brackets.ts +310 -0
- package/src/three-viewport/selection-outline.ts +183 -0
- package/src/three-viewport/skeleton-helper.ts +61 -0
- package/src/three-viewport/source-color.ts +167 -0
- package/src/three-viewport/studio-environment.ts +96 -0
- package/src/three-viewport-presentation.ts +23 -0
- package/src/tool-contribution-play.ts +74 -0
- package/src/tool-loader.ts +1798 -0
- package/src/transform-mode-request.ts +57 -0
- package/src/transient-hint.ts +78 -0
- package/src/trigger-volume-helper.ts +116 -0
- package/src/ui-source/adapter-region-includes.ts +241 -0
- package/src/ui-source/ensure-import.ts +132 -0
- package/src/ui-source/file-region-resolver.ts +302 -0
- package/src/ui-source/inspect.ts +775 -0
- package/src/ui-source/oid-transform.ts +1845 -0
- package/src/ui-source/plan-csf-story.ts +196 -0
- package/src/ui-source/plan-extract-component.ts +421 -0
- package/src/ui-source/plan-fork-component.ts +621 -0
- package/src/ui-source/plan-named-style.ts +95 -0
- package/src/ui-source/plan-source-edit.ts +353 -0
- package/src/ui-source/r3f-contract-resolver.ts +327 -0
- package/src/ui-source/r3f-diagnostic-index.ts +165 -0
- package/src/ui-source/r3f-environment-binding.ts +133 -0
- package/src/ui-source/r3f-joint-binding.ts +251 -0
- package/src/ui-source/r3f-lod-binding.ts +91 -0
- package/src/ui-source/r3f-particle-binding.ts +235 -0
- package/src/ui-source/r3f-physics-binding.ts +483 -0
- package/src/ui-source/r3f-project-contracts.ts +444 -0
- package/src/ui-source/relative-import-specifier.ts +34 -0
- package/src/ui-source/reparent-guard.ts +544 -0
- package/src/ui-source/source-edit-request.ts +97 -0
- package/src/ui-source/source-write-backend.ts +618 -0
- package/src/ui-source/syntactic-prop-specs.ts +296 -0
- package/src/ui-source/tier-source-write-backend.ts +279 -0
- package/src/ui-source/ts-ast.ts +171 -0
- package/src/ui-source/utility-class-support.ts +169 -0
- package/src/ui-source/write-component-default.ts +133 -0
- package/src/ui-source/writer.ts +1989 -0
- package/src/viewport-activation-timings.ts +840 -0
- package/src/viewport-authoring-policy.ts +186 -0
- package/src/viewport-controls-hint.ts +57 -0
- package/src/viewport-door.ts +237 -0
- package/src/viewport-shading-boundary.ts +12 -0
- package/src/vite-error-surface.ts +141 -0
- package/src/wait-until.ts +37 -0
- package/src/workspace-areas.ts +156 -0
- package/src/workspace-aux-commands.ts +11 -0
- package/src/workspace-available-documents.ts +127 -0
- package/src/workspace-core-utilities.ts +31 -0
- package/src/workspace-document-ids.ts +59 -0
- package/src/workspace-document-registry.ts +612 -0
- package/src/workspace-document-restore.ts +145 -0
- package/src/workspace-host-commands.ts +141 -0
- package/src/workspace-persistence-gate.ts +40 -0
- package/src/workspace-play-utilities.ts +44 -0
- package/src/workspace-presets.ts +425 -0
- package/src/workspace-regions.ts +294 -0
- package/src/workspace-state-persistence.ts +536 -0
- package/src/workspace-static-panels.ts +73 -0
- package/src/workspace-status-registry.ts +121 -0
- package/src/workspace-style.ts +239 -0
- package/src/workspace-utility-commands.ts +74 -0
- package/src/workspace-utility-registry.ts +263 -0
- package/src/workspace-viewport-rect.ts +97 -0
- package/src/world-adoption.ts +115 -0
- package/src/world-document-routing.ts +104 -0
- package/vite-plugin-creation-site-write.ts +184 -0
- package/vite-plugin-creation-site.ts +80 -0
- package/vite-plugin-game-static.ts +303 -0
- package/vite-plugin-module-doorways.ts +336 -0
- package/vite-plugin-product-contributions.ts +197 -0
- package/vite-plugin-project-game-static.ts +125 -0
- package/vite-plugin-project-jsx-js.ts +65 -0
- package/vite-plugin-project-root-absolute-assets.ts +359 -0
- package/vite-plugin-shared-react.ts +420 -0
- package/vite-plugin-shared-three.ts +203 -0
- package/vite-plugin-ui-oid.ts +2106 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AlignToolbar — spec 27 §6 D4.b multi-select align/distribute toolbar:
|
|
3
|
+
* shown when ≥2 world nodes are selected (align) / ≥3 (distribute), floating
|
|
4
|
+
* above the selection's union bounding box. `RootSelectionOverlay.tsx`
|
|
5
|
+
* decides WHEN this renders (its own `computeMultiSelectionAlign` capability
|
|
6
|
+
* gate — every selected id must resolve both a rect AND an owning
|
|
7
|
+
* `boxEdit`); this component owns only the button UI + routing a click
|
|
8
|
+
* through the contract.
|
|
9
|
+
*
|
|
10
|
+
* Rule zero (spec §0): this file talks ONLY to the `AuthoringAdapter`
|
|
11
|
+
* contract, via the SAME owner-routing helper (`boxEditForId`) the B2/B3
|
|
12
|
+
* gesture code already uses — no store reach-in, no `THREE.`, no
|
|
13
|
+
* `elementFromPoint`. The align/distribute MATH itself is the pure,
|
|
14
|
+
* independently-tested `computeAlignTargets`/`computeDistributeTargets` in
|
|
15
|
+
* `world-overlay-gestures.ts` — this file only maps their output onto a
|
|
16
|
+
* `begin`/`apply`/`end` bracket per node (spec:301 "one undo step each").
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
|
|
20
|
+
import {
|
|
21
|
+
faAlignCenter,
|
|
22
|
+
faAlignLeft,
|
|
23
|
+
faAlignRight,
|
|
24
|
+
faGripLines,
|
|
25
|
+
faGripLinesVertical,
|
|
26
|
+
} from '@fortawesome/free-solid-svg-icons';
|
|
27
|
+
import {
|
|
28
|
+
EditorIcon,
|
|
29
|
+
FloatingToolbar,
|
|
30
|
+
IconButton,
|
|
31
|
+
ToolbarDivider,
|
|
32
|
+
zIndex,
|
|
33
|
+
} from '@volter/editor-sdk/widgets';
|
|
34
|
+
import type { AuthoringAdapter } from '@volter/editor-project/adapter';
|
|
35
|
+
import {
|
|
36
|
+
type AlignEntry,
|
|
37
|
+
type AlignOp,
|
|
38
|
+
type AlignTarget,
|
|
39
|
+
boxEditForId,
|
|
40
|
+
computeAlignTargets,
|
|
41
|
+
computeDistributeTargets,
|
|
42
|
+
type DistributeAxis,
|
|
43
|
+
type RectLike,
|
|
44
|
+
unionRect,
|
|
45
|
+
} from './world-overlay-gestures';
|
|
46
|
+
|
|
47
|
+
export interface AlignToolbarProps {
|
|
48
|
+
adapter: AuthoringAdapter;
|
|
49
|
+
/** The current selection's id+rect pairs — already capability-checked by
|
|
50
|
+
* the caller (every id here has a resolvable owner `boxEdit`). */
|
|
51
|
+
entries: readonly AlignEntry[];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Route every {@link AlignTarget} through its owning `boxEdit`
|
|
55
|
+
* (begin/apply/end — one undo step per node, per B1/D-1) — the ONE place
|
|
56
|
+
* align/distribute clicks touch the adapter contract. Targets whose owner
|
|
57
|
+
* has no `boxEdit` (shouldn't happen given the caller's capability gate,
|
|
58
|
+
* but honest regardless — see `boxEditForId`'s own `null` contract) are
|
|
59
|
+
* silently skipped rather than throwing. */
|
|
60
|
+
function commitAlignTargets(adapter: AuthoringAdapter, targets: readonly AlignTarget[]): void {
|
|
61
|
+
for (const t of targets) {
|
|
62
|
+
const boxEdit = boxEditForId(adapter, t.id);
|
|
63
|
+
if (!boxEdit) continue;
|
|
64
|
+
const patch: Record<string, number> = {};
|
|
65
|
+
if (t.x !== undefined) patch['x'] = t.x;
|
|
66
|
+
if (t.y !== undefined) patch['y'] = t.y;
|
|
67
|
+
if (Object.keys(patch).length === 0) continue;
|
|
68
|
+
boxEdit.begin(t.id);
|
|
69
|
+
boxEdit.apply(t.id, patch);
|
|
70
|
+
boxEdit.end(t.id);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* L-7 — every other icon in this rail is a FontAwesome glyph; this toolbar
|
|
76
|
+
* was the one holdout still rendering raw Unicode math symbols (`⊢`, `⊣⊢`,
|
|
77
|
+
* `⊤`, `⇔`, …), which clash in weight/centering with the FA icon language
|
|
78
|
+
* used everywhere else. FontAwesome Free's solid set has no dedicated
|
|
79
|
+
* object-bbox align/distribute icons (only the 4 paragraph-align glyphs;
|
|
80
|
+
* verified — no `faDistribute*`/`faAlignTop`/etc. exist in
|
|
81
|
+
* `@fortawesome/free-solid-svg-icons`), so the vertical variants reuse the
|
|
82
|
+
* horizontal align glyphs rotated 90° (`rotate` below) — the same technique
|
|
83
|
+
* several icon sets use to derive a vertical-align glyph from a horizontal
|
|
84
|
+
* one — and distribute reuses the evenly-spaced-bars grip glyphs. Still a
|
|
85
|
+
* strict style-only swap: same meaning, same button size, one consistent
|
|
86
|
+
* icon family instead of a second, unrelated glyph language.
|
|
87
|
+
*/
|
|
88
|
+
const ALIGN_BUTTONS: ReadonlyArray<{
|
|
89
|
+
op: AlignOp;
|
|
90
|
+
testId: string;
|
|
91
|
+
label: string;
|
|
92
|
+
icon: IconDefinition;
|
|
93
|
+
rotate?: boolean;
|
|
94
|
+
}> = [
|
|
95
|
+
{ op: 'left', testId: 'align-left', label: 'Align left', icon: faAlignLeft },
|
|
96
|
+
{ op: 'hcenter', testId: 'align-hcenter', label: 'Align horizontal center', icon: faAlignCenter },
|
|
97
|
+
{ op: 'right', testId: 'align-right', label: 'Align right', icon: faAlignRight },
|
|
98
|
+
{ op: 'top', testId: 'align-top', label: 'Align top', icon: faAlignLeft, rotate: true },
|
|
99
|
+
{
|
|
100
|
+
op: 'vcenter',
|
|
101
|
+
testId: 'align-vcenter',
|
|
102
|
+
label: 'Align vertical center',
|
|
103
|
+
icon: faAlignCenter,
|
|
104
|
+
rotate: true,
|
|
105
|
+
},
|
|
106
|
+
{ op: 'bottom', testId: 'align-bottom', label: 'Align bottom', icon: faAlignRight, rotate: true },
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
const DISTRIBUTE_BUTTONS: ReadonlyArray<{
|
|
110
|
+
axis: DistributeAxis;
|
|
111
|
+
testId: string;
|
|
112
|
+
label: string;
|
|
113
|
+
icon: IconDefinition;
|
|
114
|
+
}> = [
|
|
115
|
+
{
|
|
116
|
+
axis: 'horizontal',
|
|
117
|
+
testId: 'distribute-horizontal',
|
|
118
|
+
label: 'Distribute horizontally',
|
|
119
|
+
icon: faGripLinesVertical,
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
axis: 'vertical',
|
|
123
|
+
testId: 'distribute-vertical',
|
|
124
|
+
label: 'Distribute vertically',
|
|
125
|
+
icon: faGripLines,
|
|
126
|
+
},
|
|
127
|
+
];
|
|
128
|
+
|
|
129
|
+
/** Where the toolbar floats: centered above `bbox`, clamped so it never
|
|
130
|
+
* renders with a negative `top` (a selection near the host's own top edge
|
|
131
|
+
* still gets a visible toolbar, pinned just under the selection instead of
|
|
132
|
+
* off-screen above it). Pure; exported mainly for the e2e/visual read, not
|
|
133
|
+
* itself independently unit-tested (position is presentation, not the
|
|
134
|
+
* align/distribute MATH this task's acceptance criteria target). */
|
|
135
|
+
function toolbarPosition(bbox: RectLike): { left: number; top: number } {
|
|
136
|
+
const height = 30;
|
|
137
|
+
const margin = 8;
|
|
138
|
+
const top = bbox.y - height - margin;
|
|
139
|
+
return { left: bbox.x, top: top < 0 ? bbox.y + bbox.height + margin : top };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function AlignToolbar({ adapter, entries }: AlignToolbarProps): React.ReactNode {
|
|
143
|
+
if (entries.length < 2) return null;
|
|
144
|
+
const bbox = unionRect(entries.map((e) => e.rect));
|
|
145
|
+
if (!bbox) return null;
|
|
146
|
+
const { left, top } = toolbarPosition(bbox);
|
|
147
|
+
const canDistribute = entries.length >= 3;
|
|
148
|
+
|
|
149
|
+
return (
|
|
150
|
+
// U6a (P6 glass-native chrome): the one floating tool cluster that still
|
|
151
|
+
// hand-rolled an opaque chrome slab — now the shared `FloatingToolbar`
|
|
152
|
+
// island (var-driven `--vgai-island-*` material, refraction-upgradable
|
|
153
|
+
// via `vgai-glass-island`; treatment-less themes emit the pre-P6 recipe
|
|
154
|
+
// through the same vars). Geometry/placement stays inline.
|
|
155
|
+
<FloatingToolbar
|
|
156
|
+
label="Align and distribute"
|
|
157
|
+
data-testid="align-toolbar"
|
|
158
|
+
style={{
|
|
159
|
+
position: 'absolute',
|
|
160
|
+
left,
|
|
161
|
+
top,
|
|
162
|
+
zIndex: zIndex.overlayLow,
|
|
163
|
+
gap: 2,
|
|
164
|
+
padding: 3,
|
|
165
|
+
}}
|
|
166
|
+
>
|
|
167
|
+
{ALIGN_BUTTONS.map(({ op, testId, label, icon, rotate }) => (
|
|
168
|
+
<IconButton
|
|
169
|
+
key={op}
|
|
170
|
+
data-testid={testId}
|
|
171
|
+
title={label}
|
|
172
|
+
aria-label={label}
|
|
173
|
+
variant="ghost"
|
|
174
|
+
size="compact"
|
|
175
|
+
onClick={() => commitAlignTargets(adapter, computeAlignTargets(entries, op))}
|
|
176
|
+
>
|
|
177
|
+
<EditorIcon
|
|
178
|
+
icon={icon}
|
|
179
|
+
aria-hidden="true"
|
|
180
|
+
style={rotate ? { transform: 'rotate(90deg)' } : undefined}
|
|
181
|
+
/>
|
|
182
|
+
</IconButton>
|
|
183
|
+
))}
|
|
184
|
+
{canDistribute && (
|
|
185
|
+
<>
|
|
186
|
+
<ToolbarDivider />
|
|
187
|
+
{DISTRIBUTE_BUTTONS.map(({ axis, testId, label, icon }) => (
|
|
188
|
+
<IconButton
|
|
189
|
+
key={axis}
|
|
190
|
+
data-testid={testId}
|
|
191
|
+
title={label}
|
|
192
|
+
aria-label={label}
|
|
193
|
+
variant="ghost"
|
|
194
|
+
size="compact"
|
|
195
|
+
onClick={() => commitAlignTargets(adapter, computeDistributeTargets(entries, axis))}
|
|
196
|
+
>
|
|
197
|
+
<EditorIcon icon={icon} aria-hidden="true" />
|
|
198
|
+
</IconButton>
|
|
199
|
+
))}
|
|
200
|
+
</>
|
|
201
|
+
)}
|
|
202
|
+
</FloatingToolbar>
|
|
203
|
+
);
|
|
204
|
+
}
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AppRoot — the editor's own tree, and what it shows before the project is
|
|
3
|
+
* readable: a loading surface while detection runs, a startup ERROR surface
|
|
4
|
+
* when it definitively fails, the editor when it succeeds. Only a DEFINITE bad
|
|
5
|
+
* answer counts as a failure — "the server has not answered yet" keeps asking
|
|
6
|
+
* (`decideProjectDetectionRecovery`), because a tab that is merely still
|
|
7
|
+
* booting must never settle into a terminal screen with no listener on it.
|
|
8
|
+
*
|
|
9
|
+
* THERE IS NO PROJECT PICKER. A session serves ONE project — `vgai edit <dir>`
|
|
10
|
+
* is how you choose it, and the workbench's own Open Folder is how you leave —
|
|
11
|
+
* so a page that has no project has nothing to offer but the sentence saying
|
|
12
|
+
* so. The picker, its New Project wizard, its `?create-from=` deep link and
|
|
13
|
+
* the "Switch Project…" route back to it are all gone with the standalone
|
|
14
|
+
* page they lived on.
|
|
15
|
+
*
|
|
16
|
+
* This component also holds the page's SESSION PRESENCE: one SSE connection
|
|
17
|
+
* for the lifetime of the page, whatever surface is on screen, plus a report
|
|
18
|
+
* of WHICH surface that is. Presence belongs at the root because the fact it
|
|
19
|
+
* asserts — this page is attached to this session — is true at the root, not
|
|
20
|
+
* inside the editor.
|
|
21
|
+
*
|
|
22
|
+
* Key principle: No Three.js, no EditorShellStore, no RAF loop until a project
|
|
23
|
+
* is readable.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { editorDocumentTitle } from '@volter/editor-sdk/session/editor-brand';
|
|
27
|
+
import {
|
|
28
|
+
ProjectCompatibilityError,
|
|
29
|
+
type StartupRecovery,
|
|
30
|
+
} from '@volter/editor-sdk/session/editor-compatibility';
|
|
31
|
+
import { Component, type ErrorInfo, type ReactNode, useEffect, useState } from 'react';
|
|
32
|
+
import { startAccountActivity } from '../account';
|
|
33
|
+
import {
|
|
34
|
+
decideProjectDetectionRecovery,
|
|
35
|
+
ProjectDetectionTimeoutError,
|
|
36
|
+
ServerProjectDetectionError,
|
|
37
|
+
type ServerProjectFailureReport,
|
|
38
|
+
} from '../boot-routing';
|
|
39
|
+
import { EditorProvider } from '../EditorContext';
|
|
40
|
+
import { editorConsole } from '../editor-console';
|
|
41
|
+
import { connectTabPresence, reportTabRoute } from '../editor-presence';
|
|
42
|
+
import { type ActiveProject, detectProject } from '../project-manager';
|
|
43
|
+
import { onTabAdopt } from '../tab-lifecycle-client';
|
|
44
|
+
import { DefaultEditorLayout } from './DefaultEditorLayout';
|
|
45
|
+
import { EditorLeaseGuard } from './EditorLeaseGuard';
|
|
46
|
+
import { StartupErrorScreen } from './StartupErrorScreen';
|
|
47
|
+
import { StartupLoadingScreen } from './StartupLoadingScreen';
|
|
48
|
+
|
|
49
|
+
type State =
|
|
50
|
+
| {
|
|
51
|
+
status: 'detecting';
|
|
52
|
+
/** When the CURRENT run of attempts began, or null while the first
|
|
53
|
+
* attempt is still in flight — an instant boot must not flash a
|
|
54
|
+
* "we're waiting" surface it will never need. */
|
|
55
|
+
waitingSince: number | null;
|
|
56
|
+
/** The last failed attempt's message, shown verbatim while we re-ask. */
|
|
57
|
+
lastError?: string;
|
|
58
|
+
}
|
|
59
|
+
| { status: 'no-project'; returnProject?: ActiveProject }
|
|
60
|
+
| {
|
|
61
|
+
status: 'error';
|
|
62
|
+
message: string;
|
|
63
|
+
recovery?: StartupRecovery;
|
|
64
|
+
report?: ServerProjectFailureReport;
|
|
65
|
+
}
|
|
66
|
+
| { status: 'ready'; project: ActiveProject };
|
|
67
|
+
|
|
68
|
+
interface EditorRuntimeBoundaryProps {
|
|
69
|
+
readonly children: ReactNode;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Keep the application-level EditorProvider alive when editor chrome throws.
|
|
74
|
+
* The provider owns the command listener, so letting an unwrapped descendant
|
|
75
|
+
* error unmount it leaves a still-beating tab that can no longer answer
|
|
76
|
+
* `vgai status`, `play`, or recovery commands. The fallback is deliberately a
|
|
77
|
+
* normal startup-error surface inside the provider: Retry re-renders the
|
|
78
|
+
* chrome; Project Browser remains reachable; the listener never goes away.
|
|
79
|
+
*/
|
|
80
|
+
class EditorRuntimeBoundary extends Component<
|
|
81
|
+
EditorRuntimeBoundaryProps,
|
|
82
|
+
{ readonly error: Error | null }
|
|
83
|
+
> {
|
|
84
|
+
override state: { readonly error: Error | null } = { error: null };
|
|
85
|
+
|
|
86
|
+
static getDerivedStateFromError(error: Error): { readonly error: Error } {
|
|
87
|
+
return { error };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
override componentDidCatch(error: Error, info: ErrorInfo): void {
|
|
91
|
+
editorConsole.error(
|
|
92
|
+
`Editor chrome crashed while the command listener stayed attached: ${error.message}\n${info.componentStack ?? ''}`,
|
|
93
|
+
'editor',
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
override render(): ReactNode {
|
|
98
|
+
if (!this.state.error) return this.props.children;
|
|
99
|
+
return (
|
|
100
|
+
<StartupErrorScreen
|
|
101
|
+
error={{ message: `The editor surface crashed: ${this.state.error.message}` }}
|
|
102
|
+
onRetry={() => this.setState({ error: null })}
|
|
103
|
+
/>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Every surface this app can show, wrapped so the supervised lease
|
|
110
|
+
* (`EditorLeaseGuard` / `editor-lease.ts`) is mounted on ALL of them.
|
|
111
|
+
*
|
|
112
|
+
* It used to be mounted on exactly one — a child of `EditorRuntimeBoundary`
|
|
113
|
+
* inside the `ready` branch — which put the watchdog in the only place a
|
|
114
|
+
* failing server tends not to leave the user. A server that dies while the
|
|
115
|
+
* launcher is up, or that takes the boot probe down with it onto the error
|
|
116
|
+
* screen, or that makes some piece of chrome throw and so trips the boundary
|
|
117
|
+
* into replacing its children (the watchdog among them, permanently), produced
|
|
118
|
+
* a page with no supervision at all: fully rendered, perfectly healthy-looking,
|
|
119
|
+
* and never going to say otherwise. The surfaces a dead server actually
|
|
120
|
+
* produces were the ones not watching for it.
|
|
121
|
+
*
|
|
122
|
+
* Being OUTSIDE the boundary is half the point and not an accident of
|
|
123
|
+
* nesting: the guard's whole job is to survive the failures that break the
|
|
124
|
+
* editor, so it must not be something the editor's own crash can unmount. It
|
|
125
|
+
* needs no context and mounts nothing but a portal, so there is nothing for it
|
|
126
|
+
* to be inside of.
|
|
127
|
+
*/
|
|
128
|
+
function EditorSurface({ children }: { readonly children: ReactNode }) {
|
|
129
|
+
return (
|
|
130
|
+
<>
|
|
131
|
+
{children}
|
|
132
|
+
<EditorLeaseGuard />
|
|
133
|
+
</>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function startupFailure(error: unknown): Extract<State, { status: 'error' }> {
|
|
138
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
139
|
+
if (error instanceof ProjectCompatibilityError) {
|
|
140
|
+
return { status: 'error', message, recovery: error.recovery };
|
|
141
|
+
}
|
|
142
|
+
// A boot probe that failed carries the server's own answer — the served
|
|
143
|
+
// path and the verbatim error — so the surface can name both instead of
|
|
144
|
+
// flattening them into one sentence.
|
|
145
|
+
if (error instanceof ServerProjectDetectionError) {
|
|
146
|
+
return { status: 'error', message, report: error.report };
|
|
147
|
+
}
|
|
148
|
+
return { status: 'error', message };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* How long ONE detection attempt waits before giving up on that attempt.
|
|
153
|
+
*
|
|
154
|
+
* This is a pacing deadline, never a verdict (`decideProjectDetectionRecovery`).
|
|
155
|
+
* Project detection is normally a pair of local fetches and finishes almost
|
|
156
|
+
* immediately, but on the FIRST boot of a fresh checkout — Vite transforming
|
|
157
|
+
* the editor graph cold — it legitimately takes far longer, and the previous
|
|
158
|
+
* code turned that elapsed deadline into a terminal error screen on an
|
|
159
|
+
* otherwise perfectly healthy tab. Abandoning an attempt is still worth doing:
|
|
160
|
+
* a request lost under a cold boot's connection pressure never settles, and
|
|
161
|
+
* re-asking is how it gets un-stuck.
|
|
162
|
+
*/
|
|
163
|
+
export const PROJECT_DETECTION_TIMEOUT_MS = 8_000;
|
|
164
|
+
|
|
165
|
+
export function detectProjectWithTimeout(
|
|
166
|
+
detect: () => Promise<ActiveProject | null> = detectProject,
|
|
167
|
+
timeoutMs = PROJECT_DETECTION_TIMEOUT_MS,
|
|
168
|
+
): Promise<ActiveProject | null> {
|
|
169
|
+
return new Promise((resolve, reject) => {
|
|
170
|
+
const timeout = window.setTimeout(() => {
|
|
171
|
+
reject(new ProjectDetectionTimeoutError(timeoutMs));
|
|
172
|
+
}, timeoutMs);
|
|
173
|
+
detect().then(
|
|
174
|
+
(project) => {
|
|
175
|
+
window.clearTimeout(timeout);
|
|
176
|
+
resolve(project);
|
|
177
|
+
},
|
|
178
|
+
(error: unknown) => {
|
|
179
|
+
window.clearTimeout(timeout);
|
|
180
|
+
reject(error);
|
|
181
|
+
},
|
|
182
|
+
);
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** Read + shape-check the `?create-from=` deep-link param (G4). Returns the
|
|
187
|
+
* candidate id, or null when absent/malformed. Ids share the example-folder
|
|
188
|
+
* shape (`hosted-example.ts`'s gate); a malformed value is treated as absent
|
|
189
|
+
* at the routing layer — the WIZARD still opens (the user's intent to create
|
|
190
|
+
* was explicit), with a non-blocking unknown-id notice. */
|
|
191
|
+
export function createFromParam(search: string): string | null {
|
|
192
|
+
const raw = new URLSearchParams(search).get('create-from');
|
|
193
|
+
if (raw === null) return null;
|
|
194
|
+
return raw.trim() || null;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/** Attempts before a still-retrying detection reports itself to the console. */
|
|
198
|
+
const PROJECT_DETECTION_REPORT_AFTER = 3;
|
|
199
|
+
|
|
200
|
+
export function AppRoot() {
|
|
201
|
+
const [state, setState] = useState<State>({ status: 'detecting', waitingSince: null });
|
|
202
|
+
const [detectionAttempt, setDetectionAttempt] = useState(0);
|
|
203
|
+
|
|
204
|
+
// Account is product-global. Keep its session current on the Welcome /
|
|
205
|
+
// Project Browser just as in the project editor; project selection must not
|
|
206
|
+
// be a prerequisite for identity or billing management.
|
|
207
|
+
useEffect(() => startAccountActivity(), []);
|
|
208
|
+
|
|
209
|
+
// Session presence for the LIFE OF THE PAGE (see the module docstring): the
|
|
210
|
+
// tab bijection counts tabs, and a tab is a tab on every surface.
|
|
211
|
+
useEffect(() => connectTabPresence(), []);
|
|
212
|
+
|
|
213
|
+
// `tab-adopt`: this tab is the session's one tab but is not on the project.
|
|
214
|
+
// Re-run detection rather than opening a second tab — the same work the
|
|
215
|
+
// Retry button does, which is exactly what adoption means here.
|
|
216
|
+
useEffect(() => onTabAdopt(() => setDetectionAttempt((attempt) => attempt + 1)), []);
|
|
217
|
+
|
|
218
|
+
// Detection RUNS UNTIL IT GETS AN ANSWER. A failure that means "the server
|
|
219
|
+
// has not answered yet" schedules another ask (backoff in boot-routing) and
|
|
220
|
+
// keeps the boot surface up, saying how long it has been waiting; only a
|
|
221
|
+
// definite bad answer lands on the terminal error surface. The alternative —
|
|
222
|
+
// one attempt, one deadline, one verdict — put a healthy tab (beating,
|
|
223
|
+
// echoing, socket up) on a dead-end screen with no command listener for the
|
|
224
|
+
// entire cold first boot of a fresh checkout.
|
|
225
|
+
useEffect(() => {
|
|
226
|
+
let cancelled = false;
|
|
227
|
+
let retryTimer: number | undefined;
|
|
228
|
+
let failures = 0;
|
|
229
|
+
const startedAt = Date.now();
|
|
230
|
+
setState({ status: 'detecting', waitingSince: null });
|
|
231
|
+
|
|
232
|
+
const ask = () => {
|
|
233
|
+
detectProjectWithTimeout().then(
|
|
234
|
+
(project) => {
|
|
235
|
+
if (cancelled) return;
|
|
236
|
+
if (project) {
|
|
237
|
+
setState({ status: 'ready', project });
|
|
238
|
+
} else {
|
|
239
|
+
setState({ status: 'no-project' });
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
(error: unknown) => {
|
|
243
|
+
if (cancelled) return;
|
|
244
|
+
failures += 1;
|
|
245
|
+
const recovery = decideProjectDetectionRecovery(error, failures);
|
|
246
|
+
if (recovery.kind === 'terminal') {
|
|
247
|
+
const failure = startupFailure(error);
|
|
248
|
+
// A TERMINAL failure renders `StartupErrorScreen` in the tab and,
|
|
249
|
+
// until now, nothing else: the tab beat, reported `no-project`,
|
|
250
|
+
// attached no command listener, and every session door read that
|
|
251
|
+
// as a healthy cold boot (`vgai status`: "commandListener not
|
|
252
|
+
// attached"). Measured 2026-09-17 on two sessions at once — a
|
|
253
|
+
// project pinned below the editor's engine, and an editor server
|
|
254
|
+
// older than the project it served — both invisible for an hour.
|
|
255
|
+
// The console is server-held, so this reaches `vgai status` and
|
|
256
|
+
// `vgai console` whether or not anyone looks at the tab.
|
|
257
|
+
const command =
|
|
258
|
+
failure.recovery && 'command' in failure.recovery ? failure.recovery.command : null;
|
|
259
|
+
editorConsole.error(
|
|
260
|
+
`Startup failed: ${failure.message}${command ? ` Run: ${command}` : ''}`,
|
|
261
|
+
'editor',
|
|
262
|
+
);
|
|
263
|
+
setState(failure);
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
267
|
+
// A RETRY THAT NEVER SUCCEEDS IS INVISIBLE FROM OUTSIDE. The boot
|
|
268
|
+
// surface says how long it has been waiting, on screen; every other
|
|
269
|
+
// door -- `vgai status`, the session journal -- sees only
|
|
270
|
+
// `route: unknown` and a tab with no command listener, which is also
|
|
271
|
+
// what a healthy cold boot looks like. A project pinned to an older
|
|
272
|
+
// engine than the editor throws here on EVERY attempt, and the tab
|
|
273
|
+
// then waits for something that cannot change, silently.
|
|
274
|
+
//
|
|
275
|
+
// So the reason goes to the editor console, which the server holds
|
|
276
|
+
// and `vgai console` prints whether or not this page ever mounts.
|
|
277
|
+
// Once, on the attempt the patient loop stops being patient about.
|
|
278
|
+
if (failures === PROJECT_DETECTION_REPORT_AFTER) {
|
|
279
|
+
editorConsole.error(
|
|
280
|
+
`Project detection has failed ${failures} times and is still retrying: ${reason}`,
|
|
281
|
+
'editor',
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
setState({
|
|
285
|
+
status: 'detecting',
|
|
286
|
+
waitingSince: startedAt,
|
|
287
|
+
lastError: reason,
|
|
288
|
+
});
|
|
289
|
+
retryTimer = window.setTimeout(ask, recovery.delayMs);
|
|
290
|
+
},
|
|
291
|
+
);
|
|
292
|
+
};
|
|
293
|
+
ask();
|
|
294
|
+
|
|
295
|
+
return () => {
|
|
296
|
+
cancelled = true;
|
|
297
|
+
if (retryTimer !== undefined) window.clearTimeout(retryTimer);
|
|
298
|
+
};
|
|
299
|
+
}, [detectionAttempt]);
|
|
300
|
+
|
|
301
|
+
// The waiting clock. Only ticks once detection has actually failed at least
|
|
302
|
+
// once, so an ordinary boot never mounts an interval at all.
|
|
303
|
+
const waitingSince = state.status === 'detecting' ? state.waitingSince : null;
|
|
304
|
+
const [waitedSeconds, setWaitedSeconds] = useState(0);
|
|
305
|
+
useEffect(() => {
|
|
306
|
+
if (waitingSince === null) {
|
|
307
|
+
setWaitedSeconds(0);
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
const tick = () =>
|
|
311
|
+
setWaitedSeconds(Math.max(0, Math.round((Date.now() - waitingSince) / 1000)));
|
|
312
|
+
tick();
|
|
313
|
+
const interval = window.setInterval(tick, 1_000);
|
|
314
|
+
return () => window.clearInterval(interval);
|
|
315
|
+
}, [waitingSince]);
|
|
316
|
+
|
|
317
|
+
// Which surface this tab is showing, reported from the ONE place that
|
|
318
|
+
// decides it. `detecting` says nothing: a booting tab is on its way to the
|
|
319
|
+
// project, and the server reads an unreported route exactly that way. That
|
|
320
|
+
// stays true through the patient retry loop — a tab still asking is still on
|
|
321
|
+
// its way, so `vgai edit` refocuses it rather than opening a second one, and
|
|
322
|
+
// the vocabulary is unchanged.
|
|
323
|
+
useEffect(() => {
|
|
324
|
+
if (state.status === 'detecting') return;
|
|
325
|
+
reportTabRoute(state.status === 'ready' ? 'project' : 'no-project');
|
|
326
|
+
}, [state.status]);
|
|
327
|
+
|
|
328
|
+
const titleSubject =
|
|
329
|
+
state.status === 'ready'
|
|
330
|
+
? state.project.config.name
|
|
331
|
+
: state.status === 'error'
|
|
332
|
+
? "Couldn't open project"
|
|
333
|
+
: null;
|
|
334
|
+
useEffect(() => {
|
|
335
|
+
document.title = editorDocumentTitle(titleSubject);
|
|
336
|
+
}, [titleSubject]);
|
|
337
|
+
|
|
338
|
+
if (state.status === 'detecting') {
|
|
339
|
+
return (
|
|
340
|
+
<EditorSurface>
|
|
341
|
+
<StartupLoadingScreen
|
|
342
|
+
wait={
|
|
343
|
+
state.waitingSince === null
|
|
344
|
+
? undefined
|
|
345
|
+
: { seconds: waitedSeconds, detail: state.lastError }
|
|
346
|
+
}
|
|
347
|
+
/>
|
|
348
|
+
</EditorSurface>
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
if (state.status === 'no-project') {
|
|
353
|
+
// A SESSION SERVES ONE PROJECT and this page has none — the folder the
|
|
354
|
+
// workbench opened is not one. There is nothing to pick from here: say
|
|
355
|
+
// which door opens a project and stop.
|
|
356
|
+
return (
|
|
357
|
+
<EditorSurface>
|
|
358
|
+
<StartupErrorScreen
|
|
359
|
+
error={{
|
|
360
|
+
message:
|
|
361
|
+
'This window has no vgai project open. A session serves one project: open a folder ' +
|
|
362
|
+
'that carries a vgai.project.json, or start one from a terminal — `volter-editor edit <folder>`.',
|
|
363
|
+
}}
|
|
364
|
+
onRetry={() => setDetectionAttempt((attempt) => attempt + 1)}
|
|
365
|
+
/>
|
|
366
|
+
</EditorSurface>
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (state.status === 'error') {
|
|
371
|
+
return (
|
|
372
|
+
<EditorSurface>
|
|
373
|
+
<StartupErrorScreen
|
|
374
|
+
error={{
|
|
375
|
+
message: state.message,
|
|
376
|
+
...(state.recovery ? { recovery: state.recovery } : {}),
|
|
377
|
+
}}
|
|
378
|
+
report={state.report}
|
|
379
|
+
onRetry={() => setDetectionAttempt((attempt) => attempt + 1)}
|
|
380
|
+
/>
|
|
381
|
+
</EditorSurface>
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
return (
|
|
386
|
+
<EditorSurface>
|
|
387
|
+
<EditorProvider>
|
|
388
|
+
<EditorRuntimeBoundary>
|
|
389
|
+
<DefaultEditorLayout />
|
|
390
|
+
</EditorRuntimeBoundary>
|
|
391
|
+
</EditorProvider>
|
|
392
|
+
</EditorSurface>
|
|
393
|
+
);
|
|
394
|
+
}
|