@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,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pixi's native spritesheet sidecar — TexturePacker hash/array JSON, the
|
|
3
|
+
* same document AssetPack writes as `image.png.json`. The game loads THAT
|
|
4
|
+
* file (`Assets.load('images/game-screen.png.json')`); the PNG is the atlas
|
|
5
|
+
* page, not the authored unit.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export interface PixiSpritesheetFrame {
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly x: number;
|
|
11
|
+
readonly y: number;
|
|
12
|
+
readonly width: number;
|
|
13
|
+
readonly height: number;
|
|
14
|
+
readonly rotated: boolean;
|
|
15
|
+
/** Untrimmed sprite canvas — Unity/Aseprite's document size. */
|
|
16
|
+
readonly sourceWidth: number;
|
|
17
|
+
readonly sourceHeight: number;
|
|
18
|
+
/** Where the packed pixels sit inside that canvas. */
|
|
19
|
+
readonly trimX: number;
|
|
20
|
+
readonly trimY: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface PixiSpritesheet {
|
|
24
|
+
readonly image: string;
|
|
25
|
+
readonly frames: readonly PixiSpritesheetFrame[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function spritesheetResolutionRank(name: string): number {
|
|
29
|
+
if (/@[0-9.]+x\./i.test(name)) return 1;
|
|
30
|
+
if (/\.webp\.json$/i.test(name)) return 2;
|
|
31
|
+
if (/\.png\.json$/i.test(name)) return 3;
|
|
32
|
+
return 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function spritesheetFamilyKey(path: string): string {
|
|
36
|
+
const slash = path.lastIndexOf('/');
|
|
37
|
+
const dir = slash < 0 ? '' : path.slice(0, slash);
|
|
38
|
+
const file = slash < 0 ? path : path.slice(slash + 1);
|
|
39
|
+
const stem = file
|
|
40
|
+
.replace(/@[0-9.]+x/i, '')
|
|
41
|
+
.replace(/\.(png|webp|jpe?g)\.json$/i, '')
|
|
42
|
+
.replace(/\.json$/i, '');
|
|
43
|
+
return dir ? `${dir}/${stem}` : stem;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function parsePixiSpritesheet(source: string): PixiSpritesheet | null {
|
|
47
|
+
let parsed: unknown;
|
|
48
|
+
try {
|
|
49
|
+
parsed = JSON.parse(source);
|
|
50
|
+
} catch {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
if (!parsed || typeof parsed !== 'object') return null;
|
|
54
|
+
const record = parsed as {
|
|
55
|
+
frames?: unknown;
|
|
56
|
+
meta?: { image?: unknown };
|
|
57
|
+
};
|
|
58
|
+
const image = typeof record.meta?.image === 'string' ? fileName(record.meta.image) : '';
|
|
59
|
+
const frames = readFrames(record.frames);
|
|
60
|
+
if (!image || frames.length === 0) return null;
|
|
61
|
+
return { image, frames };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Content/open path: `assets/images/game-screen.png#satellite`. */
|
|
65
|
+
export function splitSpritesheetAssetPath(path: string): {
|
|
66
|
+
readonly sheetPath: string;
|
|
67
|
+
readonly frameName: string | null;
|
|
68
|
+
} {
|
|
69
|
+
const trimmed = path.replace(/^\//, '');
|
|
70
|
+
const hash = trimmed.lastIndexOf('#');
|
|
71
|
+
if (hash < 0) return { sheetPath: trimmed, frameName: null };
|
|
72
|
+
return { sheetPath: trimmed.slice(0, hash), frameName: trimmed.slice(hash + 1) || null };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Tab title: the frame name, never `game-screen.png#satellite`. */
|
|
76
|
+
export function spritesheetFrameTitle(path: string): string {
|
|
77
|
+
const { sheetPath, frameName } = splitSpritesheetAssetPath(path);
|
|
78
|
+
return frameName ?? sheetPath.split('/').pop() ?? path;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function sidecarPathForSheet(sheetPath: string): string {
|
|
82
|
+
return `${sheetPath.replace(/^\//, '')}.json`;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function sheetVariantsFor(image: string): readonly string[] {
|
|
86
|
+
const ext = image.match(/\.[a-z0-9]+$/i)?.[0] ?? '';
|
|
87
|
+
const stem = image.slice(0, image.length - ext.length);
|
|
88
|
+
return [
|
|
89
|
+
image,
|
|
90
|
+
`${stem}.png`,
|
|
91
|
+
`${stem}.webp`,
|
|
92
|
+
`${stem}.jpg`,
|
|
93
|
+
`${stem}@0.5x${ext}`,
|
|
94
|
+
`${stem}@0.5x.png`,
|
|
95
|
+
`${stem}@0.5x.webp`,
|
|
96
|
+
`${stem}@2x${ext}`,
|
|
97
|
+
`${stem}@2x.png`,
|
|
98
|
+
`${stem}@2x.webp`,
|
|
99
|
+
];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function readFrames(frames: unknown): PixiSpritesheetFrame[] {
|
|
103
|
+
if (!frames || typeof frames !== 'object') return [];
|
|
104
|
+
if (Array.isArray(frames)) {
|
|
105
|
+
return frames.flatMap((entry) => {
|
|
106
|
+
if (!entry || typeof entry !== 'object') return [];
|
|
107
|
+
const row = entry as FrameRecord;
|
|
108
|
+
const name = typeof row.filename === 'string' ? row.filename : '';
|
|
109
|
+
const parsed = readFrame(row);
|
|
110
|
+
if (!name || !parsed) return [];
|
|
111
|
+
return [{ name: stripFrameExt(name), ...parsed }];
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
return Object.entries(frames as Record<string, unknown>).flatMap(([name, entry]) => {
|
|
115
|
+
if (!entry || typeof entry !== 'object') return [];
|
|
116
|
+
const parsed = readFrame(entry as FrameRecord);
|
|
117
|
+
if (!parsed) return [];
|
|
118
|
+
return [{ name: stripFrameExt(name), ...parsed }];
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
interface FrameRecord {
|
|
123
|
+
filename?: unknown;
|
|
124
|
+
frame?: unknown;
|
|
125
|
+
rotated?: unknown;
|
|
126
|
+
sourceSize?: unknown;
|
|
127
|
+
spriteSourceSize?: unknown;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function readFrame(row: FrameRecord): Omit<PixiSpritesheetFrame, 'name'> | null {
|
|
131
|
+
const box = readBox(row.frame);
|
|
132
|
+
if (!box) return null;
|
|
133
|
+
const source = readSize(row.sourceSize) ?? { width: box.width, height: box.height };
|
|
134
|
+
const trim = readPoint(row.spriteSourceSize);
|
|
135
|
+
return {
|
|
136
|
+
...box,
|
|
137
|
+
rotated: row.rotated === true,
|
|
138
|
+
sourceWidth: source.width,
|
|
139
|
+
sourceHeight: source.height,
|
|
140
|
+
trimX: trim?.x ?? 0,
|
|
141
|
+
trimY: trim?.y ?? 0,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function readBox(frame: unknown): { x: number; y: number; width: number; height: number } | null {
|
|
146
|
+
if (!frame || typeof frame !== 'object') return null;
|
|
147
|
+
const box = frame as { x?: unknown; y?: unknown; w?: unknown; h?: unknown };
|
|
148
|
+
if (
|
|
149
|
+
typeof box.x !== 'number' ||
|
|
150
|
+
typeof box.y !== 'number' ||
|
|
151
|
+
typeof box.w !== 'number' ||
|
|
152
|
+
typeof box.h !== 'number'
|
|
153
|
+
) {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
return { x: box.x, y: box.y, width: box.w, height: box.h };
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function readSize(value: unknown): { width: number; height: number } | null {
|
|
160
|
+
if (!value || typeof value !== 'object') return null;
|
|
161
|
+
const size = value as { w?: unknown; h?: unknown };
|
|
162
|
+
if (typeof size.w !== 'number' || typeof size.h !== 'number') return null;
|
|
163
|
+
return { width: size.w, height: size.h };
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function readPoint(value: unknown): { x: number; y: number } | null {
|
|
167
|
+
if (!value || typeof value !== 'object') return null;
|
|
168
|
+
const point = value as { x?: unknown; y?: unknown };
|
|
169
|
+
if (typeof point.x !== 'number' || typeof point.y !== 'number') return null;
|
|
170
|
+
return { x: point.x, y: point.y };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Packed rect Pixi samples. A rotated TexturePacker frame stores the
|
|
175
|
+
* unrotated size in `frame` and occupies the swapped rect on the page.
|
|
176
|
+
*/
|
|
177
|
+
export function packedFrameRect(
|
|
178
|
+
frame: Pick<PixiSpritesheetFrame, 'x' | 'y' | 'width' | 'height' | 'rotated'>,
|
|
179
|
+
): {
|
|
180
|
+
x: number;
|
|
181
|
+
y: number;
|
|
182
|
+
width: number;
|
|
183
|
+
height: number;
|
|
184
|
+
} {
|
|
185
|
+
return frame.rotated
|
|
186
|
+
? { x: frame.x, y: frame.y, width: frame.height, height: frame.width }
|
|
187
|
+
: { x: frame.x, y: frame.y, width: frame.width, height: frame.height };
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function fileName(path: string): string {
|
|
191
|
+
const slash = path.lastIndexOf('/');
|
|
192
|
+
return slash < 0 ? path : path.slice(slash + 1);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function stripFrameExt(name: string): string {
|
|
196
|
+
return name.replace(/\.(png|webp|jpe?g)$/i, '');
|
|
197
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export type PreviewResourceKind =
|
|
2
|
+
| 'webglContext'
|
|
3
|
+
| 'animationFrame'
|
|
4
|
+
| 'resizeObserver'
|
|
5
|
+
| 'objectUrl';
|
|
6
|
+
|
|
7
|
+
export interface PreviewResourceSnapshot {
|
|
8
|
+
webglContext: number;
|
|
9
|
+
animationFrame: number;
|
|
10
|
+
resizeObserver: number;
|
|
11
|
+
objectUrl: number;
|
|
12
|
+
peaks: Record<PreviewResourceKind, number>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const current: Record<PreviewResourceKind, number> = {
|
|
16
|
+
webglContext: 0,
|
|
17
|
+
animationFrame: 0,
|
|
18
|
+
resizeObserver: 0,
|
|
19
|
+
objectUrl: 0,
|
|
20
|
+
};
|
|
21
|
+
const peaks = { ...current };
|
|
22
|
+
|
|
23
|
+
/** Local diagnostic counter used by stress tests and the Debugger; never uploads identifiers. */
|
|
24
|
+
export function registerPreviewResource(kind: PreviewResourceKind): () => void {
|
|
25
|
+
current[kind]++;
|
|
26
|
+
peaks[kind] = Math.max(peaks[kind], current[kind]);
|
|
27
|
+
let released = false;
|
|
28
|
+
return () => {
|
|
29
|
+
if (released) return;
|
|
30
|
+
released = true;
|
|
31
|
+
current[kind] = Math.max(0, current[kind] - 1);
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function previewResourceSnapshot(): PreviewResourceSnapshot {
|
|
36
|
+
return { ...current, peaks: { ...peaks } };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function resetPreviewResourceCounters(): void {
|
|
40
|
+
for (const key of Object.keys(current) as PreviewResourceKind[]) {
|
|
41
|
+
current[key] = 0;
|
|
42
|
+
peaks[key] = 0;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const PROJECT_ASSET_COMMANDS = {
|
|
2
|
+
open: { id: 'project-asset.open', shortcut: 'Enter' },
|
|
3
|
+
rename: { id: 'project-asset.rename', shortcut: 'F2' },
|
|
4
|
+
move: { id: 'project-asset.move', shortcut: null },
|
|
5
|
+
duplicate: { id: 'project-asset.duplicate', shortcut: 'Mod+D' },
|
|
6
|
+
delete: { id: 'project-asset.delete', shortcut: 'Delete' },
|
|
7
|
+
copyPath: { id: 'project-asset.copy-path', shortcut: 'Mod+Shift+C' },
|
|
8
|
+
reveal: { id: 'project-asset.reveal', shortcut: null },
|
|
9
|
+
refresh: { id: 'project-asset.refresh', shortcut: 'Mod+R' },
|
|
10
|
+
import: { id: 'project-asset.import', shortcut: null },
|
|
11
|
+
createFolder: { id: 'project-asset.create-folder', shortcut: 'Mod+Shift+N' },
|
|
12
|
+
} as const;
|
|
13
|
+
|
|
14
|
+
export type ProjectAssetCommandId =
|
|
15
|
+
(typeof PROJECT_ASSET_COMMANDS)[keyof typeof PROJECT_ASSET_COMMANDS]['id'];
|
|
16
|
+
|
|
17
|
+
export function projectAssetCommandIds(): readonly ProjectAssetCommandId[] {
|
|
18
|
+
return Object.values(PROJECT_ASSET_COMMANDS).map((command) => command.id);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function projectContentBrowserStateKey(projectId: string): string {
|
|
22
|
+
return `vgai:project-content:v1:${projectId}`;
|
|
23
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import type { StorageBackend } from '../storage/types';
|
|
2
|
+
import { assetCapabilities } from './asset-capabilities';
|
|
3
|
+
import type { AssetHealth, AssetHealthCode } from './asset-types';
|
|
4
|
+
|
|
5
|
+
export interface ProjectAssetFileSnapshot {
|
|
6
|
+
readonly path: string;
|
|
7
|
+
readonly text?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ProjectAssetReference {
|
|
11
|
+
readonly ownerPath: string;
|
|
12
|
+
readonly jsonPath: string;
|
|
13
|
+
readonly assetPath: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ProjectAssetHealthResult {
|
|
17
|
+
readonly health: AssetHealth;
|
|
18
|
+
readonly dependencies: readonly string[];
|
|
19
|
+
readonly references: readonly ProjectAssetReference[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function collectStringPaths(value: unknown, path = '$'): { path: string; value: string }[] {
|
|
23
|
+
if (typeof value === 'string') return [{ path, value }];
|
|
24
|
+
if (Array.isArray(value)) {
|
|
25
|
+
return value.flatMap((entry, index) => collectStringPaths(entry, `${path}[${index}]`));
|
|
26
|
+
}
|
|
27
|
+
if (!value || typeof value !== 'object') return [];
|
|
28
|
+
return Object.entries(value).flatMap(([key, entry]) =>
|
|
29
|
+
collectStringPaths(entry, `${path}.${key}`),
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function externalDependencies(assetPath: string, text: string | undefined): string[] {
|
|
34
|
+
if (!text || !assetPath.toLowerCase().endsWith('.gltf')) return [];
|
|
35
|
+
try {
|
|
36
|
+
const json = JSON.parse(text) as { buffers?: { uri?: string }[]; images?: { uri?: string }[] };
|
|
37
|
+
const base = assetPath.includes('/') ? assetPath.slice(0, assetPath.lastIndexOf('/') + 1) : '';
|
|
38
|
+
return [...(json.buffers ?? []), ...(json.images ?? [])].flatMap((entry) =>
|
|
39
|
+
entry.uri && !entry.uri.startsWith('data:') ? [`${base}${entry.uri}`] : [],
|
|
40
|
+
);
|
|
41
|
+
} catch {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function inspectProjectAssetHealth(input: {
|
|
47
|
+
readonly assetPath: string;
|
|
48
|
+
readonly files: readonly ProjectAssetFileSnapshot[];
|
|
49
|
+
}): ProjectAssetHealthResult {
|
|
50
|
+
const byPath = new Map(input.files.map((file) => [file.path.replace(/^\//, ''), file]));
|
|
51
|
+
const assetPath = input.assetPath.replace(/^\//, '');
|
|
52
|
+
const asset = byPath.get(assetPath);
|
|
53
|
+
const codes = new Set<AssetHealthCode>();
|
|
54
|
+
const capability = assetCapabilities(assetPath);
|
|
55
|
+
if (!asset) codes.add('missing-file');
|
|
56
|
+
if (!capability.importable) codes.add('unsupported-format');
|
|
57
|
+
else if (!capability.runtimeReady) codes.add('source-only');
|
|
58
|
+
|
|
59
|
+
if (asset?.text && capability.kind === 'json') {
|
|
60
|
+
try {
|
|
61
|
+
JSON.parse(asset.text);
|
|
62
|
+
} catch {
|
|
63
|
+
codes.add('invalid-metadata');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const dependencies = externalDependencies(assetPath, asset?.text);
|
|
68
|
+
if (dependencies.some((path) => !byPath.has(path))) codes.add('missing-dependency');
|
|
69
|
+
// Catalog attribution is project-authoring state in .vgai/provenance.json,
|
|
70
|
+
// outside this public/-rooted storage snapshot. Do not infer it is missing
|
|
71
|
+
// from the deliberate absence of a legacy per-directory sidecar.
|
|
72
|
+
|
|
73
|
+
const references: ProjectAssetReference[] = [];
|
|
74
|
+
for (const file of input.files) {
|
|
75
|
+
// JSON is a common structured container, not a vgai material dialect.
|
|
76
|
+
// Walk any JSON document supplied by the project snapshot and report the
|
|
77
|
+
// exact path of a matching asset reference.
|
|
78
|
+
if (!file.text || !/\.json$/i.test(file.path)) continue;
|
|
79
|
+
try {
|
|
80
|
+
for (const candidate of collectStringPaths(JSON.parse(file.text))) {
|
|
81
|
+
const normalized = candidate.value.replace(/^\//, '');
|
|
82
|
+
if (normalized === assetPath) {
|
|
83
|
+
references.push({ ownerPath: file.path, jsonPath: candidate.path, assetPath });
|
|
84
|
+
} else if (normalized.startsWith('assets/') && !byPath.has(normalized)) {
|
|
85
|
+
codes.add('broken-asset-reference');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
} catch {}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (codes.size === 0) codes.add('healthy');
|
|
92
|
+
const errorCodes = new Set<AssetHealthCode>([
|
|
93
|
+
'missing-file',
|
|
94
|
+
'missing-dependency',
|
|
95
|
+
'invalid-metadata',
|
|
96
|
+
'broken-asset-reference',
|
|
97
|
+
]);
|
|
98
|
+
return {
|
|
99
|
+
health: {
|
|
100
|
+
status: [...codes].some((code) => errorCodes.has(code))
|
|
101
|
+
? 'error'
|
|
102
|
+
: codes.has('healthy')
|
|
103
|
+
? 'healthy'
|
|
104
|
+
: 'warning',
|
|
105
|
+
codes: [...codes],
|
|
106
|
+
},
|
|
107
|
+
dependencies,
|
|
108
|
+
references,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async function snapshotProjectFiles(
|
|
113
|
+
backend: StorageBackend,
|
|
114
|
+
dir = '',
|
|
115
|
+
): Promise<ProjectAssetFileSnapshot[]> {
|
|
116
|
+
const entries = await backend.list(dir);
|
|
117
|
+
const snapshots: ProjectAssetFileSnapshot[] = [];
|
|
118
|
+
for (const entry of entries) {
|
|
119
|
+
const path = dir ? `${dir}/${entry.name}` : entry.name;
|
|
120
|
+
if (entry.type === 'dir') {
|
|
121
|
+
snapshots.push(...(await snapshotProjectFiles(backend, path)));
|
|
122
|
+
} else if (/\.json$|\.gltf$/i.test(path)) {
|
|
123
|
+
snapshots.push({ path, text: await backend.read(path) });
|
|
124
|
+
} else {
|
|
125
|
+
snapshots.push({ path });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return snapshots;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export async function inspectProjectAssetHealthFromStorage(
|
|
132
|
+
backend: StorageBackend,
|
|
133
|
+
assetPath: string,
|
|
134
|
+
): Promise<ProjectAssetHealthResult> {
|
|
135
|
+
return inspectProjectAssetHealth({
|
|
136
|
+
assetPath,
|
|
137
|
+
files: await snapshotProjectFiles(backend),
|
|
138
|
+
});
|
|
139
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import type { HistoryService } from '../history/history-service';
|
|
2
|
+
import { getProjectFileHistory } from '../history/project-file-history';
|
|
3
|
+
import type { StorageBackend } from '../storage/types';
|
|
4
|
+
|
|
5
|
+
export type ProjectAssetOperation =
|
|
6
|
+
| { readonly type: 'create-folder'; readonly path: string }
|
|
7
|
+
| { readonly type: 'duplicate'; readonly source: string; readonly destination: string }
|
|
8
|
+
| { readonly type: 'move'; readonly source: string; readonly destination: string }
|
|
9
|
+
| {
|
|
10
|
+
readonly type: 'move-many';
|
|
11
|
+
readonly moves: readonly { readonly source: string; readonly destination: string }[];
|
|
12
|
+
}
|
|
13
|
+
| { readonly type: 'delete'; readonly paths: readonly string[] }
|
|
14
|
+
| { readonly type: 'import'; readonly files: readonly { path: string; bytes: Uint8Array }[] };
|
|
15
|
+
|
|
16
|
+
/** Announce a project asset write. Every consumer of `editor:assets-changed`
|
|
17
|
+
* keys off this — the panel listing, and the public-asset blob bridge that
|
|
18
|
+
* makes a newly written file loadable by its own URL. Exported because
|
|
19
|
+
* writes also happen OUTSIDE the operation union (the browser asset
|
|
20
|
+
* library's own download path). */
|
|
21
|
+
export function emitAssetMutation(detail: {
|
|
22
|
+
type: 'move' | 'delete' | 'change';
|
|
23
|
+
oldPath?: string;
|
|
24
|
+
newPath?: string;
|
|
25
|
+
paths?: readonly string[];
|
|
26
|
+
}): void {
|
|
27
|
+
if (typeof window === 'undefined') return;
|
|
28
|
+
window.dispatchEvent(new CustomEvent('editor:asset-mutation', { detail }));
|
|
29
|
+
window.dispatchEvent(new CustomEvent('editor:assets-changed'));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function validPath(path: string): string {
|
|
33
|
+
const normalized = path
|
|
34
|
+
.replace(/^\/+/, '')
|
|
35
|
+
.replace(/\\/g, '/')
|
|
36
|
+
.replace(/\/{2,}/g, '/');
|
|
37
|
+
if (
|
|
38
|
+
!normalized ||
|
|
39
|
+
normalized === '.' ||
|
|
40
|
+
normalized.split('/').some((part) => !part || part === '..')
|
|
41
|
+
) {
|
|
42
|
+
throw new Error(`Invalid project asset path: ${path}`);
|
|
43
|
+
}
|
|
44
|
+
return normalized;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function assertDestinationsFree(backend: StorageBackend, paths: readonly string[]) {
|
|
48
|
+
for (const path of paths) {
|
|
49
|
+
if (await backend.exists(path)) throw new Error(`An asset already exists at ${path}.`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Executes all writes through exact-byte project history; no UI owns filesystem mutation. */
|
|
54
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: the tagged operation union is intentionally centralized so every project mutation shares one atomic history boundary.
|
|
55
|
+
export async function executeProjectAssetOperation(
|
|
56
|
+
operation: ProjectAssetOperation,
|
|
57
|
+
dependencies: { readonly backend: StorageBackend; readonly history: HistoryService },
|
|
58
|
+
): Promise<boolean> {
|
|
59
|
+
const files = getProjectFileHistory(dependencies.history, dependencies.backend);
|
|
60
|
+
switch (operation.type) {
|
|
61
|
+
case 'create-folder': {
|
|
62
|
+
const folder = validPath(operation.path);
|
|
63
|
+
const marker = `${folder}/.vgai-folder`;
|
|
64
|
+
if (await dependencies.backend.exists(folder))
|
|
65
|
+
throw new Error(`Folder already exists: ${folder}.`);
|
|
66
|
+
return files.write(marker, '', { label: `Create folder ${folder}` });
|
|
67
|
+
}
|
|
68
|
+
case 'duplicate': {
|
|
69
|
+
const source = validPath(operation.source);
|
|
70
|
+
const destination = validPath(operation.destination);
|
|
71
|
+
await assertDestinationsFree(dependencies.backend, [destination]);
|
|
72
|
+
const bytes = await dependencies.backend.readBytes(source);
|
|
73
|
+
return files.write(destination, bytes, { label: `Duplicate ${source}` });
|
|
74
|
+
}
|
|
75
|
+
case 'move': {
|
|
76
|
+
const source = validPath(operation.source);
|
|
77
|
+
const destination = validPath(operation.destination);
|
|
78
|
+
await assertDestinationsFree(dependencies.backend, [destination]);
|
|
79
|
+
const bytes = await dependencies.backend.readBytes(source);
|
|
80
|
+
const changes = new Map<string, string | Uint8Array | null>([
|
|
81
|
+
[destination, bytes],
|
|
82
|
+
[source, null],
|
|
83
|
+
]);
|
|
84
|
+
const changed = await files.mutate(
|
|
85
|
+
[...changes].map(([path, data]) => ({ path, data })),
|
|
86
|
+
{ label: `Move ${source}` },
|
|
87
|
+
);
|
|
88
|
+
if (changed) emitAssetMutation({ type: 'move', oldPath: source, newPath: destination });
|
|
89
|
+
return changed;
|
|
90
|
+
}
|
|
91
|
+
case 'move-many': {
|
|
92
|
+
const moves = operation.moves.map((move) => ({
|
|
93
|
+
source: validPath(move.source),
|
|
94
|
+
destination: validPath(move.destination),
|
|
95
|
+
}));
|
|
96
|
+
if (moves.length === 0) return false;
|
|
97
|
+
const sources = new Set(moves.map((move) => move.source));
|
|
98
|
+
const destinations = moves.map((move) => move.destination);
|
|
99
|
+
if (new Set(destinations).size !== destinations.length) {
|
|
100
|
+
throw new Error('Batch move destinations must be unique.');
|
|
101
|
+
}
|
|
102
|
+
for (const destination of destinations) {
|
|
103
|
+
if (!sources.has(destination) && (await dependencies.backend.exists(destination))) {
|
|
104
|
+
throw new Error(`An asset already exists at ${destination}.`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const payloads = await Promise.all(
|
|
108
|
+
moves.map(async (move) => ({
|
|
109
|
+
...move,
|
|
110
|
+
bytes: await dependencies.backend.readBytes(move.source),
|
|
111
|
+
})),
|
|
112
|
+
);
|
|
113
|
+
const changes = new Map<string, string | Uint8Array | null>();
|
|
114
|
+
for (const { destination, bytes } of payloads) changes.set(destination, bytes);
|
|
115
|
+
for (const { source } of payloads) {
|
|
116
|
+
if (!destinations.includes(source)) changes.set(source, null);
|
|
117
|
+
}
|
|
118
|
+
const changed = await files.mutate(
|
|
119
|
+
[...changes].map(([path, data]) => ({ path, data })),
|
|
120
|
+
{ label: `Move ${moves.length} assets` },
|
|
121
|
+
);
|
|
122
|
+
if (changed) {
|
|
123
|
+
for (const move of moves) {
|
|
124
|
+
emitAssetMutation({ type: 'move', oldPath: move.source, newPath: move.destination });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return changed;
|
|
128
|
+
}
|
|
129
|
+
case 'delete': {
|
|
130
|
+
const paths = [...new Set(operation.paths.map(validPath))];
|
|
131
|
+
const changed = await files.mutate(
|
|
132
|
+
paths.map((path) => ({ path, data: null })),
|
|
133
|
+
{ label: `Delete ${paths.length} asset${paths.length === 1 ? '' : 's'}` },
|
|
134
|
+
);
|
|
135
|
+
if (changed) emitAssetMutation({ type: 'delete', paths });
|
|
136
|
+
return changed;
|
|
137
|
+
}
|
|
138
|
+
case 'import': {
|
|
139
|
+
const imported = operation.files.map((file) => ({
|
|
140
|
+
path: validPath(file.path),
|
|
141
|
+
data: file.bytes,
|
|
142
|
+
}));
|
|
143
|
+
await assertDestinationsFree(
|
|
144
|
+
dependencies.backend,
|
|
145
|
+
imported.map((file) => file.path),
|
|
146
|
+
);
|
|
147
|
+
const changed = await files.mutate(imported, {
|
|
148
|
+
label: `Import ${imported.length} asset${imported.length === 1 ? '' : 's'}`,
|
|
149
|
+
});
|
|
150
|
+
if (changed) emitAssetMutation({ type: 'change', paths: imported.map((file) => file.path) });
|
|
151
|
+
return changed;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The asset ROOTS Content lists, and the one place a row's root plus its
|
|
3
|
+
* root-relative path becomes a project path or a URL.
|
|
4
|
+
*
|
|
5
|
+
* `public/` is the shipped game's assets; `references/` is reference material
|
|
6
|
+
* that lives in the project and is deliberately NOT shipped (see
|
|
7
|
+
* `@vgai/sdk/output-roots` for the writer's half of the same rule). Both are
|
|
8
|
+
* ordinary directories of ordinary files — there is no reference database, no
|
|
9
|
+
* import step, and no copy into `public/` to make something appear.
|
|
10
|
+
*
|
|
11
|
+
* Why a reference is addressed through `/project-game-static/`: that middleware
|
|
12
|
+
* (`vite-plugin-project-game-static.ts`) already serves the CURRENTLY OPEN
|
|
13
|
+
* project's own folder verbatim, which is exactly what a reference needs and
|
|
14
|
+
* exactly what `public/`'s root-relative URLs are not — a public asset's URL is
|
|
15
|
+
* `/<publicRelativePath>` because a shipped game addresses it that way, and
|
|
16
|
+
* giving references the same spelling would collide with the game's own paths.
|
|
17
|
+
* Nothing new is served; a reference simply uses the project-file route that
|
|
18
|
+
* already exists.
|
|
19
|
+
*
|
|
20
|
+
* `projectPathForAssetUrl` is the inverse: a bytes reader takes the URL a
|
|
21
|
+
* document or a tile already holds and asks THIS module which project file it
|
|
22
|
+
* names.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
export const REFERENCE_ROOT = 'references';
|
|
26
|
+
|
|
27
|
+
/** A listable asset root. `public` is the default and the shipped one. */
|
|
28
|
+
export type AssetRootId = 'public' | typeof REFERENCE_ROOT;
|
|
29
|
+
|
|
30
|
+
export const ASSET_ROOTS: readonly AssetRootId[] = ['public', REFERENCE_ROOT];
|
|
31
|
+
|
|
32
|
+
/** The URL prefix a reference is served under on the local editor server. */
|
|
33
|
+
export const REFERENCE_URL_PREFIX = `/project-game-static/${REFERENCE_ROOT}/`;
|
|
34
|
+
|
|
35
|
+
/** Project-root-relative path for a root + root-relative path. */
|
|
36
|
+
export function projectAssetPath(root: AssetRootId, rootRelativePath: string): string {
|
|
37
|
+
return `${root}/${rootRelativePath}`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The URL editor chrome, asset documents and the Inspector address this asset
|
|
42
|
+
* by. Public keeps its exact existing spelling (`/textures/crate.png`).
|
|
43
|
+
*/
|
|
44
|
+
export function assetRootServingUrl(root: AssetRootId, rootRelativePath: string): string {
|
|
45
|
+
return root === REFERENCE_ROOT
|
|
46
|
+
? `${REFERENCE_URL_PREFIX}${rootRelativePath}`
|
|
47
|
+
: `/${rootRelativePath}`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Is this URL/document path a reference rather than a public asset? */
|
|
51
|
+
export function isReferenceAssetUrl(url: string): boolean {
|
|
52
|
+
return url.startsWith(REFERENCE_URL_PREFIX);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Which project file a serving URL names — the inverse of
|
|
57
|
+
* {@link assetRootServingUrl}, and the one mapping every bytes reader uses.
|
|
58
|
+
* A plain `/x.png` is a public asset, so it answers `public/x.png`, which is
|
|
59
|
+
* the rule those readers used to hardcode.
|
|
60
|
+
*/
|
|
61
|
+
export function projectPathForAssetUrl(url: string): string {
|
|
62
|
+
const servingUrl = url.startsWith('/') ? url : `/${url}`;
|
|
63
|
+
if (isReferenceAssetUrl(servingUrl)) {
|
|
64
|
+
return projectAssetPath(REFERENCE_ROOT, servingUrl.slice(REFERENCE_URL_PREFIX.length));
|
|
65
|
+
}
|
|
66
|
+
const withoutSlash = url.startsWith('/') ? url.slice(1) : url;
|
|
67
|
+
return withoutSlash.startsWith('public/') ? withoutSlash : `public/${withoutSlash}`;
|
|
68
|
+
}
|