@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,420 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ONE React for the editor's own tree — the shell's.
|
|
3
|
+
*
|
|
4
|
+
* ## The defect this closes
|
|
5
|
+
*
|
|
6
|
+
* Under the PACKAGED runtime (`server/packaged.ts`: a `@vgai/editor` npm
|
|
7
|
+
* package with no monorepo checkout) the page runs two module graphs at once:
|
|
8
|
+
*
|
|
9
|
+
* - the editor shell, a PREBUILT production bundle (`dist/assets/index-*.js`)
|
|
10
|
+
* with its own React inlined; and
|
|
11
|
+
* - the opened PROJECT's source, served fresh by a second, project-rooted
|
|
12
|
+
* Vite instance, whose bare `react` resolves — correctly, for its root — to
|
|
13
|
+
* the PROJECT's own `node_modules`.
|
|
14
|
+
*
|
|
15
|
+
* Anything the project contributes that renders INSIDE the editor's React tree
|
|
16
|
+
* therefore called hooks from a different React than the one reconciling it.
|
|
17
|
+
* Measured on a fresh scaffold against the published 0.5.17 packaged editor:
|
|
18
|
+
* all four dev-tools inspector facets (`src/tools/game-*.inspector.tsx`)
|
|
19
|
+
* REGISTERED (`editor.inspect()` listed them) and then threw
|
|
20
|
+
* `Invalid hook call … more than one copy of React in the same app` instead of
|
|
21
|
+
* drawing — and so did every other project contribution that renders (the
|
|
22
|
+
* humanoid/bird/castle builder inspectors, the World Labs asset inspector, the
|
|
23
|
+
* data-tables document). None of it was visible from a checkout: `dev.ts`
|
|
24
|
+
* serves the editor's OWN source and the project's source through ONE Vite
|
|
25
|
+
* with `resolve.dedupe: ['react', …]`, so in-repo there has only ever been one
|
|
26
|
+
* React and every in-repo check passed.
|
|
27
|
+
*
|
|
28
|
+
* ## The mechanism: URL identity
|
|
29
|
+
*
|
|
30
|
+
* The editor build emits one extra ENTRY chunk per specifier in
|
|
31
|
+
* {@link SHARED_REACT_ENTRIES} — the SHELL's own React, `react-dom`,
|
|
32
|
+
* `react-dom/client`, `react/jsx-runtime`, `react/jsx-dev-runtime`, and the one
|
|
33
|
+
* third-party package that CALLS React hooks inside the editor's tree. Because
|
|
34
|
+
* they are entries of the SAME build, rollup hoists the actual module into a
|
|
35
|
+
* chunk both they and the shell import: they are not a copy of React, they are
|
|
36
|
+
* a doorway onto the shell's instance.
|
|
37
|
+
*
|
|
38
|
+
* At serve time {@link sharedReactPlugin} resolves those specifiers, for
|
|
39
|
+
* every module in the EDITOR TREE (see below), to the built chunk's URL
|
|
40
|
+
* (`/assets/vgai-shared-react-<hash>.js`) — the SAME absolute URL the shell's
|
|
41
|
+
* own bundle imports, so the browser's module map hands both sides the one
|
|
42
|
+
* instance.
|
|
43
|
+
*
|
|
44
|
+
* ### Why the entry bodies are GENERATED, not written
|
|
45
|
+
*
|
|
46
|
+
* The obvious spelling — a one-line `export * from 'react'` — silently emits a
|
|
47
|
+
* chunk with NO named exports (measured: the built chunk exported only the
|
|
48
|
+
* default and the raw namespace). React ships CommonJS, and rollup makes
|
|
49
|
+
* `import { useState } from 'react'` work by rewriting the IMPORTER's member
|
|
50
|
+
* access, not by synthesizing static named exports a star can forward. So each
|
|
51
|
+
* entry body is generated at build time from the installed package's own
|
|
52
|
+
* runtime key list (`Object.keys(require('react'))`), and every export is that
|
|
53
|
+
* package's own function read off its own module object. That is a DOORWAY,
|
|
54
|
+
* not a shim: there is no second implementation, nothing is faked, and the
|
|
55
|
+
* list cannot drift from the installed React because it is read from it. The
|
|
56
|
+
* chunks are emitted with `preserveSignature: 'strict'` because Vite's app
|
|
57
|
+
* build otherwise sets `preserveEntrySignatures: false` and mangles an entry's
|
|
58
|
+
* export names away.
|
|
59
|
+
*
|
|
60
|
+
* ## Where the seam is drawn (measured, not assumed)
|
|
61
|
+
*
|
|
62
|
+
* {@link sharedReactPlugin}'s own doc comment carries the full rule and the
|
|
63
|
+
* live failure that set it: the redirect covers the EDITOR TREE — the
|
|
64
|
+
* contribution lane, the widget kit, and whatever project source they reach —
|
|
65
|
+
* and deliberately stops at the GAME, which mounts into its own isolated
|
|
66
|
+
* `createRoot` tree with the project's own development React and a matching
|
|
67
|
+
* development reconciler. Redirecting the game too was tried first and broke
|
|
68
|
+
* Play mode outright.
|
|
69
|
+
*
|
|
70
|
+
* {@link sharedReactPlugin} is registered ONLY by `server/packaged.ts`.
|
|
71
|
+
* `dev.ts` is untouched — it has one React already.
|
|
72
|
+
*/
|
|
73
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
74
|
+
import { createRequire } from 'node:module';
|
|
75
|
+
import path from 'node:path';
|
|
76
|
+
import { EDITOR_LANE_DIRS } from '@volter/editor-sdk/session/tool-contribution-convention';
|
|
77
|
+
import type { Plugin } from 'vite';
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* The published specifiers, and the rollup chunk NAME each appears under.
|
|
81
|
+
*
|
|
82
|
+
* The membership rule is one sentence: **a module belongs here when it CALLS
|
|
83
|
+
* React hooks while rendering inside the editor's tree.** React itself is the
|
|
84
|
+
* obvious case; a third-party component is the non-obvious one, and it fails
|
|
85
|
+
* exactly as loudly — its `useState`/`useId` read a different dispatcher than
|
|
86
|
+
* the tree reconciling it, which is "Invalid hook call" again with the
|
|
87
|
+
* project's name nowhere in the stack.
|
|
88
|
+
*
|
|
89
|
+
* `@fortawesome/react-fontawesome` is here because it is the ONLY such module
|
|
90
|
+
* `@volter/editor-sdk/widgets` reaches (measured: the kit's whole transitive bare-import
|
|
91
|
+
* closure is `react`, `react-dom`, `@fortawesome/free-solid-svg-icons` — pure
|
|
92
|
+
* path DATA, no React — and this). `SectionHeader` renders its
|
|
93
|
+
* `DisclosureIcon` unconditionally, so before this entry existed every project
|
|
94
|
+
* tool that used the kit's own section header crashed on the packaged path
|
|
95
|
+
* while the tool's own hooks were being redirected correctly.
|
|
96
|
+
*
|
|
97
|
+
* `react-dom/server` is deliberately absent: nothing renders to a string in an
|
|
98
|
+
* editor page, and an entry for it would drag React's server build into every
|
|
99
|
+
* shell bundle.
|
|
100
|
+
*
|
|
101
|
+
* KNOWN REMAINING HOLE, same class: any OTHER bare dependency a contribution
|
|
102
|
+
* renders calls its own prebundled React, and adding it here is not always the
|
|
103
|
+
* answer. `@pixi/react` is the worked case and the reason this paragraph
|
|
104
|
+
* exists — a doorway for it hands the editor's tree the SHELL's `@pixi/react`
|
|
105
|
+
* and therefore the shell's `pixi.js`, while the contribution's own
|
|
106
|
+
* `Texture`/`Assets` stay the project's: one renderer looking at another
|
|
107
|
+
* renderer's textures, the same renderer-instance split that broke Play mode
|
|
108
|
+
* when the game was redirected. The `sprite` capability's Sprite Lab took the
|
|
109
|
+
* other exit instead — it drives plain `pixi.js` imperatively
|
|
110
|
+
* (`sprite-lab/stage.ts`), because `pixi.js` calls no React hooks and so
|
|
111
|
+
* crosses nothing. Reach for that shape first; a new line in this map is for a
|
|
112
|
+
* dependency whose whole job IS rendering in the editor's tree.
|
|
113
|
+
*/
|
|
114
|
+
export const SHARED_REACT_ENTRIES = {
|
|
115
|
+
react: 'vgai-shared-react',
|
|
116
|
+
'react-dom': 'vgai-shared-react-dom',
|
|
117
|
+
'react-dom/client': 'vgai-shared-react-dom-client',
|
|
118
|
+
'react/jsx-runtime': 'vgai-shared-jsx-runtime',
|
|
119
|
+
'react/jsx-dev-runtime': 'vgai-shared-jsx-dev-runtime',
|
|
120
|
+
'@fortawesome/react-fontawesome': 'vgai-shared-fontawesome',
|
|
121
|
+
|
|
122
|
+
} as const satisfies Record<string, string>;
|
|
123
|
+
|
|
124
|
+
export type SharedReactSpecifier = keyof typeof SHARED_REACT_ENTRIES;
|
|
125
|
+
|
|
126
|
+
/** The specifiers this plugin owns — the same list `packaged.ts` keeps out of
|
|
127
|
+
* dependency prebundling, exported so the two can never drift apart. */
|
|
128
|
+
export const SHARED_REACT_SPECIFIERS = Object.keys(SHARED_REACT_ENTRIES) as SharedReactSpecifier[];
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* The emitted map, written beside the built shell. NOT `.vite/manifest.json`:
|
|
132
|
+
* this file is read out of an INSTALLED tarball, and a dot-directory is one
|
|
133
|
+
* more thing that has to survive `npm pack`.
|
|
134
|
+
*/
|
|
135
|
+
export const SHARED_REACT_MANIFEST_FILE = 'vgai-shared-react.json';
|
|
136
|
+
|
|
137
|
+
export interface SharedReactManifest {
|
|
138
|
+
/** Bare specifier → outDir-relative built chunk file (`assets/…js`). */
|
|
139
|
+
files: Record<string, string>;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const VIRTUAL_PREFIX = '\0vgai-shared-react:';
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* The body of one entry: every export the installed package actually has, read
|
|
146
|
+
* off that package's own module object.
|
|
147
|
+
*
|
|
148
|
+
* `__ns.default ?? __ns` covers both shapes this has to handle — a CommonJS
|
|
149
|
+
* package (rollup's interop puts `module.exports` on `default`) and a real ES
|
|
150
|
+
* module (the root Vite config aliases `react/jsx-dev-runtime` to
|
|
151
|
+
* `src/jsx-dev-runtime-prod-shim.ts` for builds, because production React
|
|
152
|
+
* stubs `jsxDEV` to `undefined`).
|
|
153
|
+
*/
|
|
154
|
+
export function sharedReactEntryModule(specifier: string, exportNames: readonly string[]): string {
|
|
155
|
+
const named = exportNames
|
|
156
|
+
.filter((name) => VALID_IDENTIFIER.test(name))
|
|
157
|
+
.map((name) => `export const ${name} = __m.${name};`);
|
|
158
|
+
return [
|
|
159
|
+
`import * as __ns from ${JSON.stringify(specifier)};`,
|
|
160
|
+
// Bracketed on purpose: `__ns.default` makes rollup warn that the ES-module
|
|
161
|
+
// shape (the jsx-dev-runtime shim) has no `default` export, which is the
|
|
162
|
+
// case this line exists to handle.
|
|
163
|
+
"const __m = __ns['default'] ?? __ns;",
|
|
164
|
+
'export default __m;',
|
|
165
|
+
...named,
|
|
166
|
+
'',
|
|
167
|
+
].join('\n');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const VALID_IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
171
|
+
|
|
172
|
+
/** The runtime export names of an installed package, resolved from `fromDir`. */
|
|
173
|
+
export function installedExportNames(fromDir: string, specifier: string): string[] {
|
|
174
|
+
const require_ = createRequire(path.join(fromDir, 'package.json'));
|
|
175
|
+
// biome-ignore lint/suspicious/noExplicitAny: reading an arbitrary package's runtime shape.
|
|
176
|
+
const loaded = require_(specifier) as Record<string, any>;
|
|
177
|
+
return Object.keys(loaded).filter((name) => name !== 'default');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* BUILD side: emit the five entry chunks and the manifest naming them.
|
|
182
|
+
*
|
|
183
|
+
* `fromDir` is the directory whose `node_modules` the React being published
|
|
184
|
+
* comes from — the repo root for this build, which is the same React the shell
|
|
185
|
+
* itself bundles.
|
|
186
|
+
*/
|
|
187
|
+
export function sharedReactBuildPlugin(fromDir: string): Plugin {
|
|
188
|
+
const referenceIds = new Map<SharedReactSpecifier, string>();
|
|
189
|
+
return {
|
|
190
|
+
name: 'vgai-shared-react-build',
|
|
191
|
+
apply: 'build',
|
|
192
|
+
buildStart() {
|
|
193
|
+
referenceIds.clear();
|
|
194
|
+
for (const specifier of SHARED_REACT_SPECIFIERS) {
|
|
195
|
+
referenceIds.set(
|
|
196
|
+
specifier,
|
|
197
|
+
this.emitFile({
|
|
198
|
+
type: 'chunk',
|
|
199
|
+
id: `${VIRTUAL_PREFIX}${specifier}`,
|
|
200
|
+
name: SHARED_REACT_ENTRIES[specifier],
|
|
201
|
+
// Vite's app build sets `preserveEntrySignatures: false`, which
|
|
202
|
+
// mangles an entry's export names away. Per-chunk `strict` is what
|
|
203
|
+
// keeps `useState` spelled `useState` in the emitted file — the
|
|
204
|
+
// whole point of publishing it.
|
|
205
|
+
preserveSignature: 'strict',
|
|
206
|
+
}),
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
resolveId(id) {
|
|
211
|
+
return id.startsWith(VIRTUAL_PREFIX) ? id : undefined;
|
|
212
|
+
},
|
|
213
|
+
load(id) {
|
|
214
|
+
if (!id.startsWith(VIRTUAL_PREFIX)) return undefined;
|
|
215
|
+
const specifier = id.slice(VIRTUAL_PREFIX.length);
|
|
216
|
+
return sharedReactEntryModule(specifier, installedExportNames(fromDir, specifier));
|
|
217
|
+
},
|
|
218
|
+
generateBundle() {
|
|
219
|
+
const files: Record<string, string> = {};
|
|
220
|
+
for (const [specifier, referenceId] of referenceIds) {
|
|
221
|
+
files[specifier] = this.getFileName(referenceId);
|
|
222
|
+
}
|
|
223
|
+
this.emitFile({
|
|
224
|
+
type: 'asset',
|
|
225
|
+
fileName: SHARED_REACT_MANIFEST_FILE,
|
|
226
|
+
source: `${JSON.stringify({ files } satisfies SharedReactManifest, null, 2)}\n`,
|
|
227
|
+
});
|
|
228
|
+
},
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** The manifest a built `dist/` carries, or `null` when it predates this build
|
|
233
|
+
* step (an old tarball, or a checkout whose `dist/` was never rebuilt). */
|
|
234
|
+
export function readSharedReactManifest(distPath: string): SharedReactManifest | null {
|
|
235
|
+
const manifestPath = path.join(distPath, SHARED_REACT_MANIFEST_FILE);
|
|
236
|
+
if (!existsSync(manifestPath)) return null;
|
|
237
|
+
let manifest: SharedReactManifest;
|
|
238
|
+
try {
|
|
239
|
+
manifest = JSON.parse(readFileSync(manifestPath, 'utf8')) as SharedReactManifest;
|
|
240
|
+
} catch {
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
if (SHARED_REACT_SPECIFIERS.some((specifier) => !manifest.files?.[specifier])) return null;
|
|
244
|
+
return manifest;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Specifier → URL, from a manifest. `base` is the built shell's own base (`/`
|
|
249
|
+
* for the packaged build), so these URLs are byte-identical to the ones the
|
|
250
|
+
* shell's bundle imports. That identity IS the fix: a differently-spelled URL
|
|
251
|
+
* for the same file is a second React.
|
|
252
|
+
*/
|
|
253
|
+
export function sharedReactUrls(manifest: SharedReactManifest, base = '/'): Record<string, string> {
|
|
254
|
+
const prefix = base.endsWith('/') ? base : `${base}/`;
|
|
255
|
+
return Object.fromEntries(
|
|
256
|
+
SHARED_REACT_SPECIFIERS.map((specifier) => [
|
|
257
|
+
specifier,
|
|
258
|
+
`${prefix}${manifest.files[specifier]}`,
|
|
259
|
+
]),
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* The query that marks a module as part of the EDITOR TREE — the same
|
|
265
|
+
* "the query IS the scope" device `vite-plugin-mount-isolation.ts` uses.
|
|
266
|
+
* Queries survive `cleanUrl`, so every other plugin's `.tsx` scope test still
|
|
267
|
+
* matches a marked module.
|
|
268
|
+
*/
|
|
269
|
+
export const EDITOR_TREE_QUERY = 'vgai-editor-react';
|
|
270
|
+
|
|
271
|
+
/** A file inside a `@vgai/*` package's `contributions/` directory under any
|
|
272
|
+
* `node_modules` (a real install; in a checkout the package is a symlink
|
|
273
|
+
* whose realpath is its workspace directory, already `isOwnSource`). */
|
|
274
|
+
const PACKAGE_CONTRIBUTION_PATH = /[\\/]node_modules[\\/]@vgai[\\/][^\\/]+[\\/]contributions[\\/]/;
|
|
275
|
+
|
|
276
|
+
function markEditorTree(id: string): string {
|
|
277
|
+
return id.includes(`?${EDITOR_TREE_QUERY}`) || id.includes(`&${EDITOR_TREE_QUERY}`)
|
|
278
|
+
? id
|
|
279
|
+
: `${id}${id.includes('?') ? '&' : '?'}${EDITOR_TREE_QUERY}`;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function stripQuery(id: string): string {
|
|
283
|
+
const cut = id.indexOf('?');
|
|
284
|
+
return cut === -1 ? id : id.slice(0, cut);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function isUnder(file: string, directory: string): boolean {
|
|
288
|
+
return file === directory || file.startsWith(`${directory}${path.sep}`);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
export interface SharedReactScope {
|
|
292
|
+
/** Specifier → built chunk URL (see {@link sharedReactUrls}). */
|
|
293
|
+
urls: Record<string, string>;
|
|
294
|
+
/** The installed `@vgai/editor` package root — its `src/` is `@editor/*`. */
|
|
295
|
+
editorPackageRoot: string;
|
|
296
|
+
/** Every open project root, live (the same getter the sibling plugins take). */
|
|
297
|
+
projectRoots: () => Set<string>;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* SERVE side: point the EDITOR TREE's React specifiers at the shell's built
|
|
302
|
+
* chunk URLs.
|
|
303
|
+
*
|
|
304
|
+
* ## Scope, and why it is not the whole graph
|
|
305
|
+
*
|
|
306
|
+
* The first version of this redirected React for every module this Vite
|
|
307
|
+
* instance served. It fixed the contributions and BROKE Play mode, loudly and
|
|
308
|
+
* measurably: `@react-three/fiber`'s prebundled `react-reconciler` is a
|
|
309
|
+
* DEVELOPMENT build (Vite prebundles a dev server's deps with
|
|
310
|
+
* `NODE_ENV=development`), and a dev reconciler against the shell's PRODUCTION
|
|
311
|
+
* React reads internals that production React does not have — `TypeError:
|
|
312
|
+
* Cannot read properties of undefined (reading 'push')` inside
|
|
313
|
+
* `updateContainer`, "The current testing environment is not configured to
|
|
314
|
+
* support act(...)", and finally `r3f-adapter: onCreated did not fire within
|
|
315
|
+
* 10s`. The DEV/PROD boundary is real: the shell ships a production React and
|
|
316
|
+
* the project's own graph is a development graph.
|
|
317
|
+
*
|
|
318
|
+
* So the seam is drawn where the RENDERING is: a module that renders inside
|
|
319
|
+
* the editor's own React tree uses the editor's React; the game — mounted by
|
|
320
|
+
* `createRoot` into its own isolated tree, with its own dev React and its own
|
|
321
|
+
* dev reconciler, internally consistent — keeps the project's. That is the
|
|
322
|
+
* same line `vite-plugin-module-doorways.ts` already draws for the mount
|
|
323
|
+
* call, and it is why Play mode works today.
|
|
324
|
+
*
|
|
325
|
+
* ## How the scope is decided
|
|
326
|
+
*
|
|
327
|
+
* An importer is in the editor tree when it is:
|
|
328
|
+
* - a project's `src/contributions/**` or `src/tools/**` module (the editor
|
|
329
|
+
* lanes shared with the contribution loader),
|
|
330
|
+
* - a file under the installed editor package's own `src/` (what `@editor/*`
|
|
331
|
+
* aliases to — the widget kit contributions build their panels from), or
|
|
332
|
+
* - anything already MARKED, which is how the scope propagates.
|
|
333
|
+
*
|
|
334
|
+
* Propagation is what makes this cover the real graph rather than one folder:
|
|
335
|
+
* `src/tools/data-tables.document.tsx` renders React components that live in
|
|
336
|
+
* `src/lib/data-tables/`, and a contribution may reach any project module. So
|
|
337
|
+
* when an editor-tree module imports another PROJECT-OWNED source file, the
|
|
338
|
+
* resolved id is marked and its own imports inherit the scope. Bare
|
|
339
|
+
* dependencies are deliberately NOT marked: they are prebundled, and a
|
|
340
|
+
* prebundled chunk's React is decided at prebundle time, not here.
|
|
341
|
+
* `@volter/editor-sdk/widgets` is the one dependency that must therefore be kept
|
|
342
|
+
* OUT of `optimizeDeps` (`packaged.ts` excludes it) — it renders in the editor's tree
|
|
343
|
+
* and has to be source-served for this scope to reach it.
|
|
344
|
+
*
|
|
345
|
+
* `enforce: 'pre'` so this runs ahead of Vite's own resolver and its alias
|
|
346
|
+
* plugin. The returned React id is a root-relative URL, not a filesystem path:
|
|
347
|
+
* Vite's import analysis leaves an id it cannot map into the project root as
|
|
348
|
+
* the literal import URL, and the packaged server's `express.static(dist)`
|
|
349
|
+
* answers it — so the browser fetches the same `/assets/…` file the shell
|
|
350
|
+
* already loaded.
|
|
351
|
+
*/
|
|
352
|
+
export function sharedReactPlugin({
|
|
353
|
+
urls,
|
|
354
|
+
editorPackageRoot,
|
|
355
|
+
projectRoots,
|
|
356
|
+
}: SharedReactScope): Plugin {
|
|
357
|
+
const editorSrc = path.join(editorPackageRoot, 'src');
|
|
358
|
+
const layoutSdkSrc = path.resolve(editorPackageRoot, '../editor-sdk/src');
|
|
359
|
+
const inEditorTree = (importer: string | undefined): boolean => {
|
|
360
|
+
if (!importer) return false;
|
|
361
|
+
if (importer.includes(EDITOR_TREE_QUERY)) return true;
|
|
362
|
+
const file = stripQuery(importer);
|
|
363
|
+
if (isUnder(file, editorSrc) || isUnder(file, layoutSdkSrc)) return true;
|
|
364
|
+
// A skew PACKAGE's contribution (`node_modules/@vgai/<pkg>/contributions/`)
|
|
365
|
+
// renders in the editor's tree exactly as a project's own contribution
|
|
366
|
+
// does, so it takes the shell's React and SDK. Only the contributions
|
|
367
|
+
// directory: the same package's `src/` is also game runtime (a mesh
|
|
368
|
+
// component in a world), and a game keeps its own React.
|
|
369
|
+
if (PACKAGE_CONTRIBUTION_PATH.test(file)) return true;
|
|
370
|
+
for (const root of projectRoots()) {
|
|
371
|
+
if (file === path.join(root, 'vgai.adapter.ts')) return true;
|
|
372
|
+
if (EDITOR_LANE_DIRS.some((dir) => isUnder(file, path.join(root, dir)))) return true;
|
|
373
|
+
}
|
|
374
|
+
return false;
|
|
375
|
+
};
|
|
376
|
+
/** Project-owned source the scope propagates into — never a bare dep. */
|
|
377
|
+
const isOwnSource = (file: string): boolean => {
|
|
378
|
+
if (!path.isAbsolute(file)) return false;
|
|
379
|
+
if (isUnder(file, editorSrc) || isUnder(file, layoutSdkSrc)) return true;
|
|
380
|
+
if (file.includes(`${path.sep}node_modules${path.sep}`)) return false;
|
|
381
|
+
for (const root of projectRoots()) {
|
|
382
|
+
if (isUnder(file, root)) return true;
|
|
383
|
+
}
|
|
384
|
+
return false;
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
return {
|
|
388
|
+
name: 'vgai-shared-react',
|
|
389
|
+
enforce: 'pre',
|
|
390
|
+
async resolveId(source, importer, options) {
|
|
391
|
+
// Never during dependency SCANNING. The scanner records whatever an id
|
|
392
|
+
// resolves to as a file to prebundle, so handing it the shell's URL made
|
|
393
|
+
// the boot-time optimizer die on `ENOENT: open
|
|
394
|
+
// '/assets/vgai-shared-jsx-runtime-*.js'` — measured, on the first run
|
|
395
|
+
// after this scope existed. The redirect belongs to serving, where the
|
|
396
|
+
// browser is the thing fetching the URL.
|
|
397
|
+
// `scan` is Vite's own flag on the resolve options, not part of rollup's
|
|
398
|
+
// published type — hence the cast rather than a widened signature.
|
|
399
|
+
//
|
|
400
|
+
// The scan is not the only server-side pass that follows this redirect:
|
|
401
|
+
// import analysis PRE-TRANSFORMS every static import it rewrites, and a
|
|
402
|
+
// warmup for `/assets/vgai-shared-*.js` resolves against the project root
|
|
403
|
+
// and fails the same way (measured: 64 formatted `Pre-transform error`
|
|
404
|
+
// lines from one `*.inspector.tsx` request). Vite has no per-request
|
|
405
|
+
// opt-out there, so `packaged.ts` turns `server.preTransformRequests` off
|
|
406
|
+
// for its instance — see the comment on that option for why satisfying
|
|
407
|
+
// the warmup instead would pull the whole prebuilt SPA into the project's
|
|
408
|
+
// dev module graph.
|
|
409
|
+
if ((options as { scan?: boolean } | undefined)?.scan) return undefined;
|
|
410
|
+
if (!inEditorTree(importer)) return undefined;
|
|
411
|
+
const url = urls[source];
|
|
412
|
+
if (url) return url;
|
|
413
|
+
const resolved = await this.resolve(source, importer, { ...options, skipSelf: true });
|
|
414
|
+
if (!resolved || resolved.external) return resolved ?? undefined;
|
|
415
|
+
return isOwnSource(stripQuery(resolved.id))
|
|
416
|
+
? { ...resolved, id: markEditorTree(resolved.id) }
|
|
417
|
+
: resolved;
|
|
418
|
+
},
|
|
419
|
+
};
|
|
420
|
+
}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ONE three.js for the whole page — the editor shell's.
|
|
3
|
+
*
|
|
4
|
+
* ## The defect this closes (WORK.md P2, "Packaged shell loads three.js twice")
|
|
5
|
+
*
|
|
6
|
+
* Under the PACKAGED runtime (`server/packaged.ts`: a `@vgai/editor` npm
|
|
7
|
+
* package with no monorepo checkout) the page runs two module graphs at once:
|
|
8
|
+
*
|
|
9
|
+
* - the editor shell, a PREBUILT production bundle (`dist/assets/index-*.js`)
|
|
10
|
+
* with its own `three` inlined — the viewport renderer, the gizmos, the
|
|
11
|
+
* selection outline and ~100 other shell modules import it, so it evaluates
|
|
12
|
+
* at boot; and
|
|
13
|
+
* - the opened PROJECT's source, served fresh by a second, project-rooted
|
|
14
|
+
* Vite instance, whose bare `three` resolves — correctly, for its root — to
|
|
15
|
+
* the PROJECT's own `node_modules` (prebundled into `.vite/deps/three.js`).
|
|
16
|
+
*
|
|
17
|
+
* three's own module body runs `if (window.__THREE__) console.warn('WARNING:
|
|
18
|
+
* Multiple instances of Three.js being imported.')` on evaluation, so the
|
|
19
|
+
* SECOND graph's copy trips the guard. That warning is not cosmetic: it keeps
|
|
20
|
+
* `vgai console` from reaching exit-0, a hard gate. `dev.ts` never sees it —
|
|
21
|
+
* one Vite instance, and the repo-root `vite.config.ts`'s
|
|
22
|
+
* `resolve.dedupe: ['three', …]` already collapses the project's copy onto the
|
|
23
|
+
* editor's — so nothing in a checkout ever reproduced it.
|
|
24
|
+
*
|
|
25
|
+
* ## The mechanism: URL identity (the sibling of `vite-plugin-shared-react.ts`)
|
|
26
|
+
*
|
|
27
|
+
* The editor build emits one extra ENTRY chunk for `three`
|
|
28
|
+
* ({@link sharedThreeBuildPlugin}) — the SHELL's own three. Because it is an
|
|
29
|
+
* entry of the SAME build, rollup hoists the actual module into a chunk both it
|
|
30
|
+
* and the shell import: it is not a copy of three, it is a doorway onto the
|
|
31
|
+
* shell's instance. At serve time {@link sharedThreePlugin} resolves the bare
|
|
32
|
+
* `three` specifier, for the whole PROJECT graph, to that built chunk's URL
|
|
33
|
+
* (`/assets/vgai-shared-three-<hash>.js`) — the SAME absolute URL the shell's
|
|
34
|
+
* own bundle imports, so the browser's module map hands both sides the one
|
|
35
|
+
* instance and three's body evaluates exactly once.
|
|
36
|
+
*
|
|
37
|
+
* ## Why the scope is the WHOLE project graph — unlike shared-React
|
|
38
|
+
*
|
|
39
|
+
* `sharedReactPlugin` deliberately redirects react only for the EDITOR TREE and
|
|
40
|
+
* leaves the GAME on the project's own (development) react, because React ships
|
|
41
|
+
* distinct dev/prod builds and its prebundled DEVELOPMENT reconciler must not
|
|
42
|
+
* run against the shell's PRODUCTION React (that broke Play mode, measured in
|
|
43
|
+
* that plugin's header). three has NO such split — it is one build — and
|
|
44
|
+
* `dev.ts`'s `resolve.dedupe` already proves the correct answer is ONE three
|
|
45
|
+
* for editor AND game together (the R3F entry runtime already hands Fiber's
|
|
46
|
+
* catalogue `host.three`, so a world's objects, Fiber's intrinsics and the
|
|
47
|
+
* editor viewport that adopts them must all be the SAME three or `applyProps`
|
|
48
|
+
* mis-types — see `r3f-entry-runtime.ts`). So this redirect is unscoped: every
|
|
49
|
+
* project-graph `three` import becomes the shell's one instance.
|
|
50
|
+
*
|
|
51
|
+
* ## Ingest keeps its own three — for free, by construction
|
|
52
|
+
*
|
|
53
|
+
* An INGEST root's premise is a vendored game that brought its own three. Two
|
|
54
|
+
* shapes, both preserved without a special case here:
|
|
55
|
+
*
|
|
56
|
+
* - a SOURCE game (its modules served by this same project-rooted Vite) has
|
|
57
|
+
* its bare `three` DEDUPED to the editor's instance already under `dev.ts`
|
|
58
|
+
* (see `ingest/resolve-three.ts`'s header, and the `cov-bundled-dedupe`
|
|
59
|
+
* e2e). This redirect is the packaged analogue of that dedupe — the source
|
|
60
|
+
* game lands on the shell's three exactly as it lands on the editor's in a
|
|
61
|
+
* checkout, and the three-ingest doorway's `projectThree` (which goes
|
|
62
|
+
* through this same resolver) lands there too, so the capture trap and the
|
|
63
|
+
* game agree;
|
|
64
|
+
* - a PRE-BUILT BUNDLE game inlines its own three into a blob/`public/` URL
|
|
65
|
+
* that never passes through a bare-specifier resolve, so this plugin cannot
|
|
66
|
+
* and does not touch it — it keeps its own copy, the case the doorway
|
|
67
|
+
* header calls out as inherently un-shareable.
|
|
68
|
+
*
|
|
69
|
+
* For the redirect to reach `@react-three/fiber`'s OWN `import 'three'`,
|
|
70
|
+
* `packaged.ts` also `optimizeDeps.exclude`s `three`: an excluded dep is
|
|
71
|
+
* externalized out of every prebundled chunk and resolved at serve time, where
|
|
72
|
+
* this plugin answers. Prebundling it instead would bake a second, un-
|
|
73
|
+
* redirectable three chunk into `.vite/deps` — exactly the duplicate this
|
|
74
|
+
* plugin removes.
|
|
75
|
+
*
|
|
76
|
+
* {@link sharedThreePlugin} is registered ONLY by `server/packaged.ts`.
|
|
77
|
+
* `dev.ts` is untouched — it has one three already.
|
|
78
|
+
*/
|
|
79
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
80
|
+
import path from 'node:path';
|
|
81
|
+
import type { Plugin } from 'vite';
|
|
82
|
+
import { installedExportNames, sharedReactEntryModule } from './vite-plugin-shared-react.js';
|
|
83
|
+
|
|
84
|
+
/** The bare specifier this plugin owns. three's `window.__THREE__` guard lives
|
|
85
|
+
* in its main entry (`three/build/three.core.js`, re-exported by `three`), so
|
|
86
|
+
* collapsing the main entry collapses the duplicate-instance warning; addons
|
|
87
|
+
* (`three/addons/*`, `three/examples/jsm/*`) import bare `three` internally and
|
|
88
|
+
* ride this same redirect. */
|
|
89
|
+
export const SHARED_THREE_SPECIFIER = 'three';
|
|
90
|
+
|
|
91
|
+
/** The rollup chunk NAME the shell's three is emitted under. */
|
|
92
|
+
export const SHARED_THREE_ENTRY_NAME = 'vgai-shared-three';
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* The emitted map, written beside the built shell — the sibling of
|
|
96
|
+
* `vgai-shared-react.json`, kept a SEPARATE file so an editor build that
|
|
97
|
+
* predates one manifest but not the other degrades one lane at a time.
|
|
98
|
+
*/
|
|
99
|
+
export const SHARED_THREE_MANIFEST_FILE = 'vgai-shared-three.json';
|
|
100
|
+
|
|
101
|
+
export interface SharedThreeManifest {
|
|
102
|
+
/** outDir-relative built chunk file (`assets/…js`) for `three`. */
|
|
103
|
+
file: string;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const VIRTUAL_PREFIX = '\0vgai-shared-three:';
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* BUILD side: emit the `three` entry chunk and the manifest naming it.
|
|
110
|
+
*
|
|
111
|
+
* `fromDir` is the directory whose `node_modules` the three being published
|
|
112
|
+
* comes from — the repo root for this build, which is the same three the shell
|
|
113
|
+
* itself bundles. The entry body is generated from the installed package's own
|
|
114
|
+
* runtime key list ({@link sharedReactEntryModule} / {@link installedExportNames}
|
|
115
|
+
* — generic over the specifier despite the React-shaped names), so it cannot
|
|
116
|
+
* drift from the installed three and needs no hand-maintained export list.
|
|
117
|
+
*/
|
|
118
|
+
export function sharedThreeBuildPlugin(fromDir: string): Plugin {
|
|
119
|
+
let referenceId: string | null = null;
|
|
120
|
+
return {
|
|
121
|
+
name: 'vgai-shared-three-build',
|
|
122
|
+
apply: 'build',
|
|
123
|
+
buildStart() {
|
|
124
|
+
referenceId = this.emitFile({
|
|
125
|
+
type: 'chunk',
|
|
126
|
+
id: `${VIRTUAL_PREFIX}${SHARED_THREE_SPECIFIER}`,
|
|
127
|
+
name: SHARED_THREE_ENTRY_NAME,
|
|
128
|
+
// Same reason as the shared-React entries: Vite's app build sets
|
|
129
|
+
// `preserveEntrySignatures: false`, which would mangle the entry's
|
|
130
|
+
// export names away — `strict` keeps `Mesh` spelled `Mesh`.
|
|
131
|
+
preserveSignature: 'strict',
|
|
132
|
+
});
|
|
133
|
+
},
|
|
134
|
+
resolveId(id) {
|
|
135
|
+
return id.startsWith(VIRTUAL_PREFIX) ? id : undefined;
|
|
136
|
+
},
|
|
137
|
+
load(id) {
|
|
138
|
+
if (!id.startsWith(VIRTUAL_PREFIX)) return undefined;
|
|
139
|
+
const specifier = id.slice(VIRTUAL_PREFIX.length);
|
|
140
|
+
return sharedReactEntryModule(specifier, installedExportNames(fromDir, specifier));
|
|
141
|
+
},
|
|
142
|
+
generateBundle() {
|
|
143
|
+
if (!referenceId) return;
|
|
144
|
+
this.emitFile({
|
|
145
|
+
type: 'asset',
|
|
146
|
+
fileName: SHARED_THREE_MANIFEST_FILE,
|
|
147
|
+
source: `${JSON.stringify(
|
|
148
|
+
{ file: this.getFileName(referenceId) } satisfies SharedThreeManifest,
|
|
149
|
+
null,
|
|
150
|
+
2,
|
|
151
|
+
)}\n`,
|
|
152
|
+
});
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** The manifest a built `dist/` carries, or `null` when it predates this build
|
|
158
|
+
* step (an old tarball, or a checkout whose `dist/` was never rebuilt). */
|
|
159
|
+
export function readSharedThreeManifest(distPath: string): SharedThreeManifest | null {
|
|
160
|
+
const manifestPath = path.join(distPath, SHARED_THREE_MANIFEST_FILE);
|
|
161
|
+
if (!existsSync(manifestPath)) return null;
|
|
162
|
+
try {
|
|
163
|
+
const manifest = JSON.parse(readFileSync(manifestPath, 'utf8')) as SharedThreeManifest;
|
|
164
|
+
return manifest.file ? manifest : null;
|
|
165
|
+
} catch {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* The `three` chunk URL, from a manifest. `base` is the built shell's own base
|
|
172
|
+
* (`/` for the packaged build), so this URL is byte-identical to the one the
|
|
173
|
+
* shell's bundle imports. That identity IS the fix: a differently-spelled URL
|
|
174
|
+
* for the same file is a second three.
|
|
175
|
+
*/
|
|
176
|
+
export function sharedThreeUrl(manifest: SharedThreeManifest, base = '/'): string {
|
|
177
|
+
const prefix = base.endsWith('/') ? base : `${base}/`;
|
|
178
|
+
return `${prefix}${manifest.file}`;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* SERVE side: point every project-graph `three` import at the shell's built
|
|
183
|
+
* chunk URL. Registered ONLY on the packaged runtime's project-rooted Vite.
|
|
184
|
+
*/
|
|
185
|
+
export function sharedThreePlugin(url: string): Plugin {
|
|
186
|
+
return {
|
|
187
|
+
name: 'vgai-shared-three',
|
|
188
|
+
enforce: 'pre',
|
|
189
|
+
resolveId(source, _importer, options) {
|
|
190
|
+
if (source !== SHARED_THREE_SPECIFIER) return undefined;
|
|
191
|
+
// Never during dependency SCANNING — the scanner records whatever an id
|
|
192
|
+
// resolves to as a file to prebundle, and handing it a `/assets/*` URL
|
|
193
|
+
// makes the boot optimizer die on ENOENT (the exact failure
|
|
194
|
+
// `sharedReactPlugin` documents). Returning undefined lets the scanner
|
|
195
|
+
// resolve `three` normally; because `packaged.ts` `exclude`s it from
|
|
196
|
+
// optimizeDeps, the scanner externalizes it rather than prebundling a
|
|
197
|
+
// second copy. `scan` is Vite's own flag on the resolve options, not part
|
|
198
|
+
// of rollup's published type — hence the cast.
|
|
199
|
+
if ((options as { scan?: boolean } | undefined)?.scan) return undefined;
|
|
200
|
+
return url;
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
}
|