@volter/sdk 0.0.0-stage → 0.5.203
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 +1166 -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 +317 -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 +403 -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,356 @@
|
|
|
1
|
+
import { AssetViewerSlot } from '@volter/sdk/kit/asset-viewers';
|
|
2
|
+
import { themeVars } from '@volter/sdk/widgets';
|
|
3
|
+
import { useEffect, useState, useSyncExternalStore } from 'react';
|
|
4
|
+
import { declaredRoots } from '@volter/project/adapter/manifest-interpreter';
|
|
5
|
+
import { loadGameManifest, type ResolvedAdapterRoot } from '@volter/project/manifest/load';
|
|
6
|
+
import { assetCapabilities } from '@volter/sdk/kit/asset-capabilities';
|
|
7
|
+
import { getCurrentProject } from '@volter/sdk/kit/project-manager';
|
|
8
|
+
import { projectAdapterFacet, subscribeProjectAdapter } from '@volter/sdk/kit/project-adapter';
|
|
9
|
+
import { resolveFileRegion } from '@volter/sdk/kit/ui-source/file-region-resolver';
|
|
10
|
+
import { editorServerJson } from '@volter/sdk/kit/editor-server-response';
|
|
11
|
+
import {
|
|
12
|
+
projectModuleChangeMatches,
|
|
13
|
+
subscribeProjectModuleChange,
|
|
14
|
+
} from '@volter/sdk/kit/project-module-changes';
|
|
15
|
+
import { AssetEditorShell } from '@volter/sdk/kit/components/AssetEditorShell';
|
|
16
|
+
import { CodeView, codeViewLanguage } from '../CodeView';
|
|
17
|
+
import { AudioViewer } from './AudioViewer';
|
|
18
|
+
import { ImageViewer } from './ImageViewer';
|
|
19
|
+
import { JsonAssetDocument } from './JsonAssetDocument';
|
|
20
|
+
|
|
21
|
+
export type SourceAssetRoute =
|
|
22
|
+
| 'model'
|
|
23
|
+
| 'image'
|
|
24
|
+
| 'audio'
|
|
25
|
+
| 'json'
|
|
26
|
+
| 'environment'
|
|
27
|
+
| 'lut'
|
|
28
|
+
| 'shader'
|
|
29
|
+
| 'module'
|
|
30
|
+
| 'text'
|
|
31
|
+
| 'binary';
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A project script the editor can EXECUTE, and therefore a candidate live
|
|
35
|
+
* model module (`LiveModuleDocument`). The bound is the dev server's own: only
|
|
36
|
+
* `src/**` scripts are classified, HMR-stamped and re-served on save
|
|
37
|
+
* (`server/project-hmr-files.ts`'s `classifyProjectHotUpdate` returns `ignore`
|
|
38
|
+
* for everything else), so a script outside `src/` could be imported once but
|
|
39
|
+
* never re-executed — a live document that silently stops being live. Whether
|
|
40
|
+
* such a module actually BUILDS an `Object3D` is decided by running it, never
|
|
41
|
+
* by its name.
|
|
42
|
+
*/
|
|
43
|
+
function isProjectScriptPath(assetPath: string): boolean {
|
|
44
|
+
const clean = (assetPath.split(/[?#]/, 1)[0] ?? '').replace(/^\//, '');
|
|
45
|
+
return clean.startsWith('src/') && /\.(?:[cm]?[jt]sx?)$/.test(clean);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function sourceAssetRoute(assetPath: string): SourceAssetRoute {
|
|
49
|
+
const capability = assetCapabilities(assetPath);
|
|
50
|
+
if (capability.editor === 'model') return 'model';
|
|
51
|
+
if (capability.editor === 'image') return 'image';
|
|
52
|
+
if (capability.editor === 'audio') return 'audio';
|
|
53
|
+
if (capability.editor === 'data') return 'json';
|
|
54
|
+
if (capability.editor === 'environment') return 'environment';
|
|
55
|
+
if (capability.format === 'cube') return 'lut';
|
|
56
|
+
if (capability.format === 'glsl' || capability.format === 'vert' || capability.format === 'frag')
|
|
57
|
+
return 'shader';
|
|
58
|
+
if (isProjectScriptPath(assetPath)) return 'module';
|
|
59
|
+
if (capability.editor === 'source' && capability.previewable) return 'text';
|
|
60
|
+
return 'binary';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* THE FILE IS THE SUBJECT.
|
|
65
|
+
*
|
|
66
|
+
* A source/module document had no selection context of its own, and
|
|
67
|
+
* `waitForAssetDocumentInspector` waits for exactly that — so
|
|
68
|
+
* `editor.openAsset('/src/foo.ts', 'source')` opened the document, showed the
|
|
69
|
+
* code, and then sat until the relay's budget ran out and reported a
|
|
70
|
+
* `play-stall`: a timeout about the tab for a document that was already on
|
|
71
|
+
* screen. (The JSON route acked because `JsonAssetDocument` goes through
|
|
72
|
+
* `AssetEditorShell`.)
|
|
73
|
+
*
|
|
74
|
+
* There is no invented subject here and nothing new to publish: a source
|
|
75
|
+
* document's subject is the FILE, its identity row is the filename and the
|
|
76
|
+
* kind, and its note is the Info the shell already shows for every other
|
|
77
|
+
* asset — so it registers through the SAME holder every Asset Lab document
|
|
78
|
+
* uses (`AssetEditorShell` → `AssetEditorSubject`) rather than growing a
|
|
79
|
+
* second one.
|
|
80
|
+
*/
|
|
81
|
+
function TextSourcePreview({
|
|
82
|
+
documentId,
|
|
83
|
+
assetPath,
|
|
84
|
+
active = true,
|
|
85
|
+
}: {
|
|
86
|
+
readonly documentId: string;
|
|
87
|
+
readonly assetPath: string;
|
|
88
|
+
readonly active?: boolean;
|
|
89
|
+
}) {
|
|
90
|
+
const [content, setContent] = useState<string | null>(null);
|
|
91
|
+
const [error, setError] = useState<string | null>(null);
|
|
92
|
+
const fileName = assetPath.split('/').pop() ?? assetPath;
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
let cancelled = false;
|
|
95
|
+
setContent(null);
|
|
96
|
+
setError(null);
|
|
97
|
+
const path = assetPath.replace(/^\//, '');
|
|
98
|
+
let revision = 0;
|
|
99
|
+
async function read() {
|
|
100
|
+
const request = ++revision;
|
|
101
|
+
try {
|
|
102
|
+
// The author's file as written — the project's dev server would answer
|
|
103
|
+
// a module path with its TRANSFORMED output (the globals prelude, the
|
|
104
|
+
// compiled JSX), which is not the source this document shows.
|
|
105
|
+
const url = `/__editor/source-file?path=${encodeURIComponent(path)}`;
|
|
106
|
+
const value = await fetch(url, { cache: 'no-store' }).then((response) => {
|
|
107
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
108
|
+
return response.text();
|
|
109
|
+
});
|
|
110
|
+
if (!cancelled && request === revision) {
|
|
111
|
+
setContent(value);
|
|
112
|
+
setError(null);
|
|
113
|
+
}
|
|
114
|
+
} catch (reason) {
|
|
115
|
+
if (!cancelled && request === revision)
|
|
116
|
+
setError(reason instanceof Error ? reason.message : String(reason));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const refresh = (changed: string) => {
|
|
120
|
+
if (projectModuleChangeMatches(changed, path)) void read();
|
|
121
|
+
};
|
|
122
|
+
const stop = subscribeProjectModuleChange(refresh);
|
|
123
|
+
void read();
|
|
124
|
+
return () => {
|
|
125
|
+
cancelled = true;
|
|
126
|
+
stop();
|
|
127
|
+
};
|
|
128
|
+
}, [assetPath]);
|
|
129
|
+
return (
|
|
130
|
+
<AssetEditorShell
|
|
131
|
+
documentId={documentId}
|
|
132
|
+
active={active}
|
|
133
|
+
type="source"
|
|
134
|
+
title={fileName}
|
|
135
|
+
sections={[]}
|
|
136
|
+
status={`source · ${assetPath}`}
|
|
137
|
+
fill
|
|
138
|
+
>
|
|
139
|
+
<div
|
|
140
|
+
style={{
|
|
141
|
+
padding: 12,
|
|
142
|
+
height: '100%',
|
|
143
|
+
minHeight: 0,
|
|
144
|
+
display: 'flex',
|
|
145
|
+
flexDirection: 'column',
|
|
146
|
+
gap: 8,
|
|
147
|
+
}}
|
|
148
|
+
>
|
|
149
|
+
<div
|
|
150
|
+
style={{
|
|
151
|
+
padding: 8,
|
|
152
|
+
// The well GROWS to the panel instead of stopping at a fixed
|
|
153
|
+
// budget: this document is a whole tab, and CodeView virtualizes,
|
|
154
|
+
// so there is nothing to buy by capping it. (It inherited a
|
|
155
|
+
// 560px ceiling from the small in-panel preview it was cut from,
|
|
156
|
+
// which left most of a full-tab source document empty.)
|
|
157
|
+
flex: 1,
|
|
158
|
+
minHeight: 0,
|
|
159
|
+
display: 'flex',
|
|
160
|
+
overflow: 'hidden',
|
|
161
|
+
background: themeVars.surface.inset,
|
|
162
|
+
border: `1px solid ${themeVars.boundary.default}`,
|
|
163
|
+
borderRadius: themeVars.shape.small,
|
|
164
|
+
}}
|
|
165
|
+
>
|
|
166
|
+
{error !== null || content === null ? (
|
|
167
|
+
<div
|
|
168
|
+
style={{
|
|
169
|
+
fontFamily: themeVars.typography.mono,
|
|
170
|
+
fontSize: 11,
|
|
171
|
+
lineHeight: 1.5,
|
|
172
|
+
color: error ? themeVars.semantic.danger : themeVars.content.muted,
|
|
173
|
+
padding: 4,
|
|
174
|
+
}}
|
|
175
|
+
>
|
|
176
|
+
{error ?? 'Loading…'}
|
|
177
|
+
</div>
|
|
178
|
+
) : (
|
|
179
|
+
<CodeView
|
|
180
|
+
value={content}
|
|
181
|
+
followChanges
|
|
182
|
+
language={codeViewLanguage(assetPath)}
|
|
183
|
+
fontSize={11}
|
|
184
|
+
maxHeight="100%"
|
|
185
|
+
ariaLabel={`Source of ${assetPath}`}
|
|
186
|
+
/>
|
|
187
|
+
)}
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
</AssetEditorShell>
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** A format whose native view no integration in this composition provides: the
|
|
195
|
+
* file is still a document with its own identity, like the binary route below. */
|
|
196
|
+
function NoNativeViewer({
|
|
197
|
+
documentId,
|
|
198
|
+
assetPath,
|
|
199
|
+
active,
|
|
200
|
+
}: {
|
|
201
|
+
readonly documentId: string;
|
|
202
|
+
readonly assetPath: string;
|
|
203
|
+
readonly active: boolean;
|
|
204
|
+
}) {
|
|
205
|
+
const name = assetPath.split('/').pop() ?? assetPath;
|
|
206
|
+
return (
|
|
207
|
+
<AssetEditorShell
|
|
208
|
+
documentId={documentId}
|
|
209
|
+
active={active}
|
|
210
|
+
type="source"
|
|
211
|
+
title={name}
|
|
212
|
+
sections={[]}
|
|
213
|
+
status={`no viewer · ${assetPath}`}
|
|
214
|
+
>
|
|
215
|
+
<div style={{ padding: 16, color: themeVars.content.muted, fontSize: 12 }}>
|
|
216
|
+
No editor package in this project renders {name}; the file is available in the project
|
|
217
|
+
and stays selectable and referenceable.
|
|
218
|
+
</div>
|
|
219
|
+
</AssetEditorShell>
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/** Read the file's declared surface before executing a possible model builder.
|
|
224
|
+
* A DOM or canvas component is source here; calling it outside its renderer
|
|
225
|
+
* can throw (React hooks), or perform work just to discover it is not a model.
|
|
226
|
+
* Unplaced modules retain the existing Object3D builder contract. */
|
|
227
|
+
function ProjectModuleSourceViewer({ documentId, assetPath, active }: {
|
|
228
|
+
documentId: string;
|
|
229
|
+
assetPath: string;
|
|
230
|
+
active: boolean;
|
|
231
|
+
}) {
|
|
232
|
+
const projectRoot = getCurrentProject()?.rootPath;
|
|
233
|
+
const facet = useSyncExternalStore(subscribeProjectAdapter, projectAdapterFacet);
|
|
234
|
+
const [roots, setRoots] = useState<readonly ResolvedAdapterRoot[] | null>(null);
|
|
235
|
+
const [declarationError, setDeclarationError] = useState<string | null>(null);
|
|
236
|
+
useEffect(() => {
|
|
237
|
+
let cancelled = false;
|
|
238
|
+
setRoots(null);
|
|
239
|
+
setDeclarationError(null);
|
|
240
|
+
if (!projectRoot || !facet) return;
|
|
241
|
+
void (async () => {
|
|
242
|
+
try {
|
|
243
|
+
const raw = await editorServerJson<unknown>(
|
|
244
|
+
await fetch('/volter.project.json', { cache: 'no-store' }),
|
|
245
|
+
'Reading this source file’s declared surface failed',
|
|
246
|
+
);
|
|
247
|
+
const manifest = loadGameManifest(raw, { configurationKinds: 'defer' });
|
|
248
|
+
if (!cancelled) setRoots(declaredRoots(manifest));
|
|
249
|
+
} catch (error) {
|
|
250
|
+
if (!cancelled) setDeclarationError(error instanceof Error ? error.message : String(error));
|
|
251
|
+
}
|
|
252
|
+
})();
|
|
253
|
+
return () => { cancelled = true; };
|
|
254
|
+
}, [projectRoot, facet]);
|
|
255
|
+
const preview = <TextSourcePreview documentId={documentId} assetPath={assetPath} active={active} />;
|
|
256
|
+
// Unknown declarations are not permission to execute the source.
|
|
257
|
+
if (!projectRoot || !facet || !roots || declarationError) return <>
|
|
258
|
+
{declarationError && <div role="alert">{declarationError}</div>}
|
|
259
|
+
{preview}
|
|
260
|
+
</>;
|
|
261
|
+
const path = (assetPath.split(/[?#]/, 1)[0] ?? '').replaceAll('\\', '/').replace(/^\.\//, '').replace(/^\//, '');
|
|
262
|
+
const region = resolveFileRegion({
|
|
263
|
+
file: path,
|
|
264
|
+
projectRelative: path,
|
|
265
|
+
regions: facet.regions,
|
|
266
|
+
regionOfEntry: (file) => {
|
|
267
|
+
const root = roots.find((candidate) => candidate.entry?.replace(/^\.\//, '') === file);
|
|
268
|
+
return root ? facet.regions.find((candidate) => candidate.id === root.id) : undefined;
|
|
269
|
+
},
|
|
270
|
+
});
|
|
271
|
+
if (region.surface === 'dom' || region.surface === 'canvas') return preview;
|
|
272
|
+
return <AssetViewerSlot route="module" documentId={documentId} assetPath={assetPath}
|
|
273
|
+
projectRoot={projectRoot} displayName={assetPath.split('/').pop() ?? assetPath}
|
|
274
|
+
active={active} fallback={preview} whenUnregistered={preview} />;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/** Viewer for downloaded catalog source/animation files without a magic fallback. */
|
|
278
|
+
export function SourceAssetViewer({
|
|
279
|
+
documentId,
|
|
280
|
+
assetPath,
|
|
281
|
+
active = true,
|
|
282
|
+
}: {
|
|
283
|
+
documentId: string;
|
|
284
|
+
assetPath: string;
|
|
285
|
+
active?: boolean;
|
|
286
|
+
}) {
|
|
287
|
+
switch (sourceAssetRoute(assetPath)) {
|
|
288
|
+
case 'model':
|
|
289
|
+
case 'environment':
|
|
290
|
+
case 'lut':
|
|
291
|
+
case 'shader': {
|
|
292
|
+
// The format's native view is the media integration's
|
|
293
|
+
// (`@volter/sdk/kit/asset-viewers`); without one, the file is
|
|
294
|
+
// still opened as what it is.
|
|
295
|
+
const route = sourceAssetRoute(assetPath) as 'model' | 'environment' | 'lut' | 'shader';
|
|
296
|
+
return (
|
|
297
|
+
<AssetViewerSlot
|
|
298
|
+
route={route}
|
|
299
|
+
documentId={documentId}
|
|
300
|
+
assetPath={assetPath}
|
|
301
|
+
displayName={assetPath.split('/').pop() ?? assetPath}
|
|
302
|
+
active={active}
|
|
303
|
+
whenUnregistered={<NoNativeViewer documentId={documentId} assetPath={assetPath} active={active} />}
|
|
304
|
+
/>
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
case 'image':
|
|
308
|
+
return <ImageViewer assetPath={assetPath} />;
|
|
309
|
+
case 'audio':
|
|
310
|
+
return <AudioViewer assetPath={assetPath} />;
|
|
311
|
+
case 'json':
|
|
312
|
+
// Content-routed: a native three.quarks document opens as the particle
|
|
313
|
+
// editor, any other JSON keeps the generic viewer.
|
|
314
|
+
return (
|
|
315
|
+
<JsonAssetDocument
|
|
316
|
+
documentId={documentId}
|
|
317
|
+
assetPath={assetPath}
|
|
318
|
+
displayName={assetPath.split('/').pop() ?? assetPath}
|
|
319
|
+
active={active}
|
|
320
|
+
sections={[]}
|
|
321
|
+
status={`json · ${assetPath}`}
|
|
322
|
+
/>
|
|
323
|
+
);
|
|
324
|
+
case 'module': {
|
|
325
|
+
// Content-routed, like the quarks JSON above: a project script that
|
|
326
|
+
// BUILDS an Object3D opens as the live modeling document; anything else
|
|
327
|
+
// keeps this viewer's text preview.
|
|
328
|
+
return <ProjectModuleSourceViewer documentId={documentId} assetPath={assetPath} active={active} />;
|
|
329
|
+
}
|
|
330
|
+
case 'text':
|
|
331
|
+
return <TextSourcePreview documentId={documentId} assetPath={assetPath} active={active} />;
|
|
332
|
+
case 'binary':
|
|
333
|
+
// Same subject rule as the text route above — the FILE. A document that
|
|
334
|
+
// publishes nothing is a document `editor.openAsset` can only time out
|
|
335
|
+
// against, and "no renderer" is not "no identity".
|
|
336
|
+
return (
|
|
337
|
+
<AssetEditorShell
|
|
338
|
+
documentId={documentId}
|
|
339
|
+
active={active}
|
|
340
|
+
type="binary source"
|
|
341
|
+
title={assetPath.split('/').pop() ?? assetPath}
|
|
342
|
+
sections={[]}
|
|
343
|
+
status={`binary · ${assetPath}`}
|
|
344
|
+
>
|
|
345
|
+
<div style={{ padding: 16, color: themeVars.content.muted, fontSize: 12 }}>
|
|
346
|
+
<div style={{ color: themeVars.content.primary, fontWeight: 600, marginBottom: 6 }}>
|
|
347
|
+
{assetPath.split('/').pop()}
|
|
348
|
+
</div>
|
|
349
|
+
This binary source is available in the project, but it has no safe in-editor renderer.
|
|
350
|
+
Its file remains selectable and referenceable without being misidentified as another
|
|
351
|
+
format.
|
|
352
|
+
</div>
|
|
353
|
+
</AssetEditorShell>
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One sprite from a packed atlas — Aseprite's cel / Unity's Sprite /
|
|
3
|
+
* Godot's AtlasTexture. The sheet is the source texture; this paints the
|
|
4
|
+
* named frame onto the untrimmed canvas at nearest-neighbor.
|
|
5
|
+
*/
|
|
6
|
+
import { useEffect, useRef } from 'react';
|
|
7
|
+
import { integerFitScale } from '../../asset-workflow/image-view-scale';
|
|
8
|
+
import { type PixiSpritesheetFrame, packedFrameRect } from '@volter/sdk/kit/asset-workflow/pixi-spritesheet';
|
|
9
|
+
|
|
10
|
+
export function paintSpriteFrame(
|
|
11
|
+
canvas: HTMLCanvasElement,
|
|
12
|
+
image: CanvasImageSource,
|
|
13
|
+
frame: PixiSpritesheetFrame,
|
|
14
|
+
): void {
|
|
15
|
+
const destWidth = Math.max(1, frame.sourceWidth ?? frame.width);
|
|
16
|
+
const destHeight = Math.max(1, frame.sourceHeight ?? frame.height);
|
|
17
|
+
canvas.width = destWidth;
|
|
18
|
+
canvas.height = destHeight;
|
|
19
|
+
const context = canvas.getContext('2d');
|
|
20
|
+
if (!context) return;
|
|
21
|
+
context.imageSmoothingEnabled = false;
|
|
22
|
+
context.clearRect(0, 0, destWidth, destHeight);
|
|
23
|
+
const packed = packedFrameRect(frame);
|
|
24
|
+
if (frame.rotated) {
|
|
25
|
+
context.save();
|
|
26
|
+
context.translate(frame.trimX, frame.trimY + packed.width);
|
|
27
|
+
context.rotate(-Math.PI / 2);
|
|
28
|
+
context.drawImage(
|
|
29
|
+
image,
|
|
30
|
+
packed.x,
|
|
31
|
+
packed.y,
|
|
32
|
+
packed.width,
|
|
33
|
+
packed.height,
|
|
34
|
+
0,
|
|
35
|
+
0,
|
|
36
|
+
packed.width,
|
|
37
|
+
packed.height,
|
|
38
|
+
);
|
|
39
|
+
context.restore();
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
context.drawImage(
|
|
43
|
+
image,
|
|
44
|
+
packed.x,
|
|
45
|
+
packed.y,
|
|
46
|
+
packed.width,
|
|
47
|
+
packed.height,
|
|
48
|
+
frame.trimX,
|
|
49
|
+
frame.trimY,
|
|
50
|
+
packed.width,
|
|
51
|
+
packed.height,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function SpritesheetSpriteView({
|
|
56
|
+
sheetUrl,
|
|
57
|
+
frame,
|
|
58
|
+
scale,
|
|
59
|
+
maxEdge,
|
|
60
|
+
}: {
|
|
61
|
+
sheetUrl: string;
|
|
62
|
+
frame: PixiSpritesheetFrame;
|
|
63
|
+
scale?: number;
|
|
64
|
+
maxEdge?: number;
|
|
65
|
+
}) {
|
|
66
|
+
const canvasRef = useRef<HTMLCanvasElement>(null);
|
|
67
|
+
const destWidth = Math.max(1, frame.sourceWidth ?? frame.width);
|
|
68
|
+
const destHeight = Math.max(1, frame.sourceHeight ?? frame.height);
|
|
69
|
+
const resolved =
|
|
70
|
+
maxEdge != null ? integerFitScale(destWidth, destHeight, maxEdge, maxEdge) : (scale ?? 1);
|
|
71
|
+
const displayWidth = Math.max(1, Math.round(destWidth * resolved));
|
|
72
|
+
const displayHeight = Math.max(1, Math.round(destHeight * resolved));
|
|
73
|
+
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
const canvas = canvasRef.current;
|
|
76
|
+
if (!canvas) return;
|
|
77
|
+
const image = new Image();
|
|
78
|
+
let cancelled = false;
|
|
79
|
+
image.onload = () => {
|
|
80
|
+
if (!cancelled) paintSpriteFrame(canvas, image, frame);
|
|
81
|
+
};
|
|
82
|
+
image.src = sheetUrl;
|
|
83
|
+
return () => {
|
|
84
|
+
cancelled = true;
|
|
85
|
+
};
|
|
86
|
+
}, [frame, sheetUrl]);
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
<canvas
|
|
90
|
+
ref={canvasRef}
|
|
91
|
+
width={destWidth}
|
|
92
|
+
height={destHeight}
|
|
93
|
+
aria-hidden
|
|
94
|
+
style={{
|
|
95
|
+
width: displayWidth,
|
|
96
|
+
height: displayHeight,
|
|
97
|
+
imageRendering: 'pixelated',
|
|
98
|
+
display: 'block',
|
|
99
|
+
}}
|
|
100
|
+
/>
|
|
101
|
+
);
|
|
102
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Video Asset Lab document: the clip itself, with the browser's own controls.
|
|
3
|
+
*
|
|
4
|
+
* Deliberately no custom transport, no autoplay and no muting — a reference
|
|
5
|
+
* clip is watched, and `<video controls>` is already the control surface every
|
|
6
|
+
* person on this machine knows. The bytes come from the session, which serves
|
|
7
|
+
* the project's own files.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Text, text } from '@volter/sdk/widgets';
|
|
11
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
12
|
+
|
|
13
|
+
export function VideoViewer({ assetPath }: { assetPath: string }) {
|
|
14
|
+
const [failed, setFailed] = useState(false);
|
|
15
|
+
const [size, setSize] = useState<{ w: number; h: number } | null>(null);
|
|
16
|
+
const source = assetPath;
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
setFailed(false);
|
|
19
|
+
}, [source]);
|
|
20
|
+
const name = assetPath.split('/').pop() ?? assetPath;
|
|
21
|
+
const measure = useCallback((element: HTMLVideoElement | null) => {
|
|
22
|
+
if (!element) return;
|
|
23
|
+
if (element.error) {
|
|
24
|
+
setFailed(true);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (element.videoWidth <= 0) return;
|
|
28
|
+
setSize((current) =>
|
|
29
|
+
current && current.w === element.videoWidth && current.h === element.videoHeight
|
|
30
|
+
? current
|
|
31
|
+
: { w: element.videoWidth, h: element.videoHeight },
|
|
32
|
+
);
|
|
33
|
+
}, []);
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<div
|
|
37
|
+
data-testid="video-asset-document"
|
|
38
|
+
style={{
|
|
39
|
+
height: '100%',
|
|
40
|
+
minHeight: 240,
|
|
41
|
+
display: 'flex',
|
|
42
|
+
flexDirection: 'column',
|
|
43
|
+
minWidth: 0,
|
|
44
|
+
}}
|
|
45
|
+
>
|
|
46
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '6px 8px' }}>
|
|
47
|
+
<Text tone="dim" variant="label">
|
|
48
|
+
{name}
|
|
49
|
+
</Text>
|
|
50
|
+
{size && (
|
|
51
|
+
<Text tone="muted" variant="code">
|
|
52
|
+
{size.w} × {size.h}
|
|
53
|
+
</Text>
|
|
54
|
+
)}
|
|
55
|
+
</div>
|
|
56
|
+
<div
|
|
57
|
+
className="volter-asset-transparency-well"
|
|
58
|
+
style={{
|
|
59
|
+
flex: 1,
|
|
60
|
+
minHeight: 0,
|
|
61
|
+
display: 'flex',
|
|
62
|
+
alignItems: 'center',
|
|
63
|
+
justifyContent: 'center',
|
|
64
|
+
padding: 12,
|
|
65
|
+
}}
|
|
66
|
+
>
|
|
67
|
+
{failed ? (
|
|
68
|
+
<div style={{ color: text[2], fontSize: 12, textAlign: 'center' }}>
|
|
69
|
+
{name} could not be played from {source}. The file may be missing, or its codec may not
|
|
70
|
+
be one this browser decodes.
|
|
71
|
+
</div>
|
|
72
|
+
) : (
|
|
73
|
+
<video
|
|
74
|
+
key={source}
|
|
75
|
+
src={source}
|
|
76
|
+
controls
|
|
77
|
+
playsInline
|
|
78
|
+
preload="metadata"
|
|
79
|
+
// MEASURED, not just listened for: a clip whose metadata is already
|
|
80
|
+
// decoded when React attaches (a cached file, a reopened document)
|
|
81
|
+
// fires `loadedmetadata` BEFORE the listener exists, and the header
|
|
82
|
+
// then reported no dimensions over a video the layout had already
|
|
83
|
+
// sized from real ones. The ref reads the element's own state on
|
|
84
|
+
// attach; the event covers everything that arrives later.
|
|
85
|
+
//
|
|
86
|
+
// `measure` is STABLE and its write is a no-change guard, both for
|
|
87
|
+
// the same reason: an inline ref is a new function every render, so
|
|
88
|
+
// React detaches and re-runs it every render, and a `setSize` that
|
|
89
|
+
// writes a fresh object each time is then an infinite update loop.
|
|
90
|
+
// Measured here — it took the editor's chrome down with
|
|
91
|
+
// "Maximum update depth exceeded".
|
|
92
|
+
ref={measure}
|
|
93
|
+
onError={() => setFailed(true)}
|
|
94
|
+
onLoadedMetadata={(event) => measure(event.currentTarget)}
|
|
95
|
+
style={{ maxWidth: '100%', maxHeight: '100%', display: 'block' }}
|
|
96
|
+
/>
|
|
97
|
+
)}
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
101
|
+
}
|