@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,401 @@
|
|
|
1
|
+
import type { EditorKeyActionId, KeyChord, KeymapContribution } from '@volter/editor-sdk/looks';
|
|
2
|
+
import { editorConsole } from './editor-console';
|
|
3
|
+
import {
|
|
4
|
+
adapterSettings,
|
|
5
|
+
projectSettings,
|
|
6
|
+
subscribeSettings,
|
|
7
|
+
updatePreferenceSettings,
|
|
8
|
+
updateProjectSettings,
|
|
9
|
+
userSettings,
|
|
10
|
+
} from './settings-store';
|
|
11
|
+
|
|
12
|
+
export type { EditorKeyActionId, KeyChord } from '@volter/editor-sdk/looks';
|
|
13
|
+
/**
|
|
14
|
+
* KEYMAPS — the binding table behind every editor keyboard action.
|
|
15
|
+
*
|
|
16
|
+
* The ruling (docs/ARCHITECTURE-CORE.md §Editor chrome, the "Workspaces are
|
|
17
|
+
* task-named layout memories" bullet, final sentence): *"Keymaps are
|
|
18
|
+
* orthogonal to workspaces: a `keymap` setting selects the binding table
|
|
19
|
+
* (`vgai` default; `blender` — G/R/S, A, Alt+A, `.` frame) through one
|
|
20
|
+
* indirection at the action-registry/hotkey seam."*
|
|
21
|
+
*
|
|
22
|
+
* ONE INDIRECTION means exactly this: nothing in the editor spells a literal
|
|
23
|
+
* key for a keyboard action any more. `editor-hotkeys.ts` builds its
|
|
24
|
+
* `HotkeyBinding`s from {@link keyChordsFor}, and every place that PRINTS a
|
|
25
|
+
* shortcut — the command palette (via `action-registry.ts`), the viewport
|
|
26
|
+
* toolstrip tooltips, the camera-controls hint, the snap transient hint —
|
|
27
|
+
* renders {@link shortcutFor} over the same table. Switch the keymap and the
|
|
28
|
+
* chrome tells the truth on the next paint, with no reload.
|
|
29
|
+
*
|
|
30
|
+
* The two axes this module is deliberately NOT: it is not a workspace (that is
|
|
31
|
+
* `workspace-presets.ts` — layout, keyed per project) and not an appearance
|
|
32
|
+
* preference (`theme-preference.ts`). A keymap is a per-user input preference,
|
|
33
|
+
* persisted the way that module persists palette/material: one settings
|
|
34
|
+
* key, lazily read, written on change, broadcast to `useSyncExternalStore`
|
|
35
|
+
* subscribers, and simply falling back to the default when unreadable —
|
|
36
|
+
* nothing a user authored is at stake in a stored preference.
|
|
37
|
+
*
|
|
38
|
+
* WHAT THIS DOES NOT GOVERN — the boundary, stated once: this table is the
|
|
39
|
+
* EDITOR's own chrome bindings, consumed by `hotkeys.ts`'s single `keydown`
|
|
40
|
+
* dispatcher on the editor's window. Play-mode input isolation is a different
|
|
41
|
+
* mechanism entirely and is untouched by a keymap switch: the engine's
|
|
42
|
+
* `InputManager.setEnabled` gate plus `gated-globals.ts`'s lexical
|
|
43
|
+
* `window`/`document` shadow over project modules decide whether GAME code
|
|
44
|
+
* hears a key. A game never reads this table, and no keymap entry can widen or
|
|
45
|
+
* narrow what a running game receives.
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
/** Any registered keymap's id: the editor's own `vgai`, or one a package
|
|
49
|
+
* contributes (`@volter/editor-sdk/looks`, `KeymapContribution`). */
|
|
50
|
+
export type EditorKeymapId = string;
|
|
51
|
+
|
|
52
|
+
export interface EditorKeymapDescriptor {
|
|
53
|
+
readonly id: EditorKeymapId;
|
|
54
|
+
readonly title: string;
|
|
55
|
+
readonly description: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** The editor's OWN keymap, the one every project has. Every other keymap is
|
|
59
|
+
* a package's contribution (Blender's ships with `@volter/editor-blender`). */
|
|
60
|
+
const BUILT_IN_KEYMAPS: readonly EditorKeymapDescriptor[] = Object.freeze([
|
|
61
|
+
{
|
|
62
|
+
id: 'vgai',
|
|
63
|
+
title: 'vgai',
|
|
64
|
+
description: "The editor's own bindings: W/E/R gizmo modes, Ctrl+A select all, F frames.",
|
|
65
|
+
},
|
|
66
|
+
] satisfies readonly EditorKeymapDescriptor[]);
|
|
67
|
+
|
|
68
|
+
interface ContributedKeymap {
|
|
69
|
+
readonly descriptor: EditorKeymapDescriptor;
|
|
70
|
+
readonly table: EditorKeymapTable;
|
|
71
|
+
}
|
|
72
|
+
const contributedKeymaps = new Map<string, ContributedKeymap>();
|
|
73
|
+
let registryVersion = 0;
|
|
74
|
+
|
|
75
|
+
/** Built-ins first, then contributions in registration order — the switch
|
|
76
|
+
* surfaces (View menu, palette) enumerate this. */
|
|
77
|
+
export function editorKeymaps(): readonly EditorKeymapDescriptor[] {
|
|
78
|
+
return [
|
|
79
|
+
...BUILT_IN_KEYMAPS,
|
|
80
|
+
...[...contributedKeymaps.values()].map((entry) => entry.descriptor),
|
|
81
|
+
];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function editorKeymapsVersion(): number {
|
|
85
|
+
return registryVersion;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Register a package's keymap (`workspace.keymap` contribution). The table is
|
|
90
|
+
* the editor's own bindings with the contribution's chords over them, so a
|
|
91
|
+
* keymap declares only where it differs. Returns the unregister. A duplicate
|
|
92
|
+
* id throws — ids are the `keymap` setting's values.
|
|
93
|
+
*/
|
|
94
|
+
export function registerContributedKeymap(contribution: KeymapContribution): () => void {
|
|
95
|
+
if (
|
|
96
|
+
BUILT_IN_KEYMAPS.some((entry) => entry.id === contribution.id) ||
|
|
97
|
+
contributedKeymaps.has(contribution.id)
|
|
98
|
+
)
|
|
99
|
+
throw new Error(
|
|
100
|
+
`registerContributedKeymap: keymap "${contribution.id}" is already registered.`,
|
|
101
|
+
);
|
|
102
|
+
const entry: ContributedKeymap = {
|
|
103
|
+
descriptor: {
|
|
104
|
+
id: contribution.id,
|
|
105
|
+
title: contribution.title,
|
|
106
|
+
description: contribution.description,
|
|
107
|
+
},
|
|
108
|
+
table: Object.freeze({ ...VGAI_KEYMAP, ...contribution.bindings }) as EditorKeymapTable,
|
|
109
|
+
};
|
|
110
|
+
contributedKeymaps.set(contribution.id, entry);
|
|
111
|
+
registryVersion++;
|
|
112
|
+
// A stored preference this contribution satisfies applies now, not on the
|
|
113
|
+
// next reload: the cache re-reads the setting against the wider registry.
|
|
114
|
+
cachedKeymap = null;
|
|
115
|
+
emit();
|
|
116
|
+
return () => {
|
|
117
|
+
if (contributedKeymaps.get(contribution.id) !== entry) return;
|
|
118
|
+
contributedKeymaps.delete(contribution.id);
|
|
119
|
+
registryVersion++;
|
|
120
|
+
cachedKeymap = null;
|
|
121
|
+
emit();
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function isEditorKeymapId(value: unknown): value is EditorKeymapId {
|
|
126
|
+
return (
|
|
127
|
+
typeof value === 'string' &&
|
|
128
|
+
(BUILT_IN_KEYMAPS.some((entry) => entry.id === value) || contributedKeymaps.has(value))
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export type EditorKeymapTable = Readonly<Record<EditorKeyActionId, readonly KeyChord[]>>;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* The vgai table reproduces the bindings the editor shipped before keymaps
|
|
136
|
+
* existed, chord for chord. It is the regression bar: any change here is a
|
|
137
|
+
* change to the default editor, not to a keymap.
|
|
138
|
+
*/
|
|
139
|
+
const VGAI_KEYMAP: EditorKeymapTable = Object.freeze({
|
|
140
|
+
'edit.undo': [{ key: 'z', mod: true }],
|
|
141
|
+
// Ctrl+Y mirrors Ctrl+Shift+Z (Windows convention).
|
|
142
|
+
'edit.redo': [
|
|
143
|
+
{ key: 'z', mod: true, shift: true },
|
|
144
|
+
{ key: 'y', mod: true },
|
|
145
|
+
],
|
|
146
|
+
'edit.copy': [{ key: 'c', mod: true }],
|
|
147
|
+
'edit.cut': [{ key: 'x', mod: true }],
|
|
148
|
+
'edit.paste': [{ key: 'v', mod: true }],
|
|
149
|
+
'edit.duplicate': [{ key: 'd', mod: true }],
|
|
150
|
+
'edit.group': [{ key: 'g', mod: true }],
|
|
151
|
+
'edit.wrap': [{ key: 'g', mod: true, alt: true }],
|
|
152
|
+
'edit.unwrap': [{ key: 'g', mod: true, shift: true }],
|
|
153
|
+
'edit.selectAll': [{ key: 'a', mod: true }],
|
|
154
|
+
// No dedicated chord: Escape is the vgai deselect, and it carries the
|
|
155
|
+
// scope-exit semantics too (`edit.exitScopeOrDeselect`). An empty chord list
|
|
156
|
+
// registers no binding; the printed hint falls back to Escape's.
|
|
157
|
+
'edit.deselectAll': [],
|
|
158
|
+
'edit.save': [{ key: 's', mod: true }],
|
|
159
|
+
'edit.delete': [{ key: 'delete' }, { key: 'backspace' }],
|
|
160
|
+
'edit.enterScope': [{ key: 'enter' }],
|
|
161
|
+
'edit.exitScopeOrDeselect': [{ key: 'escape' }],
|
|
162
|
+
'edit.nudgeUp': [{ key: 'arrowup' }],
|
|
163
|
+
'edit.nudgeUpCoarse': [{ key: 'arrowup', shift: true }],
|
|
164
|
+
'edit.nudgeDown': [{ key: 'arrowdown' }],
|
|
165
|
+
'edit.nudgeDownCoarse': [{ key: 'arrowdown', shift: true }],
|
|
166
|
+
'edit.nudgeLeft': [{ key: 'arrowleft' }],
|
|
167
|
+
'edit.nudgeLeftCoarse': [{ key: 'arrowleft', shift: true }],
|
|
168
|
+
'edit.nudgeRight': [{ key: 'arrowright' }],
|
|
169
|
+
'edit.nudgeRightCoarse': [{ key: 'arrowright', shift: true }],
|
|
170
|
+
'view.resetPan': [{ key: '0', mod: true }],
|
|
171
|
+
'view.commandPalette': [{ key: 'k', mod: true }],
|
|
172
|
+
'view.toggleConsole': [{ key: '`' }],
|
|
173
|
+
'view.focusMode': [{ key: 'f', mod: true, shift: true }],
|
|
174
|
+
// Blender's own workspace cycle keys, and free in this registry.
|
|
175
|
+
'workspace.cycleNext': [{ key: 'pagedown', mod: true }],
|
|
176
|
+
'workspace.cyclePrevious': [{ key: 'pageup', mod: true }],
|
|
177
|
+
// UNBOUND HERE, DELIBERATELY: this editor's own four transform tools already
|
|
178
|
+
// hold T/W/E/R, and the Select tool arrived with the Blender look (whose
|
|
179
|
+
// keymap puts it on Blender's own `W`). An empty list is the table's way of
|
|
180
|
+
// saying a keymap binds nothing to an action, and the strip's button is the
|
|
181
|
+
// tool's other door.
|
|
182
|
+
'transform.select': [],
|
|
183
|
+
'transform.combined': [{ key: 't' }],
|
|
184
|
+
'transform.translate': [{ key: 'w' }],
|
|
185
|
+
'transform.rotate': [{ key: 'e' }],
|
|
186
|
+
'transform.scale': [{ key: 'r' }],
|
|
187
|
+
'viewport.toggleSnap': [{ key: 's', shift: true }],
|
|
188
|
+
'viewport.frameSelection': [{ key: 'f' }],
|
|
189
|
+
'viewport.cyclePivot': [{ key: '.' }],
|
|
190
|
+
'viewport.vertexSnapHold': [{ key: 'v' }],
|
|
191
|
+
'viewport.snapToFloor': [{ key: '', code: 'PageDown' }],
|
|
192
|
+
'view.top': [{ key: '', code: 'Numpad7' }],
|
|
193
|
+
'view.front': [{ key: '', code: 'Numpad1' }],
|
|
194
|
+
'view.right': [{ key: '', code: 'Numpad3' }],
|
|
195
|
+
'view.perspective': [{ key: '', code: 'Numpad5' }],
|
|
196
|
+
} satisfies EditorKeymapTable);
|
|
197
|
+
|
|
198
|
+
// ---------------------------------------------------------------------------
|
|
199
|
+
// The setting
|
|
200
|
+
// ---------------------------------------------------------------------------
|
|
201
|
+
|
|
202
|
+
export const DEFAULT_EDITOR_KEYMAP: EditorKeymapId = 'vgai';
|
|
203
|
+
|
|
204
|
+
let cachedKeymap: EditorKeymapId | null = null;
|
|
205
|
+
let settingsSyncInstalled = false;
|
|
206
|
+
const listeners = new Set<() => void>();
|
|
207
|
+
|
|
208
|
+
function emit(): void {
|
|
209
|
+
for (const listener of listeners) listener();
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** The editor's own keymap ids — the ones that exist in every project. */
|
|
213
|
+
function isBuiltInKeymapId(value: unknown): boolean {
|
|
214
|
+
return typeof value === 'string' && BUILT_IN_KEYMAPS.some((entry) => entry.id === value);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** What the PROJECT selects: its adapter's declaration, its own settings over it. */
|
|
218
|
+
function projectScopedKeymap(): unknown {
|
|
219
|
+
return projectSettings().keymap ?? adapterSettings().keymap;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* A keymap a PACKAGE contributes is project-scoped: it exists only where that
|
|
224
|
+
* package is declared, so only the project may select it — its adapter
|
|
225
|
+
* (`editor: { keymap: blenderKeymap }`) or its own `.vgai/settings.json`. The
|
|
226
|
+
* USER layer chooses among the editor's own, because a cross-project default
|
|
227
|
+
* naming a skew's bindings is how a models project's G/R/S reached a game
|
|
228
|
+
* project that merely happens to declare the same package.
|
|
229
|
+
*/
|
|
230
|
+
function readStoredKeymap(): EditorKeymapId {
|
|
231
|
+
const scoped = projectScopedKeymap();
|
|
232
|
+
if (isEditorKeymapId(scoped)) return scoped;
|
|
233
|
+
const preferred = userSettings().keymap;
|
|
234
|
+
return isBuiltInKeymapId(preferred) ? (preferred as EditorKeymapId) : DEFAULT_EDITOR_KEYMAP;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const saidUnavailable = new Set<string>();
|
|
238
|
+
/**
|
|
239
|
+
* Say, once per id, that the STORED keymap is one nothing in this project
|
|
240
|
+
* contributes, so a models project opened without its Blender package
|
|
241
|
+
* explains the W/E/R it is showing. Called by the loader AFTER a contribution
|
|
242
|
+
* pass has registered what the project's packages ship — asked at boot it
|
|
243
|
+
* would warn about every keymap a package is about to contribute (measured
|
|
244
|
+
* 2026-09-17: "blender is not available" on a project whose mesh package
|
|
245
|
+
* registered it a moment later).
|
|
246
|
+
*/
|
|
247
|
+
export function reportUnavailableKeymap(): void {
|
|
248
|
+
const stored = projectScopedKeymap();
|
|
249
|
+
if (typeof stored !== 'string' || stored === DEFAULT_EDITOR_KEYMAP) return;
|
|
250
|
+
if (isEditorKeymapId(stored) || saidUnavailable.has(stored)) return;
|
|
251
|
+
saidUnavailable.add(stored);
|
|
252
|
+
editorConsole.warn(
|
|
253
|
+
`Keymap "${stored}" is not available in this project: no declared package contributes it ` +
|
|
254
|
+
`(a package ships one as a \`workspace.keymap\` contribution). Using "${DEFAULT_EDITOR_KEYMAP}".`,
|
|
255
|
+
'editor',
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/** The setting is `keymap` in the settings layers (`settings-store.ts`); a
|
|
260
|
+
* load finishing or a project's own override becoming active must not leave
|
|
261
|
+
* this module's cache lying. Installed on first read so the module has no
|
|
262
|
+
* load-time side effect. */
|
|
263
|
+
function ensureSettingsSync(): void {
|
|
264
|
+
if (settingsSyncInstalled) return;
|
|
265
|
+
settingsSyncInstalled = true;
|
|
266
|
+
subscribeSettings(() => {
|
|
267
|
+
const next = readStoredKeymap();
|
|
268
|
+
if (next === cachedKeymap) return;
|
|
269
|
+
cachedKeymap = next;
|
|
270
|
+
emit();
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/** Current keymap id (`useSyncExternalStore`-shaped snapshot). */
|
|
275
|
+
export function activeEditorKeymap(): EditorKeymapId {
|
|
276
|
+
ensureSettingsSync();
|
|
277
|
+
cachedKeymap ??= readStoredKeymap();
|
|
278
|
+
return cachedKeymap;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Switch keymaps. Live: every binding registration re-derives from the new
|
|
283
|
+
* table on this call (`editor-hotkeys.ts`) and every printed hint re-renders,
|
|
284
|
+
* so there is no reload and no restart. Choosing one of the editor's OWN
|
|
285
|
+
* keymaps writes where the key is declared; choosing a package's writes the
|
|
286
|
+
* PROJECT layer, because that is the only layer a contributed keymap is read
|
|
287
|
+
* from (see {@link readStoredKeymap}) — a gesture must land somewhere it wins.
|
|
288
|
+
*/
|
|
289
|
+
export function setEditorKeymapPreference(id: EditorKeymapId): void {
|
|
290
|
+
if (activeEditorKeymap() === id) return;
|
|
291
|
+
cachedKeymap = id;
|
|
292
|
+
if (isBuiltInKeymapId(id)) updatePreferenceSettings({ keymap: id });
|
|
293
|
+
else updateProjectSettings({ keymap: id });
|
|
294
|
+
emit();
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
export function subscribeEditorKeymap(listener: () => void): () => void {
|
|
298
|
+
listeners.add(listener);
|
|
299
|
+
return () => listeners.delete(listener);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export function __resetEditorKeymapForTest(): void {
|
|
303
|
+
cachedKeymap = null;
|
|
304
|
+
listeners.clear();
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// ---------------------------------------------------------------------------
|
|
308
|
+
// The one lookup
|
|
309
|
+
// ---------------------------------------------------------------------------
|
|
310
|
+
|
|
311
|
+
/** The active table's chords for one action. Empty means deliberately unbound. */
|
|
312
|
+
export function keyChordsFor(action: EditorKeyActionId): readonly KeyChord[] {
|
|
313
|
+
return keymapTable(activeEditorKeymap())[action];
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/** A named table, for a surface that must show a keymap it is not running.
|
|
317
|
+
* An unregistered id answers the editor's own table. */
|
|
318
|
+
export function keymapTable(id: EditorKeymapId): EditorKeymapTable {
|
|
319
|
+
return contributedKeymaps.get(id)?.table ?? VGAI_KEYMAP;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// ---------------------------------------------------------------------------
|
|
323
|
+
// Display
|
|
324
|
+
// ---------------------------------------------------------------------------
|
|
325
|
+
|
|
326
|
+
function isMacPlatform(): boolean {
|
|
327
|
+
return typeof navigator !== 'undefined' && navigator.platform.includes('Mac');
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/** Named keys whose label is neither the raw `key` nor its uppercase form. */
|
|
331
|
+
const KEY_LABELS: Readonly<Record<string, string>> = {
|
|
332
|
+
delete: 'Del',
|
|
333
|
+
backspace: 'Backspace',
|
|
334
|
+
escape: 'Esc',
|
|
335
|
+
enter: 'Enter',
|
|
336
|
+
pagedown: 'PgDn',
|
|
337
|
+
pageup: 'PgUp',
|
|
338
|
+
arrowup: '↑',
|
|
339
|
+
arrowdown: '↓',
|
|
340
|
+
arrowleft: '←',
|
|
341
|
+
arrowright: '→',
|
|
342
|
+
' ': 'Space',
|
|
343
|
+
tab: 'Tab',
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
const CODE_LABELS: Readonly<Record<string, string>> = {
|
|
347
|
+
Numpad0: 'Num0',
|
|
348
|
+
Numpad1: 'Num1',
|
|
349
|
+
Numpad2: 'Num2',
|
|
350
|
+
Numpad3: 'Num3',
|
|
351
|
+
Numpad4: 'Num4',
|
|
352
|
+
Numpad5: 'Num5',
|
|
353
|
+
Numpad6: 'Num6',
|
|
354
|
+
Numpad7: 'Num7',
|
|
355
|
+
Numpad8: 'Num8',
|
|
356
|
+
Numpad9: 'Num9',
|
|
357
|
+
NumpadDecimal: 'Num.',
|
|
358
|
+
PageDown: 'PgDn',
|
|
359
|
+
PageUp: 'PgUp',
|
|
360
|
+
End: 'End',
|
|
361
|
+
KeyG: 'G',
|
|
362
|
+
KeyH: 'H',
|
|
363
|
+
KeyJ: 'J',
|
|
364
|
+
KeyK: 'K',
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
function keyLabel(chord: KeyChord): string {
|
|
368
|
+
if (chord.code) return CODE_LABELS[chord.code] ?? chord.code;
|
|
369
|
+
return KEY_LABELS[chord.key] ?? (chord.key.length === 1 ? chord.key.toUpperCase() : chord.key);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Render one chord the way the editor's chrome has always rendered them —
|
|
374
|
+
* BOTH existing conventions preserved verbatim, because changing a printed
|
|
375
|
+
* string is a visible regression: a mod-prefixed chord reads `⌘⇧Z` / `Ctrl+⇧Z`
|
|
376
|
+
* (the command palette's shape), while a modless chord spells its modifiers
|
|
377
|
+
* out, `Shift+S` (the toolstrip's shape).
|
|
378
|
+
*/
|
|
379
|
+
export function formatChord(chord: KeyChord): string {
|
|
380
|
+
const label = keyLabel(chord);
|
|
381
|
+
if (chord.mod) {
|
|
382
|
+
const mod = isMacPlatform() ? '⌘' : 'Ctrl+';
|
|
383
|
+
return `${mod}${chord.alt ? '⌥' : ''}${chord.shift ? '⇧' : ''}${label}`;
|
|
384
|
+
}
|
|
385
|
+
const parts: string[] = [];
|
|
386
|
+
if (chord.alt) parts.push('Alt');
|
|
387
|
+
if (chord.shift) parts.push('Shift');
|
|
388
|
+
parts.push(label);
|
|
389
|
+
return parts.join('+');
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* The printed hint for an action under the ACTIVE keymap — the first chord,
|
|
394
|
+
* which every table lists in "the one to teach" order. `undefined` when the
|
|
395
|
+
* action is deliberately unbound, so a caller can fall back or omit the hint
|
|
396
|
+
* rather than print a lie.
|
|
397
|
+
*/
|
|
398
|
+
export function shortcutFor(action: EditorKeyActionId): string | undefined {
|
|
399
|
+
const chord = keyChordsFor(action)[0];
|
|
400
|
+
return chord ? formatChord(chord) : undefined;
|
|
401
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** Presentation chosen by mounted layout code. No game or website names live here. */
|
|
2
|
+
import type { WorkspaceArrangement } from '@volter/editor-sdk/layout-arrangements';
|
|
3
|
+
import { activeProjectKey } from './active-project';
|
|
4
|
+
export interface LayoutPolicy {
|
|
5
|
+
readonly immersivePlay?: boolean;
|
|
6
|
+
readonly playUtilities?: readonly string[];
|
|
7
|
+
readonly arrangement?: WorkspaceArrangement;
|
|
8
|
+
}
|
|
9
|
+
let owner: string | null = null;
|
|
10
|
+
let policy: LayoutPolicy | null = null;
|
|
11
|
+
const listeners = new Set<() => void>();
|
|
12
|
+
export function layoutPolicy(): LayoutPolicy | null {
|
|
13
|
+
return owner === activeProjectKey() ? policy : null;
|
|
14
|
+
}
|
|
15
|
+
export function subscribeLayoutPolicy(listener: () => void): () => void {
|
|
16
|
+
listeners.add(listener);
|
|
17
|
+
return () => {
|
|
18
|
+
listeners.delete(listener);
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export function installLayoutPolicy(next: LayoutPolicy): () => void {
|
|
22
|
+
owner = activeProjectKey();
|
|
23
|
+
policy = next;
|
|
24
|
+
for (const listener of listeners) listener();
|
|
25
|
+
return () => {
|
|
26
|
+
if (policy !== next) return;
|
|
27
|
+
policy = null;
|
|
28
|
+
owner = null;
|
|
29
|
+
for (const listener of listeners) listener();
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Editor → Learn-site linkage (G6).
|
|
3
|
+
*
|
|
4
|
+
* The whole editor→site half of the FTUE deep-link contract lives here:
|
|
5
|
+
* the Help/Learn menu's destinations (`ApplicationMenus.tsx`) and the
|
|
6
|
+
* read-only example viewer's lesson affordance (`status-contributions.tsx`)
|
|
7
|
+
* both consume these helpers, so the URL shapes are stated exactly once.
|
|
8
|
+
*
|
|
9
|
+
* Reference links are VERSION-PINNED: the zero-base platform-vertical plan
|
|
10
|
+
* serves immutable per-minor snapshots at `/reference/<major>.<minor>/` with
|
|
11
|
+
* `/reference/latest/` as an explicit 302 alias — so a project pinned to
|
|
12
|
+
* engine 0.5.x links `/reference/0.5/` and keeps meaning that engine forever.
|
|
13
|
+
* The pin is derived from the project's `engine.version` manifest field (an
|
|
14
|
+
* identity pin, not a range — @volter/editor-project/manifest/schema). When the version is
|
|
15
|
+
* missing or unparseable (or the `0.0.x` dev placeholder), we fall back to
|
|
16
|
+
* the unpinned reference root rather than fabricating a snapshot that can
|
|
17
|
+
* never exist.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/** Learn-site origin (site/astro.config.mjs `site`). */
|
|
21
|
+
export const LEARN_SITE_URL = 'https://vgai-learn.pages.dev/';
|
|
22
|
+
|
|
23
|
+
/** Quick-starts landing (site/src/content/x). */
|
|
24
|
+
export const LEARN_QUICK_STARTS_URL = `${LEARN_SITE_URL}quick-starts/`;
|
|
25
|
+
|
|
26
|
+
/** Manual landing (site/src/content/x). */
|
|
27
|
+
export const LEARN_MANUAL_URL = `${LEARN_SITE_URL}manual/`;
|
|
28
|
+
|
|
29
|
+
/** Unpinned reference root — the fallback when no engine version is known. */
|
|
30
|
+
export const LEARN_REFERENCE_ROOT_URL = `${LEARN_SITE_URL}reference/`;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The `<major>.<minor>` reference-snapshot pin for an engine version, or null
|
|
34
|
+
* when the version cannot honestly name a snapshot: missing, unparseable, or
|
|
35
|
+
* the `0.0.x` never-released dev placeholder. Prerelease/build suffixes
|
|
36
|
+
* (`0.5.0-rc.1`) still pin their minor — the snapshot contract is per-minor.
|
|
37
|
+
*/
|
|
38
|
+
export function referenceVersionPin(engineVersion: string | null | undefined): string | null {
|
|
39
|
+
const match = /^(\d+)\.(\d+)(?:[.+-]|$)/.exec(engineVersion?.trim() ?? '');
|
|
40
|
+
if (!match) return null;
|
|
41
|
+
const pin = `${Number(match[1])}.${Number(match[2])}`;
|
|
42
|
+
return pin === '0.0' ? null : pin;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Version-pinned Reference URL (`/reference/<major>.<minor>/`) for the given
|
|
47
|
+
* engine version; the unpinned reference root when no pin can be derived.
|
|
48
|
+
*/
|
|
49
|
+
export function learnReferenceUrl(engineVersion: string | null | undefined): string {
|
|
50
|
+
const pin = referenceVersionPin(engineVersion);
|
|
51
|
+
return pin === null ? LEARN_REFERENCE_ROOT_URL : `${LEARN_REFERENCE_ROOT_URL}${pin}/`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* A lesson URL from example `learn` metadata (FT-5), validated to an http(s)
|
|
56
|
+
* absolute URL — manifests are project-authored content, so anything else
|
|
57
|
+
* (relative paths, other schemes) renders no link rather than a broken or
|
|
58
|
+
* unsafe one. Returns null when absent or invalid.
|
|
59
|
+
*/
|
|
60
|
+
export function safeLessonUrl(lesson: string | null | undefined): string | null {
|
|
61
|
+
if (!lesson) return null;
|
|
62
|
+
try {
|
|
63
|
+
const url = new URL(lesson);
|
|
64
|
+
return url.protocol === 'https:' || url.protocol === 'http:' ? url.href : null;
|
|
65
|
+
} catch {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Open a Learn-site destination in a new tab (§6: all Help links open out). */
|
|
71
|
+
export function openLearnLink(url: string): void {
|
|
72
|
+
window.open(url, '_blank', 'noopener,noreferrer');
|
|
73
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type { AuthoringAdapter, EditorNode, PropertyDescriptor } from '@volter/editor-project/adapter';
|
|
2
|
+
import { setAuthoringInspectorField } from './authoring/consumer-actions';
|
|
3
|
+
import { forEachHierarchyNode } from './hierarchy-walk';
|
|
4
|
+
|
|
5
|
+
export const LIGHT_EXPLORER_PATHS = {
|
|
6
|
+
enabled: 'visible',
|
|
7
|
+
color: 'light.color',
|
|
8
|
+
intensity: 'light.intensity',
|
|
9
|
+
range: 'light.distance',
|
|
10
|
+
shadows: 'shadow.cast',
|
|
11
|
+
} as const;
|
|
12
|
+
|
|
13
|
+
export type LightExplorerField = keyof typeof LIGHT_EXPLORER_PATHS;
|
|
14
|
+
|
|
15
|
+
export interface LightExplorerCell<T> {
|
|
16
|
+
readonly supported: boolean;
|
|
17
|
+
readonly writable: boolean;
|
|
18
|
+
readonly value: T | null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface LightExplorerRow {
|
|
22
|
+
readonly id: string;
|
|
23
|
+
readonly name: string;
|
|
24
|
+
readonly type: string;
|
|
25
|
+
readonly enabled: LightExplorerCell<boolean>;
|
|
26
|
+
readonly color: LightExplorerCell<string>;
|
|
27
|
+
readonly intensity: LightExplorerCell<number>;
|
|
28
|
+
readonly range: LightExplorerCell<number>;
|
|
29
|
+
readonly shadows: LightExplorerCell<boolean>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface HierarchyWithInternals {
|
|
33
|
+
/** Optional editor-side hierarchy projection used by component-owning
|
|
34
|
+
* adapters. These are still real adapter nodes; they are merely folded out
|
|
35
|
+
* of the ordinary tree until a person asks to reveal implementation parts. */
|
|
36
|
+
internalChildren?(id: string): EditorNode[] | undefined;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function lightNodes(adapter: AuthoringAdapter): EditorNode[] {
|
|
40
|
+
const result: EditorNode[] = [];
|
|
41
|
+
const hierarchyWithInternals = adapter as AuthoringAdapter & HierarchyWithInternals;
|
|
42
|
+
forEachHierarchyNode(
|
|
43
|
+
adapter.hierarchy,
|
|
44
|
+
(node) => {
|
|
45
|
+
if (node.kind === 'light') result.push(node);
|
|
46
|
+
},
|
|
47
|
+
{ extraChildren: (id) => hierarchyWithInternals.internalChildren?.(id) },
|
|
48
|
+
);
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function activeLightCount(adapter: AuthoringAdapter): number {
|
|
53
|
+
return lightNodes(adapter).length;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function descriptorFor(
|
|
57
|
+
descriptors: readonly PropertyDescriptor[],
|
|
58
|
+
field: LightExplorerField,
|
|
59
|
+
): PropertyDescriptor | null {
|
|
60
|
+
return descriptors.find((descriptor) => descriptor.path === LIGHT_EXPLORER_PATHS[field]) ?? null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function cell<T>(
|
|
64
|
+
adapter: AuthoringAdapter,
|
|
65
|
+
id: string,
|
|
66
|
+
descriptors: readonly PropertyDescriptor[],
|
|
67
|
+
field: LightExplorerField,
|
|
68
|
+
accept: (value: unknown) => value is T,
|
|
69
|
+
): LightExplorerCell<T> {
|
|
70
|
+
const descriptor = descriptorFor(descriptors, field);
|
|
71
|
+
if (!descriptor || !adapter.inspector) {
|
|
72
|
+
return { supported: false, writable: false, value: null };
|
|
73
|
+
}
|
|
74
|
+
let value: unknown;
|
|
75
|
+
try {
|
|
76
|
+
value = adapter.inspector.get(id, descriptor.path);
|
|
77
|
+
} catch {
|
|
78
|
+
value = undefined;
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
supported: true,
|
|
82
|
+
writable: descriptor.readonly !== true,
|
|
83
|
+
value: accept(value) ? value : null,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const isBoolean = (value: unknown): value is boolean => typeof value === 'boolean';
|
|
88
|
+
const isString = (value: unknown): value is string => typeof value === 'string';
|
|
89
|
+
const isNumber = (value: unknown): value is number =>
|
|
90
|
+
typeof value === 'number' && Number.isFinite(value);
|
|
91
|
+
|
|
92
|
+
export function lightExplorerRows(adapter: AuthoringAdapter): LightExplorerRow[] {
|
|
93
|
+
return lightNodes(adapter).map((node) => {
|
|
94
|
+
let descriptors: readonly PropertyDescriptor[] = [];
|
|
95
|
+
try {
|
|
96
|
+
descriptors = adapter.inspector?.properties(node.id) ?? [];
|
|
97
|
+
} catch {
|
|
98
|
+
// A broken per-node inspector must not take the scene-wide inventory down.
|
|
99
|
+
}
|
|
100
|
+
const nativeType = adapter.hierarchy.object3D?.(node.id)?.type;
|
|
101
|
+
return {
|
|
102
|
+
id: node.id,
|
|
103
|
+
name: node.label,
|
|
104
|
+
type: node.typeLabel ?? nativeType ?? 'Light',
|
|
105
|
+
enabled: cell(adapter, node.id, descriptors, 'enabled', isBoolean),
|
|
106
|
+
color: cell(adapter, node.id, descriptors, 'color', isString),
|
|
107
|
+
intensity: cell(adapter, node.id, descriptors, 'intensity', isNumber),
|
|
108
|
+
range: cell(adapter, node.id, descriptors, 'range', isNumber),
|
|
109
|
+
shadows: cell(adapter, node.id, descriptors, 'shadows', isBoolean),
|
|
110
|
+
};
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function setLightExplorerField(
|
|
115
|
+
adapter: AuthoringAdapter,
|
|
116
|
+
ids: readonly string[],
|
|
117
|
+
field: LightExplorerField,
|
|
118
|
+
value: unknown,
|
|
119
|
+
): number {
|
|
120
|
+
if (!adapter.inspector) return 0;
|
|
121
|
+
let changed = 0;
|
|
122
|
+
for (const id of ids) {
|
|
123
|
+
let descriptor: PropertyDescriptor | null = null;
|
|
124
|
+
try {
|
|
125
|
+
descriptor = descriptorFor(adapter.inspector.properties(id), field);
|
|
126
|
+
} catch {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (!descriptor || descriptor.readonly) continue;
|
|
130
|
+
setAuthoringInspectorField(adapter, id, descriptor.path, value);
|
|
131
|
+
changed++;
|
|
132
|
+
}
|
|
133
|
+
return changed;
|
|
134
|
+
}
|