@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,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE JS HEAP READING — the editor's one browser-side memory signal, read by
|
|
3
|
+
* the tab census (`tab-census.ts`: the heartbeat's sample, the death line's
|
|
4
|
+
* quote) and by the Frame debugger's tile (`@volter/editor-game`). A browser
|
|
5
|
+
* property, not a scene property (M1 kept it out of the engine's
|
|
6
|
+
* render-memory on purpose), and Chromium-only: feature-detected, with the
|
|
7
|
+
* REASON returned when the global is absent — never a fabricated 0.
|
|
8
|
+
*/
|
|
9
|
+
export interface JsHeapReading {
|
|
10
|
+
readonly usedBytes: number;
|
|
11
|
+
readonly totalBytes: number;
|
|
12
|
+
/**
|
|
13
|
+
* `jsHeapSizeLimit` — the CEILING this renderer process may allocate to,
|
|
14
|
+
* which is the only one of the three that says how close to a heap death
|
|
15
|
+
* the tab is (`totalBytes` is merely what it has claimed so far). Null when
|
|
16
|
+
* the browser exposes the other two and not this one; the tab census reads
|
|
17
|
+
* it, and reads null as null.
|
|
18
|
+
*/
|
|
19
|
+
readonly limitBytes: number | null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface JsHeapUnavailable {
|
|
23
|
+
/** The honest reason the reading is absent (printed to the user). */
|
|
24
|
+
readonly unavailable: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** True when the reading is present (vs. the unavailable-reason branch). */
|
|
28
|
+
export function isJsHeapReading(
|
|
29
|
+
reading: JsHeapReading | JsHeapUnavailable,
|
|
30
|
+
): reading is JsHeapReading {
|
|
31
|
+
return !('unavailable' in reading);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Read the JS heap via the Chromium-only `performance.memory` global — the one
|
|
36
|
+
* editor-side memory signal (M1 kept it OUT of the engine's render-memory on
|
|
37
|
+
* purpose: it is a browser property, not a scene property). Feature-detected:
|
|
38
|
+
* when the global is absent (Firefox/Safari, or a locked-down Chromium), the
|
|
39
|
+
* REASON is returned so the tile prints it, never a fabricated 0. `perf` is
|
|
40
|
+
* injectable so the test can drive both branches deterministically.
|
|
41
|
+
*/
|
|
42
|
+
export function readJsHeap(
|
|
43
|
+
perf: Performance | undefined = globalThis.performance,
|
|
44
|
+
): JsHeapReading | JsHeapUnavailable {
|
|
45
|
+
const memory = (
|
|
46
|
+
perf as unknown as
|
|
47
|
+
| {
|
|
48
|
+
memory?: {
|
|
49
|
+
usedJSHeapSize?: number;
|
|
50
|
+
totalJSHeapSize?: number;
|
|
51
|
+
jsHeapSizeLimit?: number;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
| undefined
|
|
55
|
+
)?.memory;
|
|
56
|
+
if (
|
|
57
|
+
!memory ||
|
|
58
|
+
typeof memory.usedJSHeapSize !== 'number' ||
|
|
59
|
+
typeof memory.totalJSHeapSize !== 'number'
|
|
60
|
+
) {
|
|
61
|
+
return {
|
|
62
|
+
unavailable:
|
|
63
|
+
'performance.memory is unavailable — it is a non-standard Chromium-only API, not exposed by this browser.',
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
usedBytes: memory.usedJSHeapSize,
|
|
68
|
+
totalBytes: memory.totalJSHeapSize,
|
|
69
|
+
limitBytes: typeof memory.jsHeapSizeLimit === 'number' ? memory.jsHeapSizeLimit : null,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE EDITOR'S KEY ACTIONS — every action a chord can reach, as DATA.
|
|
3
|
+
*
|
|
4
|
+
* THERE IS ONE KEYBOARD AND IT IS VS CODE'S (ARCHITECTURE-CORE §The core is
|
|
5
|
+
* Code-OSS rule 3). The editor installs no `keydown` dispatcher of its own;
|
|
6
|
+
* what it publishes is this table, and the frame turns each entry into a
|
|
7
|
+
* `volter.<id>` command with a `when` clause over our panes' context keys
|
|
8
|
+
* (`scripts/workbench/generate-keymaps.mjs` writes one keybinding rule per
|
|
9
|
+
* (action, chord, keymap) into a built-in extension, read from this repo's own
|
|
10
|
+
* keymap tables — so a chord is written in ONE place whichever keyboard is
|
|
11
|
+
* driving).
|
|
12
|
+
*
|
|
13
|
+
* WHY, measured: with two listeners on one page, `1,1,1,2,2,2` typed into
|
|
14
|
+
* Monaco arrived as `,,,,,`, the file saved as `BoxGeometry(,,,,,)`, and a
|
|
15
|
+
* `Control+W` meant for the workbench opened Edit Mode's Inset tool.
|
|
16
|
+
*
|
|
17
|
+
* An action's BODY is written once, in `editor-hotkeys.ts`'s `bind()` call —
|
|
18
|
+
* the same call that fills this table also fills the binding row — so a
|
|
19
|
+
* handler cannot exist for one keyboard and not the other.
|
|
20
|
+
*/ import type { EditorKeyActionId } from '@volter/sdk/looks';
|
|
21
|
+
|
|
22
|
+
export type KeyActionScope = 'stage' | 'panel' | 'global';
|
|
23
|
+
|
|
24
|
+
export interface KeyActionEntry {
|
|
25
|
+
readonly id: EditorKeyActionId;
|
|
26
|
+
/** Run the action. The event is the host dispatcher's; the frame has none. */
|
|
27
|
+
readonly run: (event?: KeyboardEvent) => void;
|
|
28
|
+
readonly scope: KeyActionScope;
|
|
29
|
+
/**
|
|
30
|
+
* The action's own runtime gate, where it can be asked without an event —
|
|
31
|
+
* the play-state and clipboard-ownership conditions. A gate that reads the
|
|
32
|
+
* EVENT (undo/redo's editable-target test) is not lifted here: under the
|
|
33
|
+
* frame the focus condition it approximates is a `when` clause, and under
|
|
34
|
+
* the host the dispatcher still applies its own `when`.
|
|
35
|
+
*/
|
|
36
|
+
readonly enabled?: () => boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const actions = new Map<EditorKeyActionId, KeyActionEntry>();
|
|
40
|
+
let actionsVersion = 0;
|
|
41
|
+
const actionListeners = new Set<() => void>();
|
|
42
|
+
|
|
43
|
+
function emitActions(): void {
|
|
44
|
+
actionsVersion++;
|
|
45
|
+
for (const listener of actionListeners) listener();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Record what one action DOES. Last registration wins: the shell and viewport
|
|
50
|
+
* binding sets rebuild on every keymap switch (`registerKeymapBindings`), and
|
|
51
|
+
* a rebuild re-registers the same ids with fresh closures over the same store.
|
|
52
|
+
* Returns the removal, which only fires if this entry is still the live one.
|
|
53
|
+
*/
|
|
54
|
+
export function registerKeyAction(entry: KeyActionEntry): () => void {
|
|
55
|
+
actions.set(entry.id, entry);
|
|
56
|
+
emitActions();
|
|
57
|
+
return () => {
|
|
58
|
+
if (actions.get(entry.id) !== entry) return;
|
|
59
|
+
actions.delete(entry.id);
|
|
60
|
+
emitActions();
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Every action the editor currently has a handler for. */
|
|
65
|
+
export function registeredKeyActions(): readonly KeyActionEntry[] {
|
|
66
|
+
return [...actions.values()];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function keyActionsVersion(): number {
|
|
70
|
+
return actionsVersion;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function subscribeKeyActions(listener: () => void): () => void {
|
|
74
|
+
actionListeners.add(listener);
|
|
75
|
+
return () => actionListeners.delete(listener);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Run one action by id — the frame's door. `false` means the editor has no
|
|
80
|
+
* handler for it right now (the viewport set is registered only while a three
|
|
81
|
+
* stage is mounted) or its own gate refused; the frame's command answers the
|
|
82
|
+
* same, so a keybinding that reaches a dead action is visible rather than
|
|
83
|
+
* silent.
|
|
84
|
+
*/
|
|
85
|
+
export function invokeKeyAction(id: EditorKeyActionId): boolean {
|
|
86
|
+
const entry = actions.get(id);
|
|
87
|
+
if (!entry) return false;
|
|
88
|
+
if (entry.enabled && !entry.enabled()) return false;
|
|
89
|
+
entry.run();
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
import type { EditorKeyActionId, KeyChord, KeymapContribution, KeymapNavigation } from '@volter/sdk/looks';
|
|
2
|
+
import { editorConsole } from '@volter/sdk/kit/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/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
|
+
* (`volter` 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 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
|
+
* realm gate, `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 `volter`, or one a package
|
|
49
|
+
* contributes (`@volter/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: 'volter',
|
|
63
|
+
title: 'volter',
|
|
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
|
+
readonly navigation: KeymapNavigation | null;
|
|
72
|
+
}
|
|
73
|
+
const contributedKeymaps = new Map<string, ContributedKeymap>();
|
|
74
|
+
let registryVersion = 0;
|
|
75
|
+
|
|
76
|
+
/** Built-ins first, then contributions in registration order — the switch
|
|
77
|
+
* surfaces (View menu, palette) enumerate this. */
|
|
78
|
+
export function editorKeymaps(): readonly EditorKeymapDescriptor[] {
|
|
79
|
+
return [
|
|
80
|
+
...BUILT_IN_KEYMAPS,
|
|
81
|
+
...[...contributedKeymaps.values()].map((entry) => entry.descriptor),
|
|
82
|
+
];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function editorKeymapsVersion(): number {
|
|
86
|
+
return registryVersion;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Register a package's keymap (`workspace.keymap` contribution). The table is
|
|
91
|
+
* the editor's own bindings with the contribution's chords over them, so a
|
|
92
|
+
* keymap declares only where it differs. Returns the unregister. A duplicate
|
|
93
|
+
* id throws — ids are the `keymap` setting's values.
|
|
94
|
+
*/
|
|
95
|
+
export function registerContributedKeymap(contribution: KeymapContribution): () => void {
|
|
96
|
+
if (
|
|
97
|
+
BUILT_IN_KEYMAPS.some((entry) => entry.id === contribution.id) ||
|
|
98
|
+
contributedKeymaps.has(contribution.id)
|
|
99
|
+
)
|
|
100
|
+
throw new Error(
|
|
101
|
+
`registerContributedKeymap: keymap "${contribution.id}" is already registered.`,
|
|
102
|
+
);
|
|
103
|
+
const entry: ContributedKeymap = {
|
|
104
|
+
descriptor: {
|
|
105
|
+
id: contribution.id,
|
|
106
|
+
title: contribution.title,
|
|
107
|
+
description: contribution.description,
|
|
108
|
+
},
|
|
109
|
+
table: Object.freeze({ ...VOLTER_KEYMAP, ...contribution.bindings }) as EditorKeymapTable,
|
|
110
|
+
navigation: contribution.navigation ?? null,
|
|
111
|
+
};
|
|
112
|
+
contributedKeymaps.set(contribution.id, entry);
|
|
113
|
+
registryVersion++;
|
|
114
|
+
// A stored preference this contribution satisfies applies now, not on the
|
|
115
|
+
// next reload: the cache re-reads the setting against the wider registry.
|
|
116
|
+
cachedKeymap = null;
|
|
117
|
+
emit();
|
|
118
|
+
return () => {
|
|
119
|
+
if (contributedKeymaps.get(contribution.id) !== entry) return;
|
|
120
|
+
contributedKeymaps.delete(contribution.id);
|
|
121
|
+
registryVersion++;
|
|
122
|
+
cachedKeymap = null;
|
|
123
|
+
emit();
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function isEditorKeymapId(value: unknown): value is EditorKeymapId {
|
|
128
|
+
return (
|
|
129
|
+
typeof value === 'string' &&
|
|
130
|
+
(BUILT_IN_KEYMAPS.some((entry) => entry.id === value) || contributedKeymaps.has(value))
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export type EditorKeymapTable = Readonly<Record<EditorKeyActionId, readonly KeyChord[]>>;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* The volter table reproduces the bindings the editor shipped before keymaps
|
|
138
|
+
* existed, chord for chord. It is the regression bar: any change here is a
|
|
139
|
+
* change to the default editor, not to a keymap.
|
|
140
|
+
*/
|
|
141
|
+
const VOLTER_KEYMAP: EditorKeymapTable = Object.freeze({
|
|
142
|
+
'edit.undo': [{ key: 'z', mod: true }],
|
|
143
|
+
// Ctrl+Y mirrors Ctrl+Shift+Z (Windows convention).
|
|
144
|
+
'edit.redo': [
|
|
145
|
+
{ key: 'z', mod: true, shift: true },
|
|
146
|
+
{ key: 'y', mod: true },
|
|
147
|
+
],
|
|
148
|
+
'edit.copy': [{ key: 'c', mod: true }],
|
|
149
|
+
'edit.cut': [{ key: 'x', mod: true }],
|
|
150
|
+
'edit.paste': [{ key: 'v', mod: true }],
|
|
151
|
+
'edit.duplicate': [{ key: 'd', mod: true }],
|
|
152
|
+
'edit.group': [{ key: 'g', mod: true }],
|
|
153
|
+
'edit.wrap': [{ key: 'g', mod: true, alt: true }],
|
|
154
|
+
'edit.unwrap': [{ key: 'g', mod: true, shift: true }],
|
|
155
|
+
'edit.selectAll': [{ key: 'a', mod: true }],
|
|
156
|
+
// No dedicated chord: Escape is the volter deselect, and it carries the
|
|
157
|
+
// scope-exit semantics too (`edit.exitScopeOrDeselect`). An empty chord list
|
|
158
|
+
// registers no binding; the printed hint falls back to Escape's.
|
|
159
|
+
'edit.deselectAll': [],
|
|
160
|
+
'edit.save': [{ key: 's', mod: true }],
|
|
161
|
+
'edit.delete': [{ key: 'delete' }, { key: 'backspace' }],
|
|
162
|
+
'edit.enterScope': [{ key: 'enter' }],
|
|
163
|
+
'edit.exitScopeOrDeselect': [{ key: 'escape' }],
|
|
164
|
+
'edit.nudgeUp': [{ key: 'arrowup' }],
|
|
165
|
+
'edit.nudgeUpCoarse': [{ key: 'arrowup', shift: true }],
|
|
166
|
+
'edit.nudgeDown': [{ key: 'arrowdown' }],
|
|
167
|
+
'edit.nudgeDownCoarse': [{ key: 'arrowdown', shift: true }],
|
|
168
|
+
'edit.nudgeLeft': [{ key: 'arrowleft' }],
|
|
169
|
+
'edit.nudgeLeftCoarse': [{ key: 'arrowleft', shift: true }],
|
|
170
|
+
'edit.nudgeRight': [{ key: 'arrowright' }],
|
|
171
|
+
'edit.nudgeRightCoarse': [{ key: 'arrowright', shift: true }],
|
|
172
|
+
'view.resetPan': [{ key: '0', mod: true }],
|
|
173
|
+
'view.commandPalette': [{ key: 'k', mod: true }],
|
|
174
|
+
'view.toggleConsole': [{ key: '`' }],
|
|
175
|
+
'view.focusMode': [{ key: 'f', mod: true, shift: true }],
|
|
176
|
+
// Blender's own workspace cycle keys, and free in this registry.
|
|
177
|
+
'workspace.cycleNext': [{ key: 'pagedown', mod: true }],
|
|
178
|
+
'workspace.cyclePrevious': [{ key: 'pageup', mod: true }],
|
|
179
|
+
// Q, beside W/E/R: Godot's 2D Select (its 4.7.1 shortcut `canvas_item_editor/select_mode`)
|
|
180
|
+
// and Unreal's Select both sit there. The Blender look keeps Select on Blender's own `W`.
|
|
181
|
+
'transform.select': [{ key: 'q' }],
|
|
182
|
+
'transform.combined': [{ key: 't' }],
|
|
183
|
+
'transform.translate': [{ key: 'w' }],
|
|
184
|
+
'transform.rotate': [{ key: 'e' }],
|
|
185
|
+
'transform.scale': [{ key: 'r' }],
|
|
186
|
+
'viewport.toggleSnap': [{ key: 's', shift: true }],
|
|
187
|
+
'viewport.frameSelection': [{ key: 'f' }],
|
|
188
|
+
'viewport.cyclePivot': [{ key: '.' }],
|
|
189
|
+
// A 2D view's Pan and Ruler modes, on Godot's own keys (its 4.7.1 shortcuts
|
|
190
|
+
// `canvas_item_editor/pan_mode` G and `ruler_mode` M).
|
|
191
|
+
'canvas.panMode': [{ key: 'g' }],
|
|
192
|
+
'canvas.rulerMode': [{ key: 'm' }],
|
|
193
|
+
// Godot's View › Grid › Toggle Grid, Command+' (its 4.7.1 menu shortcut).
|
|
194
|
+
'canvas.toggleGrid': [{ key: "'", mod: true }],
|
|
195
|
+
'viewport.vertexSnapHold': [{ key: 'v' }],
|
|
196
|
+
'viewport.snapToFloor': [{ key: '', code: 'PageDown' }],
|
|
197
|
+
'view.top': [{ key: '', code: 'Numpad7' }],
|
|
198
|
+
'view.front': [{ key: '', code: 'Numpad1' }],
|
|
199
|
+
'view.right': [{ key: '', code: 'Numpad3' }],
|
|
200
|
+
'view.bottom': [],
|
|
201
|
+
'view.back': [],
|
|
202
|
+
'view.left': [],
|
|
203
|
+
'view.orbitLeft': [],
|
|
204
|
+
'view.orbitRight': [],
|
|
205
|
+
'view.orbitUp': [],
|
|
206
|
+
'view.orbitDown': [],
|
|
207
|
+
'view.opposite': [],
|
|
208
|
+
'view.rollLeft': [],
|
|
209
|
+
'view.rollRight': [],
|
|
210
|
+
'view.all': [],
|
|
211
|
+
'view.zoomIn': [],
|
|
212
|
+
'view.zoomOut': [],
|
|
213
|
+
'view.perspective': [{ key: '', code: 'Numpad5' }],
|
|
214
|
+
'view.projection': [],
|
|
215
|
+
'view.camera': [{ key: '', code: 'Numpad0' }],
|
|
216
|
+
} satisfies EditorKeymapTable);
|
|
217
|
+
|
|
218
|
+
// ---------------------------------------------------------------------------
|
|
219
|
+
// The setting
|
|
220
|
+
// ---------------------------------------------------------------------------
|
|
221
|
+
|
|
222
|
+
export const DEFAULT_EDITOR_KEYMAP: EditorKeymapId = 'volter';
|
|
223
|
+
|
|
224
|
+
let cachedKeymap: EditorKeymapId | null = null;
|
|
225
|
+
let settingsSyncInstalled = false;
|
|
226
|
+
const listeners = new Set<() => void>();
|
|
227
|
+
|
|
228
|
+
function emit(): void {
|
|
229
|
+
for (const listener of listeners) listener();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** The editor's own keymap ids — the ones that exist in every project. */
|
|
233
|
+
function isBuiltInKeymapId(value: unknown): boolean {
|
|
234
|
+
return typeof value === 'string' && BUILT_IN_KEYMAPS.some((entry) => entry.id === value);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/** What the PROJECT selects: its adapter's declaration, its own settings over it. */
|
|
238
|
+
function projectScopedKeymap(): unknown {
|
|
239
|
+
return projectSettings().keymap ?? adapterSettings().keymap;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* A keymap a PACKAGE contributes is project-scoped: it exists only where that
|
|
244
|
+
* package is declared, so only the project may select it — its adapter
|
|
245
|
+
* (`editor: { keymap: blenderKeymap }`) or its own `.volter/settings.json`. The
|
|
246
|
+
* USER layer chooses among the editor's own, because a cross-project default
|
|
247
|
+
* naming a skew's bindings is how a models project's G/R/S reached a game
|
|
248
|
+
* project that merely happens to declare the same package.
|
|
249
|
+
*/
|
|
250
|
+
function readStoredKeymap(): EditorKeymapId {
|
|
251
|
+
const scoped = projectScopedKeymap();
|
|
252
|
+
if (isEditorKeymapId(scoped)) return scoped;
|
|
253
|
+
const preferred = userSettings().keymap;
|
|
254
|
+
return isBuiltInKeymapId(preferred) ? (preferred as EditorKeymapId) : DEFAULT_EDITOR_KEYMAP;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const saidUnavailable = new Set<string>();
|
|
258
|
+
/**
|
|
259
|
+
* Say, once per id, that the STORED keymap is one nothing in this project
|
|
260
|
+
* contributes, so a models project opened without its Blender package
|
|
261
|
+
* explains the W/E/R it is showing. Called by the loader AFTER a contribution
|
|
262
|
+
* pass has registered what the project's packages ship — asked at boot it
|
|
263
|
+
* would warn about every keymap a package is about to contribute (measured
|
|
264
|
+
* 2026-09-17: "blender is not available" on a project whose mesh package
|
|
265
|
+
* registered it a moment later).
|
|
266
|
+
*/
|
|
267
|
+
export function reportUnavailableKeymap(): void {
|
|
268
|
+
const stored = projectScopedKeymap();
|
|
269
|
+
if (typeof stored !== 'string' || stored === DEFAULT_EDITOR_KEYMAP) return;
|
|
270
|
+
if (isEditorKeymapId(stored) || saidUnavailable.has(stored)) return;
|
|
271
|
+
saidUnavailable.add(stored);
|
|
272
|
+
editorConsole.warn(
|
|
273
|
+
`Keymap "${stored}" is not available in this project: no declared package contributes it ` +
|
|
274
|
+
`(a package ships one as a \`workspace.keymap\` contribution). Using "${DEFAULT_EDITOR_KEYMAP}".`,
|
|
275
|
+
'editor',
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/** The setting is `keymap` in the settings layers (`settings-store.ts`); a
|
|
280
|
+
* load finishing or a project's own override becoming active must not leave
|
|
281
|
+
* this module's cache lying. Installed on first read so the module has no
|
|
282
|
+
* load-time side effect. */
|
|
283
|
+
function ensureSettingsSync(): void {
|
|
284
|
+
if (settingsSyncInstalled) return;
|
|
285
|
+
settingsSyncInstalled = true;
|
|
286
|
+
subscribeSettings(() => {
|
|
287
|
+
const next = readStoredKeymap();
|
|
288
|
+
if (next === cachedKeymap) return;
|
|
289
|
+
cachedKeymap = next;
|
|
290
|
+
emit();
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/** Current keymap id (`useSyncExternalStore`-shaped snapshot). */
|
|
295
|
+
export function activeEditorKeymap(): EditorKeymapId {
|
|
296
|
+
ensureSettingsSync();
|
|
297
|
+
cachedKeymap ??= readStoredKeymap();
|
|
298
|
+
return cachedKeymap;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Switch keymaps. Live: every binding registration re-derives from the new
|
|
303
|
+
* table on this call (`editor-hotkeys.ts`) and every printed hint re-renders,
|
|
304
|
+
* so there is no reload and no restart. Choosing one of the editor's OWN
|
|
305
|
+
* keymaps writes where the key is declared; choosing a package's writes the
|
|
306
|
+
* PROJECT layer, because that is the only layer a contributed keymap is read
|
|
307
|
+
* from (see {@link readStoredKeymap}) — a gesture must land somewhere it wins.
|
|
308
|
+
*/
|
|
309
|
+
export function setEditorKeymapPreference(id: EditorKeymapId): void {
|
|
310
|
+
if (activeEditorKeymap() === id) return;
|
|
311
|
+
cachedKeymap = id;
|
|
312
|
+
if (isBuiltInKeymapId(id)) updatePreferenceSettings({ keymap: id });
|
|
313
|
+
else updateProjectSettings({ keymap: id });
|
|
314
|
+
emit();
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export function subscribeEditorKeymap(listener: () => void): () => void {
|
|
318
|
+
listeners.add(listener);
|
|
319
|
+
return () => listeners.delete(listener);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
export function __resetEditorKeymapForTest(): void {
|
|
323
|
+
cachedKeymap = null;
|
|
324
|
+
listeners.clear();
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// ---------------------------------------------------------------------------
|
|
328
|
+
// The one lookup
|
|
329
|
+
// ---------------------------------------------------------------------------
|
|
330
|
+
|
|
331
|
+
/** The active table's chords for one action. Empty means deliberately unbound. */
|
|
332
|
+
export function keyChordsFor(action: EditorKeyActionId): readonly KeyChord[] {
|
|
333
|
+
return keymapTable(activeEditorKeymap())[action];
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/** The active keymap's viewport mouse (`KeymapContribution.navigation`), the editor's own when
|
|
337
|
+
* it states none: orbit on the right button. */
|
|
338
|
+
export function activeKeymapNavigation(): KeymapNavigation {
|
|
339
|
+
return contributedKeymaps.get(activeEditorKeymap())?.navigation ?? { orbit: 'right' };
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/** A named table, for a surface that must show a keymap it is not running.
|
|
343
|
+
* An unregistered id answers the editor's own table. */
|
|
344
|
+
export function keymapTable(id: EditorKeymapId): EditorKeymapTable {
|
|
345
|
+
return contributedKeymaps.get(id)?.table ?? VOLTER_KEYMAP;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// ---------------------------------------------------------------------------
|
|
349
|
+
// Display
|
|
350
|
+
// ---------------------------------------------------------------------------
|
|
351
|
+
|
|
352
|
+
function isMacPlatform(): boolean {
|
|
353
|
+
return typeof navigator !== 'undefined' && navigator.platform.includes('Mac');
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/** Named keys whose label is neither the raw `key` nor its uppercase form. */
|
|
357
|
+
const KEY_LABELS: Readonly<Record<string, string>> = {
|
|
358
|
+
delete: 'Del',
|
|
359
|
+
backspace: 'Backspace',
|
|
360
|
+
escape: 'Esc',
|
|
361
|
+
enter: 'Enter',
|
|
362
|
+
pagedown: 'PgDn',
|
|
363
|
+
pageup: 'PgUp',
|
|
364
|
+
arrowup: '↑',
|
|
365
|
+
arrowdown: '↓',
|
|
366
|
+
arrowleft: '←',
|
|
367
|
+
arrowright: '→',
|
|
368
|
+
' ': 'Space',
|
|
369
|
+
tab: 'Tab',
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
const CODE_LABELS: Readonly<Record<string, string>> = {
|
|
373
|
+
Numpad0: 'Num0',
|
|
374
|
+
Numpad1: 'Num1',
|
|
375
|
+
Numpad2: 'Num2',
|
|
376
|
+
Numpad3: 'Num3',
|
|
377
|
+
Numpad4: 'Num4',
|
|
378
|
+
Numpad5: 'Num5',
|
|
379
|
+
Numpad6: 'Num6',
|
|
380
|
+
Numpad7: 'Num7',
|
|
381
|
+
Numpad8: 'Num8',
|
|
382
|
+
Numpad9: 'Num9',
|
|
383
|
+
NumpadDecimal: 'Num.',
|
|
384
|
+
PageDown: 'PgDn',
|
|
385
|
+
PageUp: 'PgUp',
|
|
386
|
+
End: 'End',
|
|
387
|
+
KeyG: 'G',
|
|
388
|
+
KeyH: 'H',
|
|
389
|
+
KeyJ: 'J',
|
|
390
|
+
KeyK: 'K',
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
function keyLabel(chord: KeyChord): string {
|
|
394
|
+
if (chord.code) return CODE_LABELS[chord.code] ?? chord.code;
|
|
395
|
+
return KEY_LABELS[chord.key] ?? (chord.key.length === 1 ? chord.key.toUpperCase() : chord.key);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Render one chord the way the editor's chrome has always rendered them —
|
|
400
|
+
* BOTH existing conventions preserved verbatim, because changing a printed
|
|
401
|
+
* string is a visible regression: a mod-prefixed chord reads `⌘⇧Z` / `Ctrl+⇧Z`
|
|
402
|
+
* (the command palette's shape), while a modless chord spells its modifiers
|
|
403
|
+
* out, `Shift+S` (the toolstrip's shape).
|
|
404
|
+
*/
|
|
405
|
+
export function formatChord(chord: KeyChord): string {
|
|
406
|
+
const label = keyLabel(chord);
|
|
407
|
+
if (chord.mod) {
|
|
408
|
+
const mod = isMacPlatform() ? '⌘' : 'Ctrl+';
|
|
409
|
+
return `${chord.ctrl && isMacPlatform() ? '⌃' : ''}${mod}${chord.alt ? '⌥' : ''}${chord.shift ? '⇧' : ''}${label}`;
|
|
410
|
+
}
|
|
411
|
+
const parts: string[] = [];
|
|
412
|
+
if (chord.ctrl) parts.push('Ctrl');
|
|
413
|
+
if (chord.alt) parts.push('Alt');
|
|
414
|
+
if (chord.shift) parts.push('Shift');
|
|
415
|
+
parts.push(label);
|
|
416
|
+
return parts.join('+');
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* The printed hint for an action under the ACTIVE keymap — the first chord,
|
|
421
|
+
* which every table lists in "the one to teach" order. `undefined` when the
|
|
422
|
+
* action is deliberately unbound, so a caller can fall back or omit the hint
|
|
423
|
+
* rather than print a lie.
|
|
424
|
+
*/
|
|
425
|
+
export function shortcutFor(action: EditorKeyActionId): string | undefined {
|
|
426
|
+
const chord = keyChordsFor(action)[0];
|
|
427
|
+
return chord ? formatChord(chord) : undefined;
|
|
428
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** Presentation chosen by mounted layout code. No game or website names live here. */
|
|
2
|
+
import type { WorkspaceArrangement } from '@volter/sdk/layout-arrangements';
|
|
3
|
+
import { activeProjectKey } from '@volter/sdk/kit/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
|
+
}
|