@volter/sdk 0.0.0-stage → 0.5.204
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/LICENSE +202 -0
- package/NOTICE +20 -0
- package/README.md +38 -3
- package/package.json +510 -4
- package/src/account.ts +210 -0
- package/src/chrome.ts +88 -0
- package/src/client.ts +1646 -0
- package/src/commands.ts +66 -0
- package/src/contributions.ts +619 -0
- package/src/css-numeric-style.ts +97 -0
- package/src/document-probe.ts +282 -0
- package/src/editor-view.ts +225 -0
- package/src/extension.ts +40 -0
- package/src/generations.ts +178 -0
- package/src/host.ts +1157 -0
- package/src/http-transport.browser.ts +14 -0
- package/src/http-transport.node.ts +19 -0
- package/src/index.ts +131 -0
- package/src/kit/CapabilityCoverageSection.tsx +185 -0
- package/src/kit/account-client.ts +333 -0
- package/src/kit/action-registry.ts +317 -0
- package/src/kit/active-product.ts +76 -0
- package/src/kit/active-project.ts +155 -0
- package/src/kit/adapter-editor-config.ts +25 -0
- package/src/kit/adapter-module.ts +7 -0
- package/src/kit/adapter-observation.ts +49 -0
- package/src/kit/animation/animation-clock.ts +479 -0
- package/src/kit/animation/stage-transport.ts +385 -0
- package/src/kit/api/assets.ts +365 -0
- package/src/kit/api/project-open.ts +355 -0
- package/src/kit/api/project-source.ts +180 -0
- package/src/kit/api/project-state.ts +110 -0
- package/src/kit/api/relay.ts +270 -0
- package/src/kit/api/themes.ts +45 -0
- package/src/kit/api-asset-library-wire.ts +45 -0
- package/src/kit/api-base.ts +10 -0
- package/src/kit/api-build.ts +99 -0
- package/src/kit/api-git-wire.ts +56 -0
- package/src/kit/api-logs.ts +92 -0
- package/src/kit/api-project-identity.ts +74 -0
- package/src/kit/api-settings.ts +36 -0
- package/src/kit/api-worktrees.ts +205 -0
- package/src/kit/asset-capabilities.ts +344 -0
- package/src/kit/asset-compare-core.ts +171 -0
- package/src/kit/asset-editor-context.tsx +101 -0
- package/src/kit/asset-events.ts +96 -0
- package/src/kit/asset-inspector-actions.ts +87 -0
- package/src/kit/asset-selection-viewer-registry.ts +113 -0
- package/src/kit/asset-selection.ts +146 -0
- package/src/kit/asset-thumbnails.ts +25 -0
- package/src/kit/asset-viewers.ts +115 -0
- package/src/kit/asset-workflow/asset-import-jobs.ts +106 -0
- package/src/kit/asset-workflow/asset-ledger-backend.ts +126 -0
- package/src/kit/asset-workflow/asset-ledger.ts +156 -0
- package/src/kit/asset-workflow/asset-materialization-report.ts +140 -0
- package/src/kit/asset-workflow/asset-pack-manifest.ts +320 -0
- package/src/kit/asset-workflow/asset-types.ts +142 -0
- package/src/kit/asset-workflow/audio-preview-player.ts +193 -0
- package/src/kit/asset-workflow/audio-waveform.ts +22 -0
- package/src/kit/asset-workflow/cloud-asset-client.ts +263 -0
- package/src/kit/asset-workflow/hosted-asset-materialization.ts +236 -0
- package/src/kit/asset-workflow/image-view-scale.ts +31 -0
- package/src/kit/asset-workflow/import-contract.ts +124 -0
- package/src/kit/asset-workflow/ledger-write-lock.ts +244 -0
- package/src/kit/asset-workflow/pixi-spritesheet.ts +197 -0
- package/src/kit/asset-workflow/preview-resource-lifetime.ts +44 -0
- package/src/kit/asset-workflow/project-asset-commands.ts +20 -0
- package/src/kit/asset-workflow/project-content.ts +288 -0
- package/src/kit/asset-workflow/project-source-index.ts +545 -0
- package/src/kit/asset-workflow/thumbnail-system.ts +256 -0
- package/src/kit/authoring/active-adapter.ts +200 -0
- package/src/kit/authoring/active-systems.ts +422 -0
- package/src/kit/authoring/adapter-key.ts +18 -0
- package/src/kit/authoring/authoring-asset-url.ts +27 -0
- package/src/kit/authoring/bootstrap-state.ts +49 -0
- package/src/kit/authoring/boundary-authoring-adapter.ts +189 -0
- package/src/kit/authoring/canvas-scene-guides.ts +84 -0
- package/src/kit/authoring/composite-authoring-adapter.ts +2109 -0
- package/src/kit/authoring/consumer-actions.ts +531 -0
- package/src/kit/authoring/design-time-layers.ts +852 -0
- package/src/kit/authoring/design-time-mount-registry.ts +244 -0
- package/src/kit/authoring/edit-mode-authoring.ts +637 -0
- package/src/kit/authoring/empty-project-authoring.ts +22 -0
- package/src/kit/authoring/instance-source-menu.ts +135 -0
- package/src/kit/authoring/layered-pick.ts +185 -0
- package/src/kit/authoring/mounted-root-subjects.ts +146 -0
- package/src/kit/authoring/no-authoring-adapter.ts +59 -0
- package/src/kit/authoring/object3d-document-persistence.ts +122 -0
- package/src/kit/authoring/panel-authoring.ts +121 -0
- package/src/kit/authoring/project-authoring-session.ts +105 -0
- package/src/kit/authoring/provenance.ts +99 -0
- package/src/kit/authoring/react-canvas-navigation.ts +259 -0
- package/src/kit/authoring/react-design-canvas-style.ts +20 -0
- package/src/kit/authoring/react-story-board.ts +917 -0
- package/src/kit/authoring/selection-scope.ts +195 -0
- package/src/kit/authoring/shell-document-ops.ts +169 -0
- package/src/kit/authoring/story-board-chrome-fit.ts +107 -0
- package/src/kit/authoring/story-board-presentation.ts +111 -0
- package/src/kit/authoring/three-root.ts +67 -0
- package/src/kit/authoring/viewport-tool-context.ts +73 -0
- package/src/kit/authoring/viewport-tool-owner.ts +38 -0
- package/src/kit/authoring/world-session-state.ts +101 -0
- package/src/kit/authoring-seam-evidence.ts +300 -0
- package/src/kit/availability-tick.ts +66 -0
- package/src/kit/bitmap-label.ts +120 -0
- package/src/kit/boot-routing.ts +392 -0
- package/src/kit/breakpoint-state.ts +43 -0
- package/src/kit/build-identity.ts +16 -0
- package/src/kit/bytes-codec.ts +62 -0
- package/src/kit/cancellation-reason.ts +58 -0
- package/src/kit/canvas-frames.ts +88 -0
- package/src/kit/capture-camera-pose.ts +77 -0
- package/src/kit/capture-size.ts +88 -0
- package/src/kit/chrome-registry.ts +159 -0
- package/src/kit/chrome-slot-registry.ts +91 -0
- package/src/kit/collaboration-client.ts +264 -0
- package/src/kit/collaboration-presence.ts +41 -0
- package/src/kit/command-dispatch.ts +19 -0
- package/src/kit/command-listener.ts +2182 -0
- package/src/kit/command-registry.ts +71 -0
- package/src/kit/component-board-registry.ts +205 -0
- package/src/kit/component-states-registry.ts +199 -0
- package/src/kit/components/AlignToolbar.tsx +204 -0
- package/src/kit/components/ApplicationMenus.tsx +372 -0
- package/src/kit/components/AssetEditorShell.tsx +216 -0
- package/src/kit/components/AssetInspectorToolSection.tsx +124 -0
- package/src/kit/components/BoardRulers.tsx +354 -0
- package/src/kit/components/CanvasAddNodeDialogs.tsx +529 -0
- package/src/kit/components/CanvasSceneViewport.tsx +1195 -0
- package/src/kit/components/ChromeSlot.tsx +20 -0
- package/src/kit/components/CodeView.tsx +470 -0
- package/src/kit/components/CompactInspectorShell.tsx +39 -0
- package/src/kit/components/ConsolePanel.tsx +273 -0
- package/src/kit/components/GameplaySessionTimeline.tsx +295 -0
- package/src/kit/components/InspectionProjection.tsx +932 -0
- package/src/kit/components/Inspector.tsx +270 -0
- package/src/kit/components/InspectorCanvasPreview.tsx +35 -0
- package/src/kit/components/InspectorFieldsSection.tsx +290 -0
- package/src/kit/components/InspectorStoriesSection.tsx +92 -0
- package/src/kit/components/InspectorToolSection.tsx +96 -0
- package/src/kit/components/InspectorTransformSection.tsx +245 -0
- package/src/kit/components/LightExplorerPanel.tsx +433 -0
- package/src/kit/components/MediaProperties.tsx +145 -0
- package/src/kit/components/ProjectHeader.tsx +328 -0
- package/src/kit/components/ReactCanvasControls.tsx +358 -0
- package/src/kit/components/RootSelectionOverlay.tsx +3688 -0
- package/src/kit/components/RootTextEditor.tsx +79 -0
- package/src/kit/components/SaveStatus.tsx +70 -0
- package/src/kit/components/SurfaceCrashBoundary.tsx +105 -0
- package/src/kit/components/SurfaceStateOverlay.tsx +24 -0
- package/src/kit/components/ToolContributionSurfaces.tsx +49 -0
- package/src/kit/components/ToolHost.tsx +380 -0
- package/src/kit/components/Toolbar.tsx +811 -0
- package/src/kit/components/TransientHint.tsx +44 -0
- package/src/kit/components/VersionControlSection.tsx +470 -0
- package/src/kit/components/ViewportOverlaysMenu.tsx +177 -0
- package/src/kit/components/VolterLogo.tsx +18 -0
- package/src/kit/components/WorktreeSwitcher.tsx +712 -0
- package/src/kit/components/account-documents.tsx +1162 -0
- package/src/kit/components/asset-documents.tsx +794 -0
- package/src/kit/components/asset-editor-persistence.ts +216 -0
- package/src/kit/components/asset-selection-section.tsx +545 -0
- package/src/kit/components/asset-thumbnails.tsx +307 -0
- package/src/kit/components/asset-viewers/AudioViewer.tsx +201 -0
- package/src/kit/components/asset-viewers/GenericJsonViewer.tsx +102 -0
- package/src/kit/components/asset-viewers/ImageViewer.tsx +300 -0
- package/src/kit/components/asset-viewers/JsonAssetDocument.tsx +98 -0
- package/src/kit/components/asset-viewers/OnlineAssetDetail.tsx +426 -0
- package/src/kit/components/asset-viewers/SourceAssetViewer.tsx +356 -0
- package/src/kit/components/asset-viewers/SpritesheetSpriteView.tsx +102 -0
- package/src/kit/components/asset-viewers/VideoViewer.tsx +101 -0
- package/src/kit/components/asset-viewers/shader-source.ts +144 -0
- package/src/kit/components/board-guides.ts +150 -0
- package/src/kit/components/canvas-scene-hotkeys.ts +37 -0
- package/src/kit/components/canvas-temporary-pivot.ts +34 -0
- package/src/kit/components/core-utilities.tsx +94 -0
- package/src/kit/components/inspector-preview-section.tsx +223 -0
- package/src/kit/components/inspector-revert-label.ts +20 -0
- package/src/kit/components/inspector-selection.ts +42 -0
- package/src/kit/components/inspector-stories-gating.ts +171 -0
- package/src/kit/components/inspector-transform-subject.ts +11 -0
- package/src/kit/components/inspector-transform.ts +88 -0
- package/src/kit/components/kind-documents.tsx +544 -0
- package/src/kit/components/primitives/DraftColorInput.tsx +74 -0
- package/src/kit/components/project-tool-documents.tsx +402 -0
- package/src/kit/components/scene-documents.tsx +221 -0
- package/src/kit/components/status-contributions.tsx +407 -0
- package/src/kit/components/tool-documents.tsx +302 -0
- package/src/kit/components/tool-schema-form.tsx +262 -0
- package/src/kit/components/use-after-paint.ts +41 -0
- package/src/kit/components/use-project-image-assets.ts +86 -0
- package/src/kit/components/workspace-history.ts +32 -0
- package/src/kit/components/world-documents.tsx +570 -0
- package/src/kit/components/world-overlay-gestures.ts +1939 -0
- package/src/kit/composite-screenshot.ts +2238 -0
- package/src/kit/content-entry-source-registry.ts +184 -0
- package/src/kit/contribution-surfaces.ts +48 -0
- package/src/kit/coverage/canvas-reveal.ts +192 -0
- package/src/kit/coverage/design-time-surfaces.ts +101 -0
- package/src/kit/coverage/ontology-invariants.ts +466 -0
- package/src/kit/coverage/session-vitals.ts +503 -0
- package/src/kit/crash-null-boundary.ts +36 -0
- package/src/kit/creation-site-edit.ts +1491 -0
- package/src/kit/creation-site-registry.ts +160 -0
- package/src/kit/delegate-harness-registry.ts +134 -0
- package/src/kit/document-areas.ts +70 -0
- package/src/kit/document-context-registry.ts +193 -0
- package/src/kit/document-open-registry.ts +200 -0
- package/src/kit/document-play-extension.ts +221 -0
- package/src/kit/document-preview-source.ts +20 -0
- package/src/kit/document-renderer-session.ts +138 -0
- package/src/kit/document-stage-sessions.ts +26 -0
- package/src/kit/document-viewports.ts +120 -0
- package/src/kit/editor-api.ts +46 -0
- package/src/kit/editor-chrome-capture.ts +136 -0
- package/src/kit/editor-commands.ts +176 -0
- package/src/kit/editor-console.ts +580 -0
- package/src/kit/editor-current-view.ts +56 -0
- package/src/kit/editor-document-probe.ts +1168 -0
- package/src/kit/editor-git-client.ts +115 -0
- package/src/kit/editor-hotkeys.ts +728 -0
- package/src/kit/editor-lease-view.ts +39 -0
- package/src/kit/editor-lease.ts +415 -0
- package/src/kit/editor-mode.ts +19 -0
- package/src/kit/editor-notifications.ts +140 -0
- package/src/kit/editor-presence.ts +563 -0
- package/src/kit/editor-presentation-activity.ts +58 -0
- package/src/kit/editor-presentation-notice.ts +42 -0
- package/src/kit/editor-runtime.tsx +147 -0
- package/src/kit/editor-server-response.ts +86 -0
- package/src/kit/editor-session-attribution.ts +85 -0
- package/src/kit/editor-session-mode.ts +54 -0
- package/src/kit/editor-state-facets.ts +74 -0
- package/src/kit/editor-view-presentation.ts +777 -0
- package/src/kit/environment-images.ts +58 -0
- package/src/kit/eyedropper-session.ts +60 -0
- package/src/kit/files/file-provider.ts +62 -0
- package/src/kit/files/project-files.ts +270 -0
- package/src/kit/finders/index.ts +137 -0
- package/src/kit/finders/scenes-from-entrypoint-selection.ts +387 -0
- package/src/kit/frame/frame-parts.ts +30 -0
- package/src/kit/framed-document-capture.ts +34 -0
- package/src/kit/game-globals-prelude.ts +143 -0
- package/src/kit/game-surface-defaults.ts +33 -0
- package/src/kit/gameplay-dom-recording.ts +318 -0
- package/src/kit/gameplay-export-state.ts +14 -0
- package/src/kit/gameplay-replay.ts +417 -0
- package/src/kit/gameplay-session-time.ts +9 -0
- package/src/kit/gameplay-sessions.ts +204 -0
- package/src/kit/hierarchy-component-marks.ts +298 -0
- package/src/kit/hierarchy-internals.ts +197 -0
- package/src/kit/hierarchy-kind-icon.ts +217 -0
- package/src/kit/hierarchy-menu-registry.ts +67 -0
- package/src/kit/hierarchy-node-rows.ts +307 -0
- package/src/kit/hierarchy-panel-view.ts +280 -0
- package/src/kit/hierarchy-projection.ts +76 -0
- package/src/kit/hierarchy-row-media.ts +45 -0
- package/src/kit/hierarchy-row-model.ts +308 -0
- package/src/kit/hierarchy-rows.ts +11 -0
- package/src/kit/hierarchy-walk.ts +86 -0
- package/src/kit/history/editor-session.ts +25 -0
- package/src/kit/history/history-commands.ts +147 -0
- package/src/kit/history/history-delegate.ts +187 -0
- package/src/kit/history/history-limit-notices.ts +43 -0
- package/src/kit/history/history-service.ts +1189 -0
- package/src/kit/history/persistence-coordinator.ts +35 -0
- package/src/kit/history/project-file-history.ts +386 -0
- package/src/kit/history/project-root-history-backends.ts +139 -0
- package/src/kit/history/resource-registry.ts +209 -0
- package/src/kit/history/snapshot-store.ts +103 -0
- package/src/kit/history/source-history-backend.ts +546 -0
- package/src/kit/history-types.ts +124 -0
- package/src/kit/hmr-registration-group.ts +67 -0
- package/src/kit/hmr-stable-react-context.ts +23 -0
- package/src/kit/hotkeys.ts +190 -0
- package/src/kit/inference-diagnostics.ts +69 -0
- package/src/kit/initial-project.ts +80 -0
- package/src/kit/inspection/active-subject.ts +571 -0
- package/src/kit/inspection/active-surface.ts +142 -0
- package/src/kit/inspection/compose-subject.ts +1055 -0
- package/src/kit/inspection/compose.ts +7 -0
- package/src/kit/inspection/display.ts +171 -0
- package/src/kit/inspection/document-subject.ts +109 -0
- package/src/kit/inspection/game-subject.ts +85 -0
- package/src/kit/inspection/null-subject.ts +119 -0
- package/src/kit/inspection/serialize.ts +357 -0
- package/src/kit/inspection/use-active-inspection.ts +180 -0
- package/src/kit/inspection-model.ts +542 -0
- package/src/kit/inspection-node-media.ts +58 -0
- package/src/kit/inspector-presentation.ts +203 -0
- package/src/kit/inspector-property-grouping.ts +64 -0
- package/src/kit/inspector-section-registry.ts +221 -0
- package/src/kit/instance-source-actions.ts +163 -0
- package/src/kit/js-heap.ts +71 -0
- package/src/kit/key-actions.ts +91 -0
- package/src/kit/keymap-presets.ts +428 -0
- package/src/kit/layout-policy.ts +31 -0
- package/src/kit/light-explorer-model.ts +134 -0
- package/src/kit/live-canvas-frame.ts +55 -0
- package/src/kit/live-document.ts +296 -0
- package/src/kit/live-gesture-lock.ts +50 -0
- package/src/kit/live-seam-evidence.ts +11 -0
- package/src/kit/live-session-registry.ts +220 -0
- package/src/kit/live-transition.ts +391 -0
- package/src/kit/manifest-project.ts +107 -0
- package/src/kit/module-fetch-diagnosis.ts +192 -0
- package/src/kit/mount-failure-report.ts +154 -0
- package/src/kit/native-selection-style.ts +497 -0
- package/src/kit/object3d-document-write-policy.ts +137 -0
- package/src/kit/packaged-runtime.ts +108 -0
- package/src/kit/palettes/maya.palette.json +57 -0
- package/src/kit/palettes/substance.palette.json +57 -0
- package/src/kit/performance-profiler.ts +367 -0
- package/src/kit/performance-sources.ts +69 -0
- package/src/kit/photograph-notice.ts +141 -0
- package/src/kit/play-boot-phase.ts +166 -0
- package/src/kit/play-camera-flight.ts +35 -0
- package/src/kit/png-encode.worker.ts +26 -0
- package/src/kit/presentation-surface.ts +248 -0
- package/src/kit/product-command.ts +90 -0
- package/src/kit/project-adapter.ts +1140 -0
- package/src/kit/project-asset-refresh.ts +23 -0
- package/src/kit/project-asset-roots.ts +68 -0
- package/src/kit/project-local-state.ts +151 -0
- package/src/kit/project-manager.ts +243 -0
- package/src/kit/project-module-changes.ts +201 -0
- package/src/kit/project-module-split.ts +270 -0
- package/src/kit/project-play-layers.ts +25 -0
- package/src/kit/project-provenance.ts +115 -0
- package/src/kit/project-ready.ts +42 -0
- package/src/kit/project-shape.ts +68 -0
- package/src/kit/project-tools.ts +107 -0
- package/src/kit/projection-types.ts +44 -0
- package/src/kit/readiness.ts +113 -0
- package/src/kit/renderer-resource-counts.ts +27 -0
- package/src/kit/reported-play-state.ts +90 -0
- package/src/kit/resolve-contributed-command.ts +14 -0
- package/src/kit/resolve-relative-specifier.ts +33 -0
- package/src/kit/retained-document-states.ts +91 -0
- package/src/kit/scene-document-plan.ts +320 -0
- package/src/kit/scene-live-open.ts +210 -0
- package/src/kit/scoped-game-css.ts +152 -0
- package/src/kit/served-url.ts +5 -0
- package/src/kit/session-close.ts +17 -0
- package/src/kit/session-tombstone.ts +127 -0
- package/src/kit/settings/settings-provider.ts +82 -0
- package/src/kit/settings-store.ts +348 -0
- package/src/kit/shell-document-state.ts +27 -0
- package/src/kit/shell-store-door.ts +45 -0
- package/src/kit/shell-store.ts +722 -0
- package/src/kit/source-conflict.ts +122 -0
- package/src/kit/stage-context.ts +377 -0
- package/src/kit/stage-invalidation.ts +25 -0
- package/src/kit/stage-store-registry.ts +69 -0
- package/src/kit/startup-failure.ts +80 -0
- package/src/kit/state-report-deferral.ts +73 -0
- package/src/kit/storage/host-files-storage.ts +97 -0
- package/src/kit/storage/http-storage.ts +174 -0
- package/src/kit/storage/index.ts +75 -0
- package/src/kit/storage/mem-storage.ts +158 -0
- package/src/kit/storage/path-lock.ts +44 -0
- package/src/kit/storage/paths.ts +26 -0
- package/src/kit/storage-types.ts +127 -0
- package/src/kit/stories/StoryPreviewMount.tsx +306 -0
- package/src/kit/stories/compose-project-stories.ts +255 -0
- package/src/kit/stories/prefabs-finder.ts +54 -0
- package/src/kit/stories/prefabs-from-stories.ts +182 -0
- package/src/kit/stories/project-story-regions.ts +24 -0
- package/src/kit/stories/story-capture.ts +579 -0
- package/src/kit/stories/story-declared-medium.ts +126 -0
- package/src/kit/stories/story-discovery.ts +176 -0
- package/src/kit/stories/story-dom-runtime.ts +78 -0
- package/src/kit/stories/story-grouping.ts +111 -0
- package/src/kit/stories/story-mount-turn.ts +27 -0
- package/src/kit/stories/story-presentation.ts +215 -0
- package/src/kit/stories/story-preview-component.ts +7 -0
- package/src/kit/stories/story-registry.ts +530 -0
- package/src/kit/stories-scope.ts +35 -0
- package/src/kit/story-document-openers.ts +36 -0
- package/src/kit/story-thumbnails.ts +47 -0
- package/src/kit/surface-keyboard.ts +101 -0
- package/src/kit/surface-state.ts +135 -0
- package/src/kit/system-seam-evidence.ts +72 -0
- package/src/kit/tab-census.ts +202 -0
- package/src/kit/tab-lifecycle-client.ts +227 -0
- package/src/kit/theme-library.ts +897 -0
- package/src/kit/theme-preference.ts +429 -0
- package/src/kit/three-viewport-presentation.ts +23 -0
- package/src/kit/tool-contribution-play.ts +74 -0
- package/src/kit/tool-loader.ts +1918 -0
- package/src/kit/transform-mode-request.ts +66 -0
- package/src/kit/transient-hint.ts +78 -0
- package/src/kit/transport-strip.tsx +174 -0
- package/src/kit/ui-source/adapter-region-includes.ts +238 -0
- package/src/kit/ui-source/file-region-resolver.ts +302 -0
- package/src/kit/ui-source/inspect.ts +775 -0
- package/src/kit/ui-source/source-write-backend.ts +605 -0
- package/src/kit/ui-source/tier-source-write-backend.ts +279 -0
- package/src/kit/user-local-state.ts +105 -0
- package/src/kit/viewport-activation-timings.ts +840 -0
- package/src/kit/viewport-editor-controls.ts +22 -0
- package/src/kit/viewport-presentation.ts +668 -0
- package/src/kit/viewport-surface-status.tsx +55 -0
- package/src/kit/wait-until.ts +37 -0
- package/src/kit/worker-call-metrics.ts +166 -0
- package/src/kit/workspace-areas.ts +191 -0
- package/src/kit/workspace-aux-commands.ts +11 -0
- package/src/kit/workspace-available-documents.ts +142 -0
- package/src/kit/workspace-core-utilities.ts +31 -0
- package/src/kit/workspace-document-ids.ts +59 -0
- package/src/kit/workspace-document-registry.ts +624 -0
- package/src/kit/workspace-document-restore.ts +146 -0
- package/src/kit/workspace-host-commands.ts +141 -0
- package/src/kit/workspace-persistence-gate.ts +40 -0
- package/src/kit/workspace-play-utilities.ts +44 -0
- package/src/kit/workspace-presets.ts +446 -0
- package/src/kit/workspace-regions.ts +276 -0
- package/src/kit/workspace-static-panels.ts +73 -0
- package/src/kit/workspace-status-registry.ts +121 -0
- package/src/kit/workspace-storage.ts +35 -0
- package/src/kit/workspace-style.ts +226 -0
- package/src/kit/workspace-utility-commands.ts +74 -0
- package/src/kit/workspace-utility-registry.ts +263 -0
- package/src/kit/world-adoption-event.ts +23 -0
- package/src/kit/world-adoption.ts +115 -0
- package/src/kit/world-canvas-viewport-state.ts +35 -0
- package/src/kit/world-document-routing.ts +104 -0
- package/src/kit/world-pan-state.ts +198 -0
- package/src/kit/write-pipe.ts +173 -0
- package/src/layout-arrangements.ts +5 -0
- package/src/layouts.tsx +108 -0
- package/src/looks.ts +16 -0
- package/src/project/output-roots.ts +73 -0
- package/src/project/tab-census.ts +155 -0
- package/src/project-tool-catalog.ts +104 -0
- package/src/selection.tsx +107 -0
- package/src/services.ts +18 -0
- package/src/session/build-report.ts +22 -0
- package/src/session/collaboration-types.ts +262 -0
- package/src/session/command-table.ts +327 -0
- package/src/session/discovery.ts +100 -0
- package/src/session/editor-brand.ts +48 -0
- package/src/session/editor-compatibility.ts +329 -0
- package/src/session/editor-control-lifecycle.ts +68 -0
- package/src/session/editor-control-protocol.ts +5 -0
- package/src/session/entrypoint-selection-readers.ts +66 -0
- package/src/session/entrypoint-selection-source.ts +120 -0
- package/src/session/game-css-scope.ts +30 -0
- package/src/session/hosted-attachment.ts +225 -0
- package/src/session/limited-view.ts +82 -0
- package/src/session/product-create.ts +24 -0
- package/src/session/product-locator.ts +478 -0
- package/src/session/project-module-url.ts +242 -0
- package/src/session/project-serving.ts +164 -0
- package/src/session/project-upgrade.ts +669 -0
- package/src/session/registry-format.ts +210 -0
- package/src/session/relative-path-guard.ts +56 -0
- package/src/session/scoped-game-css.ts +461 -0
- package/src/session/source-glob.ts +15 -0
- package/src/session/tool-contribution-convention.ts +123 -0
- package/src/session/workbench-locator.ts +712 -0
- package/src/session.ts +41 -0
- package/src/share.ts +160 -0
- package/src/source-analysis.ts +28 -0
- package/src/source-authoring.ts +439 -0
- package/src/tools/errors.ts +91 -0
- package/src/tools/provider-execution.ts +70 -0
- package/src/tools/registry.ts +341 -0
- package/src/tools/types.ts +159 -0
- package/src/transport.ts +100 -0
- package/src/types.ts +1693 -0
- package/src/views.ts +164 -0
- package/src/widgets/design-system.ts +93 -0
- package/src/widgets/editor-appearance.ts +151 -0
- package/src/widgets/editor-material.ts +83 -0
- package/src/widgets/icon-set-registry.ts +105 -0
- package/src/widgets/index.ts +71 -0
- package/src/widgets/inspector-widgets/AlignmentGrid.tsx +182 -0
- package/src/widgets/inspector-widgets/AssetSlotPicker.tsx +123 -0
- package/src/widgets/inspector-widgets/BorderEditor.tsx +309 -0
- package/src/widgets/inspector-widgets/ColorPicker.tsx +549 -0
- package/src/widgets/inspector-widgets/CurveEditor.tsx +359 -0
- package/src/widgets/inspector-widgets/FilterEditor.tsx +108 -0
- package/src/widgets/inspector-widgets/FontPicker.tsx +191 -0
- package/src/widgets/inspector-widgets/GradientEditor.tsx +623 -0
- package/src/widgets/inspector-widgets/ScrubbableInput.tsx +180 -0
- package/src/widgets/inspector-widgets/ShadowEditor.tsx +319 -0
- package/src/widgets/inspector-widgets/color-utils.ts +201 -0
- package/src/widgets/inspector-widgets/curve-utils.ts +212 -0
- package/src/widgets/inspector-widgets/index.ts +25 -0
- package/src/widgets/inspector-widgets/shared.tsx +140 -0
- package/src/widgets/interactive-edit-scope.ts +33 -0
- package/src/widgets/patterns/Dialog.tsx +140 -0
- package/src/widgets/patterns/Fields.tsx +44 -0
- package/src/widgets/patterns/List.tsx +25 -0
- package/src/widgets/patterns/StateSurface.tsx +40 -0
- package/src/widgets/patterns/Surfaces.tsx +122 -0
- package/src/widgets/patterns/Tabs.tsx +80 -0
- package/src/widgets/patterns/Toolbar.tsx +72 -0
- package/src/widgets/patterns/Tree.tsx +72 -0
- package/src/widgets/primitives/AnchoredMenu.tsx +260 -0
- package/src/widgets/primitives/Button.tsx +62 -0
- package/src/widgets/primitives/ColorInput.tsx +78 -0
- package/src/widgets/primitives/DraftTextInput.tsx +63 -0
- package/src/widgets/primitives/EditorIcon.tsx +157 -0
- package/src/widgets/primitives/FormControls.tsx +88 -0
- package/src/widgets/primitives/HoverPreview.tsx +96 -0
- package/src/widgets/primitives/JsonInput.tsx +113 -0
- package/src/widgets/primitives/Layout.tsx +100 -0
- package/src/widgets/primitives/Menu.tsx +161 -0
- package/src/widgets/primitives/NumberInput.tsx +169 -0
- package/src/widgets/primitives/Panel.tsx +80 -0
- package/src/widgets/primitives/SectionHeader.tsx +77 -0
- package/src/widgets/primitives/Text.tsx +54 -0
- package/src/widgets/primitives/ThemeRootPortal.tsx +52 -0
- package/src/widgets/primitives/Tooltip.tsx +204 -0
- package/src/widgets/primitives/Vec3Input.tsx +70 -0
- package/src/widgets/primitives/banner-tones.ts +32 -0
- package/src/widgets/primitives/clamp-to-viewport.ts +44 -0
- package/src/widgets/primitives/editor-icons.ts +254 -0
- package/src/widgets/primitives/panel-header-styles.ts +42 -0
- package/src/widgets/theme.ts +2841 -0
- package/src/widgets/z-index.ts +25 -0
|
@@ -0,0 +1,722 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE SHELL STORE'S MEDIA-NEUTRAL HALF (ARCHITECTURE.md §The plan, unit 3): change
|
|
3
|
+
* notification, project history, selection, play state and the Edit/Play tab derived from
|
|
4
|
+
* workspace focus. It holds no scene, object, camera or tool: `EditorShellStore` extends it with
|
|
5
|
+
* the Three half, which leaves the kit for `@volter/editor-threejs`. A kit module that needs only
|
|
6
|
+
* this half types itself against `ShellStore` (or the narrower `ShellDocumentState`).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { ViewportTab } from '@volter/sdk';
|
|
10
|
+
import { GAME_DOCUMENT_ID } from '@volter/sdk/kit/workspace-document-ids';
|
|
11
|
+
import {
|
|
12
|
+
activeWorkspaceDocumentId,
|
|
13
|
+
subscribeWorkspaceDocuments,
|
|
14
|
+
} from '@volter/sdk/kit/workspace-document-registry';
|
|
15
|
+
import type { HistoryService } from './history/history-service';
|
|
16
|
+
import type { ShellDocumentState } from './shell-document-state';
|
|
17
|
+
|
|
18
|
+
export type NotifyScope = 'content' | 'selection';
|
|
19
|
+
export type NotifyConcern = 'shell' | 'object-map';
|
|
20
|
+
|
|
21
|
+
/** The scope a coalesced pair of notifications must fire with: `'content'`
|
|
22
|
+
* unless BOTH were selection-only. */
|
|
23
|
+
function widenNotifyScope(current: NotifyScope, incoming: NotifyScope): NotifyScope {
|
|
24
|
+
return current === 'selection' && incoming === 'selection' ? 'selection' : 'content';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Which persistence regime the current play session exposes. D19 makes play
|
|
29
|
+
* edits ephemeral for every world count, and since the `.volter/` overlay
|
|
30
|
+
* sidecar was deleted outright (2026-08-02) `ephemeral` is the ONLY regime
|
|
31
|
+
* there is. `null` while not playing.
|
|
32
|
+
*/
|
|
33
|
+
export type PlayEditRegime = 'ephemeral' | null;
|
|
34
|
+
|
|
35
|
+
/** The authoring tool a view's gizmo arms. */
|
|
36
|
+
export type TransformMode = 'select' | 'combined' | 'translate' | 'rotate' | 'scale';
|
|
37
|
+
export type TransformSpace = 'world' | 'local';
|
|
38
|
+
/** A 2D scene's snapping options: the grid step and offset in scene pixels; `relative` steps from
|
|
39
|
+
* where the node started rather than from the grid; `pixel` rounds a move to whole pixels. */
|
|
40
|
+
export interface Snap2D {
|
|
41
|
+
readonly step: number;
|
|
42
|
+
readonly offsetX: number;
|
|
43
|
+
readonly offsetY: number;
|
|
44
|
+
/** A primary (stronger) grid line every this many steps. */
|
|
45
|
+
readonly primaryEvery: number;
|
|
46
|
+
/** Degrees a snapped rotation is offset from multiples of the rotate step. */
|
|
47
|
+
readonly rotationOffset: number;
|
|
48
|
+
/** Degrees a snapped 2D rotation steps by (Godot's Rotation Step, 15). */
|
|
49
|
+
readonly rotationStep: number;
|
|
50
|
+
/** What a snapped 2D scale steps by (Godot's Scale Step, 0.1). */
|
|
51
|
+
readonly scaleStep: number;
|
|
52
|
+
readonly relative: boolean;
|
|
53
|
+
readonly pixel: boolean;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Smart snapping's switch and its targets: a move aligns to the parent's box, other nodes (their
|
|
57
|
+
* sides and centres) and the view's guides; a pivot snaps to its own node's sides and centre. */
|
|
58
|
+
export interface SmartSnap {
|
|
59
|
+
readonly enabled: boolean;
|
|
60
|
+
readonly parent: boolean;
|
|
61
|
+
readonly others: boolean;
|
|
62
|
+
readonly guides: boolean;
|
|
63
|
+
readonly sides: boolean;
|
|
64
|
+
readonly center: boolean;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export type PivotMode = 'active-element' | 'median-point' | 'individual-origins';
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* WHERE the transform gizmo is drawn for a single selection — the standard DCC
|
|
71
|
+
* affordance, and PRESENTATION ONLY: an edit made about the bounds centre writes
|
|
72
|
+
* the same source values it would about the pivot (`editor-viewport.ts`).
|
|
73
|
+
*
|
|
74
|
+
* `auto` is the default because the right answer is a property of the SUBJECT,
|
|
75
|
+
* not a standing preference: an ordinary node's pivot is where its content is,
|
|
76
|
+
* and a world-anchored instanced system's is not (`instanced-presentation.ts`) —
|
|
77
|
+
* that one draws its gizmo at (0,0,0) with every unit the reader can see
|
|
78
|
+
* somewhere else. Both explicit values remain reachable, because "put the gizmo
|
|
79
|
+
* back on the actual origin" is a legitimate thing to want on exactly that node.
|
|
80
|
+
*/
|
|
81
|
+
export type GizmoAnchor = 'auto' | 'pivot' | 'center';
|
|
82
|
+
|
|
83
|
+
export interface HelperVisibility {
|
|
84
|
+
bounds: boolean;
|
|
85
|
+
lights: boolean;
|
|
86
|
+
cameras: boolean;
|
|
87
|
+
colliders: boolean;
|
|
88
|
+
joints: boolean;
|
|
89
|
+
particles: boolean;
|
|
90
|
+
lod: boolean;
|
|
91
|
+
audio: boolean;
|
|
92
|
+
splines: boolean;
|
|
93
|
+
navmesh: boolean;
|
|
94
|
+
constraints: boolean;
|
|
95
|
+
reflectionProbes: boolean;
|
|
96
|
+
triggerVolumes: boolean;
|
|
97
|
+
skeletons: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* The WEIGHT display — a mesh coloured by its active vertex group
|
|
100
|
+
* (`@volter/editor-blender`'s `blender-runtime-weights.ts`). Added 2026-09-19 (I4)
|
|
101
|
+
* because nothing in this set stood for it: `skeletons` is the bones, and
|
|
102
|
+
* Blender's own viewport overlay has a Bones checkbox but reaches weight
|
|
103
|
+
* colours through Weight Paint MODE, which an inspection surface has no
|
|
104
|
+
* brushes to enter. OFF by default, the way Blender shows no weights until
|
|
105
|
+
* you ask for them.
|
|
106
|
+
*/
|
|
107
|
+
weights: boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Blender's 3D CURSOR (`View3DOverlay.show_cursor`, the overlay popover's
|
|
110
|
+
* "3D Cursor" checkbox): the point `Scene.cursor` names, where the "to 3D
|
|
111
|
+
* Cursor" operators place and snap. ON by default, as Blender draws it.
|
|
112
|
+
*/
|
|
113
|
+
cursor: boolean;
|
|
114
|
+
/** EMPTIES — a scene's objects that are only a place (Blender's empties, drawn by its
|
|
115
|
+
* overlay's extras as axes, arrows or a shape). ON by default, as Blender draws them. */
|
|
116
|
+
empties: boolean;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* A request for whichever viewport shows this store: frame something, take a named view, move
|
|
121
|
+
* the camera. Neutral: a Three stage, a canvas scene and a board each answer the kinds they can.
|
|
122
|
+
*/
|
|
123
|
+
export type ViewportAction =
|
|
124
|
+
| { type: 'focus-entity'; id: string }
|
|
125
|
+
| { type: 'focus-selection' }
|
|
126
|
+
| { type: 'focus-scene' }
|
|
127
|
+
| { type: 'frame-all' }
|
|
128
|
+
| { type: 'zoom-view'; direction: 1 | -1 }
|
|
129
|
+
| { type: 'snap-selection-to-floor' }
|
|
130
|
+
| { type: 'set-view-preset'; preset: ViewPreset }
|
|
131
|
+
| { type: 'step-view'; step: ViewStep }
|
|
132
|
+
| { type: 'toggle-camera-view' }
|
|
133
|
+
| { type: 'toggle-projection' }
|
|
134
|
+
| {
|
|
135
|
+
type: 'set-camera-pose';
|
|
136
|
+
position: { x: number; y: number; z: number };
|
|
137
|
+
target: { x: number; y: number; z: number };
|
|
138
|
+
fov?: number;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/** The preset views: the six axes and the editor's perspective three-quarter view. */
|
|
142
|
+
export type ViewPreset = 'top' | 'front' | 'right' | 'bottom' | 'back' | 'left' | 'perspective';
|
|
143
|
+
|
|
144
|
+
/** One step of the view (Blender's `view_orbit` and `view_roll`). */
|
|
145
|
+
export type ViewStep = 'orbit-left' | 'orbit-right' | 'orbit-up' | 'orbit-down' | 'opposite' | 'roll-left' | 'roll-right';
|
|
146
|
+
|
|
147
|
+
export class ShellStore implements ShellDocumentState {
|
|
148
|
+
/** Selection is viewport-local. The public selection accessors always expose
|
|
149
|
+
* the ACTIVE viewport's set, so Edit and Play never leak subjects into one
|
|
150
|
+
* another while existing authoring adapters keep the same store contract. */
|
|
151
|
+
protected _viewportSelections: Record<ViewportTab, Set<string>> = {
|
|
152
|
+
edit: new Set<string>(),
|
|
153
|
+
play: new Set<string>(),
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
protected _history: HistoryService | null = null;
|
|
157
|
+
|
|
158
|
+
protected _playState: 'stopped' | 'playing' | 'paused' = 'stopped';
|
|
159
|
+
|
|
160
|
+
/** See {@link PlayEditRegime} — set by play-mode.ts on play-enter, cleared on play-exit. */
|
|
161
|
+
protected _playEditRegime: PlayEditRegime = null;
|
|
162
|
+
|
|
163
|
+
/** Only the session store follows workspace focus; a stage's own store is always `edit`. */
|
|
164
|
+
protected readonly _followsWorkspaceFocus: boolean;
|
|
165
|
+
|
|
166
|
+
constructor(options: { readonly followsWorkspaceFocus?: boolean } = {}) {
|
|
167
|
+
this._followsWorkspaceFocus = options.followsWorkspaceFocus === true;
|
|
168
|
+
if (!this._followsWorkspaceFocus) return;
|
|
169
|
+
// Focus is the workspace's; a flip of the derived tab is a change every reader must see.
|
|
170
|
+
let tab = this.activeViewportTab;
|
|
171
|
+
subscribeWorkspaceDocuments(() => {
|
|
172
|
+
const next = this.activeViewportTab;
|
|
173
|
+
if (next === tab) return;
|
|
174
|
+
tab = next;
|
|
175
|
+
this._notify();
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
protected _listeners = new Set<() => void>();
|
|
180
|
+
|
|
181
|
+
/** A relayed selection command applies its value synchronously but lets the
|
|
182
|
+
* hierarchy/Inspector render on the next task, after the control ack has
|
|
183
|
+
* left the page. Ordinary UI writes never use this timer. */
|
|
184
|
+
protected _deferredNotifyTimer: ReturnType<typeof setTimeout> | null = null;
|
|
185
|
+
/** The scope the pending deferred notify will fire with. A coalescing window
|
|
186
|
+
* that swallowed even one `'content'` write must fire as `'content'` — see
|
|
187
|
+
* {@link widenNotifyScope}. */
|
|
188
|
+
protected _deferredNotifyScope: NotifyScope = 'content';
|
|
189
|
+
protected _version = 0;
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Stable across live object-map churn that cannot change shell presentation.
|
|
193
|
+
* Hierarchy/viewport consumers keep using {@link getSnapshot}; chrome that
|
|
194
|
+
* reads play state, selection, tools, or document state uses this narrower
|
|
195
|
+
* snapshot and therefore does not rerender for every runtime projectile.
|
|
196
|
+
*/
|
|
197
|
+
protected _shellVersion = 0;
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Bumped on every notify EXCEPT one whose only change was WHICH NODES ARE
|
|
201
|
+
* SELECTED — see {@link contentVersion}.
|
|
202
|
+
*/
|
|
203
|
+
protected _contentVersion = 0;
|
|
204
|
+
/**
|
|
205
|
+
* Bumped when existing hierarchy-row presentation facets may have changed.
|
|
206
|
+
* Exact object-map membership deltas do not move it: newly admitted rows
|
|
207
|
+
* compute their facets on first render, while surviving rows keep the same
|
|
208
|
+
* source editability, warnings, and reflected property values.
|
|
209
|
+
*/
|
|
210
|
+
protected _hierarchyRowFacetVersion = 0;
|
|
211
|
+
|
|
212
|
+
// --- React useSyncExternalStore integration ---
|
|
213
|
+
subscribe = (listener: () => void): (() => void) => {
|
|
214
|
+
this._listeners.add(listener);
|
|
215
|
+
return () => this._listeners.delete(listener);
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
getSnapshot = (): number => this._version;
|
|
219
|
+
|
|
220
|
+
getShellSnapshot = (): number => this._shellVersion;
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* The version a TREE-SCALE derivation caches against.
|
|
224
|
+
*
|
|
225
|
+
* `_version` moves on every notify, selection included, so a panel that keys
|
|
226
|
+
* a whole-tree walk on it re-walks the tree every time a human clicks a node
|
|
227
|
+
* — measured on the scale harness as 100-430ms of main-thread block per
|
|
228
|
+
* `select` on a 20 000-node world, in a verb whose reply came back in 3ms.
|
|
229
|
+
* The tree the walk reads did not change; only the highlight did.
|
|
230
|
+
*
|
|
231
|
+
* This counter therefore advances on every notify EXCEPT one whose sole
|
|
232
|
+
* change was the contents of `_viewportSelections` — the five selection
|
|
233
|
+
* writers below, and nothing else, notify with `'selection'`. Every other
|
|
234
|
+
* mutation (including `notifyIngestEdit`, history restores, play-state
|
|
235
|
+
* changes and viewport-tab switches) advances it, so a cache keyed on it can
|
|
236
|
+
* only ever be stale for a change that never happened. Subscribers still
|
|
237
|
+
* receive a selection notify and still re-render — this decides only what
|
|
238
|
+
* they are allowed to REUSE while doing so.
|
|
239
|
+
*/
|
|
240
|
+
get contentVersion(): number {
|
|
241
|
+
return this._contentVersion;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/** See {@link _hierarchyRowFacetVersion}. */
|
|
245
|
+
get hierarchyRowFacetVersion(): number {
|
|
246
|
+
return this._hierarchyRowFacetVersion;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
get projectHistory(): HistoryService | null {
|
|
250
|
+
return this._history;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
protected _notify(
|
|
254
|
+
scope: NotifyScope = 'content',
|
|
255
|
+
concern: NotifyConcern = 'shell',
|
|
256
|
+
affectsHierarchyRowFacets = scope !== 'selection',
|
|
257
|
+
): void {
|
|
258
|
+
if (this._deferredNotifyTimer !== null) {
|
|
259
|
+
clearTimeout(this._deferredNotifyTimer);
|
|
260
|
+
this._deferredNotifyTimer = null;
|
|
261
|
+
}
|
|
262
|
+
this._beforeNotify();
|
|
263
|
+
this._version++;
|
|
264
|
+
if (concern === 'shell') this._shellVersion++;
|
|
265
|
+
if (scope !== 'selection') this._contentVersion++;
|
|
266
|
+
if (affectsHierarchyRowFacets) this._hierarchyRowFacetVersion++;
|
|
267
|
+
for (const fn of this._listeners) fn();
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
protected _transformMode: TransformMode = 'combined';
|
|
271
|
+
protected _transformSpace: TransformSpace = 'world';
|
|
272
|
+
protected _snapEnabled = false;
|
|
273
|
+
protected _snapValues = { translate: 1, rotate: 15, scale: 0.25 };
|
|
274
|
+
protected _snapToSurface = false;
|
|
275
|
+
protected _rotationSnap = false;
|
|
276
|
+
protected _snap2D: Snap2D = {
|
|
277
|
+
step: 8,
|
|
278
|
+
offsetX: 0,
|
|
279
|
+
offsetY: 0,
|
|
280
|
+
primaryEvery: 8,
|
|
281
|
+
rotationOffset: 0,
|
|
282
|
+
// Godot's Configure Snap defaults for a 2D view, its own rather than the 3D view's.
|
|
283
|
+
rotationStep: 15,
|
|
284
|
+
scaleStep: 0.1,
|
|
285
|
+
relative: false,
|
|
286
|
+
pixel: true,
|
|
287
|
+
};
|
|
288
|
+
protected _scaleSnap = false;
|
|
289
|
+
protected _smartSnap: SmartSnap = {
|
|
290
|
+
enabled: false,
|
|
291
|
+
parent: true,
|
|
292
|
+
others: true,
|
|
293
|
+
guides: true,
|
|
294
|
+
sides: true,
|
|
295
|
+
center: true,
|
|
296
|
+
};
|
|
297
|
+
protected _preserveChildrenTransform = false;
|
|
298
|
+
protected _pivotMode: PivotMode = 'active-element';
|
|
299
|
+
protected _gizmoAnchor: GizmoAnchor = 'auto';
|
|
300
|
+
protected _showHelpers = true;
|
|
301
|
+
/** Blender's Show Gizmo (`View3D.show_gizmo`), one per stage: the transform and navigation
|
|
302
|
+
* gizmos, apart from the overlays. */
|
|
303
|
+
protected _showGizmos = true;
|
|
304
|
+
protected _helperVisibility: HelperVisibility = {
|
|
305
|
+
bounds: false,
|
|
306
|
+
lights: true,
|
|
307
|
+
cameras: true,
|
|
308
|
+
colliders: true,
|
|
309
|
+
joints: true,
|
|
310
|
+
particles: true,
|
|
311
|
+
lod: true,
|
|
312
|
+
audio: true,
|
|
313
|
+
splines: true,
|
|
314
|
+
navmesh: true,
|
|
315
|
+
constraints: true,
|
|
316
|
+
reflectionProbes: true,
|
|
317
|
+
triggerVolumes: true,
|
|
318
|
+
skeletons: false,
|
|
319
|
+
weights: false,
|
|
320
|
+
cursor: true,
|
|
321
|
+
empties: true,
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
get transformMode(): TransformMode {
|
|
325
|
+
return this._transformMode;
|
|
326
|
+
}
|
|
327
|
+
get transformSpace(): TransformSpace {
|
|
328
|
+
return this._transformSpace;
|
|
329
|
+
}
|
|
330
|
+
get snapEnabled(): boolean {
|
|
331
|
+
return this._snapEnabled;
|
|
332
|
+
}
|
|
333
|
+
get snapValues() {
|
|
334
|
+
return this._snapValues;
|
|
335
|
+
}
|
|
336
|
+
get snapToSurface(): boolean {
|
|
337
|
+
return this._snapToSurface;
|
|
338
|
+
}
|
|
339
|
+
/** A 2D move's alignment to other things, beside the grid's step (Godot's Smart Snap and its
|
|
340
|
+
* Snapping Options targets; off by default there, every target on). */
|
|
341
|
+
/** A 2D rotate or scale stepping by its snap value, each its own switch (Godot's Snapping
|
|
342
|
+
* Options: Use Rotation Snap, Use Scale Snap; both off by default). */
|
|
343
|
+
/** A 2D scene's snapping options beside the magnet (Godot's Snapping Options and Configure
|
|
344
|
+
* Snap): the grid step a snapped move lands on and its offset (8 px, 0), Snap Relative (off) and
|
|
345
|
+
* Use Pixel Snap (on). The drawn grid follows the step. */
|
|
346
|
+
get snap2D(): Readonly<Snap2D> {
|
|
347
|
+
return this._snap2D;
|
|
348
|
+
}
|
|
349
|
+
setSnap2D(choice: Partial<Snap2D>): void {
|
|
350
|
+
this._snap2D = { ...this._snap2D, ...choice };
|
|
351
|
+
this._notify();
|
|
352
|
+
}
|
|
353
|
+
get rotationSnap(): boolean {
|
|
354
|
+
return this._rotationSnap;
|
|
355
|
+
}
|
|
356
|
+
get scaleSnap(): boolean {
|
|
357
|
+
return this._scaleSnap;
|
|
358
|
+
}
|
|
359
|
+
setRotationSnap(on: boolean): void {
|
|
360
|
+
this._rotationSnap = on;
|
|
361
|
+
this._notify();
|
|
362
|
+
}
|
|
363
|
+
setScaleSnap(on: boolean): void {
|
|
364
|
+
this._scaleSnap = on;
|
|
365
|
+
this._notify();
|
|
366
|
+
}
|
|
367
|
+
get smartSnap(): Readonly<SmartSnap> {
|
|
368
|
+
return this._smartSnap;
|
|
369
|
+
}
|
|
370
|
+
get preserveChildrenTransform(): boolean {
|
|
371
|
+
return this._preserveChildrenTransform;
|
|
372
|
+
}
|
|
373
|
+
get pivotMode(): PivotMode {
|
|
374
|
+
return this._pivotMode;
|
|
375
|
+
}
|
|
376
|
+
get gizmoAnchor(): GizmoAnchor {
|
|
377
|
+
return this._gizmoAnchor;
|
|
378
|
+
}
|
|
379
|
+
get showHelpers(): boolean {
|
|
380
|
+
return this._showHelpers;
|
|
381
|
+
}
|
|
382
|
+
get showGizmos(): boolean {
|
|
383
|
+
return this._showGizmos;
|
|
384
|
+
}
|
|
385
|
+
get helperVisibility(): Readonly<HelperVisibility> {
|
|
386
|
+
return this._helperVisibility;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// --- Authoring tools (per view: every stage owns its store) ---
|
|
390
|
+
setTransformMode(mode: TransformMode): void {
|
|
391
|
+
this._transformMode = mode;
|
|
392
|
+
this._notify();
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
setTransformSpace(space: TransformSpace): void {
|
|
396
|
+
this._transformSpace = space;
|
|
397
|
+
this._notify();
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
toggleSnap(): void {
|
|
401
|
+
this._snapEnabled = !this._snapEnabled;
|
|
402
|
+
this._notify();
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
setSnapValues(values: Partial<{ translate: number; rotate: number; scale: number }>): void {
|
|
406
|
+
this._snapValues = { ...this._snapValues, ...values };
|
|
407
|
+
this._notify();
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
setSmartSnap(choice: Partial<SmartSnap>): void {
|
|
411
|
+
this._smartSnap = { ...this._smartSnap, ...choice };
|
|
412
|
+
this._notify();
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
toggleSnapToSurface(): void {
|
|
416
|
+
this._snapToSurface = !this._snapToSurface;
|
|
417
|
+
this._notify();
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
togglePreserveChildrenTransform(): void {
|
|
421
|
+
this._preserveChildrenTransform = !this._preserveChildrenTransform;
|
|
422
|
+
this._notify();
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
setPivotMode(mode: PivotMode): void {
|
|
426
|
+
this._pivotMode = mode;
|
|
427
|
+
this._notify();
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
setGizmoAnchor(anchor: GizmoAnchor): void {
|
|
431
|
+
this._gizmoAnchor = anchor;
|
|
432
|
+
this._notify();
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
toggleGizmos(): void {
|
|
436
|
+
this._showGizmos = !this._showGizmos;
|
|
437
|
+
this._notify();
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
toggleHelpers(): void {
|
|
441
|
+
// The eye is a visibility gate, not a reset of the category checkboxes.
|
|
442
|
+
this._showHelpers = !this._showHelpers;
|
|
443
|
+
this._notify();
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
toggleHelperType(type: keyof HelperVisibility): void {
|
|
447
|
+
this._helperVisibility[type] = !this._helperVisibility[type];
|
|
448
|
+
if (this._helperVisibility[type]) this._showHelpers = true;
|
|
449
|
+
this._notify();
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// --- Viewport requests ---
|
|
453
|
+
protected _viewportActionListeners = new Set<(action: ViewportAction) => void>();
|
|
454
|
+
|
|
455
|
+
onViewportAction = (fn: (action: ViewportAction) => void): (() => void) => {
|
|
456
|
+
this._viewportActionListeners.add(fn);
|
|
457
|
+
return () => this._viewportActionListeners.delete(fn);
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
/** Ask the viewport showing this store to act. */
|
|
461
|
+
requestViewportAction(action: ViewportAction): void {
|
|
462
|
+
for (const fn of this._viewportActionListeners) fn(action);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/** Focus the viewport camera on a specific entity. */
|
|
466
|
+
focusOnEntity(id: string): void {
|
|
467
|
+
this.requestViewportAction({ type: 'focus-entity', id });
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/** Focus the viewport camera on the current selection. */
|
|
471
|
+
focusOnSelection(): void {
|
|
472
|
+
this.requestViewportAction({ type: 'focus-selection' });
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/** Frame everything in the view, selected or not. */
|
|
476
|
+
frameAll(): void {
|
|
477
|
+
this.requestViewportAction({ type: 'frame-all' });
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/** Step the view nearer (1) or farther (-1) by the keymap's zoom step. */
|
|
481
|
+
zoomView(direction: 1 | -1): void {
|
|
482
|
+
this.requestViewportAction({ type: 'zoom-view', direction });
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/** Frame the whole active scene. A medium may carry more with it (the Three half's game
|
|
486
|
+
* camera lookup, `EditorShellStore.focusOnScene`). */
|
|
487
|
+
focusOnScene(): void {
|
|
488
|
+
this.requestViewportAction({ type: 'focus-scene' });
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/** Drop the selection onto whatever is under it. */
|
|
492
|
+
snapSelectionToFloor(): void {
|
|
493
|
+
this.requestViewportAction({ type: 'snap-selection-to-floor' });
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/** Switch the viewport camera to a preset view (an axis, or perspective). */
|
|
497
|
+
setViewPreset(preset: ViewPreset): void {
|
|
498
|
+
this.requestViewportAction({ type: 'set-view-preset', preset });
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/** Step the view: a 15° orbit or roll, or the opposite side. */
|
|
502
|
+
stepView(step: ViewStep): void {
|
|
503
|
+
this.requestViewportAction({ type: 'step-view', step });
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/** Enter or leave the camera view, where the document has cameras to look through. */
|
|
507
|
+
toggleCameraView(): void {
|
|
508
|
+
this.requestViewportAction({ type: 'toggle-camera-view' });
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/** Switch the view between perspective and orthographic, from where it is. */
|
|
512
|
+
toggleProjection(): void {
|
|
513
|
+
this.requestViewportAction({ type: 'toggle-projection' });
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/** Move the viewport camera to an arbitrary position/target/fov pose. */
|
|
517
|
+
setCameraPose(
|
|
518
|
+
position: { x: number; y: number; z: number },
|
|
519
|
+
target: { x: number; y: number; z: number },
|
|
520
|
+
fov?: number,
|
|
521
|
+
): void {
|
|
522
|
+
this.requestViewportAction({
|
|
523
|
+
type: 'set-camera-pose',
|
|
524
|
+
position,
|
|
525
|
+
target,
|
|
526
|
+
...(fov !== undefined ? { fov } : {}),
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/** A companion half's change (the Three half's scene, tools and view options): the same
|
|
531
|
+
* notification the store's own writers send. */
|
|
532
|
+
notifyChange(
|
|
533
|
+
scope: NotifyScope = 'content',
|
|
534
|
+
concern: NotifyConcern = 'shell',
|
|
535
|
+
affectsHierarchyRowFacets = scope !== 'selection',
|
|
536
|
+
): void {
|
|
537
|
+
this._notify(scope, concern, affectsHierarchyRowFacets);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/** Coalesce control-plane presentation behind the command-result microtask.
|
|
541
|
+
* The state mutation has already landed when this is called. */
|
|
542
|
+
protected _notifyDeferred(scope: NotifyScope = 'content'): void {
|
|
543
|
+
if (this._deferredNotifyTimer !== null) {
|
|
544
|
+
this._deferredNotifyScope = widenNotifyScope(this._deferredNotifyScope, scope);
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
this._deferredNotifyScope = scope;
|
|
548
|
+
this._deferredNotifyTimer = setTimeout(() => {
|
|
549
|
+
this._deferredNotifyTimer = null;
|
|
550
|
+
const pending = this._deferredNotifyScope;
|
|
551
|
+
this._deferredNotifyScope = 'content';
|
|
552
|
+
this._notify(pending);
|
|
553
|
+
}, 0);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
attachHistory(history: HistoryService): void {
|
|
557
|
+
if (this._history === history) return;
|
|
558
|
+
if (this._history) throw new Error('EditorStore is already attached to project history.');
|
|
559
|
+
this._history = history;
|
|
560
|
+
this._onHistoryAttached();
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// --- Selection ---
|
|
564
|
+
get selectedEntityId(): string | null {
|
|
565
|
+
const selection = this._viewportSelections[this.activeViewportTab];
|
|
566
|
+
if (selection.size === 0) return null;
|
|
567
|
+
return [...selection].at(-1)!;
|
|
568
|
+
}
|
|
569
|
+
get selectedEntityIds(): ReadonlySet<string> {
|
|
570
|
+
return this._viewportSelections[this.activeViewportTab];
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
get canUndo(): boolean {
|
|
574
|
+
return this._history?.getSnapshot().canUndo ?? false;
|
|
575
|
+
}
|
|
576
|
+
get canRedo(): boolean {
|
|
577
|
+
return this._history?.getSnapshot().canRedo ?? false;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
notifyIngestEdit(): void {
|
|
581
|
+
this._notify();
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* WHICH MODE THE EDITOR IS IN — the shell's own intent, not a claim that a
|
|
586
|
+
* game is running. Read it for anything whose answer must be true from the
|
|
587
|
+
* MOMENT play is entered: the structural-edit block, the design session's
|
|
588
|
+
* suspend, the Play bar, the viewport tab, the tool `when` predicates.
|
|
589
|
+
*
|
|
590
|
+
* It is NOT the answer to "is something actually running", and it must never
|
|
591
|
+
* be reported as one. `'playing'` is written by three subsystems — play mode,
|
|
592
|
+
* ingest and module mode — and every one of them writes it BEFORE its session
|
|
593
|
+
* exists: `enterPlayMode` sets it ~130 lines and three awaits before
|
|
594
|
+
* `_instance.session` is assigned, and an ingest mount sets it before the
|
|
595
|
+
* mount is even attempted. That is deliberate (it is what swaps the viewport
|
|
596
|
+
* onto the game surface and freezes edit-mode work while the boot runs), and
|
|
597
|
+
* it is exactly why reporting the flag verbatim once printed
|
|
598
|
+
* `playState: "playing"` for a mount that had already thrown.
|
|
599
|
+
*
|
|
600
|
+
* The other question has its own door and only one caller may use it:
|
|
601
|
+
* `reported-play-state.ts`'s `deriveReportedPlayState`, which resolves the
|
|
602
|
+
* live session slots and is what `collectState` (the editor's `status` command) reports. If
|
|
603
|
+
* you are about to send this value outside the editor, you want that instead.
|
|
604
|
+
*/
|
|
605
|
+
get playState(): 'stopped' | 'playing' | 'paused' {
|
|
606
|
+
return this._playState;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* Guard structural/history mutations while a game is running. During play the
|
|
611
|
+
* store's `_scene` is the LIVE game scene (see enterPlayScene), so undo/redo
|
|
612
|
+
* (which call clearPreview + buildPreview and rebuild the whole scene) or
|
|
613
|
+
* delete/duplicate (which splice the scene graph and objectMap) would tear the
|
|
614
|
+
* scene out from under the running GameSession. Returns true (and warns) when
|
|
615
|
+
* the named op must be blocked. The intended live-edit path during play is the
|
|
616
|
+
* incremental ECS-sync transform path, not these full-scene mutations.
|
|
617
|
+
*/
|
|
618
|
+
protected _blockedDuringPlay(op: string): boolean {
|
|
619
|
+
if (this._playState === 'stopped') return false;
|
|
620
|
+
console.warn(`EditorStore: "${op}" is disabled during play mode — stop the game first.`);
|
|
621
|
+
return true;
|
|
622
|
+
}
|
|
623
|
+
setPlayState(state: 'stopped' | 'playing' | 'paused'): void {
|
|
624
|
+
const wasActive = this._playState !== 'stopped';
|
|
625
|
+
this._playState = state;
|
|
626
|
+
if (state === 'stopped') {
|
|
627
|
+
// Apply anything deferred while play/ingest was active. play-mode.ts /
|
|
628
|
+
// ingest/mount-ingest-root.ts call exitPlayScene() (restoring the editor scene) BEFORE
|
|
629
|
+
// this — so by the time we get here `_scene` is already the editor scene,
|
|
630
|
+
// never the just-torn-down game scene (see applyExternalUpdate/applyAssetMove).
|
|
631
|
+
if (wasActive) this._onPlayStopped();
|
|
632
|
+
}
|
|
633
|
+
this._notify();
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/** See {@link PlayEditRegime}. Null while not playing. */
|
|
637
|
+
get playEditRegime(): PlayEditRegime {
|
|
638
|
+
return this._playEditRegime;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/** Set by play-mode.ts's enterPlayMode/exitPlayMode — see {@link PlayEditRegime}. */
|
|
642
|
+
setPlayEditRegime(regime: PlayEditRegime): void {
|
|
643
|
+
this._playEditRegime = regime;
|
|
644
|
+
this._notify();
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
// --- Viewport tab ---
|
|
648
|
+
/**
|
|
649
|
+
* `play` exactly while the Game document is the active workspace document, else `edit`:
|
|
650
|
+
* derived from workspace focus, which Code-OSS owns, never set beside it. A surface that
|
|
651
|
+
* wants the other tab activates the document instead.
|
|
652
|
+
*/
|
|
653
|
+
get activeViewportTab(): ViewportTab {
|
|
654
|
+
return this._followsWorkspaceFocus && activeWorkspaceDocumentId() === GAME_DOCUMENT_ID ? 'play' : 'edit';
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// --- Selection ---
|
|
658
|
+
// Every writer below notifies with `'selection'` because every writer below
|
|
659
|
+
// mutates `_viewportSelections` and NOTHING ELSE. That is the whole warrant
|
|
660
|
+
// for the scope — see `contentVersion`.
|
|
661
|
+
select(id: string | null, notification: 'immediate' | 'deferred' = 'immediate'): void {
|
|
662
|
+
const selection = this._viewportSelections[this.activeViewportTab];
|
|
663
|
+
selection.clear();
|
|
664
|
+
if (id) selection.add(id);
|
|
665
|
+
if (notification === 'deferred') this._notifyDeferred('selection');
|
|
666
|
+
else this._notify('selection');
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
selectMultiple(ids: string[], notification: 'immediate' | 'deferred' = 'immediate'): void {
|
|
670
|
+
this._viewportSelections[this.activeViewportTab] = new Set(ids);
|
|
671
|
+
if (notification === 'deferred') this._notifyDeferred('selection');
|
|
672
|
+
else this._notify('selection');
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
/**
|
|
676
|
+
* Apply a control-API selection NOW and return the notification that lets presentation catch up.
|
|
677
|
+
*
|
|
678
|
+
* The normal UI methods above remain synchronous. A relayed selection is different: its caller
|
|
679
|
+
* is waiting for an acknowledgement, while notifying React can synchronously reveal hundreds of
|
|
680
|
+
* hierarchy rows and build an inspector preview before `select()` returns. The command listener
|
|
681
|
+
* uses this method so `selectedEntityIds` already answers the new truth when it acks, then runs
|
|
682
|
+
* the returned notification only after the result POST has settled. No selection is optimistic:
|
|
683
|
+
* the set is mutated before this method returns; only presentation is deferred.
|
|
684
|
+
*/
|
|
685
|
+
applySelectionBeforePresentation(ids: readonly string[]): () => void {
|
|
686
|
+
this._viewportSelections[this.activeViewportTab] = new Set(ids);
|
|
687
|
+
let presented = false;
|
|
688
|
+
return () => {
|
|
689
|
+
if (presented) return;
|
|
690
|
+
presented = true;
|
|
691
|
+
this._notify('selection');
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
addToSelection(id: string): void {
|
|
696
|
+
this._viewportSelections[this.activeViewportTab].add(id);
|
|
697
|
+
this._notify('selection');
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
toggleSelection(id: string): void {
|
|
701
|
+
const selection = this._viewportSelections[this.activeViewportTab];
|
|
702
|
+
if (selection.has(id)) {
|
|
703
|
+
selection.delete(id);
|
|
704
|
+
} else {
|
|
705
|
+
selection.add(id);
|
|
706
|
+
}
|
|
707
|
+
this._notify('selection');
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
/** Runs at the top of every `_notify()`. A document half uses it to close a
|
|
712
|
+
* pending history edit. */
|
|
713
|
+
protected _beforeNotify(): void {}
|
|
714
|
+
|
|
715
|
+
/** Runs after `attachHistory` binds the project `HistoryService`. A document
|
|
716
|
+
* half uses it to register its document resource driver. */
|
|
717
|
+
protected _onHistoryAttached(): void {}
|
|
718
|
+
|
|
719
|
+
/** Runs when `setPlayState('stopped')` ends an active play/ingest session.
|
|
720
|
+
* A document half applies mutations it deferred while play was running. */
|
|
721
|
+
protected _onPlayStopped(): void {}
|
|
722
|
+
}
|