@volter/editor-core 0.5.57
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/BUNDLED_NOTICES +1527 -0
- package/LICENSE +686 -0
- package/LICENSE-APACHE +202 -0
- package/NOTICE +18 -0
- package/README.md +24 -0
- package/dist/build/chunk-JS4D4XZ3.js +175 -0
- package/dist/build/chunk-JS4D4XZ3.js.map +7 -0
- package/dist/build/vite-plugin-product-contributions.js +100 -0
- package/dist/build/vite-plugin-product-contributions.js.map +7 -0
- package/dist/build/vite-plugin-shared-react.js +25 -0
- package/dist/build/vite-plugin-shared-react.js.map +7 -0
- package/dist/build/vite-plugin-shared-three.js +86 -0
- package/dist/build/vite-plugin-shared-three.js.map +7 -0
- package/dist/server/chunk-KMJC7AGO.js +98 -0
- package/dist/server/chunk-KMJC7AGO.js.map +7 -0
- package/dist/server/chunk-PSILUMGS.js +46 -0
- package/dist/server/chunk-PSILUMGS.js.map +7 -0
- package/dist/server/frame-proxy.js +255 -0
- package/dist/server/frame-proxy.js.map +7 -0
- package/dist/server/open-browser.js +53 -0
- package/dist/server/open-browser.js.map +7 -0
- package/dist/server/process-shutdown.js +127 -0
- package/dist/server/process-shutdown.js.map +7 -0
- package/dist/server/session-registry.js +141 -0
- package/dist/server/session-registry.js.map +7 -0
- package/dist/server/spawn-opener.js +11 -0
- package/dist/server/spawn-opener.js.map +7 -0
- package/dist/server/worktree-identity.js +11 -0
- package/dist/server/worktree-identity.js.map +7 -0
- package/dist-server/packaged.mjs +88816 -0
- package/package.json +118 -0
- package/scripts/build-plugins.mjs +14 -0
- package/scripts/build-server.mjs +26 -0
- package/scripts/build-session.mjs +9 -0
- package/server/account-credentials.ts +60 -0
- package/server/account-service.ts +1434 -0
- package/server/adapter-region-includes.ts +47 -0
- package/server/asset-catalog-v2.ts +175 -0
- package/server/asset-history-snapshots.ts +196 -0
- package/server/asset-ledger-store.ts +195 -0
- package/server/asset-library-routes.ts +1595 -0
- package/server/blender-wasm-artifact.ts +430 -0
- package/server/boot-timings.ts +106 -0
- package/server/canonical-path.ts +50 -0
- package/server/checkout-workspace-preflight.ts +349 -0
- package/server/cloud-asset-catalog.ts +158 -0
- package/server/coding-inference-launch.ts +237 -0
- package/server/collaboration-account-client.ts +202 -0
- package/server/collaboration-attribution.ts +122 -0
- package/server/collaboration-session.ts +934 -0
- package/server/comfyui-bridge.ts +248 -0
- package/server/console-ledger.ts +499 -0
- package/server/creation-site-transform.ts +304 -0
- package/server/creation-site-write.ts +648 -0
- package/server/data-file-serialize.ts +158 -0
- package/server/editor-brand-html.ts +72 -0
- package/server/editor-control-socket.ts +366 -0
- package/server/editor-server-options.ts +190 -0
- package/server/editor-server.ts +1483 -0
- package/server/editor-sse.ts +352 -0
- package/server/engine-provenance.ts +169 -0
- package/server/engine-source-restart.ts +117 -0
- package/server/frame-bridge.ts +115 -0
- package/server/frame-proxy.ts +490 -0
- package/server/frame-workbench.ts +259 -0
- package/server/frontend-handoff.ts +229 -0
- package/server/game-globals-shadow.ts +113 -0
- package/server/gameplay-session-retention.ts +149 -0
- package/server/gameplay-sessions.ts +123 -0
- package/server/generation-jobs.ts +201 -0
- package/server/generation-reconciler.ts +137 -0
- package/server/generative-execution-context.ts +59 -0
- package/server/git-workflow.ts +612 -0
- package/server/harness-chat-caller.ts +36 -0
- package/server/harness-chat-service.ts +1681 -0
- package/server/idle-shutdown.ts +170 -0
- package/server/js-profiling-policy.ts +52 -0
- package/server/launcher-settings.ts +84 -0
- package/server/local-asset-catalog.ts +410 -0
- package/server/managed-account-defaults.ts +22 -0
- package/server/mock-control-plane.ts +540 -0
- package/server/model-import-conversion.ts +345 -0
- package/server/native-credential-store.ts +162 -0
- package/server/open-browser.ts +118 -0
- package/server/packaged.ts +1192 -0
- package/server/play-stall.ts +126 -0
- package/server/process-shutdown.ts +218 -0
- package/server/product-presets.ts +55 -0
- package/server/project-build-artifact.ts +95 -0
- package/server/project-components.ts +100 -0
- package/server/project-dependency-invalidation.ts +114 -0
- package/server/project-file-scan.ts +235 -0
- package/server/project-hmr-files.ts +215 -0
- package/server/project-install-roots.ts +210 -0
- package/server/project-kinds.ts +71 -0
- package/server/project-mcp-servers.ts +82 -0
- package/server/project-module-freshness.ts +109 -0
- package/server/project-module-instance.ts +375 -0
- package/server/project-optimize-deps-entries.ts +827 -0
- package/server/project-output-writer.ts +679 -0
- package/server/project-package-origin.ts +63 -0
- package/server/project-root-surface.ts +831 -0
- package/server/project-scratch-path.ts +47 -0
- package/server/project-script-hmr.ts +619 -0
- package/server/project-serving-plugins.ts +236 -0
- package/server/project-tools.ts +653 -0
- package/server/project-validation.ts +250 -0
- package/server/project-verbs.ts +127 -0
- package/server/project-view.ts +52 -0
- package/server/project-watch.ts +1134 -0
- package/server/project-work-coordinator.ts +288 -0
- package/server/provider-credentials.ts +331 -0
- package/server/recent-projects-store.ts +98 -0
- package/server/redact-secrets.ts +71 -0
- package/server/repository-presence.ts +267 -0
- package/server/routes/account.ts +357 -0
- package/server/routes/agents.ts +60 -0
- package/server/routes/assets.ts +154 -0
- package/server/routes/build.ts +13 -0
- package/server/routes/collaboration.ts +595 -0
- package/server/routes/configurations.ts +419 -0
- package/server/routes/context.ts +264 -0
- package/server/routes/control-plane.ts +1811 -0
- package/server/routes/logs.ts +272 -0
- package/server/routes/project-identity.ts +302 -0
- package/server/routes/project-open.ts +429 -0
- package/server/routes/project-source.ts +686 -0
- package/server/routes/project-state.ts +383 -0
- package/server/routes/relay.ts +1029 -0
- package/server/routes/route-helpers.ts +29 -0
- package/server/routes/served-modules.ts +138 -0
- package/server/routes/session-tabs.ts +196 -0
- package/server/routes/settings.ts +121 -0
- package/server/routes/share-control.ts +486 -0
- package/server/routes/themes.ts +116 -0
- package/server/routes/tools.ts +230 -0
- package/server/routes/worktrees.ts +595 -0
- package/server/scoped-game-css.ts +461 -0
- package/server/server-utils.ts +1194 -0
- package/server/session-product.ts +112 -0
- package/server/session-registry.ts +230 -0
- package/server/share-claims.ts +138 -0
- package/server/share-host.ts +526 -0
- package/server/share-session-gateway.ts +1362 -0
- package/server/share-tunnel.ts +123 -0
- package/server/spawn-opener.ts +74 -0
- package/server/support/play/log-format.ts +76 -0
- package/server/support/play/session-record.ts +199 -0
- package/server/support/project/build-discipline.ts +718 -0
- package/server/support/project/inspection-node.ts +119 -0
- package/server/support/project/log-naming.ts +54 -0
- package/server/support/project/provenance.ts +290 -0
- package/server/support/project/run-name.ts +18 -0
- package/server/support/project/session-journal.ts +830 -0
- package/server/support/project/shared.ts +327 -0
- package/server/tab-bootstrap.ts +62 -0
- package/server/tab-heartbeat.ts +477 -0
- package/server/tab-lifecycle.ts +550 -0
- package/server/tab-presence.ts +1508 -0
- package/server/team-agent-mirror.ts +95 -0
- package/server/twin-auth.ts +138 -0
- package/server/vendored-lock-recorder.ts +968 -0
- package/server/worktree-identity.ts +121 -0
- package/server/worktree-management.ts +398 -0
- package/server/worktree-retention.d.mts +13 -0
- package/server/worktree-retention.mjs +205 -0
- package/src/EditorContext.tsx +169 -0
- package/src/account.ts +333 -0
- package/src/action-registry.ts +532 -0
- package/src/active-product.ts +74 -0
- package/src/active-project.ts +155 -0
- package/src/adapter-editor-config.ts +25 -0
- package/src/adapter-observation.ts +49 -0
- package/src/animation/stage-transport.ts +379 -0
- package/src/animation/three-clips-subject.ts +172 -0
- package/src/api/asset-library-wire.ts +45 -0
- package/src/api/assets.ts +365 -0
- package/src/api/base.ts +10 -0
- package/src/api/build.ts +99 -0
- package/src/api/git-wire.ts +56 -0
- package/src/api/logs.ts +92 -0
- package/src/api/project-identity.ts +74 -0
- package/src/api/project-open.ts +355 -0
- package/src/api/project-source.ts +162 -0
- package/src/api/project-state.ts +107 -0
- package/src/api/relay.ts +268 -0
- package/src/api/settings.ts +36 -0
- package/src/api/themes.ts +45 -0
- package/src/api/worktrees.ts +257 -0
- package/src/asset-compare-core.ts +171 -0
- package/src/asset-compare.ts +294 -0
- package/src/asset-editor-context.tsx +100 -0
- package/src/asset-events.ts +97 -0
- package/src/asset-inspector-actions.ts +87 -0
- package/src/asset-preview-framing.ts +357 -0
- package/src/asset-preview.ts +2802 -0
- package/src/asset-selection-viewer-registry.ts +113 -0
- package/src/asset-selection.ts +133 -0
- package/src/asset-workflow/asset-capabilities.ts +344 -0
- package/src/asset-workflow/asset-import-jobs.ts +106 -0
- package/src/asset-workflow/asset-ledger-backend.ts +126 -0
- package/src/asset-workflow/asset-ledger.ts +156 -0
- package/src/asset-workflow/asset-materialization-report.ts +140 -0
- package/src/asset-workflow/asset-pack-manifest.ts +320 -0
- package/src/asset-workflow/asset-types.ts +142 -0
- package/src/asset-workflow/asset-workflow-quality.ts +61 -0
- package/src/asset-workflow/audio-preview-player.ts +193 -0
- package/src/asset-workflow/audio-waveform.ts +22 -0
- package/src/asset-workflow/cloud-asset-client.ts +263 -0
- package/src/asset-workflow/folder-preview.ts +345 -0
- package/src/asset-workflow/hosted-asset-materialization.ts +236 -0
- package/src/asset-workflow/image-view-scale.ts +32 -0
- package/src/asset-workflow/import-contract.ts +124 -0
- package/src/asset-workflow/ledger-write-lock.ts +244 -0
- package/src/asset-workflow/model-inspection.ts +818 -0
- package/src/asset-workflow/pixi-spritesheet.ts +197 -0
- package/src/asset-workflow/preview-resource-lifetime.ts +44 -0
- package/src/asset-workflow/project-asset-commands.ts +23 -0
- package/src/asset-workflow/project-asset-health.ts +139 -0
- package/src/asset-workflow/project-asset-operations.ts +154 -0
- package/src/asset-workflow/project-asset-roots.ts +68 -0
- package/src/asset-workflow/project-content.ts +288 -0
- package/src/asset-workflow/project-source-index.ts +550 -0
- package/src/asset-workflow/thumbnail-system.ts +256 -0
- package/src/authoring/active-adapter.ts +199 -0
- package/src/authoring/active-systems.ts +422 -0
- package/src/authoring/adapter-key.ts +18 -0
- package/src/authoring/authoring-asset-url.ts +27 -0
- package/src/authoring/bootstrap-state.ts +49 -0
- package/src/authoring/boundary-authoring-adapter.ts +184 -0
- package/src/authoring/breakpoint-state.ts +43 -0
- package/src/authoring/canvas-scene-guides.ts +76 -0
- package/src/authoring/component-instance-root.ts +171 -0
- package/src/authoring/composite-authoring-adapter.ts +2110 -0
- package/src/authoring/consumer-actions.ts +520 -0
- package/src/authoring/css-numeric-style.ts +97 -0
- package/src/authoring/design-time-layers.ts +849 -0
- package/src/authoring/design-time-mount-registry.ts +235 -0
- package/src/authoring/design-time-settle.ts +343 -0
- package/src/authoring/edit-mode-authoring.ts +619 -0
- package/src/authoring/eyedropper-session.ts +60 -0
- package/src/authoring/instance-source-menu-register.ts +13 -0
- package/src/authoring/instance-source-menu.ts +135 -0
- package/src/authoring/layered-pick.ts +183 -0
- package/src/authoring/live-gesture-lock.ts +50 -0
- package/src/authoring/live-object-transform.ts +62 -0
- package/src/authoring/mount-failure-report.ts +154 -0
- package/src/authoring/mounted-root-subjects.ts +144 -0
- package/src/authoring/no-authoring-adapter.ts +55 -0
- package/src/authoring/null-inspection-subjects.tsx +75 -0
- package/src/authoring/object3d-document-persistence.ts +106 -0
- package/src/authoring/object3d-document-session-registry.ts +120 -0
- package/src/authoring/object3d-document-session.ts +1326 -0
- package/src/authoring/object3d-gesture-controller.ts +113 -0
- package/src/authoring/panel-authoring.ts +121 -0
- package/src/authoring/prefab-instance-inspector-section.tsx +237 -0
- package/src/authoring/prefab-instance-section-model.ts +55 -0
- package/src/authoring/project-authoring-session.ts +105 -0
- package/src/authoring/provenance.ts +99 -0
- package/src/authoring/quarks-particle-systems.ts +19 -0
- package/src/authoring/react-canvas-navigation.ts +255 -0
- package/src/authoring/react-design-canvas-style.ts +20 -0
- package/src/authoring/react-story-board.ts +937 -0
- package/src/authoring/selection-scope.ts +195 -0
- package/src/authoring/shell-document-ops.ts +169 -0
- package/src/authoring/shell-object3d-document-write-policy.ts +108 -0
- package/src/authoring/shell-viewport-policy.ts +48 -0
- package/src/authoring/source-object3d-authoring-adapter.ts +526 -0
- package/src/authoring/stories-scope.ts +35 -0
- package/src/authoring/story-board-chrome-fit.ts +107 -0
- package/src/authoring/story-board-presentation.ts +111 -0
- package/src/authoring/three-projection-core.ts +226 -0
- package/src/authoring/viewport-pick-context.ts +40 -0
- package/src/authoring/viewport-raycast.ts +240 -0
- package/src/authoring/viewport-tool-context.ts +73 -0
- package/src/authoring/world-canvas-viewport-state.ts +35 -0
- package/src/authoring/world-hidden-viewport.ts +152 -0
- package/src/authoring/world-pan-state.ts +198 -0
- package/src/authoring/world-session-state.ts +101 -0
- package/src/authoring/write-pipe.ts +173 -0
- package/src/availability-tick.ts +66 -0
- package/src/bitmap-label.ts +120 -0
- package/src/blender-tab-metrics.ts +161 -0
- package/src/board-open-actions.ts +20 -0
- package/src/boot-routing.ts +391 -0
- package/src/build-identity.ts +15 -0
- package/src/bytes-codec.ts +62 -0
- package/src/camera-authoring.ts +175 -0
- package/src/cancellation-reason.ts +58 -0
- package/src/canvas-preview-frames.ts +482 -0
- package/src/capture-camera-pose.ts +77 -0
- package/src/chrome-registry.ts +159 -0
- package/src/chrome-slot-registry.ts +91 -0
- package/src/collaboration-client.ts +264 -0
- package/src/collaboration-presence.ts +41 -0
- package/src/command-dispatch.ts +19 -0
- package/src/command-listener.ts +2743 -0
- package/src/command-registry.ts +70 -0
- package/src/component-board-registry.ts +205 -0
- package/src/component-states-registry.ts +200 -0
- package/src/components/AgentPresentationNotice.tsx +75 -0
- package/src/components/AlignToolbar.tsx +204 -0
- package/src/components/AppRoot.tsx +394 -0
- package/src/components/ApplicationMenus.tsx +415 -0
- package/src/components/AssetBrowser.tsx +2843 -0
- package/src/components/AssetEditorShell.tsx +216 -0
- package/src/components/AssetInspectorToolSection.tsx +124 -0
- package/src/components/BoardRulers.tsx +354 -0
- package/src/components/CameraInfo.tsx +81 -0
- package/src/components/CanvasSceneViewport.tsx +556 -0
- package/src/components/CapabilityCoverageSection.tsx +185 -0
- package/src/components/CenterDocuments.tsx +22 -0
- package/src/components/ChromeSlot.tsx +20 -0
- package/src/components/CodeView.tsx +470 -0
- package/src/components/CollaborationHeaderControl.css +74 -0
- package/src/components/CompactInspectorCard.tsx +190 -0
- package/src/components/CompactInspectorShell.tsx +39 -0
- package/src/components/ConsolePanel.css +55 -0
- package/src/components/ConsolePanel.tsx +270 -0
- package/src/components/DefaultEditorLayout.tsx +106 -0
- package/src/components/DocumentHeaderStrip.tsx +96 -0
- package/src/components/DocumentShelfRail.tsx +45 -0
- package/src/components/DocumentThumbnail.tsx +345 -0
- package/src/components/EditorLeaseGuard.tsx +372 -0
- package/src/components/ErrorBanner.tsx +123 -0
- package/src/components/FolderPreviewTile.tsx +159 -0
- package/src/components/GameHierarchy.tsx +3842 -0
- package/src/components/GameplaySessionTimeline.tsx +295 -0
- package/src/components/InspectionProjection.tsx +968 -0
- package/src/components/Inspector.tsx +233 -0
- package/src/components/InspectorCanvasPreview.tsx +35 -0
- package/src/components/InspectorFieldsSection.tsx +290 -0
- package/src/components/InspectorObjectPreview.tsx +57 -0
- package/src/components/InspectorStoriesSection.tsx +92 -0
- package/src/components/InspectorToolSection.tsx +96 -0
- package/src/components/InspectorTransformSection.tsx +245 -0
- package/src/components/LightExplorerPanel.tsx +433 -0
- package/src/components/MediaProperties.tsx +145 -0
- package/src/components/NonThreeAuthoringBootstrap.tsx +19 -0
- package/src/components/Object3DDocumentToolbar.css +100 -0
- package/src/components/Object3DDocumentToolbar.tsx +454 -0
- package/src/components/Object3DDocumentViewport.tsx +58 -0
- package/src/components/ProjectHeader.css +617 -0
- package/src/components/ProjectHeader.tsx +328 -0
- package/src/components/ProjectLayout.tsx +249 -0
- package/src/components/ReactCanvasControls.tsx +284 -0
- package/src/components/RootSelectionOverlay.tsx +3162 -0
- package/src/components/RootTextEditor.tsx +79 -0
- package/src/components/SaveStatus.tsx +70 -0
- package/src/components/StageHost.tsx +1954 -0
- package/src/components/StageOverlays.tsx +21 -0
- package/src/components/StartupErrorScreen.tsx +76 -0
- package/src/components/StartupLoadingScreen.tsx +65 -0
- package/src/components/StatsOverlay.tsx +78 -0
- package/src/components/SurfaceStateOverlay.tsx +24 -0
- package/src/components/ToolContributionSurfaces.tsx +65 -0
- package/src/components/ToolHost.tsx +370 -0
- package/src/components/ToolObject3DPreview.tsx +39 -0
- package/src/components/Toolbar.tsx +595 -0
- package/src/components/TransientHint.tsx +44 -0
- package/src/components/TransportStrip.tsx +174 -0
- package/src/components/VersionControlSection.tsx +470 -0
- package/src/components/VgaiLogo.css +83 -0
- package/src/components/VgaiLogo.tsx +35 -0
- package/src/components/ViewportControlsHint.tsx +60 -0
- package/src/components/ViewportFurniture.tsx +401 -0
- package/src/components/ViewportOverlay.tsx +145 -0
- package/src/components/ViewportOverlaysMenu.tsx +153 -0
- package/src/components/ViewportShadingMenu.tsx +300 -0
- package/src/components/ViewportViewMenu.tsx +101 -0
- package/src/components/WorkspaceDocumentSurface.tsx +204 -0
- package/src/components/WorkspaceUtilitySurface.tsx +22 -0
- package/src/components/WorktreeSwitcher.css +239 -0
- package/src/components/WorktreeSwitcher.tsx +890 -0
- package/src/components/account-documents.tsx +1162 -0
- package/src/components/asset-documents.tsx +812 -0
- package/src/components/asset-editor-persistence.ts +216 -0
- package/src/components/asset-selection-section.tsx +535 -0
- package/src/components/asset-thumbnails.tsx +312 -0
- package/src/components/asset-viewers/AudioViewer.tsx +201 -0
- package/src/components/asset-viewers/EntityModelDocument.tsx +122 -0
- package/src/components/asset-viewers/EnvironmentAssetDocument.tsx +440 -0
- package/src/components/asset-viewers/GenericJsonViewer.tsx +102 -0
- package/src/components/asset-viewers/ImageViewer.tsx +300 -0
- package/src/components/asset-viewers/JsonAssetDocument.tsx +93 -0
- package/src/components/asset-viewers/LiveModuleDocument.tsx +417 -0
- package/src/components/asset-viewers/LutAssetDocument.tsx +444 -0
- package/src/components/asset-viewers/ModelAssetDocument.tsx +105 -0
- package/src/components/asset-viewers/Object3DPreview.tsx +359 -0
- package/src/components/asset-viewers/OnlineAssetDetail.tsx +421 -0
- package/src/components/asset-viewers/PasteboardModuleDocument.tsx +67 -0
- package/src/components/asset-viewers/QuarksAssetDocument.tsx +526 -0
- package/src/components/asset-viewers/ShaderAssetDocument.tsx +743 -0
- package/src/components/asset-viewers/SourceAssetViewer.tsx +281 -0
- package/src/components/asset-viewers/SpritesheetSpriteView.tsx +102 -0
- package/src/components/asset-viewers/VideoViewer.tsx +101 -0
- package/src/components/asset-viewers/shader-source.ts +144 -0
- package/src/components/asset-workflow.css +731 -0
- package/src/components/board-guides.ts +150 -0
- package/src/components/compact-inspector.css +539 -0
- package/src/components/core-utilities.tsx +90 -0
- package/src/components/editor-notifications.css +40 -0
- package/src/components/engine-workspace.css +274 -0
- package/src/components/inspector-preview-section.tsx +238 -0
- package/src/components/inspector-property-grouping.ts +64 -0
- package/src/components/inspector-revert-label.ts +20 -0
- package/src/components/inspector-selection.ts +42 -0
- package/src/components/inspector-stories-gating.ts +171 -0
- package/src/components/inspector-transform-subject.ts +11 -0
- package/src/components/inspector-transform.ts +75 -0
- package/src/components/kind-documents.tsx +500 -0
- package/src/components/palette-action-publisher.tsx +140 -0
- package/src/components/primitives/DraftColorInput.tsx +74 -0
- package/src/components/product-shell.css +1829 -0
- package/src/components/project-tool-documents.tsx +410 -0
- package/src/components/scene-documents.tsx +223 -0
- package/src/components/stage-keyboard.tsx +37 -0
- package/src/components/stage-overlay-set.tsx +107 -0
- package/src/components/stage-presence-markers.ts +478 -0
- package/src/components/standard-viewport-dressing.ts +417 -0
- package/src/components/status-contributions.tsx +403 -0
- package/src/components/tool-documents.tsx +309 -0
- package/src/components/tool-schema-form.tsx +262 -0
- package/src/components/use-after-paint.ts +41 -0
- package/src/components/use-project-image-assets.ts +86 -0
- package/src/components/viewport-header-controls.css +90 -0
- package/src/components/viewport-surface-status.tsx +55 -0
- package/src/components/workspace-history.ts +32 -0
- package/src/components/workspace-static-panel-registry.tsx +152 -0
- package/src/components/workspace-surfaces.css +621 -0
- package/src/components/world-documents.tsx +586 -0
- package/src/components/world-overlay-gestures.ts +1694 -0
- package/src/composite-screenshot.ts +1641 -0
- package/src/console-sync.ts +131 -0
- package/src/constraint-helper.ts +338 -0
- package/src/content-entry-source-registry.ts +184 -0
- package/src/coverage/authoring-seam-evidence.ts +300 -0
- package/src/coverage/canvas-reveal.ts +192 -0
- package/src/coverage/design-time-surfaces.ts +101 -0
- package/src/coverage/live-seam-evidence.ts +11 -0
- package/src/coverage/ontology-invariants.ts +466 -0
- package/src/coverage/session-vitals.ts +501 -0
- package/src/coverage/system-seam-evidence.ts +72 -0
- package/src/crash-null-boundary.ts +36 -0
- package/src/creation-site-edit.ts +1479 -0
- package/src/creation-site-registry.ts +160 -0
- package/src/delegate-harness-registry.ts +143 -0
- package/src/document-context-registry.ts +177 -0
- package/src/document-open-registry.ts +200 -0
- package/src/document-preview-source.ts +20 -0
- package/src/document-renderer-session.ts +138 -0
- package/src/editor-api.ts +46 -0
- package/src/editor-chrome-capture.ts +139 -0
- package/src/editor-commands.ts +164 -0
- package/src/editor-console.ts +563 -0
- package/src/editor-current-view.ts +82 -0
- package/src/editor-document-probe.ts +881 -0
- package/src/editor-git-client.ts +115 -0
- package/src/editor-host-door.ts +462 -0
- package/src/editor-hotkeys.ts +842 -0
- package/src/editor-lease-view.ts +39 -0
- package/src/editor-lease.ts +415 -0
- package/src/editor-mode.ts +19 -0
- package/src/editor-notifications.ts +140 -0
- package/src/editor-presence.ts +563 -0
- package/src/editor-presentation-activity.ts +50 -0
- package/src/editor-presentation-notice.ts +42 -0
- package/src/editor-runtime.tsx +145 -0
- package/src/editor-server-response.ts +86 -0
- package/src/editor-session-attribution.ts +75 -0
- package/src/editor-session-mode.ts +54 -0
- package/src/editor-shell-store.ts +1304 -0
- package/src/editor-state-facets.ts +74 -0
- package/src/editor-styles.css +33 -0
- package/src/editor-view-presentation.ts +810 -0
- package/src/editor-viewport.ts +5302 -0
- package/src/entity-lod.ts +31 -0
- package/src/entity-object.ts +91 -0
- package/src/files/file-provider.ts +62 -0
- package/src/files/project-files.ts +264 -0
- package/src/finders/index.ts +136 -0
- package/src/finders/scenes-from-entrypoint-selection.ts +387 -0
- package/src/frame/bridge.tsx +1408 -0
- package/src/frame/product.ts +77 -0
- package/src/gameplay-dom-recording.ts +319 -0
- package/src/gameplay-export-state.ts +14 -0
- package/src/gameplay-replay.ts +417 -0
- package/src/gameplay-session-time.ts +9 -0
- package/src/gameplay-sessions.ts +204 -0
- package/src/harness-chat-types.ts +253 -0
- package/src/hierarchy-component-marks.ts +298 -0
- package/src/hierarchy-drop.ts +91 -0
- package/src/hierarchy-expansion-state.ts +80 -0
- package/src/hierarchy-header-slot.ts +52 -0
- package/src/hierarchy-internals.ts +197 -0
- package/src/hierarchy-kind-icon.ts +217 -0
- package/src/hierarchy-mark-reader.ts +73 -0
- package/src/hierarchy-menu-registry.ts +67 -0
- package/src/hierarchy-node-rows.ts +307 -0
- package/src/hierarchy-panel-view.ts +280 -0
- package/src/hierarchy-projection.ts +76 -0
- package/src/hierarchy-row-cache.ts +243 -0
- package/src/hierarchy-row-model.ts +308 -0
- package/src/hierarchy-rows.ts +11 -0
- package/src/hierarchy-walk.ts +86 -0
- package/src/history/editor-session.ts +25 -0
- package/src/history/history-commands.ts +147 -0
- package/src/history/history-delegate.ts +163 -0
- package/src/history/history-limit-notices.ts +43 -0
- package/src/history/history-service.ts +1173 -0
- package/src/history/persistence-coordinator.ts +35 -0
- package/src/history/project-file-history.ts +386 -0
- package/src/history/project-root-history-backends.ts +139 -0
- package/src/history/resource-registry.ts +209 -0
- package/src/history/snapshot-store.ts +103 -0
- package/src/history/source-history-backend.ts +546 -0
- package/src/history/types.ts +124 -0
- package/src/hmr-registration-group.ts +67 -0
- package/src/hmr-stable-react-context.ts +23 -0
- package/src/hotkeys.ts +188 -0
- package/src/inference-diagnostics.ts +69 -0
- package/src/initial-project.ts +80 -0
- package/src/inspection/active-subject.ts +578 -0
- package/src/inspection/active-surface.ts +142 -0
- package/src/inspection/compose.ts +1064 -0
- package/src/inspection/display.ts +170 -0
- package/src/inspection/document-subject.ts +109 -0
- package/src/inspection/game-subject.ts +85 -0
- package/src/inspection/model.ts +542 -0
- package/src/inspection/null-subject.ts +115 -0
- package/src/inspection/serialize.ts +357 -0
- package/src/inspection/use-active-inspection.ts +180 -0
- package/src/inspector-presentation.ts +201 -0
- package/src/inspector-section-registry.ts +221 -0
- package/src/instance-source-actions.ts +163 -0
- package/src/instanced-presentation.ts +164 -0
- package/src/js-heap.ts +71 -0
- package/src/key-actions.ts +91 -0
- package/src/keymap-presets.ts +401 -0
- package/src/layout-policy.ts +31 -0
- package/src/learn-links.ts +73 -0
- package/src/light-explorer-model.ts +134 -0
- package/src/live-canvas-frame.ts +55 -0
- package/src/live-document.ts +279 -0
- package/src/live-module-source.ts +230 -0
- package/src/live-session-registry.ts +220 -0
- package/src/live-transition.ts +633 -0
- package/src/manifest-project.ts +107 -0
- package/src/model-thumbnail.ts +523 -0
- package/src/native-selection-style.ts +202 -0
- package/src/object3d-document-write-policy.ts +137 -0
- package/src/packaged-runtime.ts +108 -0
- package/src/palettes/maya.palette.json +57 -0
- package/src/palettes/substance.palette.json +57 -0
- package/src/pasteboard-module.ts +81 -0
- package/src/performance-profiler.ts +367 -0
- package/src/performance-sources.ts +69 -0
- package/src/play-boot-phase.ts +145 -0
- package/src/presentation-surface.ts +248 -0
- package/src/project-adapter.ts +1143 -0
- package/src/project-asset-refresh.ts +26 -0
- package/src/project-declaration-refresh.ts +31 -0
- package/src/project-local-state.ts +118 -0
- package/src/project-manager.ts +243 -0
- package/src/project-module-changes.ts +163 -0
- package/src/project-module-split.ts +266 -0
- package/src/project-provenance.ts +115 -0
- package/src/project-ready.ts +42 -0
- package/src/project-session-reset.ts +67 -0
- package/src/project-shape.ts +68 -0
- package/src/project-tool-discovery.ts +66 -0
- package/src/project-tools.ts +107 -0
- package/src/project-work-types.ts +149 -0
- package/src/projection/three.ts +898 -0
- package/src/projection/types.ts +44 -0
- package/src/readiness.ts +113 -0
- package/src/reflection-probe-helper.ts +142 -0
- package/src/reported-play-state.ts +90 -0
- package/src/resolve-relative-specifier.ts +33 -0
- package/src/scene-document-plan.ts +315 -0
- package/src/scene-framing.ts +315 -0
- package/src/scene-live-open.ts +210 -0
- package/src/scene-view-fog.ts +89 -0
- package/src/scoped-game-css.ts +152 -0
- package/src/session-orphan-record.ts +193 -0
- package/src/session-tombstone.ts +126 -0
- package/src/settings/settings-provider.ts +82 -0
- package/src/settings-store.ts +345 -0
- package/src/shared-view-restore.ts +42 -0
- package/src/shell-store-door.ts +45 -0
- package/src/source-conflict.ts +122 -0
- package/src/spatial-handle-visuals.ts +332 -0
- package/src/stage-context.ts +341 -0
- package/src/stage-store-registry.ts +63 -0
- package/src/stale-chunk-recovery.ts +34 -0
- package/src/state-report-deferral.ts +73 -0
- package/src/storage/host-files-storage.ts +97 -0
- package/src/storage/http-storage.ts +174 -0
- package/src/storage/index.ts +75 -0
- package/src/storage/mem-storage.ts +149 -0
- package/src/storage/path-lock.ts +44 -0
- package/src/storage/paths.ts +26 -0
- package/src/storage/types.ts +116 -0
- package/src/stories/StoryComponentThumbnail.tsx +184 -0
- package/src/stories/StoryPreviewMount.tsx +306 -0
- package/src/stories/component-content-source.tsx +106 -0
- package/src/stories/component-states-source.ts +78 -0
- package/src/stories/compose-project-stories.ts +255 -0
- package/src/stories/pixi-story-model.ts +30 -0
- package/src/stories/prefabs-finder.ts +54 -0
- package/src/stories/prefabs-from-stories.ts +182 -0
- package/src/stories/project-story-discovery.ts +78 -0
- package/src/stories/project-story-regions.ts +24 -0
- package/src/stories/story-actions.ts +54 -0
- package/src/stories/story-capture-command.ts +124 -0
- package/src/stories/story-capture.ts +584 -0
- package/src/stories/story-declared-medium.ts +126 -0
- package/src/stories/story-discovery.ts +176 -0
- package/src/stories/story-document-openers.ts +36 -0
- package/src/stories/story-dom-runtime.ts +78 -0
- package/src/stories/story-grouping.ts +111 -0
- package/src/stories/story-lane.ts +88 -0
- package/src/stories/story-mount-turn.ts +27 -0
- package/src/stories/story-opener.ts +260 -0
- package/src/stories/story-pixi-preview.ts +408 -0
- package/src/stories/story-presentation.ts +215 -0
- package/src/stories/story-registry.ts +517 -0
- package/src/stories/story-three-preview.ts +807 -0
- package/src/stories/three-story-model.ts +96 -0
- package/src/story-three-preview-runtime.ts +56 -0
- package/src/surface-keyboard.ts +112 -0
- package/src/surface-state.ts +124 -0
- package/src/tab-bootstrap.js +628 -0
- package/src/tab-census.ts +198 -0
- package/src/tab-lifecycle-client.ts +196 -0
- package/src/theme-library.ts +844 -0
- package/src/theme-preference.ts +378 -0
- package/src/theme.css +3437 -0
- package/src/three-viewport/bone-selection-highlight.ts +119 -0
- package/src/three-viewport/camera-fit.ts +41 -0
- package/src/three-viewport/interactive-renderer.ts +132 -0
- package/src/three-viewport/selection-brackets.ts +310 -0
- package/src/three-viewport/selection-outline.ts +183 -0
- package/src/three-viewport/skeleton-helper.ts +61 -0
- package/src/three-viewport/source-color.ts +167 -0
- package/src/three-viewport/studio-environment.ts +96 -0
- package/src/three-viewport-presentation.ts +23 -0
- package/src/tool-contribution-play.ts +74 -0
- package/src/tool-loader.ts +1798 -0
- package/src/transform-mode-request.ts +57 -0
- package/src/transient-hint.ts +78 -0
- package/src/trigger-volume-helper.ts +116 -0
- package/src/ui-source/adapter-region-includes.ts +241 -0
- package/src/ui-source/ensure-import.ts +132 -0
- package/src/ui-source/file-region-resolver.ts +302 -0
- package/src/ui-source/inspect.ts +775 -0
- package/src/ui-source/oid-transform.ts +1845 -0
- package/src/ui-source/plan-csf-story.ts +196 -0
- package/src/ui-source/plan-extract-component.ts +421 -0
- package/src/ui-source/plan-fork-component.ts +621 -0
- package/src/ui-source/plan-named-style.ts +95 -0
- package/src/ui-source/plan-source-edit.ts +353 -0
- package/src/ui-source/r3f-contract-resolver.ts +327 -0
- package/src/ui-source/r3f-diagnostic-index.ts +165 -0
- package/src/ui-source/r3f-environment-binding.ts +133 -0
- package/src/ui-source/r3f-joint-binding.ts +251 -0
- package/src/ui-source/r3f-lod-binding.ts +91 -0
- package/src/ui-source/r3f-particle-binding.ts +235 -0
- package/src/ui-source/r3f-physics-binding.ts +483 -0
- package/src/ui-source/r3f-project-contracts.ts +444 -0
- package/src/ui-source/relative-import-specifier.ts +34 -0
- package/src/ui-source/reparent-guard.ts +544 -0
- package/src/ui-source/source-edit-request.ts +97 -0
- package/src/ui-source/source-write-backend.ts +618 -0
- package/src/ui-source/syntactic-prop-specs.ts +296 -0
- package/src/ui-source/tier-source-write-backend.ts +279 -0
- package/src/ui-source/ts-ast.ts +171 -0
- package/src/ui-source/utility-class-support.ts +169 -0
- package/src/ui-source/write-component-default.ts +133 -0
- package/src/ui-source/writer.ts +1989 -0
- package/src/viewport-activation-timings.ts +840 -0
- package/src/viewport-authoring-policy.ts +186 -0
- package/src/viewport-controls-hint.ts +57 -0
- package/src/viewport-door.ts +237 -0
- package/src/viewport-shading-boundary.ts +12 -0
- package/src/vite-error-surface.ts +141 -0
- package/src/wait-until.ts +37 -0
- package/src/workspace-areas.ts +156 -0
- package/src/workspace-aux-commands.ts +11 -0
- package/src/workspace-available-documents.ts +127 -0
- package/src/workspace-core-utilities.ts +31 -0
- package/src/workspace-document-ids.ts +59 -0
- package/src/workspace-document-registry.ts +612 -0
- package/src/workspace-document-restore.ts +145 -0
- package/src/workspace-host-commands.ts +141 -0
- package/src/workspace-persistence-gate.ts +40 -0
- package/src/workspace-play-utilities.ts +44 -0
- package/src/workspace-presets.ts +425 -0
- package/src/workspace-regions.ts +294 -0
- package/src/workspace-state-persistence.ts +536 -0
- package/src/workspace-static-panels.ts +73 -0
- package/src/workspace-status-registry.ts +121 -0
- package/src/workspace-style.ts +239 -0
- package/src/workspace-utility-commands.ts +74 -0
- package/src/workspace-utility-registry.ts +263 -0
- package/src/workspace-viewport-rect.ts +97 -0
- package/src/world-adoption.ts +115 -0
- package/src/world-document-routing.ts +104 -0
- package/vite-plugin-creation-site-write.ts +184 -0
- package/vite-plugin-creation-site.ts +80 -0
- package/vite-plugin-game-static.ts +303 -0
- package/vite-plugin-module-doorways.ts +336 -0
- package/vite-plugin-product-contributions.ts +197 -0
- package/vite-plugin-project-game-static.ts +125 -0
- package/vite-plugin-project-jsx-js.ts +65 -0
- package/vite-plugin-project-root-absolute-assets.ts +359 -0
- package/vite-plugin-shared-react.ts +420 -0
- package/vite-plugin-shared-three.ts +203 -0
- package/vite-plugin-ui-oid.ts +2106 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WHAT A STAGE IS SHOWING — the ONE derived answer every stage capability asks.
|
|
3
|
+
*
|
|
4
|
+
* ARCHITECTURE-CORE §One stage: there is one 3D stage host, and a capability is
|
|
5
|
+
* present on a stage wherever its CONDITION holds — never by the origin or kind
|
|
6
|
+
* of the document that happens to have opened it. Before this, four gates spelled
|
|
7
|
+
* that question four ways in three places (`threeSurfaceToolsApply` for the shelf
|
|
8
|
+
* rail, `showThreejsTools` in the scene panel, `studioStage`/`hasShell` in the
|
|
9
|
+
* document host), which is why a prefab's stage and the world root's stage could
|
|
10
|
+
* not be the same code.
|
|
11
|
+
*
|
|
12
|
+
* It is a FUNCTION over the stores the panels already subscribe to, not a store
|
|
13
|
+
* of its own — the method transcribed from `inspection/active-surface.ts`, whose
|
|
14
|
+
* docblock states the rule: the surface is derived, never held. Callers keep
|
|
15
|
+
* their existing `useSyncExternalStore` subscriptions (shell store, active
|
|
16
|
+
* authoring, the session registry); this module only reads.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { stageTransformDoor } from '@volter/editor-sdk/contributions';
|
|
20
|
+
import { getActiveAuthoring } from './authoring/active-adapter';
|
|
21
|
+
import { CompositeAuthoringAdapter } from './authoring/composite-authoring-adapter';
|
|
22
|
+
import { object3DDocumentSession } from './authoring/object3d-document-session-registry';
|
|
23
|
+
import {
|
|
24
|
+
isViewportToolContextVisible,
|
|
25
|
+
resolveViewportToolContext,
|
|
26
|
+
} from './authoring/viewport-tool-context';
|
|
27
|
+
import { isThreejsSurfaceVisible } from './authoring/world-hidden-viewport';
|
|
28
|
+
import type { EditorShellStore } from './editor-shell-store';
|
|
29
|
+
import { stageStore } from './stage-store-registry';
|
|
30
|
+
import { activeWorkspaceDocumentId, openWorkspaceDocuments } from './workspace-document-registry';
|
|
31
|
+
|
|
32
|
+
export type StageSurface = 'three' | 'canvas' | 'dom';
|
|
33
|
+
|
|
34
|
+
/** What the stage's document IS — the document's own `presentation()` kind
|
|
35
|
+
* (`WorkspaceDocumentDescriptor.presentation`), folded to the subjects a
|
|
36
|
+
* stage distinguishes. `unknown` when the descriptor declares none. */
|
|
37
|
+
export type StageSubject =
|
|
38
|
+
| { readonly kind: 'composition' } // presentation 'scene' | 'world' (a scene, a manifest root)
|
|
39
|
+
| { readonly kind: 'story' } // 'story' — a piece in isolation with its parameters
|
|
40
|
+
| { readonly kind: 'artifact' } // 'asset' — an ecosystem artifact (glTF, particles, a model)
|
|
41
|
+
| { readonly kind: 'data' } // 'document' — an adapter-table document (a model, a page)
|
|
42
|
+
| { readonly kind: 'unknown' };
|
|
43
|
+
|
|
44
|
+
export interface StageSelection {
|
|
45
|
+
readonly count: number;
|
|
46
|
+
/** The surface that owns the whole selection; null when empty or mixed. */
|
|
47
|
+
readonly surface: StageSurface | null;
|
|
48
|
+
/** Whether that owner is painted on this stage (hidden roots are not). */
|
|
49
|
+
readonly visible: boolean;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Whether the stage has chrome of its own, or is EMBEDDED in another surface
|
|
54
|
+
* with none (the inspector's object preview). It is a genuine condition OF THE
|
|
55
|
+
* STAGE — the same kind of fact as `surface`, `selection` and `play` — never
|
|
56
|
+
* the origin or kind of a document; and the HOST is the only thing that knows
|
|
57
|
+
* it, because an embedded preview has no workspace document at all (which is
|
|
58
|
+
* exactly why `subjectOf` answers `unknown` for one). So the host supplies it
|
|
59
|
+
* and nothing is inferred (decided 2026-09-18, an application of
|
|
60
|
+
* ARCHITECTURE-CORE §One stage's own rule).
|
|
61
|
+
*/
|
|
62
|
+
export type StageChrome = 'document' | 'embedded';
|
|
63
|
+
|
|
64
|
+
export interface StageContext {
|
|
65
|
+
readonly documentId: string | null;
|
|
66
|
+
readonly chrome: StageChrome;
|
|
67
|
+
readonly subject: StageSubject;
|
|
68
|
+
/** The surface the stage paints; null when nothing is showing. */
|
|
69
|
+
readonly surface: StageSurface | null;
|
|
70
|
+
readonly selection: StageSelection;
|
|
71
|
+
readonly play: 'stopped' | 'playing' | 'paused';
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const EMPTY_SELECTION: StageSelection = { count: 0, surface: null, visible: false };
|
|
75
|
+
|
|
76
|
+
function stageSurfaceOf(kind: string | undefined): StageSurface | null {
|
|
77
|
+
return kind === 'three' || kind === 'canvas' || kind === 'dom' ? kind : null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function subjectFromKind(kind: string | undefined): StageSubject {
|
|
81
|
+
switch (kind) {
|
|
82
|
+
case 'scene':
|
|
83
|
+
case 'world':
|
|
84
|
+
return { kind: 'composition' };
|
|
85
|
+
case 'story':
|
|
86
|
+
return { kind: 'story' };
|
|
87
|
+
case 'asset':
|
|
88
|
+
return { kind: 'artifact' };
|
|
89
|
+
case 'document':
|
|
90
|
+
return { kind: 'data' };
|
|
91
|
+
default:
|
|
92
|
+
return { kind: 'unknown' };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function subjectOf(documentId: string | null): StageSubject {
|
|
97
|
+
if (documentId === null) return { kind: 'unknown' };
|
|
98
|
+
const open = openWorkspaceDocuments().find((doc) => doc.descriptor.id === documentId);
|
|
99
|
+
if (!open) return { kind: 'unknown' };
|
|
100
|
+
const presentation = open.descriptor.presentation?.() ?? null;
|
|
101
|
+
const projected = subjectFromKind(presentation?.kind);
|
|
102
|
+
if (projected.kind !== 'unknown') return projected;
|
|
103
|
+
// The document's own declared KIND is the fallback, and it is a real answer
|
|
104
|
+
// rather than a guess: `presentation()` is the ADDRESSABLE projection of a
|
|
105
|
+
// document, and a document can legitimately have none while still being an
|
|
106
|
+
// artifact — `asset-documents.tsx:258` returns null for an ONLINE asset and
|
|
107
|
+
// for one with no project path, and reading only the projection took the
|
|
108
|
+
// studio stage off exactly those (measured 2026-09-18, which is why the
|
|
109
|
+
// `documentKind` prop could not simply be deleted without this).
|
|
110
|
+
return subjectFromKind(open.descriptor.kind);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Whether this adapter PAINTS a three surface at all, selection or not — the
|
|
115
|
+
* no-selection branch of what `threeSurfaceToolsApply` asked before this module
|
|
116
|
+
* existed, transcribed verbatim. A composite paints three when some child does;
|
|
117
|
+
* a single adapter paints three when it is not rect-capable and can hand back an
|
|
118
|
+
* `Object3D` for a node.
|
|
119
|
+
*/
|
|
120
|
+
function adapterPaintsThree(adapter: ReturnType<typeof getActiveAuthoring>): boolean {
|
|
121
|
+
if (adapter instanceof CompositeAuthoringAdapter)
|
|
122
|
+
return adapter.childAdapters().some((child) => child.kind === 'three');
|
|
123
|
+
return !adapter.rects && typeof adapter.hierarchy.object3D === 'function';
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function worldStageContext(
|
|
127
|
+
store: EditorShellStore,
|
|
128
|
+
documentId: string | null,
|
|
129
|
+
subject: StageSubject,
|
|
130
|
+
chrome: StageChrome,
|
|
131
|
+
): StageContext {
|
|
132
|
+
const adapter = getActiveAuthoring(store);
|
|
133
|
+
const surface: StageSurface | null =
|
|
134
|
+
isThreejsSurfaceVisible(store) && adapterPaintsThree(adapter) ? 'three' : null;
|
|
135
|
+
const play = store.playState;
|
|
136
|
+
const count = store.selectedEntityIds.size;
|
|
137
|
+
if (count === 0)
|
|
138
|
+
return { documentId, chrome, subject, surface, selection: EMPTY_SELECTION, play };
|
|
139
|
+
const context = resolveViewportToolContext(adapter, store.selectedEntityIds);
|
|
140
|
+
return {
|
|
141
|
+
documentId,
|
|
142
|
+
chrome,
|
|
143
|
+
subject,
|
|
144
|
+
surface,
|
|
145
|
+
selection: {
|
|
146
|
+
count,
|
|
147
|
+
surface: stageSurfaceOf(context?.kind),
|
|
148
|
+
visible: isViewportToolContextVisible(store, context),
|
|
149
|
+
},
|
|
150
|
+
play,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* The stage a given document is showing.
|
|
156
|
+
*
|
|
157
|
+
* Two shapes answer this, and which one applies is a FACT about the document —
|
|
158
|
+
* not a kind it declares: a DOCUMENT stage has registered an
|
|
159
|
+
* `Object3DDocumentSession` (a model, a prefab story, an isolation scene) and
|
|
160
|
+
* its selection is its session's own; everything else is the WORLD stage — the
|
|
161
|
+
* manifest's roots under the shell store, whose selection is the shell's and
|
|
162
|
+
* whose surface is subject to the world-hidden eye.
|
|
163
|
+
*/
|
|
164
|
+
export function documentStageContext(
|
|
165
|
+
store: EditorShellStore,
|
|
166
|
+
documentId: string,
|
|
167
|
+
chrome: StageChrome = 'document',
|
|
168
|
+
): StageContext {
|
|
169
|
+
const subject = subjectOf(documentId);
|
|
170
|
+
const session = object3DDocumentSession(documentId);
|
|
171
|
+
if (session === null) return worldStageContext(store, documentId, subject, chrome);
|
|
172
|
+
// A document stage's own selection: the session reads it straight off its
|
|
173
|
+
// authoring adapter, and its stage is the only thing painting it, so an owner
|
|
174
|
+
// it reports is by construction three-owned and visible here.
|
|
175
|
+
const count = session.selection().length;
|
|
176
|
+
return {
|
|
177
|
+
documentId,
|
|
178
|
+
chrome,
|
|
179
|
+
subject,
|
|
180
|
+
surface: 'three',
|
|
181
|
+
selection: { count, surface: count > 0 ? 'three' : null, visible: true },
|
|
182
|
+
play: store.playState,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** The stage the FOCUSED document is showing; the world stage when no document
|
|
187
|
+
* is active (the shell with nothing focused still paints the world root). */
|
|
188
|
+
export function focusedStageContext(store: EditorShellStore): StageContext {
|
|
189
|
+
const documentId = activeWorkspaceDocumentId();
|
|
190
|
+
if (documentId !== null) return documentStageContext(store, documentId);
|
|
191
|
+
return worldStageContext(store, null, { kind: 'unknown' }, 'document');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* THE STORE THE FOCUSED STAGE RUNS ON — where a shared panel reads per-stage
|
|
196
|
+
* state (selection, scene/objectMap, camera pose, orbit target, tool state,
|
|
197
|
+
* view options like `showStats`/shading).
|
|
198
|
+
*
|
|
199
|
+
* `shell` is the answer for a focused document with no stage of its own — a
|
|
200
|
+
* tool tab, a text document, the Game tab. That is not a fallback in name
|
|
201
|
+
* only: the world root's stage runs on the session store (see
|
|
202
|
+
* `StageHost.tsx`'s world-root install), so a panel asked while focus sits
|
|
203
|
+
* off every stage keeps reporting the world, exactly as it did before §One
|
|
204
|
+
* stage unit 4.
|
|
205
|
+
*
|
|
206
|
+
* It is a FUNCTION, like the rest of this module: the caller keeps its own
|
|
207
|
+
* subscriptions, and a panel that reads this subscribes to
|
|
208
|
+
* `subscribeStageStores` and `subscribeWorkspaceDocuments` so a mount or a
|
|
209
|
+
* tab switch re-renders it against the new answer.
|
|
210
|
+
*/
|
|
211
|
+
export function focusedStageStore(shell: EditorShellStore): EditorShellStore {
|
|
212
|
+
return stageStore(activeWorkspaceDocumentId()) ?? shell;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** The host transform strip on a stage's shelf (Blender's persistent rail),
|
|
216
|
+
* where the editor viewport's own gizmo is what it drives. This is the
|
|
217
|
+
* `gizmo` arm of {@link stageTransformDriver} and nothing else asks it. */
|
|
218
|
+
export function transformToolsApply(ctx: StageContext): boolean {
|
|
219
|
+
if (ctx.surface !== 'three') return false;
|
|
220
|
+
if (ctx.selection.count === 0) return true;
|
|
221
|
+
return ctx.selection.surface === 'three' && ctx.selection.visible;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* WHAT THE HOST'S TRANSFORM TOOLS DRIVE ON THIS STAGE — one answer the shelf's
|
|
226
|
+
* strip and the header's transform wells both ask.
|
|
227
|
+
*
|
|
228
|
+
* `gizmo` `EditorViewport`'s `TransformControls`, through the stage's own
|
|
229
|
+
* `EditorShellStore.transformMode` (`stage-store-registry.ts` — NOT
|
|
230
|
+
* the shell's; see `ToolStrip`'s note for the measurement that
|
|
231
|
+
* separates them). The header's four wells configure that same gizmo,
|
|
232
|
+
* so they are drawn with it.
|
|
233
|
+
* `modal` the stage transforms MODALLY instead and declared how
|
|
234
|
+
* (`registerStageTransform`): a mesh module's `G`/`R`/`S`. The three
|
|
235
|
+
* single-channel tools arm it; the all-handles tool and the header
|
|
236
|
+
* wells are NOT DRAWN, because a modal transform is no gizmo and has
|
|
237
|
+
* nothing for a well to configure.
|
|
238
|
+
* `none` not a three stage, or the selection belongs to another surface —
|
|
239
|
+
* `transformToolsApply`'s own condition, unchanged.
|
|
240
|
+
*
|
|
241
|
+
* A DOCUMENT STAGE IS NOT AUTOMATICALLY THE MODAL CASE, and assuming it was is
|
|
242
|
+
* the error this docblock replaces: measured 2026-09-19 on a prefab story, a
|
|
243
|
+
* session-painted stage DOES draw the host's gizmo on its selection. Only a
|
|
244
|
+
* stage that declares a door takes the modal arm.
|
|
245
|
+
*/
|
|
246
|
+
export type StageTransformDriver = 'gizmo' | 'modal' | 'none';
|
|
247
|
+
|
|
248
|
+
export function stageTransformDriver(ctx: StageContext): StageTransformDriver {
|
|
249
|
+
if (!transformToolsApply(ctx)) return 'none';
|
|
250
|
+
return stageTransformDoor(ctx.documentId) === null ? 'gizmo' : 'modal';
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/** The three tools that need a selection (ViewportOverlay, CameraInfo). */
|
|
254
|
+
export function threeSelectionToolsApply(ctx: StageContext): boolean {
|
|
255
|
+
return (
|
|
256
|
+
ctx.surface === 'three' &&
|
|
257
|
+
ctx.selection.count > 0 &&
|
|
258
|
+
ctx.selection.surface === 'three' &&
|
|
259
|
+
ctx.selection.visible
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* THE ARTIFACT-FLAVOURED SUBJECT — a piece shown IN ISOLATION that is not the
|
|
265
|
+
* project's own live composition: an artifact (a glTF, a particle system, a
|
|
266
|
+
* model asset), a story (a prefab mounted with its parameters), or a stage
|
|
267
|
+
* EMBEDDED in another surface with no workspace document at all (the
|
|
268
|
+
* inspector's object preview, which is why nothing can infer this one and the
|
|
269
|
+
* host supplies `chrome`).
|
|
270
|
+
*
|
|
271
|
+
* This is the question `documentKind: 'source' | 'asset'` asked as a PROP the
|
|
272
|
+
* caller chose, and it is the base the two conditions below are written
|
|
273
|
+
* against, so they cannot drift apart: it drives the source adapter's
|
|
274
|
+
* `documentKind` (its "derived asset" provenance line and its `model-asset`
|
|
275
|
+
* hierarchy kind) and the `asset` performance-source kind.
|
|
276
|
+
*
|
|
277
|
+
* DATA is deliberately not here. A mesh module is the project's own CODE — it
|
|
278
|
+
* opens in an isolation scene (§A model is data) but nothing about it is a
|
|
279
|
+
* derived asset, and saying so is what the `documentKind` prop did by
|
|
280
|
+
* accident once the studio grew a data arm.
|
|
281
|
+
*/
|
|
282
|
+
export function assetSubjectApplies(ctx: StageContext): boolean {
|
|
283
|
+
return (
|
|
284
|
+
ctx.chrome === 'embedded' || ctx.subject.kind === 'story' || ctx.subject.kind === 'artifact'
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* THE STUDIO PRESENTATION — the alpha clear and the editor's own backdrop
|
|
290
|
+
* behind a piece in isolation.
|
|
291
|
+
*
|
|
292
|
+
* ARCHITECTURE-CORE §A model is data: "opening data opens an ISOLATION SCENE
|
|
293
|
+
* around it … whose story is the STUDIO". So the studio is every
|
|
294
|
+
* artifact-flavoured subject PLUS data — a mesh module, a page, anything the
|
|
295
|
+
* adapter's table calls a document.
|
|
296
|
+
*
|
|
297
|
+
* The one condition on the data arm is the LOOK, and it is a condition rather
|
|
298
|
+
* than a kind: the studio's backdrop is the EDITOR'S (the alpha canvas over the
|
|
299
|
+
* `.vgai-object3d-studio-stage` bloom), and a look that declares its own
|
|
300
|
+
* `color.viewport` group has already said what the 3D viewport is painted —
|
|
301
|
+
* Blender's flat #3f3f3f — so painting the studio over it would be the editor
|
|
302
|
+
* overruling the skew.
|
|
303
|
+
*
|
|
304
|
+
* `lookPaintsViewport` is that group's presence, and it is a PARAMETER rather
|
|
305
|
+
* than a read inside here for two reasons: this module is derived-never-held
|
|
306
|
+
* and the look is not one of the stores its callers already subscribe to (the
|
|
307
|
+
* host subscribes to the theme root itself, `StageHost.tsx`); and importing
|
|
308
|
+
* the renderer's token reader here put `native-selection-style.ts` into
|
|
309
|
+
* `main.tsx`'s pinned closure for a layout predicate, which is the erosion the
|
|
310
|
+
* closure gate exists to stop (measured 2026-09-18: +1 file on `main.tsx` and
|
|
311
|
+
* on both builds). `native-selection-style.ts`'s `lookDeclaresViewportColors`
|
|
312
|
+
* is the one reader of that token, so the stage and the renderer cannot
|
|
313
|
+
* disagree about what is on screen.
|
|
314
|
+
*/
|
|
315
|
+
export function studioStageApplies(ctx: StageContext, lookPaintsViewport: boolean): boolean {
|
|
316
|
+
if (assetSubjectApplies(ctx)) return true;
|
|
317
|
+
return ctx.subject.kind === 'data' && !lookPaintsViewport;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* THE IDENTITY-ROW FRAME — the Asset Lab shell around the stage: the row that
|
|
322
|
+
* names the thing, its type and its path, and the one registrar of the
|
|
323
|
+
* document's own workspace selection (the host registers it wherever this
|
|
324
|
+
* shell is absent, and exactly one of the two must).
|
|
325
|
+
*
|
|
326
|
+
* ARCHITECTURE-CORE §One stage: "the identity row when the subject is an
|
|
327
|
+
* ARTIFACT rather than source". It was the studio presentation's own answer
|
|
328
|
+
* until the studio gained a data arm, and it must not follow it there: a mesh
|
|
329
|
+
* module is the project's CODE, so an Asset-Lab row naming it a type and a
|
|
330
|
+
* file path, wrapped around the mesh editor's own header, would say the
|
|
331
|
+
* opposite of what the document is.
|
|
332
|
+
*
|
|
333
|
+
* An EMBEDDED stage never takes it — it has no chrome of its own by
|
|
334
|
+
* definition. Whether a STORY should keep it is the ruling's own open reading
|
|
335
|
+
* (a prefab's truth is source too); no frame of a story document has been
|
|
336
|
+
* read against that sentence, so this stays exactly what
|
|
337
|
+
* `assetSubjectApplies` says and nothing is re-decided blind.
|
|
338
|
+
*/
|
|
339
|
+
export function identityRowApplies(ctx: StageContext): boolean {
|
|
340
|
+
return ctx.chrome === 'document' && assetSubjectApplies(ctx);
|
|
341
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WHICH STORE A STAGE RUNS ON — the live identities behind
|
|
3
|
+
* `focusedStageStore()` (`stage-context.ts`).
|
|
4
|
+
*
|
|
5
|
+
* ARCHITECTURE-CORE §One stage: no stage is on "the" store by birthright.
|
|
6
|
+
* Every mounted stage owns an `EditorShellStore` holding its own per-stage
|
|
7
|
+
* state — selection, scene/objectMap, camera pose, orbit target, tool state
|
|
8
|
+
* and view options — and the shared panels read whichever one the FOCUSED
|
|
9
|
+
* document's stage runs on. Before this, only one stage's store was reachable
|
|
10
|
+
* (the shell's), so a control mounted over a model or a prefab drove a
|
|
11
|
+
* different stage's state: the grid button toggled the world's grid, and the
|
|
12
|
+
* camera readout reported a camera nobody was looking through.
|
|
13
|
+
*
|
|
14
|
+
* A registry of live identities, deliberately shaped like
|
|
15
|
+
* `authoring/object3d-document-session-registry.ts` — the same job for the
|
|
16
|
+
* same objects, and the reason it is not merged into that module is that a
|
|
17
|
+
* stage has a store BEFORE it has a session (the world root's stage has no
|
|
18
|
+
* `Object3DDocumentSession` at all, measured 2026-09-18). A leaf module with
|
|
19
|
+
* no imports beyond the store's type, so any lane may read it without an
|
|
20
|
+
* import cycle.
|
|
21
|
+
*/
|
|
22
|
+
import type { EditorShellStore } from './editor-shell-store';
|
|
23
|
+
|
|
24
|
+
const stores = new Map<string, { store: EditorShellStore }>();
|
|
25
|
+
let registryVersion = 0;
|
|
26
|
+
const listeners = new Set<() => void>();
|
|
27
|
+
|
|
28
|
+
function notify(): void {
|
|
29
|
+
registryVersion++;
|
|
30
|
+
for (const listener of [...listeners]) listener();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** A mounted stage declares the store it runs on. Re-registering the same
|
|
34
|
+
* document replaces it; the returned unregister drops it. */
|
|
35
|
+
export function registerStageStore(documentId: string, store: EditorShellStore): () => void {
|
|
36
|
+
const registration = { store };
|
|
37
|
+
stores.set(documentId, registration);
|
|
38
|
+
notify();
|
|
39
|
+
return () => {
|
|
40
|
+
if (stores.get(documentId) !== registration) return;
|
|
41
|
+
stores.delete(documentId);
|
|
42
|
+
notify();
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** The store that document's stage runs on, or `null` for a document with no
|
|
47
|
+
* stage of its own (a tool tab, a text document, the Game tab). */
|
|
48
|
+
export function stageStore(documentId: string | null): EditorShellStore | null {
|
|
49
|
+
return documentId === null ? null : (stores.get(documentId)?.store ?? null);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** `useSyncExternalStore` shape — a stage mounting or unmounting changes what
|
|
53
|
+
* `focusedStageStore()` answers, so a panel that reads it subscribes here. */
|
|
54
|
+
export function subscribeStageStores(listener: () => void): () => void {
|
|
55
|
+
listeners.add(listener);
|
|
56
|
+
return () => {
|
|
57
|
+
listeners.delete(listener);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function stageStoresVersion(): number {
|
|
62
|
+
return registryVersion;
|
|
63
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A LAZY CHUNK THAT NO LONGER EXISTS RELOADS THE PAGE ONCE.
|
|
3
|
+
*
|
|
4
|
+
* The hosted editor is deployed as hashed chunks and a promotion replaces
|
|
5
|
+
* every one of them: a tab that loaded the previous build keeps working until
|
|
6
|
+
* it lazily imports a chunk it has not touched yet — the first Play of a
|
|
7
|
+
* session, an Inspector preview — and gets a 404 for a hash the host no
|
|
8
|
+
* longer serves. Vite surfaces that as `vite:preloadError` on `window`, and
|
|
9
|
+
* the editor showed it as a crash whose Retry could never succeed ("Failed to
|
|
10
|
+
* fetch dynamically imported module … InspectorObjectPreview-…js", runhuman
|
|
11
|
+
* pass 146, a session that straddled a promotion). One ordinary reload picks
|
|
12
|
+
* up the current build; the guard keeps a genuinely broken host from looping.
|
|
13
|
+
*/
|
|
14
|
+
const RELOAD_GUARD_KEY = 'vgai:stale-chunk-reload';
|
|
15
|
+
|
|
16
|
+
export function installStaleChunkRecovery(): void {
|
|
17
|
+
if (typeof window === 'undefined') return;
|
|
18
|
+
window.addEventListener('vite:preloadError', (event) => {
|
|
19
|
+
let last = 0;
|
|
20
|
+
try {
|
|
21
|
+
last = Number(sessionStorage.getItem(RELOAD_GUARD_KEY) ?? 0);
|
|
22
|
+
} catch {
|
|
23
|
+
// storage unavailable — reload once regardless
|
|
24
|
+
}
|
|
25
|
+
if (Date.now() - last < 60_000) return; // already reloaded for this; let the crash surface show
|
|
26
|
+
try {
|
|
27
|
+
sessionStorage.setItem(RELOAD_GUARD_KEY, String(Date.now()));
|
|
28
|
+
} catch {
|
|
29
|
+
// storage unavailable
|
|
30
|
+
}
|
|
31
|
+
event.preventDefault();
|
|
32
|
+
window.location.reload();
|
|
33
|
+
});
|
|
34
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keeping the editor's status snapshot off the interaction critical path.
|
|
3
|
+
*
|
|
4
|
+
* `collectState` (command-listener.ts) is not a read — it RE-DERIVES the whole
|
|
5
|
+
* status surface. Two families dominate, and both scale with the size of the
|
|
6
|
+
* project rather than with the size of the change:
|
|
7
|
+
*
|
|
8
|
+
* - the hierarchy walk behind `entities`/`entityCount`, and
|
|
9
|
+
* - the capability GRADING facets (`rootCoverage`, `systemCoverage`,
|
|
10
|
+
* `projectCoverage`, `authoringCoverage`, `ontologyInvariants`), each
|
|
11
|
+
* documented as re-derived on read; `rootCoverage`'s conformance probe
|
|
12
|
+
* walks the hierarchy AGAIN, once per mounted root, allocating a receipt
|
|
13
|
+
* object and a formatted sentence per node.
|
|
14
|
+
*
|
|
15
|
+
* Measured 2026-08-19 through the session journal on `examples/first-person`
|
|
16
|
+
* in play mode, 251 hierarchy nodes:
|
|
17
|
+
*
|
|
18
|
+
* collectState total 76ms = rootCoverage 30ms
|
|
19
|
+
* + 2 x hierarchy walk 23ms
|
|
20
|
+
* JSON.stringify of the 41KB result: 0.0ms. Sending it: 0.1ms.
|
|
21
|
+
*
|
|
22
|
+
* So none of the cost is serialization or transport; all of it is derivation,
|
|
23
|
+
* and it is superlinear in node count (56 nodes: 1.5ms per walk; 251 nodes:
|
|
24
|
+
* 23ms). On a game-heavy project the same function measured 1.2-1.3s of
|
|
25
|
+
* main-thread block.
|
|
26
|
+
*
|
|
27
|
+
* That would be survivable if it ran rarely. It does not: `reportLatestState`
|
|
28
|
+
* is wired to the store's own change notification, to restart-required, to the
|
|
29
|
+
* ingest capture wait, to the adapter load, to every command completion, and
|
|
30
|
+
* to focus/blur/visibilitychange. So the whole derivation ran on every
|
|
31
|
+
* selection click and several times over during a mount — which is why the
|
|
32
|
+
* defect reads as "the editor is slow to touch" while an idle tab is fine.
|
|
33
|
+
*
|
|
34
|
+
* The fix is not to derive less truth, it is to derive it OFF the critical
|
|
35
|
+
* path: an interaction reports immediately with the cheap fields fresh and the
|
|
36
|
+
* derived families reused from the last full snapshot, and schedules ONE
|
|
37
|
+
* deferred full collect that makes them current again. `vgai status` readers
|
|
38
|
+
* are never handed a snapshot older than that deferral, and the snapshot
|
|
39
|
+
* already carries its own age.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* How long the deferred full collect may wait for an idle moment before the
|
|
44
|
+
* browser runs it anyway. Short enough that "current shortly after the change"
|
|
45
|
+
* stays true for a `vgai status` reader; long enough that the interaction that
|
|
46
|
+
* triggered it paints first, which is the entire point.
|
|
47
|
+
*/
|
|
48
|
+
export const DEFERRED_FULL_REPORT_TIMEOUT_MS = 500;
|
|
49
|
+
|
|
50
|
+
interface IdleCallbackHost {
|
|
51
|
+
requestIdleCallback?: (callback: () => void, options?: { timeout?: number }) => number;
|
|
52
|
+
cancelIdleCallback?: (handle: number) => void;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Run `report` off the critical path — at the next idle moment, or when
|
|
57
|
+
* {@link DEFERRED_FULL_REPORT_TIMEOUT_MS} expires, whichever comes first.
|
|
58
|
+
* Returns the canceller the caller's teardown must run.
|
|
59
|
+
*
|
|
60
|
+
* Falls back to a task (`setTimeout`) where `requestIdleCallback` is missing
|
|
61
|
+
* (Safari before 17, and jsdom): still off the triggering handler's own frame,
|
|
62
|
+
* which is what makes the interaction cheap.
|
|
63
|
+
*/
|
|
64
|
+
export function scheduleDeferredFullReport(report: () => void): () => void {
|
|
65
|
+
const host = globalThis as IdleCallbackHost;
|
|
66
|
+
const idle = host.requestIdleCallback;
|
|
67
|
+
if (typeof idle === 'function') {
|
|
68
|
+
const handle = idle.call(globalThis, report, { timeout: DEFERRED_FULL_REPORT_TIMEOUT_MS });
|
|
69
|
+
return () => host.cancelIdleCallback?.call(globalThis, handle);
|
|
70
|
+
}
|
|
71
|
+
const handle = setTimeout(report, 0);
|
|
72
|
+
return () => clearTimeout(handle);
|
|
73
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `StorageBackend`, answered by the WORKBENCH'S OWN FILE SERVICE (U5).
|
|
3
|
+
*
|
|
4
|
+
* ARCHITECTURE-CORE §The core is Code-OSS: *"the storage backends → file
|
|
5
|
+
* system providers, the dev server as one provider"*. What that turned out to
|
|
6
|
+
* mean, measured: both product shapes already have a real file service over
|
|
7
|
+
* the project folder (desktop's disk provider, the REH's `vscode-remote://`),
|
|
8
|
+
* so there is nothing to PROVIDE — the door CALLS what exists
|
|
9
|
+
* (`files/project-files.ts` states the decision and the reason).
|
|
10
|
+
*
|
|
11
|
+
* This class is how the existing `StorageBackend` callers — forty-odd of
|
|
12
|
+
* them, from the asset browser to the provenance ledger — reach that file
|
|
13
|
+
* service without one of them changing. It is a DECORATOR, not a fourth
|
|
14
|
+
* backend: it overrides exactly the three operations where "is this the
|
|
15
|
+
* workbench's own write?" is a question that has an answer (`read`,
|
|
16
|
+
* `readBytes`, `write`) and delegates everything else to the tier's real
|
|
17
|
+
* backend. `remove`, `mkdir`, `stat`, `list` and `watch` are the session's
|
|
18
|
+
* still, because the file door deliberately carries no remove/mkdir — a
|
|
19
|
+
* member nobody reads is cut, and nothing in the frame needs them yet.
|
|
20
|
+
*
|
|
21
|
+
* THE ROOT DIFFERENCE IS THE WHOLE JOB. `StorageBackend`'s paths on the server
|
|
22
|
+
* tier are rooted at `<project>/public/` (`http-storage.ts`'s header) while
|
|
23
|
+
* the file door's are PROJECT-RELATIVE, because that is the spelling the frame
|
|
24
|
+
* can resolve against its workspace folder. This class is the `public/` view:
|
|
25
|
+
* one prefix, in one place, instead of forty callers learning a second
|
|
26
|
+
* spelling.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import { projectFiles } from '../files/project-files';
|
|
30
|
+
import type { DirEntry, Stat, StorageBackend, WatchCallback } from './types';
|
|
31
|
+
|
|
32
|
+
export class HostFilesStorage implements StorageBackend {
|
|
33
|
+
readonly id: string;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @param inner the tier's own backend, which still owns every operation the
|
|
37
|
+
* file door does not carry — and which is also the FALLBACK while the
|
|
38
|
+
* frame has taken ownership but not yet installed its provider (the mount
|
|
39
|
+
* window `files/file-provider.ts` describes).
|
|
40
|
+
* @param root the project-relative prefix these paths live under. Always
|
|
41
|
+
* `public` today; named rather than hardcoded so the prefix is visible at
|
|
42
|
+
* the call site that chose it.
|
|
43
|
+
*/
|
|
44
|
+
constructor(
|
|
45
|
+
private readonly inner: StorageBackend,
|
|
46
|
+
private readonly root = 'public',
|
|
47
|
+
) {
|
|
48
|
+
this.id = `frame:${inner.id}`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private resolve(path: string): string {
|
|
52
|
+
const key = path.replace(/\\/g, '/').replace(/^\/+/, '');
|
|
53
|
+
return key ? `${this.root}/${key}` : this.root;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
read(path: string): Promise<string> {
|
|
57
|
+
return projectFiles.read(this.resolve(path));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
readBytes(path: string): Promise<Uint8Array> {
|
|
61
|
+
return projectFiles.readBytes(this.resolve(path));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
write(path: string, data: string | Uint8Array): Promise<void> {
|
|
65
|
+
return projectFiles.write(this.resolve(path), data);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async writeIfAbsent(path: string, data: string | Uint8Array): Promise<boolean> {
|
|
69
|
+
if (await this.exists(path)) return false;
|
|
70
|
+
await this.write(path, data);
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
list(dir: string): Promise<DirEntry[]> {
|
|
75
|
+
return this.inner.list(dir);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
stat(path: string): Promise<Stat | null> {
|
|
79
|
+
return this.inner.stat(path);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
exists(path: string): Promise<boolean> {
|
|
83
|
+
return projectFiles.exists(this.resolve(path));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
mkdir(path: string): Promise<void> {
|
|
87
|
+
return this.inner.mkdir(path);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
remove(path: string): Promise<void> {
|
|
91
|
+
return this.inner.remove(path);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
watch(callback: WatchCallback): () => void {
|
|
95
|
+
return this.inner.watch(callback);
|
|
96
|
+
}
|
|
97
|
+
}
|