@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,336 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The editor's MODULE DOORWAYS: synthetic ES modules that statically re-export
|
|
3
|
+
* a fixed set of members, so the editor SHELL reaches a package through the
|
|
4
|
+
* OPENED PROJECT's Vite graph instead of through its own prebuilt bundle.
|
|
5
|
+
*
|
|
6
|
+
* One plugin, one declarative table per doorway. Everything below is the same
|
|
7
|
+
* two-line mechanism — `resolveId` maps `/__vgai-<name>` to a `\0`-prefixed
|
|
8
|
+
* virtual id, `load` answers with a literal string of `export … from '<bare
|
|
9
|
+
* specifier>'` lines — and the ONLY thing that ever differed between the five
|
|
10
|
+
* was the specifier table, so the tables are the module's data and the plugin
|
|
11
|
+
* machinery is written once.
|
|
12
|
+
*
|
|
13
|
+
* ## Why a doorway exists at all
|
|
14
|
+
*
|
|
15
|
+
* Under the PACKAGED runtime (`server/packaged.ts` — a `@vgai/editor` npm
|
|
16
|
+
* package with no monorepo checkout) the editor shell is a prebuilt production
|
|
17
|
+
* bundle with its own React, three, `@react-three/fiber`, `pixi.js`,
|
|
18
|
+
* `@pixi/react` and `@storybook/react` inlined, while the opened project's
|
|
19
|
+
* source is served by a SEPARATE, project-rooted Vite instance that resolves
|
|
20
|
+
* those same bare specifiers from the PROJECT's `node_modules`. A bare static
|
|
21
|
+
* `import` in shell code therefore holds a DIFFERENT module instance than the
|
|
22
|
+
* objects it is pointed at. A doorway is how the shell asks the project's graph
|
|
23
|
+
* for the same identity the project itself resolved: the synthetic body's
|
|
24
|
+
* specifiers go through that instance's own transform-time resolver and its own
|
|
25
|
+
* `optimizeDeps` prebundle cache, exactly the way a project entry module's own
|
|
26
|
+
* `import … from 'react'` does.
|
|
27
|
+
*
|
|
28
|
+
* `dev.ts` has no such split — one Vite
|
|
29
|
+
* instance, and the repo-root `vite.config.ts`'s `resolve.dedupe` already
|
|
30
|
+
* collapses `react`/`three`/`pixi.js`/`@pixi/react`/`@react-three/fiber` onto
|
|
31
|
+
* one instance — so this plugin is registered ONLY on the packaged runtime's
|
|
32
|
+
* project-rooted instance, plus the root `vitest.config.ts` (two doorways
|
|
33
|
+
* there, so the branch is exercisable headlessly).
|
|
34
|
+
*
|
|
35
|
+
* ## Why the doorways stay SEPARATE modules
|
|
36
|
+
*
|
|
37
|
+
* The plugin merges; the MODULES deliberately do not. Each doorway is fetched
|
|
38
|
+
* only when the lane that needs it actually mounts, so its packages are only
|
|
39
|
+
* ever demanded of a project that has them:
|
|
40
|
+
*
|
|
41
|
+
* - a DOM/canvas-only project must not resolve `@react-three/fiber` merely to
|
|
42
|
+
* mount an ordinary React root (which is why the r3f rows are not on the
|
|
43
|
+
* react-world doorway — keeping them there meant a valid 2D project could
|
|
44
|
+
* not boot the packaged editor without installing an unrelated renderer
|
|
45
|
+
* stack), nor a three-only project `@pixi/react`;
|
|
46
|
+
* - an INGEST root's whole premise is a game that brought its OWN stack, so
|
|
47
|
+
* the three-ingest doorway does not borrow `/__vgai-r3f-runtime` even though
|
|
48
|
+
* that module already publishes `projectThree` and reusing it would be one
|
|
49
|
+
* line: a vendored plain-three game has no Fiber installed, and demanding it
|
|
50
|
+
* would break the exact case the doorway closes;
|
|
51
|
+
* - `@storybook/react` is a devDependency a project may drop, so a project
|
|
52
|
+
* with no stories must never pay for it and a project missing it must lose
|
|
53
|
+
* only the story lane (with an error naming the missing package, surfaced by
|
|
54
|
+
* `src/story-dom-runtime.ts`), never react-world mounting.
|
|
55
|
+
*
|
|
56
|
+
* ## The measured defects, per doorway
|
|
57
|
+
*
|
|
58
|
+
* These are the failures each row set was bought with. None of them reproduce
|
|
59
|
+
* from a checkout — every one needs a real packaged build.
|
|
60
|
+
*
|
|
61
|
+
* ### `/__vgai-react-world-runtime` (`REACT_WORLD_DOORWAY`)
|
|
62
|
+
*
|
|
63
|
+
* Mounting a react world with `createRoot` from the editor's own bundle while
|
|
64
|
+
* the entry component's hooks ran against the project's `react` produced two
|
|
65
|
+
* React module instances: `useContext`/`useState` read and wrote different
|
|
66
|
+
* internal singletons, and `useContext` threw on a `null` dispatcher (confirmed
|
|
67
|
+
* live; see `server/packaged.ts`'s header, "React-world OID authoring parity",
|
|
68
|
+
* and `src/react-mount-runtime.ts`'s `resolveReactRootMountRuntime`).
|
|
69
|
+
*
|
|
70
|
+
* A real-browser run then caught a SECOND bug the wiring tests could not see:
|
|
71
|
+
* `flushSync` must come from bare `react-dom`, and this instance's
|
|
72
|
+
* `optimizeDeps` uses a project-entry-scoped crawl, so an injected bare
|
|
73
|
+
* specifier the crawl cannot see is served RAW — `react-dom`'s package entry
|
|
74
|
+
* re-exports its implementation through a `NODE_ENV`-conditional `require(...)`
|
|
75
|
+
* the raw-serve path cannot see through. Because a doorway is ONE ES module
|
|
76
|
+
* with several `export … from` statements, that single broken re-export sinks
|
|
77
|
+
* the whole dynamic import, breaking even Play mode's `ReactRootAdapter.mount()`
|
|
78
|
+
* which never touches `flushSync`:
|
|
79
|
+
*
|
|
80
|
+
* SyntaxError: The requested module '/node_modules/react-dom/index.js'
|
|
81
|
+
* does not provide an export named 'flushSync'
|
|
82
|
+
*
|
|
83
|
+
* — gone once bare `react-dom` was in `optimizeDeps.include`, in the same run.
|
|
84
|
+
* That is what `EDITOR_RUNTIME_MODULE_SPECIFIERS` (below, read by
|
|
85
|
+
* `server/project-optimize-deps-entries.ts`) exists to keep true.
|
|
86
|
+
*
|
|
87
|
+
* WHICH react the graph then points at is not this module's business and has
|
|
88
|
+
* changed: `packaged.ts` redirects every React specifier in this graph to the
|
|
89
|
+
* editor SHELL's own built React chunks (`vite-plugin-shared-react.ts`), so the
|
|
90
|
+
* page has exactly one React the way `dev.ts` always did. The contract is
|
|
91
|
+
* unchanged and still load-bearing — the mount call and the entry component's
|
|
92
|
+
* hooks must resolve `react` through the SAME graph, whatever that graph points
|
|
93
|
+
* at.
|
|
94
|
+
*
|
|
95
|
+
* ### `/__vgai-canvas-runtime` (`CANVAS_DOORWAY`)
|
|
96
|
+
*
|
|
97
|
+
* `src/authoring/canvas-design-mount.ts` and `src/binding-resolver.ts` are
|
|
98
|
+
* SHELL modules. A bare `await import('@vgai/game-runtime/canvas-react')` there built the
|
|
99
|
+
* adapter — and thus called `createRoot` and `extend` — with the SHELL's
|
|
100
|
+
* copies, then rendered the PROJECT's world component inside it. Measured on a
|
|
101
|
+
* packaged build against `examples/retro-shooter`:
|
|
102
|
+
*
|
|
103
|
+
* Invalid hook call … more than one copy of React in the same app (×12)
|
|
104
|
+
* TypeError: Cannot read properties of null (reading 'useSyncExternalStore')
|
|
105
|
+
* [design-time-layers] world "world" (canvas) failed to mount:
|
|
106
|
+
* canvas world "world": no first commit within 10s
|
|
107
|
+
*
|
|
108
|
+
* — the canvas world never design-mounted, and the Scene view was a Boundary
|
|
109
|
+
* node.
|
|
110
|
+
*
|
|
111
|
+
* `projectPixi` rides along because mounting is only half of what the editor
|
|
112
|
+
* does to a canvas world. Everything AFTERWARDS — the authoring adapter that
|
|
113
|
+
* duplicates a node, the drop that loads a texture, the capture trap an ingest
|
|
114
|
+
* root installs, the preview that photographs a selection — is SHELL code
|
|
115
|
+
* holding `pixi.js` VALUES, and those values came from a different module
|
|
116
|
+
* instance than the objects they point at. Four measured failures:
|
|
117
|
+
*
|
|
118
|
+
* - `object.constructor === Container` is FALSE for every project node, so
|
|
119
|
+
* `PixiAuthoringAdapter`'s duplicate gate refuses a plain project Container
|
|
120
|
+
* with the sentence it reserves for a game's own subclass;
|
|
121
|
+
* - `Assets.load` reads the SHELL's cache, so an image dropped on the world is
|
|
122
|
+
* fetched and decoded a second time into a texture the project's own loader
|
|
123
|
+
* has never heard of;
|
|
124
|
+
* - `installSceneCapture2D` traps the SHELL's `Application.prototype`, which an
|
|
125
|
+
* ingested game never calls — MEASURED on a packaged build of the
|
|
126
|
+
* `bunnymark` ingest fixture, the mount died with the engine's own words:
|
|
127
|
+
* "the game never rendered, or it bundles its own (un-shared) copy of
|
|
128
|
+
* pixi.js" (8s of visible time, then the whole root failed by name);
|
|
129
|
+
* - a selection preview clones a project subtree through a five-way
|
|
130
|
+
* `instanceof` chain of SHELL classes, which every branch misses, and renders
|
|
131
|
+
* the result on a SHELL `Application` against the project's GPU textures.
|
|
132
|
+
*
|
|
133
|
+
* So, stated once: A CANVAS SURFACE HOLDS ONE PIXI NAMESPACE, and it is the one
|
|
134
|
+
* the graph its objects came from resolved. The mount site chooses it
|
|
135
|
+
* (`resolveCanvasPixiForEditor`) and hands it to whatever it constructs;
|
|
136
|
+
* nothing downstream reaches for a static import. `CanvasHostContext` carries
|
|
137
|
+
* no renderer namespace (the mount calls `extend(PIXI)` with its OWN `pixi.js`
|
|
138
|
+
* import, which is the project's once this doorway resolves it), so the MOUNT
|
|
139
|
+
* needs nothing further.
|
|
140
|
+
*
|
|
141
|
+
* ### `/__vgai-three-ingest-runtime` (`THREE_INGEST_DOORWAY`)
|
|
142
|
+
*
|
|
143
|
+
* `src/authoring/ingest-root-adapter.ts` is SHELL code, and it installed the
|
|
144
|
+
* render accessor trap on the `three` it statically imported — while the
|
|
145
|
+
* ingested game's entry is served as `/@fs/<project>/…` by the project-rooted
|
|
146
|
+
* Vite and therefore resolves the PROJECT's `three`. The trap sat on a
|
|
147
|
+
* `WebGLRenderer.prototype` the game never constructs. The engine states the
|
|
148
|
+
* invariant in `adapter/ingest/scene-capture.ts`'s own header — "every trap
|
|
149
|
+
* must be installed on the SAME `three` module/addon instance the game uses" —
|
|
150
|
+
* and says exactly what a violation looks like. MEASURED on a packaged build
|
|
151
|
+
* (published `@vgai/editor@0.5.20`, real npm install) against a ~30-line
|
|
152
|
+
* unmodified three.js game declared as a `{ surface: 'three', ingest: {} }`
|
|
153
|
+
* root:
|
|
154
|
+
*
|
|
155
|
+
* WARNING: Multiple instances of Three.js being imported.
|
|
156
|
+
* Scene capture timed out after 15000ms of VISIBLE time (0ms
|
|
157
|
+
* browser-suspended …) — the game never rendered, or it bundles its own
|
|
158
|
+
* (un-shared) copy of three.
|
|
159
|
+
*
|
|
160
|
+
* — three.js's own duplicate-instance guard naming the cause, beside the mount
|
|
161
|
+
* failing by name 15 seconds later. The ADDONS ride along because they are the
|
|
162
|
+
* same identity question: `EffectComposer` and `CSS3DRenderer` are FILES inside
|
|
163
|
+
* the `three` package tree, so an unmodified game's `three/addons/…` import
|
|
164
|
+
* resolves to the copy beside its own `three`, and trapping the shell's would
|
|
165
|
+
* miss a composer-driven or CSS3D-driven game for precisely that reason.
|
|
166
|
+
*
|
|
167
|
+
* ### `/__vgai-story-runtime` (`STORY_DOORWAY`)
|
|
168
|
+
*
|
|
169
|
+
* A CSF module is dynamically imported through the project's Vite graph
|
|
170
|
+
* (`src/stories/story-discovery.ts`'s `/@fs/` import), so its components' hooks
|
|
171
|
+
* resolve against the PROJECT's own `react` — while `mountIsolatedStory`
|
|
172
|
+
* (`StoryPreviewMount.tsx`) rendered them with the editor SPA's statically
|
|
173
|
+
* bundled `react-dom`, and `compose-project-stories.ts` composed them with the
|
|
174
|
+
* editor's own bundled `@storybook/react`. Two React module instances: every
|
|
175
|
+
* story render died on "Invalid hook call" — confirmed live in a package-native
|
|
176
|
+
* project, where the Stories panel and the `vgai screenshot` story lane were
|
|
177
|
+
* both dead.
|
|
178
|
+
*
|
|
179
|
+
* ### `/__vgai-r3f-runtime` (`R3F_DOORWAY`)
|
|
180
|
+
*
|
|
181
|
+
* The three lane's original doorway, and the pattern the canvas and
|
|
182
|
+
* three-ingest ones were transcribed from: the R3F entry adjudicator, plus
|
|
183
|
+
* `projectThree` for the same reason `projectPixi` exists on the canvas
|
|
184
|
+
* doorway.
|
|
185
|
+
*
|
|
186
|
+
* ## Why the module BODY is exported (`doorwayModuleSource`)
|
|
187
|
+
*
|
|
188
|
+
* A synthesized module hangs off no file the `optimizeDeps` crawl can reach, so
|
|
189
|
+
* its specifiers were discovered only when a lane first mounted — mid-session —
|
|
190
|
+
* which re-optimizes and hard-reloads the controlling tab. Measured on a real
|
|
191
|
+
* canonical-Pixi project with a cold `node_modules/.vite`: the boot pass
|
|
192
|
+
* prebundled 19 deps; one request for the synthetic modules took it to 21,
|
|
193
|
+
* adding `three` and `@react-three/fiber` — two optimizer waves, two reloads.
|
|
194
|
+
* `server/project-optimize-deps-entries.ts` closes that by reading
|
|
195
|
+
* `EDITOR_RUNTIME_MODULE_SPECIFIERS` out of the SAME strings the browser is
|
|
196
|
+
* served, which is what stops the prebundle list from drifting from what the
|
|
197
|
+
* modules actually import.
|
|
198
|
+
*/
|
|
199
|
+
import { STORY_RUNTIME_PATH } from '@volter/editor-sdk/host';
|
|
200
|
+
import type { Plugin } from 'vite';
|
|
201
|
+
|
|
202
|
+
/** One `from '<specifier>'` line of a doorway's synthetic module body. */
|
|
203
|
+
export interface ModuleDoorwayRow {
|
|
204
|
+
/** The bare (or aliased) specifier this row re-exports from. */
|
|
205
|
+
readonly from: string;
|
|
206
|
+
/**
|
|
207
|
+
* Named re-exports, verbatim and in order — `'createRoot as createR3FRoot'`
|
|
208
|
+
* is a single entry, because the rename IS the published name.
|
|
209
|
+
*/
|
|
210
|
+
readonly names?: readonly string[];
|
|
211
|
+
/**
|
|
212
|
+
* Publish the specifier's whole namespace under this binding
|
|
213
|
+
* (`import * as projectThree from 'three'` + `export { projectThree }`).
|
|
214
|
+
* Namespace imports lead the module body and their re-export closes it, the
|
|
215
|
+
* way a hand-written module reads.
|
|
216
|
+
*/
|
|
217
|
+
readonly namespace?: string;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** A synthetic module the editor shell imports by URL to reach the project's graph. */
|
|
221
|
+
export interface ModuleDoorway {
|
|
222
|
+
/** The URL shell code imports (`/__vgai-r3f-runtime`). Part of the public API. */
|
|
223
|
+
readonly path: string;
|
|
224
|
+
readonly rows: readonly ModuleDoorwayRow[];
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* The dynamic-import-facing URL `src/binding-resolver.ts`'s
|
|
229
|
+
* `resolveReactRootMountRuntime` imports.
|
|
230
|
+
*/
|
|
231
|
+
export const REACT_WORLD_RUNTIME_PATH = '/__vgai-react-world-runtime';
|
|
232
|
+
export const R3F_RUNTIME_PATH = '/__vgai-r3f-runtime';
|
|
233
|
+
export const CANVAS_RUNTIME_PATH = '/__vgai-canvas-runtime';
|
|
234
|
+
export const THREE_INGEST_RUNTIME_PATH = '/__vgai-three-ingest-runtime';
|
|
235
|
+
/** The dynamic-import-facing URL `stories/story-dom-runtime.ts` imports. Its
|
|
236
|
+
* one spelling is `@volter/editor-sdk/host`, because a reader reaches a host
|
|
237
|
+
* fact through the published door and never through this build tier; this
|
|
238
|
+
* plugin still owns WHAT is served at that address, below. */
|
|
239
|
+
export { STORY_RUNTIME_PATH };
|
|
240
|
+
|
|
241
|
+
export const R3F_DOORWAY: ModuleDoorway = {
|
|
242
|
+
path: R3F_RUNTIME_PATH,
|
|
243
|
+
rows: [
|
|
244
|
+
{ from: 'three', namespace: 'projectThree' },
|
|
245
|
+
{ from: 'react', names: ['createElement'] },
|
|
246
|
+
{
|
|
247
|
+
from: '@react-three/fiber',
|
|
248
|
+
names: ['createRoot as createR3FRoot', 'extend as extendThree'],
|
|
249
|
+
},
|
|
250
|
+
],
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
export const THREE_INGEST_DOORWAY: ModuleDoorway = {
|
|
254
|
+
path: THREE_INGEST_RUNTIME_PATH,
|
|
255
|
+
rows: [
|
|
256
|
+
{ from: 'three', namespace: 'projectThree' },
|
|
257
|
+
{
|
|
258
|
+
from: 'three/examples/jsm/postprocessing/EffectComposer.js',
|
|
259
|
+
names: ['EffectComposer'],
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
from: 'three/examples/jsm/renderers/CSS3DRenderer.js',
|
|
263
|
+
names: ['CSS3DRenderer'],
|
|
264
|
+
},
|
|
265
|
+
],
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
export const STORY_DOORWAY: ModuleDoorway = {
|
|
269
|
+
path: STORY_RUNTIME_PATH,
|
|
270
|
+
rows: [
|
|
271
|
+
{ from: '@storybook/react', names: ['composeStories', 'setProjectAnnotations'] },
|
|
272
|
+
{ from: 'react-dom', names: ['flushSync'] },
|
|
273
|
+
{ from: 'react-dom/client', names: ['createRoot'] },
|
|
274
|
+
],
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Every doorway the PACKAGED runtime serves, in registration order.
|
|
279
|
+
*
|
|
280
|
+
* `vitest.config.ts` deliberately registers a SUBSET (react-world + story), and
|
|
281
|
+
* `dev.ts` registers none — see the header for why a doorway is only ever
|
|
282
|
+
* served to a lane that asked for it.
|
|
283
|
+
*/
|
|
284
|
+
export const PACKAGED_MODULE_DOORWAYS: readonly ModuleDoorway[] = [
|
|
285
|
+
R3F_DOORWAY,
|
|
286
|
+
THREE_INGEST_DOORWAY,
|
|
287
|
+
STORY_DOORWAY,
|
|
288
|
+
];
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* The exact module text a doorway is served as — a literal string of STATIC
|
|
292
|
+
* `import`/`export … from` lines and nothing else, so every specifier goes
|
|
293
|
+
* through the serving instance's own resolver.
|
|
294
|
+
*/
|
|
295
|
+
export function doorwayModuleSource(doorway: ModuleDoorway): string {
|
|
296
|
+
const lines: string[] = [];
|
|
297
|
+
for (const row of doorway.rows) {
|
|
298
|
+
if (row.namespace) lines.push(`import * as ${row.namespace} from '${row.from}';`);
|
|
299
|
+
}
|
|
300
|
+
for (const row of doorway.rows) {
|
|
301
|
+
if (!row.names || row.names.length === 0) continue;
|
|
302
|
+
lines.push(`export { ${row.names.join(', ')} } from '${row.from}';`);
|
|
303
|
+
}
|
|
304
|
+
for (const row of doorway.rows) {
|
|
305
|
+
if (row.namespace) lines.push(`export { ${row.namespace} };`);
|
|
306
|
+
}
|
|
307
|
+
return lines.join('\n');
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/** A doorway's private virtual id — `\0`-prefixed so no other plugin claims it. */
|
|
311
|
+
function virtualIdOf(doorway: ModuleDoorway): string {
|
|
312
|
+
return `\0vgai${doorway.path.replace(/^\/__vgai/, '')}`;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* The ONE plugin serving every doorway handed to it.
|
|
317
|
+
*
|
|
318
|
+
* Registered per host with the doorways that host is meant to answer for, which
|
|
319
|
+
* is the whole conditional cost model: a doorway not in this list is not a
|
|
320
|
+
* module the graph can reach, so its packages are never demanded.
|
|
321
|
+
*/
|
|
322
|
+
export function moduleDoorwaysPlugin(doorways: readonly ModuleDoorway[]): Plugin {
|
|
323
|
+
const byPath = new Map(doorways.map((doorway) => [doorway.path, virtualIdOf(doorway)]));
|
|
324
|
+
const bodies = new Map(
|
|
325
|
+
doorways.map((doorway) => [virtualIdOf(doorway), doorwayModuleSource(doorway)]),
|
|
326
|
+
);
|
|
327
|
+
return {
|
|
328
|
+
name: 'vgai-module-doorways',
|
|
329
|
+
resolveId(id) {
|
|
330
|
+
return byPath.get(id);
|
|
331
|
+
},
|
|
332
|
+
load(id) {
|
|
333
|
+
return bodies.get(id);
|
|
334
|
+
},
|
|
335
|
+
};
|
|
336
|
+
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `vgai:contributions/<package>` — a package's DECLARED contributions, read at
|
|
3
|
+
* build/serve time and served as a module of static `import()`s.
|
|
4
|
+
*
|
|
5
|
+
* A PRODUCT is code (ARCHITECTURE-CORE §The target shape, rule 8: "Compositions
|
|
6
|
+
* are code; the frame's and the loader's manifests are declarations and stay").
|
|
7
|
+
* `packages/game-editor/src/index.ts` and `packages/model-editor/src/index.ts`
|
|
8
|
+
* name the packages they mount, in TypeScript, and each name is spelled as an
|
|
9
|
+
* import of this virtual module:
|
|
10
|
+
*
|
|
11
|
+
* import blender from 'vgai:contributions/@vgai/blender';
|
|
12
|
+
*
|
|
13
|
+
* whose body this plugin synthesizes from that package's own
|
|
14
|
+
* `package.json#vgai.contributions`:
|
|
15
|
+
*
|
|
16
|
+
* export default [
|
|
17
|
+
* { entryPath: '@vgai/blender/contributions/blender.command.ts',
|
|
18
|
+
* load: () => import('@vgai/blender/contributions/blender.command') },
|
|
19
|
+
* …
|
|
20
|
+
* ];
|
|
21
|
+
*
|
|
22
|
+
* The declaration is the ONE source. Nothing is committed that a script
|
|
23
|
+
* generates, and a package that grows a contribution grows every product that
|
|
24
|
+
* names it with no second edit anywhere — which is the defect the generated
|
|
25
|
+
* table (`builds.generated.ts`, 529 committed lines derived from `builds/*.json`)
|
|
26
|
+
* existed to remove and then re-introduced from the other side: the table was
|
|
27
|
+
* committed, so it went stale, and a pre-commit check had to exist to notice.
|
|
28
|
+
*
|
|
29
|
+
* WHY A PLUGIN AND NOT `import.meta.glob`. A glob is a path pattern over THIS
|
|
30
|
+
* package's tree; what a product mounts is another package's own list, and a
|
|
31
|
+
* package's contributions live behind its export map, not at a path a consumer
|
|
32
|
+
* may guess. So the plugin reads the manifest the loader already reads
|
|
33
|
+
* (`server/project-tools.ts`'s `packageContributionModules` reads the same key
|
|
34
|
+
* for a PROJECT's declared packages) and emits the same `{ entryPath, load }`
|
|
35
|
+
* shape `tool-loader.ts` consumes. `vite-plugin-module-doorways.ts` is the
|
|
36
|
+
* precedent for the mechanism: `resolveId` maps a private id, `load` answers
|
|
37
|
+
* with a literal module body of static statements, and every specifier in it
|
|
38
|
+
* goes through the serving instance's own resolver.
|
|
39
|
+
*
|
|
40
|
+
* THE `entryPath` IS THE PACKAGE SPECIFIER, with its extension, because that is
|
|
41
|
+
* what the SESSION reports for the same module (`project-tools.ts` records a
|
|
42
|
+
* package's contribution by the manifest's own `./contributions/x.ts` spelling)
|
|
43
|
+
* and `tool-loader.ts` dedupes a package the product bundles against one the
|
|
44
|
+
* open project declares BY THAT STRING. The `load` import drops the extension
|
|
45
|
+
* for the same reason the old generator did: `@vgai/x/contributions/*` is an
|
|
46
|
+
* export-map wildcard, and the bundler resolves the extension.
|
|
47
|
+
*
|
|
48
|
+
* WHERE THE MANIFEST IS FOUND. From the IMPORTER — the product module doing the
|
|
49
|
+
* importing — through Node resolution of `<name>/package.json`, so the product
|
|
50
|
+
* reads the package its own install resolves. `resolveId` is the only hook with
|
|
51
|
+
* an importer, so it resolves the manifest and remembers it for `load`.
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
import { readFileSync } from 'node:fs';
|
|
55
|
+
import { createRequire } from 'node:module';
|
|
56
|
+
import { dirname, isAbsolute, join } from 'node:path';
|
|
57
|
+
import { pathToFileURL } from 'node:url';
|
|
58
|
+
import type { Plugin } from 'vite';
|
|
59
|
+
|
|
60
|
+
/** The specifier prefix a product writes. Part of the kit's public surface: a
|
|
61
|
+
* product package's source contains this string and nothing else about how a
|
|
62
|
+
* contribution is found. */
|
|
63
|
+
export const PRODUCT_CONTRIBUTIONS_PREFIX = 'vgai:contributions/';
|
|
64
|
+
|
|
65
|
+
/** One contribution a product bundles: the package specifier `tool-loader.ts`
|
|
66
|
+
* records as the module's `file`, and the lazy import the bundler follows. */
|
|
67
|
+
export interface BundledContribution {
|
|
68
|
+
readonly entryPath: string;
|
|
69
|
+
readonly load: () => Promise<unknown>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** The module text served for one package's declared contributions. Exported so
|
|
73
|
+
* the closure meter can read the same list this serves without re-deriving the
|
|
74
|
+
* rule (`scripts/validate-editor-closure.mjs`). */
|
|
75
|
+
export function productContributionsModuleSource(
|
|
76
|
+
packageName: string,
|
|
77
|
+
declared: readonly string[],
|
|
78
|
+
): string {
|
|
79
|
+
const rows = declared.map((entry) => {
|
|
80
|
+
const relative = entry.replace(/^\.\//, '');
|
|
81
|
+
const specifier = `${packageName}/${relative}`;
|
|
82
|
+
const importable = specifier.replace(/\.(tsx|ts|jsx|js)$/, '');
|
|
83
|
+
return (
|
|
84
|
+
` { entryPath: ${JSON.stringify(specifier)}, ` +
|
|
85
|
+
`load: () => import(${JSON.stringify(importable)}) },`
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
return [
|
|
89
|
+
`// ${packageName}'s package.json#vgai.contributions, read at build time by`,
|
|
90
|
+
'// packages/editor/vite-plugin-product-contributions.ts.',
|
|
91
|
+
'export default [',
|
|
92
|
+
...rows,
|
|
93
|
+
'];',
|
|
94
|
+
'',
|
|
95
|
+
].join('\n');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** A package's declared contribution modules, or a throw naming the package. */
|
|
99
|
+
export function readDeclaredContributions(manifestPath: string, packageName: string): string[] {
|
|
100
|
+
let manifest: { vgai?: { contributions?: unknown } };
|
|
101
|
+
try {
|
|
102
|
+
manifest = JSON.parse(readFileSync(manifestPath, 'utf8')) as typeof manifest;
|
|
103
|
+
} catch (error) {
|
|
104
|
+
throw new Error(
|
|
105
|
+
`${manifestPath} is not readable (${error instanceof Error ? error.message : String(error)}), ` +
|
|
106
|
+
`so ${packageName}'s contributions cannot be composed into this product.`,
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
const declared = manifest.vgai?.contributions;
|
|
110
|
+
if (declared === undefined)
|
|
111
|
+
throw new Error(
|
|
112
|
+
`${packageName} declares no package.json#vgai.contributions, so there is nothing for a ` +
|
|
113
|
+
'product to mount from it. A package that contributes declares its modules there; a ' +
|
|
114
|
+
'package that only exports code is imported by name instead.',
|
|
115
|
+
);
|
|
116
|
+
if (!Array.isArray(declared) || declared.some((entry) => typeof entry !== 'string'))
|
|
117
|
+
throw new Error(
|
|
118
|
+
`${packageName}'s package.json#vgai.contributions must be an array of ./-relative modules.`,
|
|
119
|
+
);
|
|
120
|
+
return declared as string[];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Resolve `<name>/package.json` from the importing module's own directory.
|
|
125
|
+
*
|
|
126
|
+
* `createRequire` walks `node_modules` upward exactly as the runtime does, so a
|
|
127
|
+
* product resolves the package version its own install carries — and in this
|
|
128
|
+
* workspace that is the checkout's symlink, which is the same file the estate
|
|
129
|
+
* scan reads.
|
|
130
|
+
*/
|
|
131
|
+
function locateManifest(packageName: string, importer: string | undefined): string {
|
|
132
|
+
const from = importer && isAbsolute(importer) ? importer : join(process.cwd(), 'index.js');
|
|
133
|
+
const require = createRequire(pathToFileURL(from));
|
|
134
|
+
try {
|
|
135
|
+
return require.resolve(`${packageName}/package.json`);
|
|
136
|
+
} catch {
|
|
137
|
+
// An export map without a `./package.json` entry: fall back to the package
|
|
138
|
+
// directory Node resolves for the bare name's own files.
|
|
139
|
+
const resolvedFrom = createRequire(pathToFileURL(from));
|
|
140
|
+
const found = resolvedFrom.resolve(packageName);
|
|
141
|
+
let dir = dirname(found);
|
|
142
|
+
for (;;) {
|
|
143
|
+
const candidate = join(dir, 'package.json');
|
|
144
|
+
try {
|
|
145
|
+
if (JSON.parse(readFileSync(candidate, 'utf8')).name === packageName) return candidate;
|
|
146
|
+
} catch {
|
|
147
|
+
/* keep walking */
|
|
148
|
+
}
|
|
149
|
+
const parent = dirname(dir);
|
|
150
|
+
if (parent === dir)
|
|
151
|
+
throw new Error(
|
|
152
|
+
`${packageName} is not installed where ${from} can resolve it, so this product cannot ` +
|
|
153
|
+
'mount its contributions. Declare it as a dependency of the product package.',
|
|
154
|
+
);
|
|
155
|
+
dir = parent;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* The ONE plugin serving every `vgai:contributions/<package>` a product names.
|
|
162
|
+
*
|
|
163
|
+
* Registered on the repo-root `vite.config.ts` — which is both the product
|
|
164
|
+
* BUILD's config and the dev session's `configFile`
|
|
165
|
+
* (`packages/editor/server/dev.ts`), so one registration answers both hosts.
|
|
166
|
+
* The PACKAGED host's project-rooted instance never sees a product module (the
|
|
167
|
+
* product is a built chunk there), so it registers nothing.
|
|
168
|
+
*/
|
|
169
|
+
export function productContributionsPlugin(): Plugin {
|
|
170
|
+
const manifests = new Map<string, string>();
|
|
171
|
+
return {
|
|
172
|
+
name: 'vgai-product-contributions',
|
|
173
|
+
resolveId(id, importer) {
|
|
174
|
+
if (!id.startsWith(PRODUCT_CONTRIBUTIONS_PREFIX)) return null;
|
|
175
|
+
const packageName = id.slice(PRODUCT_CONTRIBUTIONS_PREFIX.length);
|
|
176
|
+
if (packageName === '')
|
|
177
|
+
throw new Error(
|
|
178
|
+
`"${id}" names no package — the form is \`${PRODUCT_CONTRIBUTIONS_PREFIX}<package>\`.`,
|
|
179
|
+
);
|
|
180
|
+
const virtual = `\0${id}`;
|
|
181
|
+
manifests.set(virtual, locateManifest(packageName, importer));
|
|
182
|
+
return virtual;
|
|
183
|
+
},
|
|
184
|
+
load(id) {
|
|
185
|
+
const manifestPath = manifests.get(id);
|
|
186
|
+
if (manifestPath === undefined) return null;
|
|
187
|
+
const packageName = id.slice(`\0${PRODUCT_CONTRIBUTIONS_PREFIX}`.length);
|
|
188
|
+
// Watched, so a package that grows a contribution refreshes the product
|
|
189
|
+
// in a live session instead of waiting for a restart.
|
|
190
|
+
this.addWatchFile(manifestPath);
|
|
191
|
+
return productContributionsModuleSource(
|
|
192
|
+
packageName,
|
|
193
|
+
readDeclaredContributions(manifestPath, packageName),
|
|
194
|
+
);
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vite-plugin-project-game-static — D-X2 (slice S1): the external-folder
|
|
3
|
+
* sibling of `vite-plugin-game-static.ts`. Serves the CURRENTLY OPEN
|
|
4
|
+
* project's own folder VERBATIM (no vite transform) at
|
|
5
|
+
* `/project-game-static/<path>` -> `<projectRoot>/<path>`, so a game's own
|
|
6
|
+
* data files reach it untransformed — an AssetPack `.json` spritesheet stays
|
|
7
|
+
* raw JSON instead of becoming an ESM module, the same R-X1 rationale
|
|
8
|
+
* `vite-plugin-game-static.ts`'s header records for the vendored route, just
|
|
9
|
+
* rooted at an arbitrary user folder.
|
|
10
|
+
*
|
|
11
|
+
* `getProjectRoot` is a THUNK, not a captured string: `open-project` can
|
|
12
|
+
* switch the current project live (`server/dev.ts`'s `onProjectOpened`
|
|
13
|
+
* callback), and this route must follow the CURRENT project root, not a
|
|
14
|
+
* boot-time snapshot — every request re-reads it. No project open (thunk
|
|
15
|
+
* returns `undefined`) -> `next()`, never a 5xx.
|
|
16
|
+
*
|
|
17
|
+
* `configureServer`-only: it exists to serve an OPENED project's files, which
|
|
18
|
+
* is a session's job and nothing else's.
|
|
19
|
+
*/
|
|
20
|
+
import { readFile } from 'node:fs/promises';
|
|
21
|
+
import { extname, join, normalize, resolve, sep } from 'node:path';
|
|
22
|
+
import type { Plugin } from 'vite';
|
|
23
|
+
import { MIME } from './vite-plugin-game-static';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Resolve `rel` against `projectRoot`, refusing anything that escapes it.
|
|
27
|
+
* Plain `startsWith(root)` would wrongly admit a sibling folder that merely
|
|
28
|
+
* shares `root` as a string prefix (e.g. root `/a/b` and filePath `/a/bc/evil`)
|
|
29
|
+
* — the boundary must fall on a real path separator (or be an exact match).
|
|
30
|
+
* Returns `null` for an escape attempt.
|
|
31
|
+
*/
|
|
32
|
+
function resolveInsideProjectRoot(projectRoot: string, rel: string): string | null {
|
|
33
|
+
const root = resolve(projectRoot);
|
|
34
|
+
const filePath = normalize(join(root, rel));
|
|
35
|
+
if (filePath === root || filePath.startsWith(root + sep)) return filePath;
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** `req.url`'s path portion (query stripped), project-root-relative (leading
|
|
40
|
+
* slash removed). Empty for the bare mount path (`/project-game-static`
|
|
41
|
+
* itself, with nothing after it). */
|
|
42
|
+
function requestRelPath(url: string | undefined): string {
|
|
43
|
+
// `.split('?')` always yields at least one element — `noUncheckedIndexedAccess`
|
|
44
|
+
// types index access as possibly-undefined regardless, so fall back to ''.
|
|
45
|
+
const path = (url ?? '').split('?')[0] ?? '';
|
|
46
|
+
return path.startsWith('/') ? path.slice(1) : path;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* One `Range: bytes=…` header against a known size. Returns the inclusive
|
|
51
|
+
* range to send, `null` for "send the whole file" (absent, malformed, or a
|
|
52
|
+
* form this route does not implement — a multi-range request is legal to
|
|
53
|
+
* answer with the full body), or `'unsatisfiable'` for a start past the end,
|
|
54
|
+
* which must be a 416 rather than a silently clamped success.
|
|
55
|
+
*/
|
|
56
|
+
export function parseByteRange(
|
|
57
|
+
header: string | string[] | undefined,
|
|
58
|
+
size: number,
|
|
59
|
+
): { start: number; end: number } | 'unsatisfiable' | null {
|
|
60
|
+
if (typeof header !== 'string') return null;
|
|
61
|
+
const match = /^bytes=(\d*)-(\d*)$/.exec(header.trim());
|
|
62
|
+
if (!match) return null;
|
|
63
|
+
const [, rawStart, rawEnd] = match;
|
|
64
|
+
if (rawStart === '' && rawEnd === '') return null;
|
|
65
|
+
// A suffix range (`bytes=-500`) asks for the LAST n bytes.
|
|
66
|
+
const start = rawStart === '' ? Math.max(0, size - Number(rawEnd)) : Number(rawStart);
|
|
67
|
+
const end = rawStart === '' || rawEnd === '' ? size - 1 : Math.min(Number(rawEnd), size - 1);
|
|
68
|
+
if (!Number.isFinite(start) || !Number.isFinite(end)) return null;
|
|
69
|
+
if (size === 0 || start >= size || start > end) return 'unsatisfiable';
|
|
70
|
+
return { start, end };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function projectGameStaticPlugin(getProjectRoot: () => string | undefined): Plugin {
|
|
74
|
+
return {
|
|
75
|
+
name: 'vgai-project-game-static',
|
|
76
|
+
configureServer(server) {
|
|
77
|
+
server.middlewares.use('/project-game-static', async (req, res, next) => {
|
|
78
|
+
const projectRoot = getProjectRoot();
|
|
79
|
+
if (!projectRoot) return next(); // no project open — nothing to serve
|
|
80
|
+
|
|
81
|
+
const rel = requestRelPath(req.url);
|
|
82
|
+
if (!rel) return next();
|
|
83
|
+
|
|
84
|
+
const filePath = resolveInsideProjectRoot(projectRoot, rel);
|
|
85
|
+
if (!filePath) {
|
|
86
|
+
res.statusCode = 403;
|
|
87
|
+
res.end('forbidden');
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
const buf = await readFile(filePath);
|
|
93
|
+
res.setHeader('Content-Type', MIME[extname(filePath)] ?? 'application/octet-stream');
|
|
94
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
95
|
+
// RANGE, and it is load-bearing for video. A `<video>` element seeks by
|
|
96
|
+
// asking for a byte range, and a route that answers every request with
|
|
97
|
+
// the whole file and no `Accept-Ranges` cannot be seeked at all: the
|
|
98
|
+
// clip's own first frame never paints (measured — a reference tile and
|
|
99
|
+
// its Asset Lab document both showed black over a bright opening
|
|
100
|
+
// frame), and the scrubber does nothing. Everything else is unaffected:
|
|
101
|
+
// a request with no `Range` still gets the ordinary 200 below.
|
|
102
|
+
res.setHeader('Accept-Ranges', 'bytes');
|
|
103
|
+
const range = parseByteRange(req.headers['range'], buf.byteLength);
|
|
104
|
+
if (range === 'unsatisfiable') {
|
|
105
|
+
res.statusCode = 416;
|
|
106
|
+
res.setHeader('Content-Range', `bytes */${buf.byteLength}`);
|
|
107
|
+
res.end();
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (range) {
|
|
111
|
+
res.statusCode = 206;
|
|
112
|
+
res.setHeader('Content-Range', `bytes ${range.start}-${range.end}/${buf.byteLength}`);
|
|
113
|
+
res.setHeader('Content-Length', range.end - range.start + 1);
|
|
114
|
+
res.end(buf.subarray(range.start, range.end + 1));
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
res.statusCode = 200;
|
|
118
|
+
res.end(buf);
|
|
119
|
+
} catch {
|
|
120
|
+
next();
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|