@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,500 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KIND DOCUMENTS — an adapter-table document (a model, a page; ARCHITECTURE-CORE
|
|
3
|
+
* §The project model, "Documents, not scenes") opened in the editor
|
|
4
|
+
* registered for its kind (owner ruling, 2026-09-05: the tab IS the thing —
|
|
5
|
+
* `cage`, kind Model — and the editor is chosen by the document's kind; code
|
|
6
|
+
* is never a fallback, it opens only when code is opened).
|
|
7
|
+
*
|
|
8
|
+
* A `workspace.document` contribution declares `export const documentKind =
|
|
9
|
+
* 'model'` (`tool-loader.ts`, `documentContributionForKind`). Opening a table
|
|
10
|
+
* entry of that kind opens ONE document per entry — id `document:<entry id>`,
|
|
11
|
+
* title = the entry's label — whose content, header and shelf are the
|
|
12
|
+
* contribution's own components mounted through the same `ToolHost` a tool
|
|
13
|
+
* document uses, with the entry handed over as `props.document`
|
|
14
|
+
* (`ToolDocumentEntry`). Persisted and restored by the entry's id
|
|
15
|
+
* (`workspace-state-persistence.ts`); presented in view links as
|
|
16
|
+
* `{ kind: 'document', id }`. A kind with no registered editor opens nothing
|
|
17
|
+
* here and the caller falls back to the entry's source, by its own choice.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import type { ToolDocumentEntry } from '@volter/editor-sdk/contributions';
|
|
21
|
+
import { themeVars } from '@volter/editor-sdk/widgets';
|
|
22
|
+
import type { DocumentEntry } from '@volter/editor-project/adapter/adapter-module';
|
|
23
|
+
import { type ComponentType, useSyncExternalStore } from 'react';
|
|
24
|
+
import { setSelectedAsset } from '../asset-selection';
|
|
25
|
+
import { assetCapabilities } from '../asset-workflow/asset-capabilities';
|
|
26
|
+
import {
|
|
27
|
+
awaitAnnouncedObject3DDocumentSession,
|
|
28
|
+
waitForContributedDocumentMount,
|
|
29
|
+
} from '../document-context-registry';
|
|
30
|
+
import { registerDocumentOpener } from '../document-open-registry';
|
|
31
|
+
import type { AssetKind, ViewportTab } from '../editor-shell-store';
|
|
32
|
+
import {
|
|
33
|
+
projectAdapterFacet,
|
|
34
|
+
type ResolvedDocumentTable,
|
|
35
|
+
subscribeProjectAdapter,
|
|
36
|
+
} from '../project-adapter';
|
|
37
|
+
import {
|
|
38
|
+
documentContributionForKind,
|
|
39
|
+
getGlobalToolContributions,
|
|
40
|
+
subscribeToolContributions,
|
|
41
|
+
} from '../tool-loader';
|
|
42
|
+
import { waitUntil } from '../wait-until';
|
|
43
|
+
import {
|
|
44
|
+
type OpenWorkspaceDocumentOptions,
|
|
45
|
+
openWorkspaceDocument,
|
|
46
|
+
openWorkspaceDocuments,
|
|
47
|
+
type WorkspaceDocumentContentProps,
|
|
48
|
+
} from '../workspace-document-registry';
|
|
49
|
+
import { registerWorkspaceDocumentRestorer } from '../workspace-document-restore';
|
|
50
|
+
import { openAssetDocument } from './asset-documents';
|
|
51
|
+
import { ToolHost } from './ToolHost';
|
|
52
|
+
|
|
53
|
+
export interface KindDocumentStore {
|
|
54
|
+
setActiveViewportTab(tab: ViewportTab): void;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const PREFIX = 'document:';
|
|
58
|
+
|
|
59
|
+
/** Stable identity for one table entry's document. */
|
|
60
|
+
export function kindDocumentId(entryId: string): string {
|
|
61
|
+
return `${PREFIX}${entryId}`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** The table entry id a kind document id names, or `null` for another kind of id. */
|
|
65
|
+
export function kindDocumentEntryId(documentId: string): string | null {
|
|
66
|
+
return documentId.startsWith(PREFIX) ? documentId.slice(PREFIX.length) : null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** The entries of every open kind document, by document id — what content,
|
|
70
|
+
* header and shelf mounts read, and what persistence records. */
|
|
71
|
+
const entries = new Map<
|
|
72
|
+
string,
|
|
73
|
+
{ readonly entry: DocumentEntry; readonly props: ToolDocumentEntry }
|
|
74
|
+
>();
|
|
75
|
+
|
|
76
|
+
export function kindDocumentEntry(documentId: string): DocumentEntry | undefined {
|
|
77
|
+
return entries.get(documentId)?.entry;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function asToolDocumentEntry(entry: DocumentEntry): ToolDocumentEntry {
|
|
81
|
+
return {
|
|
82
|
+
id: entry.id,
|
|
83
|
+
kind: entry.kind,
|
|
84
|
+
label: entry.label,
|
|
85
|
+
...(entry.source
|
|
86
|
+
? {
|
|
87
|
+
source: {
|
|
88
|
+
path: entry.source.path,
|
|
89
|
+
...(entry.source.export ? { export: entry.source.export } : {}),
|
|
90
|
+
},
|
|
91
|
+
}
|
|
92
|
+
: {}),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* What a table entry of a kind NOTHING edits opens as: the asset its source
|
|
98
|
+
* already is. A module, or anything the asset routes do not know, opens as
|
|
99
|
+
* source; a kind the routes DO know (a model, an image, a video) opens in its
|
|
100
|
+
* own viewer. Before this, every unedited kind opened as source.
|
|
101
|
+
*/
|
|
102
|
+
export function uneditedKindAssetKind(entry: DocumentEntry): AssetKind {
|
|
103
|
+
const path = entry.source?.path;
|
|
104
|
+
if (!path) return 'source';
|
|
105
|
+
const kind = assetCapabilities(path).kind;
|
|
106
|
+
return kind === 'model' ||
|
|
107
|
+
kind === 'image' ||
|
|
108
|
+
kind === 'video' ||
|
|
109
|
+
kind === 'audio' ||
|
|
110
|
+
kind === 'json'
|
|
111
|
+
? kind
|
|
112
|
+
: 'source';
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Is there an editor registered for documents of `kind`? */
|
|
116
|
+
export function hasKindEditor(kind: string): boolean {
|
|
117
|
+
return documentContributionForKind(kind) !== undefined;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Open (or activate) the document for one table entry in the editor
|
|
122
|
+
* registered for its kind. `false` (opens nothing) when no contribution
|
|
123
|
+
* declares that kind — the caller decides what an unedited kind opens as.
|
|
124
|
+
*/
|
|
125
|
+
export function openKindDocument(
|
|
126
|
+
store: KindDocumentStore | null,
|
|
127
|
+
entry: DocumentEntry,
|
|
128
|
+
options: OpenWorkspaceDocumentOptions = {},
|
|
129
|
+
): boolean {
|
|
130
|
+
const contribution = documentContributionForKind(entry.kind);
|
|
131
|
+
if (!contribution) return false;
|
|
132
|
+
const id = kindDocumentId(entry.id);
|
|
133
|
+
entries.set(id, { entry, props: asToolDocumentEntry(entry) });
|
|
134
|
+
openWorkspaceDocument(
|
|
135
|
+
{
|
|
136
|
+
id,
|
|
137
|
+
// The tab is the THING: the entry's own label, never the editor's name.
|
|
138
|
+
title: entry.label,
|
|
139
|
+
kind: 'document',
|
|
140
|
+
workspaceRole: 'authored-subject',
|
|
141
|
+
provenance: {
|
|
142
|
+
...(entry.source ? { sourcePath: entry.source.path } : {}),
|
|
143
|
+
origin: contribution.file,
|
|
144
|
+
},
|
|
145
|
+
Content: KindDocumentContent,
|
|
146
|
+
...(contribution.Toolbar ? { Toolbar: KindDocumentToolbar } : {}),
|
|
147
|
+
...(contribution.Shelf ? { Shelf: KindDocumentShelf } : {}),
|
|
148
|
+
presentation: () => ({ kind: 'document', id: entry.id }),
|
|
149
|
+
persist: () => ({ entryId: entry.id }),
|
|
150
|
+
onDispose: (documentId) => {
|
|
151
|
+
entries.delete(documentId);
|
|
152
|
+
},
|
|
153
|
+
...(store ? { onActivate: () => store.setActiveViewportTab('edit') } : {}),
|
|
154
|
+
},
|
|
155
|
+
options,
|
|
156
|
+
);
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* THE `document` ADDRESS (`document-open-registry.ts`) — the other half of the
|
|
162
|
+
* `presentation()` above. An entry's id is the whole address; which editor
|
|
163
|
+
* opens it, and what that document's id turns out to be, are this module's
|
|
164
|
+
* rules and the presenter no longer holds either. Registered at module load,
|
|
165
|
+
* the shape `packages/game/src/story-documents/three-story-documents.tsx:239`
|
|
166
|
+
* uses.
|
|
167
|
+
*
|
|
168
|
+
* SETTLING is the two waits an explicit address needs, and they are separate
|
|
169
|
+
* because they fail differently. The TABLE resolves more than once — a
|
|
170
|
+
* contributed finder (the mesh capability's models finder) registers after the
|
|
171
|
+
* first resolution and brings its entries — so a missing entry is not yet an
|
|
172
|
+
* answer; and a kind's EDITOR arrives with the contribution pass, which on a
|
|
173
|
+
* cold reload is well past the default window. Each refuses in its own words:
|
|
174
|
+
* a table that lists no such document is a different defect from a kind
|
|
175
|
+
* nothing can edit, and only this module can tell them apart.
|
|
176
|
+
*/
|
|
177
|
+
registerDocumentOpener<{ readonly id: string }>({
|
|
178
|
+
id: 'document',
|
|
179
|
+
owner: 'kind-documents',
|
|
180
|
+
open: (store, request) => {
|
|
181
|
+
const entry = tableEntry(request.id);
|
|
182
|
+
if (!entry || !hasKindEditor(entry.kind)) return null;
|
|
183
|
+
return openKindDocument(store, entry) ? kindDocumentId(entry.id) : null;
|
|
184
|
+
},
|
|
185
|
+
settle: async (request) => {
|
|
186
|
+
const REGISTRATION_WINDOW_MS = 20_000;
|
|
187
|
+
await waitUntil(() => tableEntry(request.id) !== undefined, REGISTRATION_WINDOW_MS);
|
|
188
|
+
const entry = tableEntry(request.id);
|
|
189
|
+
if (!entry) throw new Error(`The project's document table lists no document: ${request.id}`);
|
|
190
|
+
if (await waitUntil(() => hasKindEditor(entry.kind), REGISTRATION_WINDOW_MS)) return;
|
|
191
|
+
throw new Error(
|
|
192
|
+
`No editor is registered for documents of kind '${entry.kind}' (${request.id})`,
|
|
193
|
+
);
|
|
194
|
+
},
|
|
195
|
+
/**
|
|
196
|
+
* THE KIND'S OWN READINESS — a contributed document is ready to be driven
|
|
197
|
+
* once its React root has committed and, if that root mounted a stage, once
|
|
198
|
+
* the stage has registered its Object3D session. The presenter used to hold
|
|
199
|
+
* this rule for this address by name (`editor-view-presentation.ts`'s
|
|
200
|
+
* `kind === 'tool' || 'asset'`); it belongs here, where the contribution the
|
|
201
|
+
* host mounted is what answers.
|
|
202
|
+
*/
|
|
203
|
+
ready: async (documentId) => {
|
|
204
|
+
await waitForContributedDocumentMount(documentId);
|
|
205
|
+
await awaitAnnouncedObject3DDocumentSession(documentId);
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
function tableEntry(id: string): DocumentEntry | undefined {
|
|
210
|
+
return projectAdapterFacet()?.scenes.entries.find((candidate) => candidate.id === id);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* `openKindDocument` once the kind's editor is registered — now, or when the
|
|
215
|
+
* contribution pass that brings it completes. A restored layout and a
|
|
216
|
+
* shared view both name a document before the project's contributions have
|
|
217
|
+
* loaded (measured 2026-09-05: the entry arrived, the editor had not, and
|
|
218
|
+
* the document opened nothing). Gives up when the project changes under it.
|
|
219
|
+
*/
|
|
220
|
+
export function openKindDocumentWhenReady(
|
|
221
|
+
store: KindDocumentStore | null,
|
|
222
|
+
entry: DocumentEntry,
|
|
223
|
+
options: OpenWorkspaceDocumentOptions = {},
|
|
224
|
+
): void {
|
|
225
|
+
if (openKindDocument(store, entry, options)) return;
|
|
226
|
+
const stop = subscribeToolContributions(() => {
|
|
227
|
+
if (openKindDocument(store, entry, options)) stop();
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** Every open kind document takes its slots afresh when contributions
|
|
232
|
+
* change (a module re-evaluated on save may have gained or lost its
|
|
233
|
+
* `Toolbar`); `openWorkspaceDocument` on an open id refreshes the descriptor. */
|
|
234
|
+
export function installKindDocumentRefresh(store: KindDocumentStore): () => void {
|
|
235
|
+
return subscribeToolContributions(() => {
|
|
236
|
+
const open = new Set(openWorkspaceDocuments().map((d) => d.descriptor.id));
|
|
237
|
+
for (const [id, { entry }] of entries) {
|
|
238
|
+
if (!open.has(id)) continue;
|
|
239
|
+
if (documentContributionForKind(entry.kind))
|
|
240
|
+
openKindDocument(store, entry, { activate: false });
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// --- Restore, and what this kind does when a project opens ----------------
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Run `fn` with the table entry `entryId` names once the adapter's table
|
|
249
|
+
* lists it — now, or on the adapter change that brings it. A table resolves
|
|
250
|
+
* MORE THAN ONCE: a contributed finder (the mesh capability's models finder)
|
|
251
|
+
* registers after the first resolution and the table is resolved again with
|
|
252
|
+
* its entries, so "not pending" is not "complete" (measured 2026-09-05: a
|
|
253
|
+
* model document restored on the first resolution found no entry). Stops
|
|
254
|
+
* waiting when the project changes under it.
|
|
255
|
+
*/
|
|
256
|
+
function whenDocumentEntry(entryId: string, fn: (entry: DocumentEntry) => void): void {
|
|
257
|
+
const attempt = (): boolean => {
|
|
258
|
+
const facet = projectAdapterFacet();
|
|
259
|
+
if (!facet) return false;
|
|
260
|
+
const entry = facet.scenes.entries.find((candidate) => candidate.id === entryId);
|
|
261
|
+
if (!entry) return false;
|
|
262
|
+
fn(entry);
|
|
263
|
+
return true;
|
|
264
|
+
};
|
|
265
|
+
if (attempt()) return;
|
|
266
|
+
const stop = subscribeProjectAdapter(() => {
|
|
267
|
+
if (attempt()) stop();
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/** The table entry a fresh checkout opens on: the declared default when it
|
|
272
|
+
* is a document with a source (and not a scene, which is pinned elsewhere),
|
|
273
|
+
* else the NEWEST such entry — the table lists finder sources newest first,
|
|
274
|
+
* so with several models and nothing declared the one most recently written
|
|
275
|
+
* is the one on screen (Photoshop reopens the last document; a models
|
|
276
|
+
* project with two models and no record used to open on nothing at all). */
|
|
277
|
+
function defaultTableEntry(table: ResolvedDocumentTable): DocumentEntry | null {
|
|
278
|
+
const candidates = table.entries.filter(
|
|
279
|
+
(entry) => entry.kind !== 'scene' && entry.kind !== 'prefab' && entry.source !== undefined,
|
|
280
|
+
);
|
|
281
|
+
const declared = candidates.find((entry) => entry.id === table.default);
|
|
282
|
+
if (declared) return declared;
|
|
283
|
+
return candidates[0] ?? null;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* THE THING BEING WORKED ON IS THE DOCUMENT. Blender opens on its scene,
|
|
288
|
+
* Photoshop on its file; a models project should open on the model the agent
|
|
289
|
+
* or the person is making, not on the starter cube it scaffolded. Measured
|
|
290
|
+
* 2026-09-06: an owner watched a bench session write `mushroom.ts`, look at it
|
|
291
|
+
* nine times, and the viewport showed `cage` throughout, because the only
|
|
292
|
+
* automatic open was the boot-time default.
|
|
293
|
+
*
|
|
294
|
+
* So: when the adapter table gains a NEW non-scene entry after its first
|
|
295
|
+
* settled resolution (a model module written to `src/models/`, a page added),
|
|
296
|
+
* the latest entry opens as a replaceable preview, selected the way a Content
|
|
297
|
+
* click leaves it. Explicitly opened or edited tabs stay open. A discovery
|
|
298
|
+
* batch opens only one preview: importing a scene with 35 model modules must
|
|
299
|
+
* not create 35 GPU contexts. Entries already in the table are the user's to open;
|
|
300
|
+
* an entry that comes back after a rename is new to the table and opens.
|
|
301
|
+
* Installed once per project load; the previous watch is dropped.
|
|
302
|
+
*/
|
|
303
|
+
let stopFollowingTableDocuments: (() => void) | null = null;
|
|
304
|
+
/** The follow rule's baseline, persisted as this kind's own session state. */
|
|
305
|
+
let seenTableIds: Set<string> | null = null;
|
|
306
|
+
/**
|
|
307
|
+
* A table entry that APPEARS while this workspace is open is the document
|
|
308
|
+
* being worked on (Blender opens on its scene, Photoshop on its file): open
|
|
309
|
+
* it, active, selected the way a Content click leaves it. `seen` is the
|
|
310
|
+
* baseline a previous page of this workspace persisted — without it every
|
|
311
|
+
* Vite full reload (a tsconfig event, an invalidation the graph cannot
|
|
312
|
+
* patch) reset the baseline to "everything now", and a model written in
|
|
313
|
+
* the seconds around a reload was never opened (measured 2026-09-06: an
|
|
314
|
+
* agent iterated a mushroom 24 times while the owner's viewport showed the
|
|
315
|
+
* starter cube).
|
|
316
|
+
*/
|
|
317
|
+
function followNewTableDocuments(store: KindDocumentStore, seen?: readonly string[]): void {
|
|
318
|
+
stopFollowingTableDocuments?.();
|
|
319
|
+
let known: Set<string> | null = seen ? new Set(seen) : null;
|
|
320
|
+
const observe = (): void => {
|
|
321
|
+
const facet = projectAdapterFacet();
|
|
322
|
+
if (!facet || facet.documentsPending) return;
|
|
323
|
+
const ids = new Set(facet.scenes.entries.map((entry) => entry.id));
|
|
324
|
+
if (known === null) {
|
|
325
|
+
known = ids;
|
|
326
|
+
seenTableIds = ids;
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
const entry = [...facet.scenes.entries]
|
|
330
|
+
.reverse()
|
|
331
|
+
.find(
|
|
332
|
+
(candidate) =>
|
|
333
|
+
!known?.has(candidate.id) &&
|
|
334
|
+
candidate.kind !== 'scene' &&
|
|
335
|
+
candidate.kind !== 'prefab' &&
|
|
336
|
+
candidate.source &&
|
|
337
|
+
hasKindEditor(candidate.kind),
|
|
338
|
+
);
|
|
339
|
+
// Advance before opening: document activation can publish the table again.
|
|
340
|
+
known = ids;
|
|
341
|
+
seenTableIds = ids;
|
|
342
|
+
if (entry?.source && openKindDocument(store, entry, { activate: true, preview: true })) {
|
|
343
|
+
setSelectedAsset({
|
|
344
|
+
path: `/${entry.source.path}`,
|
|
345
|
+
name: entry.label,
|
|
346
|
+
kind: 'source',
|
|
347
|
+
capabilities: assetCapabilities(entry.source.path),
|
|
348
|
+
origin: 'project',
|
|
349
|
+
health: 'healthy',
|
|
350
|
+
selectionCount: 1,
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
observe();
|
|
355
|
+
stopFollowingTableDocuments = subscribeProjectAdapter(observe);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function openDefaultTableDocument(store: KindDocumentStore): void {
|
|
359
|
+
const attempt = (): boolean => {
|
|
360
|
+
const facet = projectAdapterFacet();
|
|
361
|
+
if (!facet || facet.documentsPending) return false;
|
|
362
|
+
// "SOMETHING IS ALREADY OPEN" MEANS A DOCUMENT A PERSON IS IN — never an
|
|
363
|
+
// AREA document. A workspace's own `areas` (the Model workspace's Timeline)
|
|
364
|
+
// open with the layout, before the adapter's table has settled, and they
|
|
365
|
+
// are never activatable (`workspace-document-registry.ts` gates activation
|
|
366
|
+
// on `!descriptor.area`). Counting one as "the session already has a
|
|
367
|
+
// document" is what left a fresh `--template models` scaffold under the
|
|
368
|
+
// Code-OSS frame with "No document open yet (0 registered)" and the cube
|
|
369
|
+
// never opened — measured 2026-09-20, walk 3 beat 2: the table held
|
|
370
|
+
// `model:src/models/cube.blend` while `open` held only the timeline.
|
|
371
|
+
if (openWorkspaceDocuments().some((document) => !document.descriptor.area)) return true;
|
|
372
|
+
const entry = defaultTableEntry(facet.scenes);
|
|
373
|
+
if (entry?.source) {
|
|
374
|
+
const path = `/${entry.source.path}`;
|
|
375
|
+
// The kind's own editor when one is registered (a model opens as a
|
|
376
|
+
// model); the source only for a kind nothing edits.
|
|
377
|
+
if (!openKindDocument(store, entry)) {
|
|
378
|
+
openAssetDocument(store, path, uneditedKindAssetKind(entry));
|
|
379
|
+
}
|
|
380
|
+
// Opened AND selected, the way a Content click leaves it: the kind's
|
|
381
|
+
// own asset inspector (a model's Edit mesh door) is the first thing
|
|
382
|
+
// the Inspector shows.
|
|
383
|
+
setSelectedAsset({
|
|
384
|
+
path,
|
|
385
|
+
name: entry.label,
|
|
386
|
+
kind: 'source',
|
|
387
|
+
capabilities: assetCapabilities(entry.source.path),
|
|
388
|
+
origin: 'project',
|
|
389
|
+
health: 'healthy',
|
|
390
|
+
selectionCount: 1,
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
return true;
|
|
394
|
+
};
|
|
395
|
+
if (attempt()) return;
|
|
396
|
+
const stop = subscribeProjectAdapter(() => {
|
|
397
|
+
if (attempt()) stop();
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
registerWorkspaceDocumentRestorer({
|
|
402
|
+
kind: 'document',
|
|
403
|
+
owner: 'kind-documents',
|
|
404
|
+
// The table resolves asynchronously; an entry that is gone (or a kind whose
|
|
405
|
+
// editor is gone) reopens nothing, like a deleted tool. It also resolves
|
|
406
|
+
// AFTER the restore loop has ended and the stored active id has been asked
|
|
407
|
+
// for, so a kind document that was the active tab must activate ITSELF as
|
|
408
|
+
// it reopens — or the page lands on whichever sibling resolved first (a
|
|
409
|
+
// session reloaded onto the starter cube while its mushroom was the tab in
|
|
410
|
+
// use, 2026-09-06).
|
|
411
|
+
restore: ({ state, active, store }) => {
|
|
412
|
+
const record = state as { entryId?: unknown } | null | undefined;
|
|
413
|
+
const entryId = typeof record?.entryId === 'string' ? record.entryId : null;
|
|
414
|
+
if (!entryId) return false;
|
|
415
|
+
whenDocumentEntry(entryId, (entry) => {
|
|
416
|
+
openKindDocumentWhenReady(store, entry, { activate: active });
|
|
417
|
+
});
|
|
418
|
+
return true;
|
|
419
|
+
},
|
|
420
|
+
persistKindState: () => (seenTableIds ? { seen: [...seenTableIds] } : undefined),
|
|
421
|
+
beginRestore: ({ state, hasDocumentsToRestore, store }) => {
|
|
422
|
+
const record = state as { seen?: unknown } | null | undefined;
|
|
423
|
+
const seen = Array.isArray(record?.seen)
|
|
424
|
+
? record.seen.filter((id): id is string => typeof id === 'string')
|
|
425
|
+
: undefined;
|
|
426
|
+
// A SESSION WITH NOTHING TO RESTORE opens on the project's own DEFAULT
|
|
427
|
+
// document — what the adapter table declares (or its one non-scene
|
|
428
|
+
// entry): a models project opens its model, a website its page. Scenes
|
|
429
|
+
// have their pinned door (`CenterDocuments`) and are not this one's
|
|
430
|
+
// business.
|
|
431
|
+
//
|
|
432
|
+
// This used to read `!hasRecord`, and "a project that recorded 'nothing
|
|
433
|
+
// open' keeps nothing open" stood beside it as if it were a decision. It
|
|
434
|
+
// was a hole: closing the last document writes `open: []`, and every boot
|
|
435
|
+
// after that restored nothing and opened nothing (walk 5 beat 0 —
|
|
436
|
+
// measured on a `model-editor create` scaffold, where the product's cover
|
|
437
|
+
// then sat out its 90 s budget and blamed Blender for a model nobody had
|
|
438
|
+
// asked it to open).
|
|
439
|
+
if (!hasDocumentsToRestore) openDefaultTableDocument(store);
|
|
440
|
+
followNewTableDocuments(store, seen);
|
|
441
|
+
},
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
function useContribution(documentId: string) {
|
|
445
|
+
useSyncExternalStore(subscribeToolContributions, getGlobalToolContributions);
|
|
446
|
+
const entry = entries.get(documentId)?.props;
|
|
447
|
+
return { entry, contribution: entry ? documentContributionForKind(entry.kind) : undefined };
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
export function KindDocumentToolbar({ documentId, active }: WorkspaceDocumentContentProps) {
|
|
451
|
+
const { entry, contribution } = useContribution(documentId);
|
|
452
|
+
if (!entry || !contribution?.Toolbar) return null;
|
|
453
|
+
return (
|
|
454
|
+
<ToolHost
|
|
455
|
+
key={`${contribution.id}:${contribution.version}:toolbar:${documentId}`}
|
|
456
|
+
contribution={contribution}
|
|
457
|
+
Component={contribution.Toolbar as unknown as ComponentType<Record<string, unknown>>}
|
|
458
|
+
documentId={documentId}
|
|
459
|
+
active={active}
|
|
460
|
+
document={entry}
|
|
461
|
+
/>
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
export function KindDocumentShelf({ documentId, active }: WorkspaceDocumentContentProps) {
|
|
466
|
+
const { entry, contribution } = useContribution(documentId);
|
|
467
|
+
if (!entry || !contribution?.Shelf) return null;
|
|
468
|
+
return (
|
|
469
|
+
<ToolHost
|
|
470
|
+
key={`${contribution.id}:${contribution.version}:shelf:${documentId}`}
|
|
471
|
+
contribution={contribution}
|
|
472
|
+
Component={contribution.Shelf as unknown as ComponentType<Record<string, unknown>>}
|
|
473
|
+
documentId={documentId}
|
|
474
|
+
active={active}
|
|
475
|
+
document={entry}
|
|
476
|
+
/>
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
export function KindDocumentContent({ documentId, active }: WorkspaceDocumentContentProps) {
|
|
481
|
+
const { entry, contribution } = useContribution(documentId);
|
|
482
|
+
if (!entry || !contribution) {
|
|
483
|
+
return (
|
|
484
|
+
<div
|
|
485
|
+
style={{ padding: 12, fontSize: 12, color: themeVars.content.muted, pointerEvents: 'auto' }}
|
|
486
|
+
>
|
|
487
|
+
No editor is registered for this document's kind — close this document.
|
|
488
|
+
</div>
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
return (
|
|
492
|
+
<ToolHost
|
|
493
|
+
key={`${contribution.id}:${contribution.version}:${documentId}`}
|
|
494
|
+
contribution={contribution}
|
|
495
|
+
documentId={documentId}
|
|
496
|
+
active={active}
|
|
497
|
+
document={entry}
|
|
498
|
+
/>
|
|
499
|
+
);
|
|
500
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE PALETTE'S ACTION TABLE — built once, read by whichever palette owns the
|
|
3
|
+
* window (`editor-commands.ts`, WORK.md §The core is Code-OSS U8).
|
|
4
|
+
*
|
|
5
|
+
* `buildPaletteActions` is the list a palette assembles
|
|
6
|
+
* inline in a `useMemo`. It is a function here for one reason: under the
|
|
7
|
+
* Code-OSS frame our palette is never mounted, and the WORKBENCH's ⌘⇧P has to
|
|
8
|
+
* list the same entries with the same labels. One author, two readers.
|
|
9
|
+
*
|
|
10
|
+
* `PaletteActionPublisher` is the frame's reader. It renders nothing; it
|
|
11
|
+
* subscribes to exactly what the palette's `useMemo` depended on (the shell
|
|
12
|
+
* store, the history commands, the contributed-chrome version) and publishes
|
|
13
|
+
* the resulting table into `editor-commands.ts`, where the bridge picks it
|
|
14
|
+
* up. It republishes only when the table's SIGNATURE changes — the store
|
|
15
|
+
* emits on every shell change and re-registering three dozen VS Code menu
|
|
16
|
+
* items for an unchanged list would be churn the frame can see.
|
|
17
|
+
*/
|
|
18
|
+
import { useEffect, useMemo, useRef, useSyncExternalStore } from 'react';
|
|
19
|
+
import { buildEntityActions, buildStaticActions, type EditorAction } from '../action-registry';
|
|
20
|
+
import { buildBoardOpenActions } from '../board-open-actions';
|
|
21
|
+
import {
|
|
22
|
+
contributedActions,
|
|
23
|
+
contributedChromeVersion,
|
|
24
|
+
subscribeContributedChrome,
|
|
25
|
+
} from '../chrome-registry';
|
|
26
|
+
import { publishPaletteActions } from '../editor-commands';
|
|
27
|
+
import { useEditorStore, useHistoryCommandSnapshot, useHistoryCommands } from '../editor-runtime';
|
|
28
|
+
import type { EditorShellStore } from '../editor-shell-store';
|
|
29
|
+
import type { HistoryCommandSnapshot, HistoryCommands } from '../history/history-commands';
|
|
30
|
+
import { editorKeymapsVersion, subscribeEditorKeymap } from '../keymap-presets';
|
|
31
|
+
import { subscribeWorkspaceStyles, workspaceStylesVersion } from '../workspace-style';
|
|
32
|
+
import { buildProjectToolActions } from './project-tool-documents';
|
|
33
|
+
import { buildToolActions } from './tool-documents';
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Every action the palette would list, in the order it groups them. Reads
|
|
37
|
+
* live snapshots throughout: the caller re-invokes rather than this caching.
|
|
38
|
+
*/
|
|
39
|
+
export function buildPaletteActions(
|
|
40
|
+
store: EditorShellStore,
|
|
41
|
+
history: HistoryCommands,
|
|
42
|
+
historySnapshot: HistoryCommandSnapshot,
|
|
43
|
+
): EditorAction[] {
|
|
44
|
+
const statics = buildStaticActions(store, history, historySnapshot);
|
|
45
|
+
// W3 (workspace-shell §9/W3) — document-open discovery lives HERE now
|
|
46
|
+
// that the permanent bottom tabs are gone: document-placement project
|
|
47
|
+
// tools and contributed documents. All read live snapshots. A PACKAGE's
|
|
48
|
+
// live set (the Behavior debugger's one action per running actor) arrives
|
|
49
|
+
// through `contributedActions()` below, pushed by its own service — the
|
|
50
|
+
// host names no package here.
|
|
51
|
+
const documents = [
|
|
52
|
+
...buildProjectToolActions(store),
|
|
53
|
+
...buildBoardOpenActions(),
|
|
54
|
+
...buildToolActions(store),
|
|
55
|
+
];
|
|
56
|
+
const entities = buildEntityActions(store);
|
|
57
|
+
// A package's actions (`@volter/editor-sdk/chrome`), beside the editor's own.
|
|
58
|
+
const contributed: EditorAction[] = contributedActions().map((action) => ({
|
|
59
|
+
id: action.id,
|
|
60
|
+
label: action.label,
|
|
61
|
+
category: 'action',
|
|
62
|
+
execute: action.execute,
|
|
63
|
+
}));
|
|
64
|
+
return [...statics, ...documents, ...contributed, ...entities];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function signatureOf(actions: readonly EditorAction[]): string {
|
|
68
|
+
return actions.map((action) => `${action.id}\u0000${action.label}`).join('\u0001');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Renders nothing: it publishes the action table ⌘⇧P lists. Mounted by
|
|
72
|
+
* `DefaultEditorLayout`. */
|
|
73
|
+
export function PaletteActionPublisher() {
|
|
74
|
+
const store = useEditorStore();
|
|
75
|
+
const history = useHistoryCommands();
|
|
76
|
+
const historySnapshot = useHistoryCommandSnapshot();
|
|
77
|
+
const chromeVersion = useSyncExternalStore(
|
|
78
|
+
subscribeContributedChrome,
|
|
79
|
+
contributedChromeVersion,
|
|
80
|
+
contributedChromeVersion,
|
|
81
|
+
);
|
|
82
|
+
// The store's own version: the entity actions are the SELECTION's, so the
|
|
83
|
+
// table is stale the moment a selection changes without this.
|
|
84
|
+
const shellVersion = useSyncExternalStore(
|
|
85
|
+
store.subscribe,
|
|
86
|
+
store.getShellSnapshot ?? store.getSnapshot,
|
|
87
|
+
);
|
|
88
|
+
// THE LOOK AND THE KEYMAP REGISTRIES, which `buildStaticActions` also reads
|
|
89
|
+
// and neither of the two above covers. A package registers its
|
|
90
|
+
// `workspace.style`/`workspace.keymap` contribution when the project's
|
|
91
|
+
// packages load — AFTER this publisher first mounts — and without these two
|
|
92
|
+
// subscriptions the table it published is the one from before that moment,
|
|
93
|
+
// permanently: under the frame this component is mounted for the window's
|
|
94
|
+
// whole life, so nothing ever re-runs the memo. Measured 2026-09-20 on a
|
|
95
|
+
// `--template models` scaffold: ⌘⇧P listed `VGAI: Workspace Style: Classic /
|
|
96
|
+
// Glass / Maya / Substance` and NOT `Blender`, so the one gesture that
|
|
97
|
+
// switches the LOOK (palette + material + icons + regions in one act, which
|
|
98
|
+
// is why it is a command and not a settings key) did not exist in the only
|
|
99
|
+
// palette that window has — walk 2's beat 10. Standalone was hidden by an
|
|
100
|
+
// accident: a palette component is mounted per open, so an identical memo
|
|
101
|
+
// is fresh every time.
|
|
102
|
+
const styleVersion = useSyncExternalStore(
|
|
103
|
+
subscribeWorkspaceStyles,
|
|
104
|
+
workspaceStylesVersion,
|
|
105
|
+
workspaceStylesVersion,
|
|
106
|
+
);
|
|
107
|
+
const keymapVersion = useSyncExternalStore(
|
|
108
|
+
subscribeEditorKeymap,
|
|
109
|
+
editorKeymapsVersion,
|
|
110
|
+
editorKeymapsVersion,
|
|
111
|
+
);
|
|
112
|
+
const actions = useMemo(
|
|
113
|
+
() => buildPaletteActions(store, history, historySnapshot),
|
|
114
|
+
// The four versions ARE the subscriptions' snapshots: they are dependencies
|
|
115
|
+
// so that a package loading, or a selection changing, re-lists the table.
|
|
116
|
+
[store, history, historySnapshot, chromeVersion, shellVersion, styleVersion, keymapVersion],
|
|
117
|
+
);
|
|
118
|
+
const lastSignature = useRef<string | null>(null);
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
const signature = signatureOf(actions);
|
|
121
|
+
if (signature === lastSignature.current) return;
|
|
122
|
+
lastSignature.current = signature;
|
|
123
|
+
publishPaletteActions(
|
|
124
|
+
actions.map((action) => ({
|
|
125
|
+
id: action.id,
|
|
126
|
+
label: action.label,
|
|
127
|
+
category: action.category,
|
|
128
|
+
run: action.execute,
|
|
129
|
+
})),
|
|
130
|
+
);
|
|
131
|
+
}, [actions]);
|
|
132
|
+
useEffect(
|
|
133
|
+
() => () => {
|
|
134
|
+
lastSignature.current = null;
|
|
135
|
+
publishPaletteActions([]);
|
|
136
|
+
},
|
|
137
|
+
[],
|
|
138
|
+
);
|
|
139
|
+
return null;
|
|
140
|
+
}
|