@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,497 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme-backed renderer selection ink shared by the native Three and Pixi
|
|
3
|
+
* views. CSS can consume `var(--volter-accent)` directly; WebGL cannot, so this
|
|
4
|
+
* module resolves the inherited token to the integer both renderers speak.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useMemo, useSyncExternalStore } from 'react';
|
|
8
|
+
import { EDITOR_THEME_CLASS, graphiteDarkEditorTheme, STAGE_WORD_MODES } from '@volter/sdk/widgets';
|
|
9
|
+
|
|
10
|
+
/** Import/SSR fallback: Graphite Dark's canonical blue accent. */
|
|
11
|
+
export const DEFAULT_NATIVE_SELECTION_COLOR = 0x579eff;
|
|
12
|
+
|
|
13
|
+
export interface NativeSelectionColors {
|
|
14
|
+
readonly visible: number;
|
|
15
|
+
readonly hidden: number;
|
|
16
|
+
/** The ACTIVE object's outline (`color.viewport.active`, Blender's lighter orange), or the
|
|
17
|
+
* selection's own when the palette names none. */
|
|
18
|
+
readonly active?: { readonly visible: number; readonly hidden: number };
|
|
19
|
+
/** THE OUTLINE'S FORM (`stage.outlineStyle`, `outlineWidth`, `outlineHidden`):
|
|
20
|
+
* `soft`, the editor's own blurred halo, or `crisp` at a width in device pixels; and whether
|
|
21
|
+
* the parts other objects hide are drawn too. Absent is the editor's own. */
|
|
22
|
+
readonly outline?: { readonly style: 'soft' | 'crisp'; readonly width: number | null; readonly hidden: boolean };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function rgbHex(red: number, green: number, blue: number): number {
|
|
26
|
+
return (red << 16) | (green << 8) | blue;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function parseNormalizedColor(value: string): number | null {
|
|
30
|
+
const hex = /^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.exec(value.trim())?.[1];
|
|
31
|
+
if (hex) {
|
|
32
|
+
const opaque = hex.length === 3 ? [...hex].map((digit) => `${digit}${digit}`).join('') : hex;
|
|
33
|
+
return Number.parseInt(opaque.slice(0, 6), 16);
|
|
34
|
+
}
|
|
35
|
+
const rgb =
|
|
36
|
+
/^rgba?\(\s*(\d+(?:\.\d+)?)\s*(?:,\s*|\s+)(\d+(?:\.\d+)?)\s*(?:,\s*|\s+)(\d+(?:\.\d+)?)/i.exec(
|
|
37
|
+
value.trim(),
|
|
38
|
+
);
|
|
39
|
+
if (!rgb) return null;
|
|
40
|
+
const channels = rgb.slice(1, 4).map((channel) => Math.round(Number(channel)));
|
|
41
|
+
if (channels.some((channel) => channel < 0 || channel > 255)) return null;
|
|
42
|
+
return rgbHex(channels[0]!, channels[1]!, channels[2]!);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Normalize any browser-valid CSS color (custom palettes may use HSL/names). */
|
|
46
|
+
function parseCssColor(value: string): number | null {
|
|
47
|
+
const direct = parseNormalizedColor(value);
|
|
48
|
+
if (direct !== null || typeof document === 'undefined') return direct;
|
|
49
|
+
if (typeof CSS !== 'undefined' && !CSS.supports('color', value)) return null;
|
|
50
|
+
const context = document.createElement('canvas').getContext('2d');
|
|
51
|
+
if (!context) return null;
|
|
52
|
+
context.fillStyle = '#010203';
|
|
53
|
+
context.fillStyle = value;
|
|
54
|
+
return parseNormalizedColor(String(context.fillStyle));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function themeRoot(element?: Element | null): Element | null {
|
|
58
|
+
if (typeof document === 'undefined') return null;
|
|
59
|
+
return (
|
|
60
|
+
element?.closest(`.${EDITOR_THEME_CLASS}`) ?? document.querySelector(`.${EDITOR_THEME_CLASS}`)
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function dimColor(color: number): number {
|
|
65
|
+
const red = Math.round(((color >> 16) & 0xff) * 0.42);
|
|
66
|
+
const green = Math.round(((color >> 8) & 0xff) * 0.42);
|
|
67
|
+
const blue = Math.round((color & 0xff) * 0.42);
|
|
68
|
+
return rgbHex(red, green, blue);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Current palette accent, with a same-hue dim variant for occluded 3D edges. */
|
|
72
|
+
function themeToken(root: Element | null, name: string): string {
|
|
73
|
+
return root && typeof getComputedStyle !== 'undefined'
|
|
74
|
+
? getComputedStyle(root).getPropertyValue(name).trim()
|
|
75
|
+
: '';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* THE STAGE'S COLOURS ARE THE WORKBENCH'S FIRST. Under the Code-OSS frame each is a theme
|
|
80
|
+
* colour (`volter.viewport.*`, `volter.gizmo.*`, the frame's `volterColors.ts`) the look sets and a
|
|
81
|
+
* person's `workbench.colorCustomizations` override, emitted as `--vscode-<id>` with dots as
|
|
82
|
+
* dashes; the page's own token is what the look said, read where there is no workbench.
|
|
83
|
+
*/
|
|
84
|
+
const WORKBENCH_COLOR: Readonly<Record<string, string>> = {
|
|
85
|
+
'--volter-viewport-background': '--vscode-volter-viewport-background',
|
|
86
|
+
'--volter-viewport-grid': '--vscode-volter-viewport-grid',
|
|
87
|
+
'--volter-viewport-axis-x': '--vscode-volter-viewport-axisX',
|
|
88
|
+
'--volter-viewport-axis-y': '--vscode-volter-viewport-axisY',
|
|
89
|
+
'--volter-viewport-axis-z': '--vscode-volter-viewport-axisZ',
|
|
90
|
+
'--volter-viewport-selection': '--vscode-volter-viewport-selection',
|
|
91
|
+
'--volter-viewport-active': '--vscode-volter-viewport-active',
|
|
92
|
+
'--volter-viewport-wire': '--vscode-volter-viewport-wire',
|
|
93
|
+
'--volter-gizmo-x': '--vscode-volter-gizmo-x',
|
|
94
|
+
'--volter-gizmo-y': '--vscode-volter-gizmo-y',
|
|
95
|
+
'--volter-gizmo-z': '--vscode-volter-gizmo-z',
|
|
96
|
+
'--volter-gizmo-navigation-x': '--vscode-volter-gizmo-navigationX',
|
|
97
|
+
'--volter-gizmo-navigation-y': '--vscode-volter-gizmo-navigationY',
|
|
98
|
+
'--volter-gizmo-navigation-z': '--vscode-volter-gizmo-navigationZ',
|
|
99
|
+
'--volter-gizmo-hover': '--vscode-volter-gizmo-hover',
|
|
100
|
+
'--volter-gizmo-drag': '--vscode-volter-gizmo-drag',
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
function stageColorToken(root: Element | null, name: string): string {
|
|
104
|
+
const workbench = WORKBENCH_COLOR[name];
|
|
105
|
+
return (workbench ? themeToken(root, workbench) : '') || themeToken(root, name);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** The palette's selection colour: its viewport group's when it carries one
|
|
109
|
+
* (Blender's orange), the accent otherwise. */
|
|
110
|
+
export function nativeSelectionColors(element?: Element | null): NativeSelectionColors {
|
|
111
|
+
const root = themeRoot(element);
|
|
112
|
+
const raw = stageColorToken(root, '--volter-viewport-selection') || themeToken(root, '--volter-accent');
|
|
113
|
+
const visible =
|
|
114
|
+
parseCssColor(raw || graphiteDarkEditorTheme.color.accent.default) ??
|
|
115
|
+
DEFAULT_NATIVE_SELECTION_COLOR;
|
|
116
|
+
const active = parseCssColor(stageColorToken(root, '--volter-viewport-active'));
|
|
117
|
+
const style = themeToken(root, '--volter-viewport-outline-style');
|
|
118
|
+
const width = Number.parseFloat(themeToken(root, '--volter-viewport-outline-width'));
|
|
119
|
+
const hidden = themeToken(root, '--volter-viewport-outline-hidden');
|
|
120
|
+
return {
|
|
121
|
+
visible,
|
|
122
|
+
hidden: dimColor(visible),
|
|
123
|
+
...(active === null ? {} : { active: { visible: active, hidden: dimColor(active) } }),
|
|
124
|
+
...(style === '' && hidden === '' && !Number.isFinite(width)
|
|
125
|
+
? {}
|
|
126
|
+
: {
|
|
127
|
+
outline: {
|
|
128
|
+
style: style === 'crisp' ? 'crisp' : 'soft',
|
|
129
|
+
width: Number.isFinite(width) && width > 0 ? width : null,
|
|
130
|
+
hidden: hidden !== 'false',
|
|
131
|
+
},
|
|
132
|
+
}),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** The palette's VIEWPORT GROUP (`EditorTheme.color.viewport`), each member
|
|
137
|
+
* `null` when the palette carries none — the viewport keeps its own then. */
|
|
138
|
+
export interface NativeViewportLook {
|
|
139
|
+
readonly background: number | null;
|
|
140
|
+
readonly grid: number | null;
|
|
141
|
+
readonly axisX: number | null;
|
|
142
|
+
readonly axisY: number | null;
|
|
143
|
+
readonly axisZ: number | null;
|
|
144
|
+
/** `stage.axisLineWidth`, device px, or `null` for the editor's own. */
|
|
145
|
+
readonly axisLineWidth: number | null;
|
|
146
|
+
readonly active: number | null;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Whether the ACTIVE LOOK declares a `color.viewport` group at all — the
|
|
151
|
+
* question "is the backdrop the look's, or the editor's own?"
|
|
152
|
+
* (ARCHITECTURE-CORE §A model is data: a data subject opens in an isolation
|
|
153
|
+
* scene whose story is the studio, and the studio's backdrop is the editor's;
|
|
154
|
+
* a look that paints the viewport itself — Blender's flat grey — has already
|
|
155
|
+
* answered, and the studio must not paint over it).
|
|
156
|
+
*
|
|
157
|
+
* `background` alone is the whole test because the group is ALL-OR-NOTHING:
|
|
158
|
+
* `EditorTheme.color.viewport` makes every member required, and a palette
|
|
159
|
+
* DOCUMENT that carries a partial group is rejected by name at parse
|
|
160
|
+
* (`theme-library.ts`'s viewport reconstruction). So the group is present
|
|
161
|
+
* exactly when this token paints.
|
|
162
|
+
*/
|
|
163
|
+
export function lookDeclaresViewportColors(element?: Element | null): boolean {
|
|
164
|
+
return nativeViewportLook(element).background !== null;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** Whether the look paints its viewport LIGHT (relative luminance above one half). The ink that
|
|
168
|
+
* reads over a declared viewport is the palette's `content.onAccent` on a dark one (Blender's
|
|
169
|
+
* white over its grey) and its ordinary `content.primary` on a light one (ink over
|
|
170
|
+
* paper), where the on-accent ink is the same colour as the ground. */
|
|
171
|
+
export function lookPaintsLightViewport(element?: Element | null): boolean {
|
|
172
|
+
const background = nativeViewportLook(element).background;
|
|
173
|
+
if (background === null) return false;
|
|
174
|
+
const r = (background >> 16) & 0xff, g = (background >> 8) & 0xff, b = background & 0xff;
|
|
175
|
+
return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255 > 0.5;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export function nativeViewportLook(element?: Element | null): NativeViewportLook {
|
|
179
|
+
const root = themeRoot(element);
|
|
180
|
+
const read = (name: string): number | null => {
|
|
181
|
+
const raw = stageColorToken(root, name);
|
|
182
|
+
return raw ? parseCssColor(raw) : null;
|
|
183
|
+
};
|
|
184
|
+
return {
|
|
185
|
+
background: read('--volter-viewport-background'),
|
|
186
|
+
grid: read('--volter-viewport-grid'),
|
|
187
|
+
axisX: read('--volter-viewport-axis-x'),
|
|
188
|
+
axisY: read('--volter-viewport-axis-y'),
|
|
189
|
+
axisZ: read('--volter-viewport-axis-z'),
|
|
190
|
+
axisLineWidth: (() => {
|
|
191
|
+
const raw = themeToken(root, '--volter-viewport-axis-line-width');
|
|
192
|
+
const value = raw ? Number.parseFloat(raw) : Number.NaN;
|
|
193
|
+
return Number.isFinite(value) ? value : null;
|
|
194
|
+
})(),
|
|
195
|
+
active: read('--volter-viewport-active'),
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** THE LOOK'S GIZMO COLOURS AND HIGHLIGHT (`EditorTheme.color.gizmo`, and
|
|
200
|
+
* `stage.gizmoOpacity`/`gizmoHighlightSaturation`/`gizmoHighlightValue`), each
|
|
201
|
+
* `null` when the look names none — the viewport keeps its own then. `axes` are X, Y, Z. */
|
|
202
|
+
export interface NativeGizmoLook {
|
|
203
|
+
readonly axes: readonly [number, number, number] | null;
|
|
204
|
+
/** The navigation gizmo's own X, Y, Z, or `null` to draw it in {@link axes}. */
|
|
205
|
+
readonly navigation: readonly [number, number, number] | null;
|
|
206
|
+
readonly hover: number | null;
|
|
207
|
+
readonly drag: number | null;
|
|
208
|
+
readonly opacity: number | null;
|
|
209
|
+
readonly arrowLength: number | null;
|
|
210
|
+
readonly arrowHead: number | null;
|
|
211
|
+
readonly ringWidth: number | null;
|
|
212
|
+
readonly navigationForm: 'balls' | 'godot' | 'cones' | 'triad';
|
|
213
|
+
/** The viewport's background, which the ball form mixes its colours toward by depth. */
|
|
214
|
+
readonly background: number | null;
|
|
215
|
+
readonly navigationSize: number | null;
|
|
216
|
+
readonly navigationCorner: 'top-right' | 'bottom-left';
|
|
217
|
+
readonly highlightSaturation: number | null;
|
|
218
|
+
readonly highlightValue: number | null;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export function nativeGizmoLook(element?: Element | null): NativeGizmoLook {
|
|
222
|
+
const root = themeRoot(element);
|
|
223
|
+
const color = (name: string): number | null => {
|
|
224
|
+
const raw = stageColorToken(root, name);
|
|
225
|
+
return raw ? parseCssColor(raw) : null;
|
|
226
|
+
};
|
|
227
|
+
const number = (name: string): number | null => {
|
|
228
|
+
const raw = themeToken(root, name);
|
|
229
|
+
if (!raw) return null;
|
|
230
|
+
const value = Number.parseFloat(raw);
|
|
231
|
+
return Number.isFinite(value) ? value : null;
|
|
232
|
+
};
|
|
233
|
+
const trio = (prefix: string): readonly [number, number, number] | null => {
|
|
234
|
+
const x = color(`${prefix}-x`);
|
|
235
|
+
const y = color(`${prefix}-y`);
|
|
236
|
+
const z = color(`${prefix}-z`);
|
|
237
|
+
return x !== null && y !== null && z !== null ? [x, y, z] : null;
|
|
238
|
+
};
|
|
239
|
+
return {
|
|
240
|
+
axes: trio('--volter-gizmo'),
|
|
241
|
+
navigation: trio('--volter-gizmo-navigation'),
|
|
242
|
+
hover: color('--volter-gizmo-hover'),
|
|
243
|
+
drag: color('--volter-gizmo-drag'),
|
|
244
|
+
opacity: number('--volter-viewport-gizmo-opacity'),
|
|
245
|
+
arrowLength: number('--volter-viewport-gizmo-arrow-length'),
|
|
246
|
+
arrowHead: number('--volter-viewport-gizmo-arrow-head'),
|
|
247
|
+
ringWidth: number('--volter-viewport-gizmo-ring-width'),
|
|
248
|
+
navigationSize: number('--volter-viewport-navigation-size'),
|
|
249
|
+
background: color('--volter-viewport-background'),
|
|
250
|
+
navigationForm: ((form) => (form === 'cones' || form === 'triad' || form === 'godot' ? form : 'balls'))(
|
|
251
|
+
themeToken(root, '--volter-viewport-navigation-gizmo'),
|
|
252
|
+
),
|
|
253
|
+
navigationCorner:
|
|
254
|
+
themeToken(root, '--volter-viewport-navigation-corner') === 'bottom-left' ? 'bottom-left' : 'top-right',
|
|
255
|
+
highlightSaturation: number('--volter-viewport-gizmo-highlight-saturation'),
|
|
256
|
+
highlightValue: number('--volter-viewport-gizmo-highlight-value'),
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* THE LOOK'S TRANSFORM-GIZMO SIZE, in px per gizmo unit
|
|
262
|
+
* (`EditorTheme.stage.gizmoSize`), or `null` when the look names
|
|
263
|
+
* none — which is every look but Blender's, and means "keep three's own
|
|
264
|
+
* viewport-relative handle".
|
|
265
|
+
*
|
|
266
|
+
* Read off the emitted token for the same reason the colours above are: WebGL
|
|
267
|
+
* cannot consume a CSS variable, and the theme object reaching the viewport
|
|
268
|
+
* would be a second source for a value the stylesheet already carries.
|
|
269
|
+
* `editor-viewport.ts` is the one caller and it says what it does with the
|
|
270
|
+
* number; nothing here knows about three's units.
|
|
271
|
+
*/
|
|
272
|
+
export function nativeViewportGizmoSize(element?: Element | null): number | null {
|
|
273
|
+
const raw = themeToken(themeRoot(element), '--volter-viewport-gizmo-size');
|
|
274
|
+
if (!raw) return null;
|
|
275
|
+
const value = Number.parseFloat(raw);
|
|
276
|
+
return Number.isFinite(value) && value > 0 ? value : null;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/** THE BOX-SELECT OUTLINE'S DASH the look states (`EditorTheme.stage.marqueeDash`), in device
|
|
280
|
+
* pixels, or `null` for the editor's own solid line. Its colours need no reader: the rectangle
|
|
281
|
+
* is DOM, so it paints `themeVars.viewport.marquee*` directly. */
|
|
282
|
+
export function nativeViewportMarqueeDash(element?: Element | null): number | null {
|
|
283
|
+
const value = Number.parseFloat(themeToken(themeRoot(element), '--volter-viewport-marquee-dash'));
|
|
284
|
+
return Number.isFinite(value) && value > 0 ? value : null;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/** THE FLOOR GRID'S LINES the look states (`EditorTheme.stage.gridLineWidth` and
|
|
288
|
+
* its siblings), in device pixels, with the editor's own hairline floor for any it leaves out:
|
|
289
|
+
* one level, one pixel, the major lines drawn like the minor. */
|
|
290
|
+
export function nativeViewportGrid(element?: Element | null): {
|
|
291
|
+
readonly lineWidth: number;
|
|
292
|
+
readonly majorWidth: number;
|
|
293
|
+
readonly majorContrast: number;
|
|
294
|
+
} {
|
|
295
|
+
const root = themeRoot(element);
|
|
296
|
+
const read = (name: string, fallback: number): number => {
|
|
297
|
+
const value = Number.parseFloat(themeToken(root, name) ?? '');
|
|
298
|
+
return Number.isFinite(value) && value > 0 ? value : fallback;
|
|
299
|
+
};
|
|
300
|
+
const lineWidth = read('--volter-viewport-grid-line-width', 1);
|
|
301
|
+
return {
|
|
302
|
+
lineWidth,
|
|
303
|
+
majorWidth: read('--volter-viewport-grid-major-width', lineWidth),
|
|
304
|
+
majorContrast: read('--volter-viewport-grid-major-contrast', 1),
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/** HOW THE LOOK DRAWS THE SELECTION BOX MARK (`stage.selectionBox` and its width),
|
|
309
|
+
* with the editor's own corner brackets at 3 CSS px for what it leaves out. */
|
|
310
|
+
/** The selection wire's look: the palette's `viewport.wire` and `stage.wireOpacity`,
|
|
311
|
+
* each `null` for the editor's own (the selection colour at half opacity). */
|
|
312
|
+
export function nativeViewportWire(element?: Element | null): {
|
|
313
|
+
readonly color: number | null;
|
|
314
|
+
readonly opacity: number | null;
|
|
315
|
+
} {
|
|
316
|
+
const root = themeRoot(element);
|
|
317
|
+
const raw = stageColorToken(root, '--volter-viewport-wire');
|
|
318
|
+
const opacity = Number.parseFloat(themeToken(root, '--volter-viewport-wire-opacity'));
|
|
319
|
+
return {
|
|
320
|
+
color: raw ? parseCssColor(raw) : null,
|
|
321
|
+
opacity: Number.isFinite(opacity) ? opacity : null,
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
export function nativeViewportSelectionBox(element?: Element | null): {
|
|
326
|
+
readonly edges: boolean;
|
|
327
|
+
readonly lineWidth: number | null;
|
|
328
|
+
readonly frame: 'world' | 'object';
|
|
329
|
+
} {
|
|
330
|
+
const root = themeRoot(element);
|
|
331
|
+
const width = Number.parseFloat(themeToken(root, '--volter-viewport-selection-box-width'));
|
|
332
|
+
return {
|
|
333
|
+
edges: themeToken(root, '--volter-viewport-selection-box') === 'edges',
|
|
334
|
+
frame: themeToken(root, '--volter-viewport-selection-box-frame') === 'object' ? 'object' : 'world',
|
|
335
|
+
lineWidth: Number.isFinite(width) && width > 0 ? width : null,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/** THE STAGE'S OWN CHROME as the look places it (`StageContribution.chrome`), each member
|
|
340
|
+
* resolved to the editor's own arrangement where the look states none. */
|
|
341
|
+
export interface NativeViewportChrome {
|
|
342
|
+
readonly bar: 'none' | 'strip' | 'pills';
|
|
343
|
+
readonly viewName: 'text' | 'menu' | 'gizmo' | 'bar';
|
|
344
|
+
readonly tools: 'shelf' | 'bar-start' | 'bar-end';
|
|
345
|
+
readonly display: 'corner' | 'bar-start' | 'bar-end';
|
|
346
|
+
readonly transformControls: 'header' | 'bar';
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/** The chrome's members as one string, a stable snapshot for `useSyncExternalStore`
|
|
350
|
+
* ({@link viewportChromeFromKey} reads it back). */
|
|
351
|
+
export function nativeViewportChromeKey(element?: Element | null): string {
|
|
352
|
+
const root = themeRoot(element);
|
|
353
|
+
return [
|
|
354
|
+
'--volter-viewport-chrome-bar',
|
|
355
|
+
'--volter-viewport-chrome-view-name',
|
|
356
|
+
'--volter-viewport-chrome-tools',
|
|
357
|
+
'--volter-viewport-chrome-display',
|
|
358
|
+
'--volter-viewport-chrome-transform-controls',
|
|
359
|
+
]
|
|
360
|
+
.map((name) => themeToken(root, name))
|
|
361
|
+
.join('|');
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
export function viewportChromeFromKey(key: string): NativeViewportChrome {
|
|
365
|
+
const [bar, viewName, tools, display, transformControls] = key.split('|');
|
|
366
|
+
const bars = ['strip', 'pills'] as const;
|
|
367
|
+
const names = ['menu', 'gizmo', 'bar'] as const;
|
|
368
|
+
const places = ['bar-start', 'bar-end'] as const;
|
|
369
|
+
const pick = <T extends string>(value: string | undefined, members: readonly T[], fallback: T): T =>
|
|
370
|
+
members.includes(value as T) ? (value as T) : fallback;
|
|
371
|
+
return {
|
|
372
|
+
bar: pick(bar, bars, 'none'),
|
|
373
|
+
viewName: pick(viewName, names, 'text'),
|
|
374
|
+
tools: pick(tools, places, 'shelf'),
|
|
375
|
+
display: pick(display, places, 'corner'),
|
|
376
|
+
transformControls: transformControls === 'bar' ? 'bar' : 'header',
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export function nativeViewportChrome(element?: Element | null): NativeViewportChrome {
|
|
381
|
+
return viewportChromeFromKey(nativeViewportChromeKey(element));
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/** The key, read from the theme only when the theme changes: a stage's furniture re-renders on
|
|
385
|
+
* every camera move, and the tokens are computed style. */
|
|
386
|
+
let chromeKey: string | null = null;
|
|
387
|
+
function subscribeViewportChrome(listener: () => void): () => void {
|
|
388
|
+
return subscribeNativeSelectionTheme(null, () => {
|
|
389
|
+
chromeKey = nativeViewportChromeKey();
|
|
390
|
+
listener();
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
function viewportChromeSnapshot(): string {
|
|
394
|
+
chromeKey ??= nativeViewportChromeKey();
|
|
395
|
+
return chromeKey;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/** THE STAGE'S CONTROLS IN THE TARGET'S WORDS (`StageContribution.words`): a mode's name, or
|
|
399
|
+
* the helpers menu's, where the look names it; `undefined` keeps the editor's own. */
|
|
400
|
+
export interface NativeViewportWords {
|
|
401
|
+
readonly shading: Readonly<Partial<Record<string, string>>>;
|
|
402
|
+
readonly helpers: string | undefined;
|
|
403
|
+
}
|
|
404
|
+
let wordsKey: string | null = null;
|
|
405
|
+
function viewportWordsKeyNow(): string {
|
|
406
|
+
const root = themeRoot();
|
|
407
|
+
return JSON.stringify([
|
|
408
|
+
STAGE_WORD_MODES.map((mode) => themeToken(root, `--volter-viewport-word-${mode}`)),
|
|
409
|
+
themeToken(root, '--volter-viewport-word-helpers'),
|
|
410
|
+
]);
|
|
411
|
+
}
|
|
412
|
+
function subscribeViewportWords(listener: () => void): () => void {
|
|
413
|
+
return subscribeNativeSelectionTheme(null, () => {
|
|
414
|
+
wordsKey = viewportWordsKeyNow();
|
|
415
|
+
listener();
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
function viewportWordsSnapshot(): string {
|
|
419
|
+
wordsKey ??= viewportWordsKeyNow();
|
|
420
|
+
return wordsKey;
|
|
421
|
+
}
|
|
422
|
+
/** The look's words for the stage's controls, following a change of look. */
|
|
423
|
+
export function useViewportWords(): NativeViewportWords {
|
|
424
|
+
const key = useSyncExternalStore(subscribeViewportWords, viewportWordsSnapshot, viewportWordsSnapshot);
|
|
425
|
+
return useMemo(() => {
|
|
426
|
+
const [modes, helpers] = JSON.parse(key) as [string[], string];
|
|
427
|
+
const shading: Record<string, string> = {};
|
|
428
|
+
STAGE_WORD_MODES.forEach((mode, index) => {
|
|
429
|
+
if (modes[index]) shading[mode] = modes[index];
|
|
430
|
+
});
|
|
431
|
+
return { shading, helpers: helpers || undefined };
|
|
432
|
+
}, [key]);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/** The look's stage chrome, following a change of look. */
|
|
436
|
+
export function useViewportChrome(): NativeViewportChrome {
|
|
437
|
+
const key = useSyncExternalStore(subscribeViewportChrome, viewportChromeSnapshot, viewportChromeSnapshot);
|
|
438
|
+
return useMemo(() => viewportChromeFromKey(key), [key]);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Observe the one theme root's inline token update. This includes saved theme
|
|
443
|
+
* changes and unsaved Theme Manager previews; neither renderer has to poll
|
|
444
|
+
* `getComputedStyle` on every frame.
|
|
445
|
+
*/
|
|
446
|
+
export function subscribeNativeSelectionTheme(
|
|
447
|
+
element: Element | null | undefined,
|
|
448
|
+
listener: () => void,
|
|
449
|
+
): () => void {
|
|
450
|
+
listener();
|
|
451
|
+
const root = themeRoot(element);
|
|
452
|
+
if (!root || typeof MutationObserver === 'undefined') return () => {};
|
|
453
|
+
const observer = new MutationObserver(listener);
|
|
454
|
+
observer.observe(root, { attributes: true, attributeFilter: ['style'] });
|
|
455
|
+
// AND THE WORKBENCH'S COLOURS, which the frame applies after the look's own tokens land and a
|
|
456
|
+
// person's customizations change without touching this root (`subscribeWorkbenchStageColors`).
|
|
457
|
+
const stopWorkbench = subscribeWorkbenchStageColors(root, listener);
|
|
458
|
+
return () => {
|
|
459
|
+
observer.disconnect();
|
|
460
|
+
stopWorkbench();
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* THE WORKBENCH'S STAGE COLOURS, watched once for every subscriber: Code-OSS writes them into a
|
|
466
|
+
* stylesheet in the document head, which changes for many other reasons (every stylesheet a
|
|
467
|
+
* module loads), so one observer reads the stage's colours once per change and wakes the
|
|
468
|
+
* subscribers only when they moved.
|
|
469
|
+
*/
|
|
470
|
+
const workbenchListeners = new Set<() => void>();
|
|
471
|
+
let workbenchObserver: MutationObserver | null = null;
|
|
472
|
+
let workbenchSeen = '';
|
|
473
|
+
|
|
474
|
+
function subscribeWorkbenchStageColors(root: Element, listener: () => void): () => void {
|
|
475
|
+
const signature = () =>
|
|
476
|
+
Object.values(WORKBENCH_COLOR)
|
|
477
|
+
.map((name) => themeToken(root, name))
|
|
478
|
+
.join('|');
|
|
479
|
+
workbenchListeners.add(listener);
|
|
480
|
+
if (!workbenchObserver && typeof document !== 'undefined' && document.head) {
|
|
481
|
+
workbenchSeen = signature();
|
|
482
|
+
workbenchObserver = new MutationObserver(() => {
|
|
483
|
+
const next = signature();
|
|
484
|
+
if (next === workbenchSeen) return;
|
|
485
|
+
workbenchSeen = next;
|
|
486
|
+
for (const each of [...workbenchListeners]) each();
|
|
487
|
+
});
|
|
488
|
+
workbenchObserver.observe(document.head, { childList: true, subtree: true, characterData: true });
|
|
489
|
+
}
|
|
490
|
+
return () => {
|
|
491
|
+
workbenchListeners.delete(listener);
|
|
492
|
+
if (workbenchListeners.size === 0 && workbenchObserver) {
|
|
493
|
+
workbenchObserver.disconnect();
|
|
494
|
+
workbenchObserver = null;
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WHAT THE ASSET LAB 3D DOCUMENT ASKS THE SHELL — the one collaborator
|
|
3
|
+
* `StageHost.tsx` (with its toolbar) declares and the shell
|
|
4
|
+
* installs at boot.
|
|
5
|
+
*
|
|
6
|
+
* ARCHITECTURE-CORE §Editor chrome, "The viewport stack is separable": a
|
|
7
|
+
* surface below the shell never imports the shell's transport, a world
|
|
8
|
+
* authoring adapter, or project discovery. The 3D document was importing four
|
|
9
|
+
* modules to answer three questions —
|
|
10
|
+
*
|
|
11
|
+
* · where do this document's own bytes go? (`object3d-document-persistence`
|
|
12
|
+
* → project file history → the resource history backend)
|
|
13
|
+
* · how do I replace a whole SOURCE file? (`ui-source/tier-source-write-backend`
|
|
14
|
+
* for the tier's recorder + `history/source-history-backend` to run it)
|
|
15
|
+
* · where does a thumbnail framing get recorded? (`asset-workflow/thumbnail-system`
|
|
16
|
+
* to read `.volter/thumbnails.json` + `components/asset-editor-persistence`
|
|
17
|
+
* to write it, which reaches `editor-api.ts`)
|
|
18
|
+
*
|
|
19
|
+
* — and every one of those is TRANSPORT. Measured, those edges were 72 of the
|
|
20
|
+
* document's 213 files, all of them behind the server SDK barrel; the document
|
|
21
|
+
* itself only ever needed "hand these bytes to the project and tell me whether
|
|
22
|
+
* one moved".
|
|
23
|
+
*
|
|
24
|
+
* ## The default is the NO-SHELL answer, and it is deliberate
|
|
25
|
+
*
|
|
26
|
+
* {@link DEFAULT_OBJECT3D_DOCUMENT_WRITE_POLICY} is what a document mounted
|
|
27
|
+
* with no shell above it (a bounded host; a fixture) gets: there is no
|
|
28
|
+
* project to write to, so each member REFUSES by name rather than
|
|
29
|
+
* half-answering. Every call site here already renders a refusal — the
|
|
30
|
+
* document's error state, the toolbar's error banner — because the same
|
|
31
|
+
* refusal is what a read-only tier produced before this seam existed
|
|
32
|
+
* ("This editor tier cannot write project source").
|
|
33
|
+
*
|
|
34
|
+
* In the editor the shell policy is installed once by `EditorProvider`
|
|
35
|
+
* (`EditorContext.tsx`), beside the viewport policy and before any document
|
|
36
|
+
* mounts, so today's behaviour is unchanged.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
import type {
|
|
40
|
+
Object3DDocumentPersistenceSession,
|
|
41
|
+
OpenObject3DDocumentPersistenceOptions,
|
|
42
|
+
} from './authoring/object3d-document-persistence';
|
|
43
|
+
import type { HistoryService } from '@volter/sdk/kit/history/history-service';
|
|
44
|
+
|
|
45
|
+
/** Re-exported from its declaration site so a consumer of this seam does not
|
|
46
|
+
* import the persistence module (which reaches project file history) for a
|
|
47
|
+
* type. `import type` is erased, so this costs the closure nothing. */
|
|
48
|
+
export type { Object3DDocumentPersistenceSession } from './authoring/object3d-document-persistence';
|
|
49
|
+
|
|
50
|
+
/** A whole-file SOURCE replacement — the document's animation binding and its
|
|
51
|
+
* single-module documents both write this way. */
|
|
52
|
+
export interface Object3DDocumentSourceReplacement {
|
|
53
|
+
readonly file: string;
|
|
54
|
+
readonly source: string;
|
|
55
|
+
readonly label: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** The camera framing `.volter/thumbnails.json` records for one asset.
|
|
59
|
+
* `undefined` is the RESET — remove this asset's framing. */
|
|
60
|
+
export interface Object3DDocumentThumbnailFraming {
|
|
61
|
+
readonly position: [number, number, number];
|
|
62
|
+
readonly target: [number, number, number];
|
|
63
|
+
readonly fov?: number;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface Object3DDocumentWritePolicy {
|
|
67
|
+
/**
|
|
68
|
+
* Open the persistence baseline for a document that declares a binding.
|
|
69
|
+
* The session owns transaction ordering, checksum preflight and canonical
|
|
70
|
+
* undo/redo; the document only calls `commit`.
|
|
71
|
+
*/
|
|
72
|
+
openPersistence<TDocument>(
|
|
73
|
+
options: OpenObject3DDocumentPersistenceOptions<TDocument>,
|
|
74
|
+
): Promise<Object3DDocumentPersistenceSession<TDocument>>;
|
|
75
|
+
/**
|
|
76
|
+
* Replace a whole source file through the tier's recorder, in `history`.
|
|
77
|
+
* Resolves to whether a byte actually moved. The HISTORY lookup stays with
|
|
78
|
+
* the document (it holds the session's service already, and its two call
|
|
79
|
+
* sites word an absent one differently); what the shell owns here is the
|
|
80
|
+
* WRITE BACKEND — the thing a read-only tier does not have.
|
|
81
|
+
*/
|
|
82
|
+
replaceSource(
|
|
83
|
+
history: HistoryService,
|
|
84
|
+
request: Object3DDocumentSourceReplacement,
|
|
85
|
+
): Promise<boolean>;
|
|
86
|
+
/**
|
|
87
|
+
* Record (or clear, with `undefined`) this asset's thumbnail framing in the
|
|
88
|
+
* project's thumbnail manifest. Refuses loudly rather than rebuilding a
|
|
89
|
+
* manifest it could not read.
|
|
90
|
+
*/
|
|
91
|
+
saveThumbnailFraming(
|
|
92
|
+
assetPath: string,
|
|
93
|
+
framing: Object3DDocumentThumbnailFraming | undefined,
|
|
94
|
+
): Promise<void>;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** The one refusal, worded for the member that raised it. Rejected rather than
|
|
98
|
+
* thrown so every member answers the same way; each call site is already
|
|
99
|
+
* inside the `await` of a try/catch that renders the message. */
|
|
100
|
+
function refuse<T>(what: string): Promise<T> {
|
|
101
|
+
return Promise.reject(new Error(`This editor tier cannot ${what}.`));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export const DEFAULT_OBJECT3D_DOCUMENT_WRITE_POLICY: Object3DDocumentWritePolicy = {
|
|
105
|
+
openPersistence: () => refuse('persist Asset Lab documents'),
|
|
106
|
+
// The exact wording a read-only tier produced when the document asked the
|
|
107
|
+
// tier recorder for a source-write backend and got none.
|
|
108
|
+
replaceSource: () => refuse('write project source'),
|
|
109
|
+
saveThumbnailFraming: () => refuse('write project thumbnail framing'),
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
let _policy: Object3DDocumentWritePolicy = DEFAULT_OBJECT3D_DOCUMENT_WRITE_POLICY;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Install the shell's composition. One owner, same rule as
|
|
116
|
+
* `installViewportAuthoringPolicy` and the store's `attachHistory`:
|
|
117
|
+
* re-installing the SAME policy is a no-op (React strict-mode double-invokes
|
|
118
|
+
* the provider body), a DIFFERENT one throws rather than letting two shells
|
|
119
|
+
* disagree about where a document's bytes go.
|
|
120
|
+
*/
|
|
121
|
+
export function installObject3DDocumentWritePolicy(policy: Object3DDocumentWritePolicy): void {
|
|
122
|
+
if (_policy === policy) return;
|
|
123
|
+
if (_policy !== DEFAULT_OBJECT3D_DOCUMENT_WRITE_POLICY) {
|
|
124
|
+
throw new Error('An Object3D document write policy is already installed.');
|
|
125
|
+
}
|
|
126
|
+
_policy = policy;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** The installed policy, or the no-shell default. */
|
|
130
|
+
export function object3DDocumentWritePolicy(): Object3DDocumentWritePolicy {
|
|
131
|
+
return _policy;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** Test seam: drop the installed policy. */
|
|
135
|
+
export function __resetObject3DDocumentWritePolicyForTest(): void {
|
|
136
|
+
_policy = DEFAULT_OBJECT3D_DOCUMENT_WRITE_POLICY;
|
|
137
|
+
}
|