@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,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hierarchy row glyphs. Canvas kinds used to fall through to a circle because
|
|
3
|
+
* KIND_ICON only named three-lane kinds — every Sprite/Text/Container looked
|
|
4
|
+
* the same.
|
|
5
|
+
*
|
|
6
|
+
* THE THREE OBJECT KINDS OWN THEIR NAMES, for the same reason
|
|
7
|
+
* `editorIcons.modeling` does (`components/primitives/editor-icons.ts` — read
|
|
8
|
+
* its docblock) and here the reason is COLOUR rather than shape. An icon set
|
|
9
|
+
* keys a glyph by `icon.iconName` and may give it a category TONE, so a tone
|
|
10
|
+
* on `cube` would tint EVERY site that asks for a cube — and measured in the
|
|
11
|
+
* live editor, the Blender set's `object` orange landed on the viewport
|
|
12
|
+
* header's Perspective/Orthographic dropdown (`Object3DDocumentToolbar.tsx`
|
|
13
|
+
* draws it with `faCube`) and on the transform-space toggle, neither of which
|
|
14
|
+
* is an object. `faLightbulb` and `faCamera` reuse the same way (the viewport
|
|
15
|
+
* lighting overlay, the camera view menu).
|
|
16
|
+
*
|
|
17
|
+
* Blender's evidence for the colour is the OUTLINER specifically — a row's
|
|
18
|
+
* type glyph — so the tone belongs to a name only the outliner asks for.
|
|
19
|
+
* The `icon` tuple stays Font Awesome's, so a set that does not carry these
|
|
20
|
+
* names paints exactly what it painted before.
|
|
21
|
+
*/
|
|
22
|
+
import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
|
|
23
|
+
import {
|
|
24
|
+
faBookOpen,
|
|
25
|
+
faCamera,
|
|
26
|
+
faCircle,
|
|
27
|
+
faCircleDot,
|
|
28
|
+
faCirclePlay,
|
|
29
|
+
faCode,
|
|
30
|
+
faCube,
|
|
31
|
+
faDrawPolygon,
|
|
32
|
+
faFont,
|
|
33
|
+
faImage,
|
|
34
|
+
faLayerGroup,
|
|
35
|
+
faLightbulb,
|
|
36
|
+
faLink,
|
|
37
|
+
faList,
|
|
38
|
+
faObjectGroup,
|
|
39
|
+
faPuzzlePiece,
|
|
40
|
+
faSquare,
|
|
41
|
+
faSquareCheck,
|
|
42
|
+
faVideoSlash,
|
|
43
|
+
faVolumeHigh,
|
|
44
|
+
} from '@fortawesome/free-solid-svg-icons';
|
|
45
|
+
|
|
46
|
+
/** A definition under a name of OURS carrying Font Awesome's drawing until an
|
|
47
|
+
* icon set supplies its own — the same three lines as `editor-icons.ts`'s
|
|
48
|
+
* `meshGlyph`, kept local so this module's import closure stays FA-only. */
|
|
49
|
+
function outlinerGlyph(iconName: string, source: IconDefinition): IconDefinition {
|
|
50
|
+
return { ...source, iconName: iconName as IconDefinition['iconName'] };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const OUTLINER_OBJECT = outlinerGlyph('outliner-object', faCube);
|
|
54
|
+
const OUTLINER_LIGHT = outlinerGlyph('outliner-light', faLightbulb);
|
|
55
|
+
const OUTLINER_CAMERA = outlinerGlyph('outliner-camera', faCamera);
|
|
56
|
+
// The speaker is the header's mute button too (`HeaderTelemetry.tsx`), which is
|
|
57
|
+
// exactly the reuse this module's docblock names: an outliner tone on the bare
|
|
58
|
+
// `volume-high` would tint that control as well.
|
|
59
|
+
const OUTLINER_AUDIO = outlinerGlyph('outliner-audio', faVolumeHigh);
|
|
60
|
+
/**
|
|
61
|
+
* A DATABLOCK row, not an object row — the geometry a mesh carries
|
|
62
|
+
* (ARCHITECTURE-CORE §A model is
|
|
63
|
+
* data). Blender's Outliner draws it in the DATA green where the object above
|
|
64
|
+
* it is orange, which is the whole reason it gets a name of its own rather
|
|
65
|
+
* than reusing the rail's `properties-data`: the two are the same drawing but
|
|
66
|
+
* the two sites' STATES differ: the outliner composites its glyphs at α 0.80
|
|
67
|
+
* over the row, and so does the Properties rail's CLOSED tab, while its open
|
|
68
|
+
* tab paints the ink full. One ink, three states — the palette carries the
|
|
69
|
+
* ink and each site declares its own alpha (`theme.ts`'s category docblock
|
|
70
|
+
* carries the solve and the frames it was measured in).
|
|
71
|
+
*/
|
|
72
|
+
const OUTLINER_DATA = outlinerGlyph('outliner-data', faDrawPolygon);
|
|
73
|
+
/**
|
|
74
|
+
* A MESH object's own mark. Blender's Outliner does not draw a cube for one:
|
|
75
|
+
* measured on `outliner.png`, the Cube row carries an apex-down triangle — the
|
|
76
|
+
* object-type sibling of the datablock's mark, in the object orange — while
|
|
77
|
+
* `outliner-object`'s cube stays for a generic three-object row that names no
|
|
78
|
+
* mesh. A set without the name draws Font Awesome's cube, exactly as before.
|
|
79
|
+
*/
|
|
80
|
+
const OUTLINER_MESH = outlinerGlyph('outliner-mesh', faCube);
|
|
81
|
+
|
|
82
|
+
const KIND_ICON: Record<string, IconDefinition> = {
|
|
83
|
+
three: OUTLINER_OBJECT,
|
|
84
|
+
react: faCode,
|
|
85
|
+
canvas: faLayerGroup,
|
|
86
|
+
scene: faBookOpen,
|
|
87
|
+
mesh: OUTLINER_MESH,
|
|
88
|
+
'skinned-mesh': OUTLINER_MESH,
|
|
89
|
+
'mesh-data': OUTLINER_DATA,
|
|
90
|
+
// A MODEL DOCUMENT'S ROOT is the datablock, not an object carrying one
|
|
91
|
+
// (ARCHITECTURE-CORE §A model is data) — which is why `@volter/editor-blender` hangs a
|
|
92
|
+
// `mesh-data` row off it in the first place. These are the two kind names
|
|
93
|
+
// `source-object3d-authoring-adapter.ts` mints for that root, and they read
|
|
94
|
+
// the DATA glyph for the same reason `mesh-data` does. This is the "one
|
|
95
|
+
// line here and nothing else moves" the note below describes; the consumer
|
|
96
|
+
// that needed it is the Properties breadcrumb, whose glyph Blender takes
|
|
97
|
+
// from the datablock and never from the open tab.
|
|
98
|
+
'three-source': OUTLINER_DATA,
|
|
99
|
+
'model-asset': OUTLINER_DATA,
|
|
100
|
+
light: OUTLINER_LIGHT,
|
|
101
|
+
camera: OUTLINER_CAMERA,
|
|
102
|
+
audio: OUTLINER_AUDIO,
|
|
103
|
+
'reflection-probe': faCircleDot,
|
|
104
|
+
group: faObjectGroup,
|
|
105
|
+
object: faCircle,
|
|
106
|
+
component: faPuzzlePiece,
|
|
107
|
+
img: faImage,
|
|
108
|
+
a: faLink,
|
|
109
|
+
ul: faList,
|
|
110
|
+
ol: faList,
|
|
111
|
+
li: faList,
|
|
112
|
+
button: faSquare,
|
|
113
|
+
sprite: faImage,
|
|
114
|
+
animatedsprite: faCirclePlay,
|
|
115
|
+
nineslicesprite: faImage,
|
|
116
|
+
tilingsprite: faImage,
|
|
117
|
+
text: faFont,
|
|
118
|
+
graphics: faSquare,
|
|
119
|
+
container: faObjectGroup,
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* THE TWO RESTRICTION-COLUMN GLYPHS THAT ARE NOT THE EYE — Blender's Disable
|
|
124
|
+
* in Renders column (`outliner_draw.cc:1363-1384`). Names of OURS for the same
|
|
125
|
+
* reason the outliner marks above have them: the bare `camera` name is the
|
|
126
|
+
* viewport header's camera menu, and a skin that drew Blender's
|
|
127
|
+
* `restrict_render_*` mark under it would repaint that menu too.
|
|
128
|
+
*/
|
|
129
|
+
export const OUTLINER_RENDER_ON = outlinerGlyph('outliner-render-on', faCamera);
|
|
130
|
+
export const OUTLINER_RENDER_OFF = outlinerGlyph('outliner-render-off', faVideoSlash);
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* THE EXCLUDE COLUMN's pair — Blender's leftmost restriction column, drawn for
|
|
134
|
+
* `LayerCollection` rows (`outliner_draw.cc:1634-1653`). It asks for
|
|
135
|
+
* `ICON_NONE` on an icon toggle, which is how a boolean draws the WIDGET's own
|
|
136
|
+
* checkbox, so the marks are `checkbox_hlt` / `checkbox_dehlt` — named here the
|
|
137
|
+
* way the render pair is, because a bare `checkbox` name would repaint every
|
|
138
|
+
* checkbox in the editor.
|
|
139
|
+
*/
|
|
140
|
+
export const OUTLINER_EXCLUDE_ON = outlinerGlyph('outliner-exclude-on', faSquareCheck);
|
|
141
|
+
export const OUTLINER_EXCLUDE_OFF = outlinerGlyph('outliner-exclude-off', faSquare);
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* A `blender-` KIND NAMES ITS OWN GLYPH, and that is the whole rule.
|
|
145
|
+
*
|
|
146
|
+
* `@volter/editor-blender`'s Outliner rows carry Blender's own `ICON_*` per row
|
|
147
|
+
* (`tree_element_get_icon`, `outliner_draw.cc:2619-2945`) — 70-odd marks across
|
|
148
|
+
* the object types, the data types, the modifier and constraint families. A
|
|
149
|
+
* table here with one line per mark would be a transcription of Blender's
|
|
150
|
+
* switch maintained in a second place; the adapter already knows the name, so
|
|
151
|
+
* the kind IS the name (`blender-outliner-ob-mesh`, `blender-mod-subsurf`) and
|
|
152
|
+
* the icon SET decides whether it draws it. A set that does not carry the name
|
|
153
|
+
* falls through to Font Awesome's circle, exactly as any unknown kind does.
|
|
154
|
+
*/
|
|
155
|
+
const BLENDER_KIND = /^blender-[a-z0-9-]+$/;
|
|
156
|
+
|
|
157
|
+
export function hierarchyKindIcon(
|
|
158
|
+
kind: string,
|
|
159
|
+
fallback: IconDefinition = faCircle,
|
|
160
|
+
): IconDefinition {
|
|
161
|
+
const known = KIND_ICON[kind];
|
|
162
|
+
if (known) return known;
|
|
163
|
+
if (BLENDER_KIND.test(kind)) return outlinerGlyph(kind, fallback);
|
|
164
|
+
return fallback;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* THE DATABLOCK KINDS — the rows Blender's Outliner hangs OFF an object rather
|
|
169
|
+
* than under it, and the one place this editor decides which those are.
|
|
170
|
+
*
|
|
171
|
+
* Measured on `outliner.png`: at rest every object row is COLLAPSED and carries
|
|
172
|
+
* its datablock as an inline glyph after the label, one cell to the right
|
|
173
|
+
* (Camera's at src x 288-327, Cube's at 263-302, Light's at 266-291 — the label
|
|
174
|
+
* ink ends at 246/222/218, so the gap is 40-41 device px, one 20-point cell
|
|
175
|
+
* every time). Expanding is what produces the child row.
|
|
176
|
+
*
|
|
177
|
+
* WHY A KIND LIST AND NOT A ROLE. The datablock row is `role: 'element'`
|
|
178
|
+
* and so is every ordinary JSX
|
|
179
|
+
* child in the DOM and React lanes — a rule keyed on the role would collapse
|
|
180
|
+
* those trees by default, which is a regression, not a transcription. The KIND
|
|
181
|
+
* is the adapter's own vocabulary and this module is already where the host
|
|
182
|
+
* reads it: `KIND_ICON` above gives `mesh-data` the DATA glyph because it is a
|
|
183
|
+
* datablock. A future `light-data`/`camera-data` adds one line here and
|
|
184
|
+
* nothing else moves.
|
|
185
|
+
*
|
|
186
|
+
* `EditorNode` gains no field for this. The kind is open by construction (the
|
|
187
|
+
* previous unit's ruling), so a new noun on the kernel object would buy
|
|
188
|
+
* nothing that the name the adapter already sends does not.
|
|
189
|
+
*/
|
|
190
|
+
const DATABLOCK_KINDS: ReadonlySet<string> = new Set([
|
|
191
|
+
'mesh-data',
|
|
192
|
+
// Blender's own DATA marks, which is exactly what
|
|
193
|
+
// `tree_element_get_icon_from_id` (`outliner_draw.cc:2479-2610`) answers for
|
|
194
|
+
// a non-object ID: the mark a Model document's rows carry for an object's
|
|
195
|
+
// data, its materials and its shape keys. The object marks
|
|
196
|
+
// (`blender-outliner-ob-*`) are deliberately NOT here — those are the row
|
|
197
|
+
// itself, not something hung off it.
|
|
198
|
+
'blender-material-data',
|
|
199
|
+
'blender-shapekey-data',
|
|
200
|
+
'blender-texture-data',
|
|
201
|
+
'blender-image-data',
|
|
202
|
+
]);
|
|
203
|
+
|
|
204
|
+
/** The prefixes of the same set that are keyed by a VALUE rather than a struct
|
|
205
|
+
* — a light's lamp type and a probe's (`outliner_draw.cc:2508-2521`,
|
|
206
|
+
* `:2578-2589`) — plus the `OUTLINER_DATA_*` family. */
|
|
207
|
+
const DATABLOCK_KIND_PREFIXES: readonly string[] = [
|
|
208
|
+
'blender-outliner-data-',
|
|
209
|
+
'blender-light-',
|
|
210
|
+
'blender-lightprobe-',
|
|
211
|
+
];
|
|
212
|
+
|
|
213
|
+
export function isDatablockKind(kind: string | undefined): boolean {
|
|
214
|
+
if (kind === undefined) return false;
|
|
215
|
+
if (DATABLOCK_KINDS.has(kind)) return true;
|
|
216
|
+
return DATABLOCK_KIND_PREFIXES.some((prefix) => kind.startsWith(prefix));
|
|
217
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ShellStore } from '@volter/sdk/kit/shell-store';
|
|
2
|
+
/**
|
|
3
|
+
* Hierarchy context-menu contribution registry — the escape hatch for
|
|
4
|
+
* first-party-only row actions that are NOT contract-expressible through
|
|
5
|
+
* `StructureProvider`/`InspectorProvider`. `GameHierarchy` (the contract-only
|
|
6
|
+
* shell) calls {@link getHierarchyMenuItems} and appends whatever comes back
|
|
7
|
+
* to its own Rename/Duplicate/Show-Hide/Lock/Delete items — it never branches
|
|
8
|
+
* on WHICH registration fired, keeping Rule Zero intact: the shell still
|
|
9
|
+
* speaks only the `AuthoringAdapter` contract, and only a REGISTRATION module
|
|
10
|
+
* is allowed to reach into store internals.
|
|
11
|
+
*
|
|
12
|
+
* PERMANENT adapter-module contribution seam, the same status as
|
|
13
|
+
* `inspector-section-registry.ts`: first-party affordances that aren't
|
|
14
|
+
* (yet, or ever) contract-expressible register through here instead of the
|
|
15
|
+
* contract-only shell branching on adapter identity. If a given affordance later
|
|
16
|
+
* becomes contract-expressible, its OWN registration is removed at that point —
|
|
17
|
+
* the registry mechanism itself is not temporary. Nothing registers today, and
|
|
18
|
+
* an empty registry is a legitimate state.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
export interface HierarchyMenuContext {
|
|
23
|
+
/** The row's node id (an `EditorNode.id` — format-neutral). */
|
|
24
|
+
readonly nodeId: string;
|
|
25
|
+
readonly store: ShellStore;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface HierarchyMenuItem {
|
|
29
|
+
readonly label: string;
|
|
30
|
+
readonly action: () => void;
|
|
31
|
+
readonly color?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
type Matcher = (ctx: HierarchyMenuContext) => boolean;
|
|
35
|
+
type ItemsFactory = (ctx: HierarchyMenuContext) => HierarchyMenuItem[];
|
|
36
|
+
|
|
37
|
+
interface Registration {
|
|
38
|
+
readonly match: Matcher;
|
|
39
|
+
readonly items: ItemsFactory;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const registrations: Registration[] = [];
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Register a set of first-party (or other non-contract) hierarchy context-menu
|
|
46
|
+
* items. `match` decides whether this registration applies to a given row;
|
|
47
|
+
* `items` builds the actual entries when it does (called only when `match`
|
|
48
|
+
* returns true). Returns an unregister function.
|
|
49
|
+
*/
|
|
50
|
+
export function registerHierarchyMenuItems(match: Matcher, items: ItemsFactory): () => void {
|
|
51
|
+
const reg: Registration = { match, items };
|
|
52
|
+
registrations.push(reg);
|
|
53
|
+
return () => {
|
|
54
|
+
const idx = registrations.indexOf(reg);
|
|
55
|
+
if (idx >= 0) registrations.splice(idx, 1);
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Every registered item that applies to `ctx`, in registration order. */
|
|
60
|
+
export function getHierarchyMenuItems(ctx: HierarchyMenuContext): HierarchyMenuItem[] {
|
|
61
|
+
return registrations.filter((r) => r.match(ctx)).flatMap((r) => r.items(ctx));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Test-only reset for module-level menu registrations. */
|
|
65
|
+
export function __resetHierarchyMenuRegistryForTest(): void {
|
|
66
|
+
registrations.length = 0;
|
|
67
|
+
}
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure row-flattening for `IngestHierarchy` (no React) — D-W4 (F14/F18),
|
|
3
|
+
* extracted the same way `hierarchy-rows.ts` extracts `SceneHierarchy`'s
|
|
4
|
+
* equivalent, so the key/collapse/cycle-guard logic is unit-testable without
|
|
5
|
+
* rendering.
|
|
6
|
+
*
|
|
7
|
+
* §0.5's ground truth: an ingested game's structural ids
|
|
8
|
+
* (`ingest:<path>:<type>:<name>`, `@volter/editor-threejs/adapter/ingest/structural-ids`'s
|
|
9
|
+
* `assignStructuralIds`) are baked ONCE at capture and are the key every
|
|
10
|
+
* editor surface addresses an object by — never touched here. But
|
|
11
|
+
* `IngestHierarchy` re-reads the LIVE `Object3D` tree every render
|
|
12
|
+
* (`adapter.hierarchy.node(id)`), and a live game can reorder or clone
|
|
13
|
+
* subtrees after capture, so the SAME baked id can legitimately show up in
|
|
14
|
+
* more than one place in a single walk — `EditorNode.id` alone is no longer
|
|
15
|
+
* a safe React key, and naively recursing `childIds` with no guard can loop
|
|
16
|
+
* forever if a stale/duplicated id ever points back at one of its own
|
|
17
|
+
* ancestors.
|
|
18
|
+
*
|
|
19
|
+
* Per-parent child cap, copied from `hierarchy-rows.ts`'s
|
|
20
|
+
* `flattenVisibleRows`/ `CHILD_CAP`/`MORE_ID_PREFIX` (same constants, no
|
|
21
|
+
* drift). Unlike first-party (which only caps in play mode), the adapter
|
|
22
|
+
* panel's tree is BY DEFINITION a live game scene graph, so `capEnabled`
|
|
23
|
+
* defaults to `false` here (matching this function's PRE-cap behavior
|
|
24
|
+
* byte-for-byte — every existing caller/test that doesn't pass the new params
|
|
25
|
+
* keeps working unchanged) and `IngestHierarchy` explicitly turns it on for
|
|
26
|
+
* the browse view. Search bypasses the cap by calling with `capEnabled=false`
|
|
27
|
+
* (D-C4) — the exact same "flatten UNCAPPED, filter flat" shape this module
|
|
28
|
+
* already used for search before the cap existed.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
import type { EditorNode, HierarchyProvider } from '@volter/project/adapter';
|
|
32
|
+
import { CHILD_CAP, MORE_ID_PREFIX } from './hierarchy-rows';
|
|
33
|
+
|
|
34
|
+
/** One flattened, render-ready row over an ingested game's live hierarchy. */
|
|
35
|
+
export interface HierarchyNodeRow {
|
|
36
|
+
readonly node: EditorNode;
|
|
37
|
+
readonly depth: number;
|
|
38
|
+
/**
|
|
39
|
+
* Render key material: the walk path (root index, then child index at
|
|
40
|
+
* each level) — NOT `node.id` alone. Stays unique across a render even
|
|
41
|
+
* when the id scheme collides, because it is derived from POSITION in
|
|
42
|
+
* the walk, not from the adapter's (potentially stale/duplicated) data.
|
|
43
|
+
*/
|
|
44
|
+
readonly pathKey: string;
|
|
45
|
+
readonly hasChildren: boolean;
|
|
46
|
+
/** True when an ANCESTOR's `pathKey` is in the caller's collapsed-set —
|
|
47
|
+
* i.e. this row is inside a collapsed subtree (F18). The row itself is
|
|
48
|
+
* still included in the returned array (so a search can still find it);
|
|
49
|
+
* the component filters it out when not searching. */
|
|
50
|
+
readonly hiddenByCollapse: boolean;
|
|
51
|
+
/** Present on a synthetic "… N more" row that reveals capped siblings
|
|
52
|
+
* (D-C2) — `parentPathKey` is the capped parent's `pathKey`, `hidden` is
|
|
53
|
+
* how many of its children are not shown. Never present on a real row. */
|
|
54
|
+
readonly more?: { readonly parentPathKey: string; readonly hidden: number };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Backstop against a childIds list this guard's own dedup somehow doesn't
|
|
59
|
+
* anticipate (e.g. a very deep but genuinely acyclic live tree) — ingested
|
|
60
|
+
* games are not expected to nest anywhere near this deep; this is a second,
|
|
61
|
+
* independent safety net, not the primary guard (see `visited` below).
|
|
62
|
+
*/
|
|
63
|
+
const MAX_DEPTH = 500;
|
|
64
|
+
|
|
65
|
+
/** How many of a parent's children to walk (D-C1/D-C3) — split out of `walk`
|
|
66
|
+
* below purely to keep that function's cognitive-complexity score down. */
|
|
67
|
+
function childLimit(
|
|
68
|
+
capEnabled: boolean,
|
|
69
|
+
revealed: ReadonlyMap<string, number>,
|
|
70
|
+
parentPathKey: string,
|
|
71
|
+
): number {
|
|
72
|
+
return capEnabled
|
|
73
|
+
? Math.max(CHILD_CAP, revealed.get(parentPathKey) ?? CHILD_CAP)
|
|
74
|
+
: Number.POSITIVE_INFINITY;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** The synthetic "… N more" row for a capped parent (D-C2) — a render-only
|
|
78
|
+
* stub, never fed back to the adapter. Split out of `walk` below purely to
|
|
79
|
+
* keep that function's cognitive-complexity score down. */
|
|
80
|
+
function buildMoreRow(
|
|
81
|
+
parentPathKey: string,
|
|
82
|
+
depth: number,
|
|
83
|
+
parentId: string,
|
|
84
|
+
hiddenByCollapse: boolean,
|
|
85
|
+
hidden: number,
|
|
86
|
+
): HierarchyNodeRow {
|
|
87
|
+
return {
|
|
88
|
+
node: {
|
|
89
|
+
id: `${MORE_ID_PREFIX}${parentPathKey}`,
|
|
90
|
+
label: '',
|
|
91
|
+
kind: 'object',
|
|
92
|
+
parentId,
|
|
93
|
+
childIds: [],
|
|
94
|
+
},
|
|
95
|
+
depth,
|
|
96
|
+
pathKey: `${parentPathKey}/__more__`,
|
|
97
|
+
hasChildren: false,
|
|
98
|
+
hiddenByCollapse,
|
|
99
|
+
more: { parentPathKey, hidden },
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Flatten an ingest adapter's hierarchy into display rows.
|
|
105
|
+
*
|
|
106
|
+
* F14 cycle/dup guard: `visited` tracks every `node.id` already emitted in
|
|
107
|
+
* THIS walk. A live game reordering/cloning objects can make the same baked
|
|
108
|
+
* id reachable from more than one place (a real duplicate) or, in principle,
|
|
109
|
+
* from one of its own descendants (a cycle) — either way the id is stale
|
|
110
|
+
* data describing the CURRENT live scene, not a second logical node. The
|
|
111
|
+
* chosen semantics: render the first occurrence encountered (root-first,
|
|
112
|
+
* then depth-first child order) and silently skip every later one — no
|
|
113
|
+
* second row, and a cycle can never recurse forever. `collapsedKeys` is
|
|
114
|
+
* keyed by `pathKey`, not `node.id` (F18) — a walk-path is stable for "this
|
|
115
|
+
* position in the tree shape", which is what "collapsed" means to a user
|
|
116
|
+
* looking at the panel; keying by id would let a stale/reused id apply a
|
|
117
|
+
* collapse to the WRONG node after a live reorder, or fail to distinguish
|
|
118
|
+
* two positions that happen to share a duplicated id.
|
|
119
|
+
*
|
|
120
|
+
* D-C1/D-C3 cap: when `capEnabled`, each parent's children are limited to
|
|
121
|
+
* `max(CHILD_CAP, revealed.get(parentPathKey) ?? CHILD_CAP)` and a synthetic
|
|
122
|
+
* more-row is appended when some are hidden (D-C2). D-C5: children beyond
|
|
123
|
+
* the limit are never walked, so never added to `visited` — a duplicate id
|
|
124
|
+
* whose first structural occurrence was capped away still renders at its
|
|
125
|
+
* next reachable occurrence (the dedup guard's "once, not zero times"
|
|
126
|
+
* guarantee holds). D-C6: a COLLAPSED parent (its own `pathKey` is in
|
|
127
|
+
* `collapsedKeys`) contributes no child rows and no more-row at all when
|
|
128
|
+
* capped — the walk stops at the parent itself rather than descending and
|
|
129
|
+
* relying on `hiddenByCollapse` filtering, since a more-row would otherwise
|
|
130
|
+
* still need suppressing. Uncapped calls (search, D-C4) are unaffected:
|
|
131
|
+
* collapse only ever gates recursion when `capEnabled`, so a collapsed
|
|
132
|
+
* subtree's matches stay reachable when searching, exactly as before.
|
|
133
|
+
*/
|
|
134
|
+
export function flattenHierarchyRows(
|
|
135
|
+
hierarchy: Pick<HierarchyProvider, 'roots' | 'node'>,
|
|
136
|
+
collapsedKeys: ReadonlySet<string>,
|
|
137
|
+
revealed: ReadonlyMap<string, number> = new Map(),
|
|
138
|
+
capEnabled = false,
|
|
139
|
+
): HierarchyNodeRow[] {
|
|
140
|
+
const rows: HierarchyNodeRow[] = [];
|
|
141
|
+
const visited = new Set<string>();
|
|
142
|
+
|
|
143
|
+
const walk = (node: EditorNode, depth: number, pathKey: string, parentHidden: boolean): void => {
|
|
144
|
+
if (visited.has(node.id) || depth > MAX_DEPTH) return;
|
|
145
|
+
visited.add(node.id);
|
|
146
|
+
|
|
147
|
+
const hasChildren = node.childIds.length > 0;
|
|
148
|
+
rows.push({ node, depth, pathKey, hasChildren, hiddenByCollapse: parentHidden });
|
|
149
|
+
|
|
150
|
+
const isCollapsed = collapsedKeys.has(pathKey);
|
|
151
|
+
if (capEnabled && isCollapsed) return; // D-C6: nothing of a collapsed subtree renders.
|
|
152
|
+
|
|
153
|
+
const childHidden = parentHidden || isCollapsed;
|
|
154
|
+
const shown = Math.min(node.childIds.length, childLimit(capEnabled, revealed, pathKey));
|
|
155
|
+
|
|
156
|
+
for (let i = 0; i < shown; i++) {
|
|
157
|
+
const child = hierarchy.node(node.childIds[i]!);
|
|
158
|
+
if (child) walk(child, depth + 1, `${pathKey}.${i}`, childHidden);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (capEnabled && node.childIds.length > shown) {
|
|
162
|
+
rows.push(
|
|
163
|
+
buildMoreRow(pathKey, depth + 1, node.id, childHidden, node.childIds.length - shown),
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
hierarchy.roots().forEach((root, i) => {
|
|
169
|
+
walk(root, 0, `r${i}`, false);
|
|
170
|
+
});
|
|
171
|
+
return rows;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Patch an uncapped structural snapshot after an identity-unique projection
|
|
176
|
+
* reports the parents whose direct child lists changed.
|
|
177
|
+
*
|
|
178
|
+
* Each changed parent's complete visible subtree is replaced in place. This
|
|
179
|
+
* preserves every unaffected row object and avoids asking the provider about
|
|
180
|
+
* the rest of a large world. Rebuilding the parent (not only its new child)
|
|
181
|
+
* is what preserves exact sibling order and walk-path keys after insert,
|
|
182
|
+
* remove, or reparent. `null` is the conservative answer whenever the delta
|
|
183
|
+
* cannot be related to the previous snapshot; the caller then takes the full
|
|
184
|
+
* {@link flattenHierarchyRows} path.
|
|
185
|
+
*
|
|
186
|
+
* This helper requires provider-unique ids. The live Three projector supplies
|
|
187
|
+
* that invariant when it supplies the parent delta; arbitrary hierarchy
|
|
188
|
+
* providers continue to use the full flattener and its duplicate-id guard.
|
|
189
|
+
*/
|
|
190
|
+
export function patchUniqueHierarchyRows(
|
|
191
|
+
hierarchy: Pick<HierarchyProvider, 'node'>,
|
|
192
|
+
previous: readonly HierarchyNodeRow[],
|
|
193
|
+
changedParentIds: ReadonlySet<string>,
|
|
194
|
+
): HierarchyNodeRow[] | null {
|
|
195
|
+
if (changedParentIds.size === 0) return previous as HierarchyNodeRow[];
|
|
196
|
+
|
|
197
|
+
const rowIndexById = new Map<string, number>();
|
|
198
|
+
for (let index = 0; index < previous.length; index += 1) {
|
|
199
|
+
const row = previous[index]!;
|
|
200
|
+
if (!row.more) rowIndexById.set(row.node.id, index);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
interface Replacement {
|
|
204
|
+
readonly start: number;
|
|
205
|
+
readonly end: number;
|
|
206
|
+
readonly row: HierarchyNodeRow;
|
|
207
|
+
readonly node: EditorNode;
|
|
208
|
+
}
|
|
209
|
+
const candidates: Replacement[] = [];
|
|
210
|
+
for (const id of changedParentIds) {
|
|
211
|
+
const start = rowIndexById.get(id);
|
|
212
|
+
const node = hierarchy.node(id);
|
|
213
|
+
// A removed internal parent is covered by its changed surviving ancestor.
|
|
214
|
+
// Validate that relationship below after all surviving candidates are known.
|
|
215
|
+
if (start === undefined || node === null) continue;
|
|
216
|
+
const row = previous[start]!;
|
|
217
|
+
let end = start + 1;
|
|
218
|
+
while (end < previous.length && previous[end]!.depth > row.depth) end += 1;
|
|
219
|
+
candidates.push({ start, end, row, node });
|
|
220
|
+
}
|
|
221
|
+
if (candidates.length === 0) return null;
|
|
222
|
+
|
|
223
|
+
candidates.sort((a, b) => a.start - b.start);
|
|
224
|
+
const replacements: Replacement[] = [];
|
|
225
|
+
for (const candidate of candidates) {
|
|
226
|
+
const ancestor = replacements.at(-1);
|
|
227
|
+
if (ancestor && candidate.start < ancestor.end) continue;
|
|
228
|
+
replacements.push(candidate);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Every changed parent that existed in the previous snapshot must either be
|
|
232
|
+
// rebuilt itself or lie inside a rebuilt ancestor. Otherwise the delta is
|
|
233
|
+
// incomplete for this view (for example a decorator hid the raw parent).
|
|
234
|
+
for (const id of changedParentIds) {
|
|
235
|
+
const oldIndex = rowIndexById.get(id);
|
|
236
|
+
if (oldIndex === undefined) continue;
|
|
237
|
+
if (!replacements.some(({ start, end }) => oldIndex >= start && oldIndex < end)) return null;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const flattenSubtree = (replacement: Replacement): HierarchyNodeRow[] | null => {
|
|
241
|
+
const rows: HierarchyNodeRow[] = [];
|
|
242
|
+
const visited = new Set<string>();
|
|
243
|
+
let valid = true;
|
|
244
|
+
const walk = (node: EditorNode, depth: number, pathKey: string): void => {
|
|
245
|
+
if (!valid) return;
|
|
246
|
+
if (visited.has(node.id) || depth > MAX_DEPTH) {
|
|
247
|
+
valid = false;
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
visited.add(node.id);
|
|
251
|
+
rows.push({
|
|
252
|
+
node,
|
|
253
|
+
depth,
|
|
254
|
+
pathKey,
|
|
255
|
+
hasChildren: node.childIds.length > 0,
|
|
256
|
+
hiddenByCollapse: false,
|
|
257
|
+
});
|
|
258
|
+
for (let childIndex = 0; childIndex < node.childIds.length; childIndex += 1) {
|
|
259
|
+
const child = hierarchy.node(node.childIds[childIndex]!);
|
|
260
|
+
if (child) walk(child, depth + 1, `${pathKey}.${String(childIndex)}`);
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
walk(replacement.node, replacement.row.depth, replacement.row.pathKey);
|
|
264
|
+
return valid ? rows : null;
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
const next = [...previous];
|
|
268
|
+
for (let index = replacements.length - 1; index >= 0; index -= 1) {
|
|
269
|
+
const replacement = replacements[index]!;
|
|
270
|
+
const rows = flattenSubtree(replacement);
|
|
271
|
+
if (rows === null) return null;
|
|
272
|
+
next.splice(replacement.start, replacement.end - replacement.start, ...rows);
|
|
273
|
+
}
|
|
274
|
+
return next;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/** Stable React key for a row — walk path + id, so it never collides even
|
|
278
|
+
* when the underlying id scheme does (F14). */
|
|
279
|
+
export function hierarchyRowKey(row: Pick<HierarchyNodeRow, 'pathKey' | 'node'>): string {
|
|
280
|
+
return `${row.pathKey}:${row.node.id}`;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* The pure start/end row-index math for the hierarchy panel's
|
|
285
|
+
* scroll-windowed rendering. Kept here (not inlined in the component) for two
|
|
286
|
+
* reasons: it is unit-testable standalone with no React/jsdom involved, and a
|
|
287
|
+
* tamper test can `vi.mock` this ONE function to neutralize windowing (return
|
|
288
|
+
* the full range) and prove the render-bounding behavior actually depends on
|
|
289
|
+
* it, not on some other accidental cap.
|
|
290
|
+
*
|
|
291
|
+
* `overscan` extra rows are kept rendered on each side of the visible band
|
|
292
|
+
* so a fast scroll or keyboard nav doesn't flash empty space before the next
|
|
293
|
+
* paint catches up. `end` is clamped to `totalRows`; `start` is clamped to 0
|
|
294
|
+
* (never negative near the top of the list).
|
|
295
|
+
*/
|
|
296
|
+
export function hierarchyRowWindow(
|
|
297
|
+
totalRows: number,
|
|
298
|
+
scrollTop: number,
|
|
299
|
+
viewportPx: number,
|
|
300
|
+
rowH: number,
|
|
301
|
+
overscan: number,
|
|
302
|
+
): { start: number; end: number } {
|
|
303
|
+
const start = Math.max(0, Math.floor(scrollTop / rowH) - overscan);
|
|
304
|
+
const visibleCount = Math.ceil(viewportPx / rowH) + overscan * 2;
|
|
305
|
+
const end = Math.min(totalRows, start + visibleCount);
|
|
306
|
+
return { start, end };
|
|
307
|
+
}
|