@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,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE ANSWER A STUCK PLAY OWES ITS CALLER.
|
|
3
|
+
*
|
|
4
|
+
* ## What this replaces
|
|
5
|
+
*
|
|
6
|
+
* Measured 2026-08-20 with `packages/editor/scripts/scale-harness`, canvas lane,
|
|
7
|
+
* N=20000, four consecutive runs. `vgai play` spent its full 120s budget and was
|
|
8
|
+
* refused with
|
|
9
|
+
*
|
|
10
|
+
* Command timed out — the tab is present (last heartbeat 0.8s ago) and
|
|
11
|
+
* did not respond.
|
|
12
|
+
*
|
|
13
|
+
* and then `screenshot` (15s) and `stop` (30s) were refused with that same
|
|
14
|
+
* sentence. Three silent timeouts in a row, and every reader — `vgai status`,
|
|
15
|
+
* the tab table, the journal — described a healthy session, because the
|
|
16
|
+
* heartbeat is a WORKER and kept beating at 0.4s while the page's main thread
|
|
17
|
+
* sat inside one 199.5-second synchronous block.
|
|
18
|
+
*
|
|
19
|
+
* The sentence was true and useless. It named the tab (fine), the beat (fine),
|
|
20
|
+
* and nothing about the eight-step boot that was actually stuck.
|
|
21
|
+
*
|
|
22
|
+
* ## The rule
|
|
23
|
+
*
|
|
24
|
+
* The page publishes each play-boot phase BEFORE that phase's work starts
|
|
25
|
+
* (`src/play-boot-phase.ts`), on the control channel, as its own tiny message —
|
|
26
|
+
* never inside the state snapshot, which is the expensive derivation a wedged
|
|
27
|
+
* page cannot produce. So the server always holds the phase the page was
|
|
28
|
+
* ENTERING when it went quiet, and this module turns that into the refusal, the
|
|
29
|
+
* journal row and the console entry.
|
|
30
|
+
*
|
|
31
|
+
* Pure and clock-injected: no I/O, no globals. `test/play-stall.test.ts` drives
|
|
32
|
+
* every branch directly.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
/** What the page last said about its play boot, as the server holds it. */
|
|
36
|
+
export interface PlayPhaseRecord {
|
|
37
|
+
/** The phase being entered, or `null` once the boot settled either way. */
|
|
38
|
+
readonly phase: string | null;
|
|
39
|
+
/** Page clock: when it entered that phase. Never used for arithmetic — the
|
|
40
|
+
* two clocks are not the same clock — only carried for the record. */
|
|
41
|
+
readonly at: number;
|
|
42
|
+
/** The play attempt's ordinal on the page. */
|
|
43
|
+
readonly run: number;
|
|
44
|
+
/** SERVER clock: when this report landed. Every age below is measured from
|
|
45
|
+
* here, because it is the only timestamp both parties agree on. */
|
|
46
|
+
readonly receivedAt: number;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Commands whose timeout is about play whether or not a boot is in flight. */
|
|
50
|
+
const PLAY_FAMILY = new Set(['play', 'restart', 'stop', 'pause', 'resume', 'step']);
|
|
51
|
+
|
|
52
|
+
export interface PlayStallDiagnosis {
|
|
53
|
+
/** The full refusal the caller receives. */
|
|
54
|
+
readonly message: string;
|
|
55
|
+
/** The phase named, or `null` when no boot was in flight. */
|
|
56
|
+
readonly phase: string | null;
|
|
57
|
+
/** How long the page had been in it when the command expired, or `null`. */
|
|
58
|
+
readonly phaseAgeMs: number | null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Compose the refusal for a relayed command that ran out of budget.
|
|
63
|
+
*
|
|
64
|
+
* `base` is the sentence the relay already produces (`Command timed out — the
|
|
65
|
+
* tab is present (…) and did not respond.`). It is kept VERBATIM and only
|
|
66
|
+
* extended: the CLI's own retry classifier matches fragments of these
|
|
67
|
+
* refusals (`vgai-cli/src/play-retry.ts`), and a rewritten message would
|
|
68
|
+
* silently change which failures it treats as retryable.
|
|
69
|
+
*/
|
|
70
|
+
export function playStallDiagnosis(args: {
|
|
71
|
+
readonly command: unknown;
|
|
72
|
+
readonly base: string;
|
|
73
|
+
readonly phase: PlayPhaseRecord | null;
|
|
74
|
+
readonly now: number;
|
|
75
|
+
}): PlayStallDiagnosis {
|
|
76
|
+
const { base, phase, now } = args;
|
|
77
|
+
const command = typeof args.command === 'string' ? args.command : '';
|
|
78
|
+
const booting = phase !== null && phase.phase !== null;
|
|
79
|
+
|
|
80
|
+
if (booting) {
|
|
81
|
+
const ageMs = Math.max(0, now - phase.receivedAt);
|
|
82
|
+
return {
|
|
83
|
+
phase: phase.phase,
|
|
84
|
+
phaseAgeMs: ageMs,
|
|
85
|
+
message:
|
|
86
|
+
`${base} The page is still inside "${phase.phase}" — it entered that step ` +
|
|
87
|
+
`${(ageMs / 1000).toFixed(1)}s ago and has not left it. The page's own main thread is ` +
|
|
88
|
+
'inside that step; the heartbeat above is a worker, which is why the tab looks healthy ' +
|
|
89
|
+
'while nothing the page owns can answer. `volter-editor status` names the same phase, and the ' +
|
|
90
|
+
'session journal has the row.',
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (PLAY_FAMILY.has(command)) {
|
|
95
|
+
const settled = phase === null ? null : Math.max(0, now - phase.receivedAt);
|
|
96
|
+
const when =
|
|
97
|
+
settled === null
|
|
98
|
+
? 'this session has never reported one'
|
|
99
|
+
: `the last one settled ${(settled / 1000).toFixed(1)}s ago`;
|
|
100
|
+
return {
|
|
101
|
+
phase: null,
|
|
102
|
+
phaseAgeMs: null,
|
|
103
|
+
message:
|
|
104
|
+
`${base} No play boot is in flight (${when}), so the page went quiet somewhere other ` +
|
|
105
|
+
'than play start — a heartbeat proves the tab, never the page.',
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return { phase: null, phaseAgeMs: null, message: base };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* The console-ledger condition text for a stalled command.
|
|
114
|
+
*
|
|
115
|
+
* Deliberately keyed on the PHASE and not on the elapsed time: the ledger
|
|
116
|
+
* fingerprints on the message, so putting a duration in it would make every
|
|
117
|
+
* occurrence a fresh condition and turn a repeating stall into a wall of
|
|
118
|
+
* one-count rows — the exact dedup failure `console-ledger.ts` exists to
|
|
119
|
+
* prevent, in the other direction.
|
|
120
|
+
*/
|
|
121
|
+
export function playStallConsoleMessage(command: unknown, phase: string | null): string {
|
|
122
|
+
const verb = typeof command === 'string' && command.length > 0 ? command : 'a command';
|
|
123
|
+
return phase === null
|
|
124
|
+
? `\`${verb}\` timed out against a beating tab whose page never answered, with no play boot in flight.`
|
|
125
|
+
: `\`${verb}\` timed out while the page was inside "${phase}".`;
|
|
126
|
+
}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { type ChildProcess, execFileSync } from 'node:child_process';
|
|
2
|
+
import type { Server } from 'node:http';
|
|
3
|
+
|
|
4
|
+
/** How long a detached child gets between SIGTERM and SIGKILL when its caller
|
|
5
|
+
* does not say. A caller INSIDE the session's shutdown list passes a smaller
|
|
6
|
+
* number, because its own budget is smaller than this — see
|
|
7
|
+
* `createProcessShutdown`'s note on the arithmetic. */
|
|
8
|
+
const DEFAULT_STOP_GRACE_MS = 5_000;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Terminate a detached child and its whole process tree. Shared by the e2e
|
|
12
|
+
* server harness and the packaged E2E runner: keeping this under `server/`
|
|
13
|
+
* makes the runtime utility part of the editor package instead of forcing a
|
|
14
|
+
* published command to import an unshipped e2e helper.
|
|
15
|
+
*
|
|
16
|
+
* `graceMs` is the SIGTERM→SIGKILL window. It is a parameter because the
|
|
17
|
+
* session's shutdown list has a tighter budget than this default: a child that
|
|
18
|
+
* outlives its caller's own exit is an ORPHAN holding a reserved port, so the
|
|
19
|
+
* escalation has to complete inside the caller's window, not after it.
|
|
20
|
+
*/
|
|
21
|
+
export function stopProcess(proc: ChildProcess, graceMs = DEFAULT_STOP_GRACE_MS): Promise<void> {
|
|
22
|
+
const signalGroup = (signal: NodeJS.Signals) => {
|
|
23
|
+
if (proc.pid === undefined) return;
|
|
24
|
+
if (process.platform === 'win32') {
|
|
25
|
+
try {
|
|
26
|
+
execFileSync('taskkill', ['/PID', String(proc.pid), '/T', '/F'], { stdio: 'ignore' });
|
|
27
|
+
} catch {
|
|
28
|
+
/* already dead, or taskkill unavailable */
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
proc.kill(signal);
|
|
32
|
+
} catch {
|
|
33
|
+
/* already dead */
|
|
34
|
+
}
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
process.kill(-proc.pid, signal);
|
|
39
|
+
} catch {
|
|
40
|
+
try {
|
|
41
|
+
proc.kill(signal);
|
|
42
|
+
} catch {
|
|
43
|
+
/* already dead */
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
return new Promise((resolve) => {
|
|
49
|
+
if (proc.exitCode !== null || proc.signalCode !== null) {
|
|
50
|
+
signalGroup('SIGKILL');
|
|
51
|
+
resolve();
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const timer = setTimeout(() => {
|
|
55
|
+
signalGroup('SIGKILL');
|
|
56
|
+
resolve();
|
|
57
|
+
}, graceMs);
|
|
58
|
+
proc.on('exit', () => {
|
|
59
|
+
clearTimeout(timer);
|
|
60
|
+
signalGroup('SIGKILL');
|
|
61
|
+
resolve();
|
|
62
|
+
});
|
|
63
|
+
signalGroup('SIGTERM');
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* ONE RESOURCE THIS SESSION IS STOPPING, and the name a post-mortem will read.
|
|
69
|
+
*
|
|
70
|
+
* The name is required because the failure this list exists to survive is
|
|
71
|
+
* UNATTENDED: a task that never settles is only visible as the ABSENCE of
|
|
72
|
+
* everything after it, and "cleanup timed out" with no name leaves a reader
|
|
73
|
+
* guessing which resource is still alive.
|
|
74
|
+
*/
|
|
75
|
+
export interface ShutdownTask {
|
|
76
|
+
/** What this stops, in the words a journal line should carry. */
|
|
77
|
+
readonly name: string;
|
|
78
|
+
run(): void | Promise<void>;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface ProcessShutdownOptions {
|
|
82
|
+
/** The WHOLE list's backstop. Bigger than `taskTimeoutMs` and nothing more:
|
|
83
|
+
* with every task bounded and independent, the list's own duration is the
|
|
84
|
+
* slowest task's, and this only catches a bug in the bounding itself. */
|
|
85
|
+
timeoutMs?: number;
|
|
86
|
+
/** Each task's OWN bound. See the note on `createProcessShutdown`. */
|
|
87
|
+
taskTimeoutMs?: number;
|
|
88
|
+
tasks: ReadonlyArray<ShutdownTask>;
|
|
89
|
+
exit?: (code: number) => void;
|
|
90
|
+
log?: (message: string) => void;
|
|
91
|
+
/** Where a task that did not finish, or threw, is RECORDED — the session
|
|
92
|
+
* journal, handed in by the host because this module owns no project. */
|
|
93
|
+
journal?: (record: {
|
|
94
|
+
readonly task: string;
|
|
95
|
+
readonly outcome: 'timeout' | 'failed';
|
|
96
|
+
readonly ms: number;
|
|
97
|
+
readonly detail?: string;
|
|
98
|
+
}) => void;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Stop accepting requests and forcibly release persistent HTTP/SSE sockets. */
|
|
102
|
+
export function closeHttpServer(server: Server): Promise<void> {
|
|
103
|
+
return new Promise((resolve, reject) => {
|
|
104
|
+
if (!server.listening) {
|
|
105
|
+
server.closeAllConnections?.();
|
|
106
|
+
resolve();
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
server.close((error) => (error ? reject(error) : resolve()));
|
|
110
|
+
// `server.close()` waits for persistent SSE/keep-alive connections. They
|
|
111
|
+
// have no useful work after process shutdown begins, so close them after
|
|
112
|
+
// removing the listener and eliminate the restart race on the HTTP port.
|
|
113
|
+
server.closeAllConnections?.();
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Build an idempotent, bounded signal handler.
|
|
119
|
+
*
|
|
120
|
+
* Node's default signal exit is disabled as soon as an application installs
|
|
121
|
+
* a SIGTERM/SIGINT listener. Tooling loaders (notably tsx/esbuild) may retain
|
|
122
|
+
* internal handles even after every application server and watcher closes,
|
|
123
|
+
* so waiting for an empty event loop is not a shutdown contract. Resources
|
|
124
|
+
* get one bounded graceful window and then the process exits explicitly.
|
|
125
|
+
*
|
|
126
|
+
* EVERY TASK RUNS INDEPENDENTLY AND EVERY TASK IS BOUNDED BY ITSELF. Both
|
|
127
|
+
* halves were bought by one measurement (2026-09-21, load average ~30, one
|
|
128
|
+
* `vgai close`): the session's journal had no `session-shutdown` line, the
|
|
129
|
+
* Code-OSS server survived as PPID 1 still holding its reserved `frame` port,
|
|
130
|
+
* and the next `vgai edit` refused by name. A shared bound is what makes one
|
|
131
|
+
* slow resource spend everybody's window, and the arithmetic has to close:
|
|
132
|
+
* `vgai close` SIGTERMs, waits 5.5 s and SIGKILLs the session's process GROUP —
|
|
133
|
+
* which never reaches the Code-OSS server, because that child is spawned
|
|
134
|
+
* detached into a group of its own. So the last of these tasks has to have
|
|
135
|
+
* FINISHED by then, not merely started, or a child outlives its parent with
|
|
136
|
+
* nobody left to signal it.
|
|
137
|
+
*
|
|
138
|
+
* A TASK THAT DOES NOT FINISH IS NAMED (`journal`), because the only other
|
|
139
|
+
* evidence it leaves is the absence of everything downstream of it.
|
|
140
|
+
*/
|
|
141
|
+
export function createProcessShutdown(
|
|
142
|
+
options: ProcessShutdownOptions,
|
|
143
|
+
): (why: string) => Promise<void> {
|
|
144
|
+
// 4 s per task, 4.8 s for the list: the whole shutdown fits inside `vgai
|
|
145
|
+
// close`'s 5.5 s grace with room for the process's own exit, which the old
|
|
146
|
+
// 2 s tab wait plus a 5 s shared cleanup budget did not. The 4 s is sized so
|
|
147
|
+
// a task that must follow the tab-close notice (whose own budget is 2 s)
|
|
148
|
+
// still has ~2 s of its own — see dev.ts's list.
|
|
149
|
+
const taskTimeoutMs = options.taskTimeoutMs ?? 4_000;
|
|
150
|
+
const timeoutMs = options.timeoutMs ?? 4_800;
|
|
151
|
+
const exit = options.exit ?? ((code: number) => process.exit(code));
|
|
152
|
+
const log = options.log ?? ((message: string) => process.stderr.write(`${message}\n`));
|
|
153
|
+
const journal = options.journal ?? (() => {});
|
|
154
|
+
let pending: Promise<void> | null = null;
|
|
155
|
+
|
|
156
|
+
/** One task, bounded by itself. Rejects with the task's NAME in the message,
|
|
157
|
+
* so the aggregate line below reads as a list of resources. */
|
|
158
|
+
const runTask = async (task: ShutdownTask): Promise<void> => {
|
|
159
|
+
const startedAt = Date.now();
|
|
160
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
161
|
+
try {
|
|
162
|
+
const outcome = await Promise.race([
|
|
163
|
+
Promise.resolve(task.run()).then(() => 'done' as const),
|
|
164
|
+
new Promise<'timeout'>((resolve) => {
|
|
165
|
+
timer = setTimeout(() => resolve('timeout'), taskTimeoutMs);
|
|
166
|
+
}),
|
|
167
|
+
]);
|
|
168
|
+
if (outcome === 'timeout') {
|
|
169
|
+
journal({ task: task.name, outcome: 'timeout', ms: Date.now() - startedAt });
|
|
170
|
+
throw new Error(`${task.name} did not finish within ${taskTimeoutMs}ms`);
|
|
171
|
+
}
|
|
172
|
+
} catch (error) {
|
|
173
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
174
|
+
if (!detail.endsWith(`within ${taskTimeoutMs}ms`))
|
|
175
|
+
journal({ task: task.name, outcome: 'failed', ms: Date.now() - startedAt, detail });
|
|
176
|
+
throw error;
|
|
177
|
+
} finally {
|
|
178
|
+
if (timer) clearTimeout(timer);
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
return (why: string) => {
|
|
183
|
+
if (pending) return pending;
|
|
184
|
+
pending = (async () => {
|
|
185
|
+
let timeout: ReturnType<typeof setTimeout> | undefined;
|
|
186
|
+
const cleanup = Promise.allSettled(options.tasks.map(runTask));
|
|
187
|
+
const result = await Promise.race([
|
|
188
|
+
cleanup.then((settled) => ({ type: 'settled' as const, settled })),
|
|
189
|
+
new Promise<{ type: 'timeout' }>((resolve) => {
|
|
190
|
+
timeout = setTimeout(() => resolve({ type: 'timeout' }), timeoutMs);
|
|
191
|
+
}),
|
|
192
|
+
]);
|
|
193
|
+
if (timeout) clearTimeout(timeout);
|
|
194
|
+
|
|
195
|
+
if (result.type === 'timeout') {
|
|
196
|
+
log(`[vgai-editor] cleanup timed out after ${timeoutMs}ms (${why}); forcing exit`);
|
|
197
|
+
exit(1);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const failures = result.settled.filter(
|
|
201
|
+
(item): item is PromiseRejectedResult => item.status === 'rejected',
|
|
202
|
+
);
|
|
203
|
+
if (failures.length > 0) {
|
|
204
|
+
log(
|
|
205
|
+
`[vgai-editor] cleanup failed (${why}): ${failures
|
|
206
|
+
.map((item) =>
|
|
207
|
+
item.reason instanceof Error ? item.reason.message : String(item.reason),
|
|
208
|
+
)
|
|
209
|
+
.join('; ')}`,
|
|
210
|
+
);
|
|
211
|
+
exit(1);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
exit(0);
|
|
215
|
+
})();
|
|
216
|
+
return pending;
|
|
217
|
+
};
|
|
218
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WHAT THIS SESSION'S PRODUCT CAN CREATE — the New Project screen's half of
|
|
3
|
+
* the declaration a product's `bin` reads.
|
|
4
|
+
*
|
|
5
|
+
* CREATION IS THE PRODUCT'S (ARCHITECTURE-CORE §The target shape, rule 1): the
|
|
6
|
+
* presets, their names and what a project declares live in
|
|
7
|
+
* `<product>/presets.mjs`, never in the kit. The CLI reads that file when
|
|
8
|
+
* a person types `<product> create`; this session reads the SAME file, of the
|
|
9
|
+
* SAME product it is already serving, so the wizard and the command line
|
|
10
|
+
* cannot offer different compositions.
|
|
11
|
+
*
|
|
12
|
+
* Plain ESM, dynamically imported: the declaration is a product's code, not a
|
|
13
|
+
* config, and a running session must not compile it.
|
|
14
|
+
*/
|
|
15
|
+
import { existsSync } from 'node:fs';
|
|
16
|
+
import { join } from 'node:path';
|
|
17
|
+
import { pathToFileURL } from 'node:url';
|
|
18
|
+
import { assertProductCreateDeclaration, type ProductCreateDeclaration } from '@volter/editor-sdk/session/product-create';
|
|
19
|
+
import { sessionProduct } from './session-product';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Where a product declares its presets, relative to its package root. Beside
|
|
23
|
+
* `src/`, never inside it: `src/` is the product's FRAME entry — the one module
|
|
24
|
+
* its workbench build compiles — and this declaration is read by Node, at the
|
|
25
|
+
* command line and here, and compiled by nothing.
|
|
26
|
+
*/
|
|
27
|
+
export const PRODUCT_PRESETS_PATH = 'presets.mjs';
|
|
28
|
+
|
|
29
|
+
export interface ProductCreatePresets {
|
|
30
|
+
readonly declaration: ProductCreateDeclaration;
|
|
31
|
+
/** The file it came from — every refusal names it. */
|
|
32
|
+
readonly source: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The create declaration of the product this session serves, or `null` when
|
|
37
|
+
* there is no product to ask (no project open, or a project that declares
|
|
38
|
+
* none). A product that exists but ships no declaration THROWS: it is a broken
|
|
39
|
+
* product, and a wizard silently offering nothing is how that stays unnoticed.
|
|
40
|
+
*/
|
|
41
|
+
export async function sessionCreatePresets(
|
|
42
|
+
projectPath: string | null,
|
|
43
|
+
): Promise<ProductCreatePresets | null> {
|
|
44
|
+
const product = sessionProduct(projectPath);
|
|
45
|
+
if (product === null) return null;
|
|
46
|
+
const source = join(product.dir, PRODUCT_PRESETS_PATH);
|
|
47
|
+
if (!existsSync(source))
|
|
48
|
+
throw new Error(
|
|
49
|
+
`${product.name} declares no create presets (${source} is missing), so this session cannot ` +
|
|
50
|
+
'create a project. A product owns its own compositions — see ' +
|
|
51
|
+
'@volter/editor-sdk/session/product-create for its executable declaration.',
|
|
52
|
+
);
|
|
53
|
+
const module = (await import(pathToFileURL(source).href)) as { default?: unknown };
|
|
54
|
+
return { declaration: assertProductCreateDeclaration(module.default, source), source };
|
|
55
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Packages the OPEN PROJECT'S native `dist/` after its own `npm run build`.
|
|
3
|
+
* The zip is an ordinary web artifact and the report is ephemeral editor
|
|
4
|
+
* telemetry — neither creates an editor-private project format.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { Dirent } from 'node:fs';
|
|
8
|
+
import { mkdir, readdir, readFile, stat, writeFile } from 'node:fs/promises';
|
|
9
|
+
import { dirname, join, relative, resolve, sep } from 'node:path';
|
|
10
|
+
import {
|
|
11
|
+
type BuildReport,
|
|
12
|
+
type BuildReportFile,
|
|
13
|
+
WEB_BUILD_ARTIFACT,
|
|
14
|
+
} from '@volter/editor-sdk/session/build-report';
|
|
15
|
+
import { zipSync } from 'fflate';
|
|
16
|
+
import { resolveManifestPath } from '@volter/editor-project/manifest/locate';
|
|
17
|
+
|
|
18
|
+
interface OutputFile extends BuildReportFile {
|
|
19
|
+
readonly absolutePath: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function portablePath(path: string): string {
|
|
23
|
+
return path.split(sep).join('/');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async function collectFiles(root: string, directory = root): Promise<OutputFile[]> {
|
|
27
|
+
let entries: Dirent[];
|
|
28
|
+
try {
|
|
29
|
+
entries = await readdir(directory, { withFileTypes: true });
|
|
30
|
+
} catch (error) {
|
|
31
|
+
const code = (error as NodeJS.ErrnoException).code;
|
|
32
|
+
if (code === 'ENOENT') {
|
|
33
|
+
throw new Error(
|
|
34
|
+
`The project's build completed without creating ${root}. ` +
|
|
35
|
+
'Its native build script must emit a static dist/ directory.',
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const files: OutputFile[] = [];
|
|
42
|
+
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
43
|
+
const absolutePath = join(directory, entry.name);
|
|
44
|
+
if (entry.isDirectory()) {
|
|
45
|
+
files.push(...(await collectFiles(root, absolutePath)));
|
|
46
|
+
} else if (entry.isFile()) {
|
|
47
|
+
files.push({
|
|
48
|
+
absolutePath,
|
|
49
|
+
path: portablePath(relative(root, absolutePath)),
|
|
50
|
+
bytes: (await stat(absolutePath)).size,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return files;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** The ignored, machine-local artifact used by the editor's Download action. */
|
|
58
|
+
export function projectBuildArtifactPath(projectRoot: string): string {
|
|
59
|
+
return resolve(projectRoot, '.vgai', 'tmp', 'build', WEB_BUILD_ARTIFACT);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export async function packageProjectWebBuild(projectRoot: string): Promise<BuildReport> {
|
|
63
|
+
const distRoot = resolve(projectRoot, 'dist');
|
|
64
|
+
const files = await collectFiles(distRoot);
|
|
65
|
+
if (files.length === 0) {
|
|
66
|
+
throw new Error(`The project's native build emitted an empty ${distRoot}.`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const archive: Record<string, Uint8Array> = Object.create(null) as Record<string, Uint8Array>;
|
|
70
|
+
for (const file of files) archive[file.path] = await readFile(file.absolutePath);
|
|
71
|
+
|
|
72
|
+
// Keep the native manifest beside the static output, matching the existing
|
|
73
|
+
// deploy staging contract. If a custom build already emitted one, the source
|
|
74
|
+
// manifest is the authority and intentionally replaces it.
|
|
75
|
+
archive['vgai.project.json'] = await readFile(resolveManifestPath(projectRoot));
|
|
76
|
+
|
|
77
|
+
const bytes = zipSync(archive, { level: 6 });
|
|
78
|
+
const artifactPath = projectBuildArtifactPath(projectRoot);
|
|
79
|
+
await mkdir(dirname(artifactPath), { recursive: true });
|
|
80
|
+
await writeFile(artifactPath, bytes);
|
|
81
|
+
|
|
82
|
+
const outputBytes = files.reduce((sum, file) => sum + file.bytes, 0);
|
|
83
|
+
const largestFiles = files
|
|
84
|
+
.map(({ path, bytes }) => ({ path, bytes }))
|
|
85
|
+
.sort((a, b) => b.bytes - a.bytes || a.path.localeCompare(b.path))
|
|
86
|
+
.slice(0, 12);
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
artifact: WEB_BUILD_ARTIFACT,
|
|
90
|
+
artifactBytes: bytes.byteLength,
|
|
91
|
+
outputBytes,
|
|
92
|
+
fileCount: files.length,
|
|
93
|
+
largestFiles,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { Dirent } from 'node:fs';
|
|
2
|
+
import { readdir, readFile } from 'node:fs/promises';
|
|
3
|
+
import { join, relative, sep } from 'node:path';
|
|
4
|
+
import { resolveManifestPath } from '@volter/editor-project/manifest/locate';
|
|
5
|
+
import type { ProjectComponentEntry } from '../src/asset-workflow/project-content';
|
|
6
|
+
import {
|
|
7
|
+
compareProjectComponents,
|
|
8
|
+
discoverComponentsInSource,
|
|
9
|
+
type IndexedProjectSource,
|
|
10
|
+
omitRootDocumentComponents,
|
|
11
|
+
projectFileSurfaces,
|
|
12
|
+
projectRegionEntries,
|
|
13
|
+
projectRootEntries,
|
|
14
|
+
reportUnreadableRegions,
|
|
15
|
+
} from '../src/asset-workflow/project-source-index';
|
|
16
|
+
import { ADAPTER_MODULE_FILENAME } from '../src/ui-source/adapter-region-includes';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* ABSENT resolves `null`; every OTHER failure rejects — the contract
|
|
20
|
+
* {@link projectRegionEntries} reads, and the classification only this side
|
|
21
|
+
* (which knows the backend is Node's fs) can make. A blanket
|
|
22
|
+
* `.catch(() => '')` here would report a permissions error or a corrupt file
|
|
23
|
+
* as "this project declares nothing", which is a declaration it never made.
|
|
24
|
+
*/
|
|
25
|
+
async function readOptionalFile(path: string): Promise<string | null> {
|
|
26
|
+
try {
|
|
27
|
+
return await readFile(path, 'utf8');
|
|
28
|
+
} catch (error) {
|
|
29
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return null;
|
|
30
|
+
throw error;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const SOURCE_EXTENSION = /\.(?:[cm]?[jt]sx)$/i;
|
|
35
|
+
const SKIPPED_DIRECTORIES = new Set(['node_modules', 'dist', 'build', '.git', '.vgai', 'tools']);
|
|
36
|
+
|
|
37
|
+
function indexSourceEntry(
|
|
38
|
+
directory: string,
|
|
39
|
+
entry: Dirent,
|
|
40
|
+
pending: string[],
|
|
41
|
+
files: string[],
|
|
42
|
+
): void {
|
|
43
|
+
const absolute = join(directory, entry.name);
|
|
44
|
+
if (entry.isDirectory()) {
|
|
45
|
+
if (!SKIPPED_DIRECTORIES.has(entry.name) && !entry.name.startsWith('.')) {
|
|
46
|
+
pending.push(absolute);
|
|
47
|
+
}
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (entry.isFile() && SOURCE_EXTENSION.test(entry.name)) files.push(absolute);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function discoverProjectComponents(
|
|
54
|
+
projectRoot: string,
|
|
55
|
+
): Promise<ProjectComponentEntry[]> {
|
|
56
|
+
const pending = [join(projectRoot, 'src')];
|
|
57
|
+
const files: string[] = [];
|
|
58
|
+
// Same ENOENT-only rule as `readOptionalFile` above: a missing directory
|
|
59
|
+
// is an honest "nothing declared here"; a permissions error or I/O failure
|
|
60
|
+
// is NOT — swallowing it would render a short component list as a fact
|
|
61
|
+
// about the project.
|
|
62
|
+
const enoentEmpty = (error: unknown): never[] => {
|
|
63
|
+
if ((error as NodeJS.ErrnoException)?.code === 'ENOENT') return [];
|
|
64
|
+
throw error;
|
|
65
|
+
};
|
|
66
|
+
while (pending.length > 0 && files.length < 512) {
|
|
67
|
+
const directory = pending.shift()!;
|
|
68
|
+
const entries = await readdir(directory, { withFileTypes: true }).catch(enoentEmpty);
|
|
69
|
+
for (const entry of entries) indexSourceEntry(directory, entry, pending, files);
|
|
70
|
+
}
|
|
71
|
+
const sources = (
|
|
72
|
+
await Promise.all(
|
|
73
|
+
files.map(async (absolute): Promise<IndexedProjectSource[]> => {
|
|
74
|
+
const path = relative(projectRoot, absolute).split(sep).join('/');
|
|
75
|
+
return readFile(absolute, 'utf8')
|
|
76
|
+
.then((source) => [{ path, source }])
|
|
77
|
+
.catch(enoentEmpty);
|
|
78
|
+
}),
|
|
79
|
+
)
|
|
80
|
+
).flat();
|
|
81
|
+
// A file's surface is its REGION, resolved by the one shared resolver from
|
|
82
|
+
// this project's declarations and its own import edges — never from whichever
|
|
83
|
+
// library a file happens to name in its text.
|
|
84
|
+
const { regions, unreadable } = await projectRegionEntries(
|
|
85
|
+
() => readOptionalFile(resolveManifestPath(projectRoot)),
|
|
86
|
+
() => readOptionalFile(join(projectRoot, ADAPTER_MODULE_FILENAME)),
|
|
87
|
+
);
|
|
88
|
+
// Never dropped: the real loader evaluates the module and WOULD honor an
|
|
89
|
+
// `include` this static read could not see, so an unreported `unreadable`
|
|
90
|
+
// is the two readers disagreeing with nobody told.
|
|
91
|
+
if (unreadable) reportUnreadableRegions(projectRoot, unreadable);
|
|
92
|
+
const surfaces = projectFileSurfaces(sources, regions);
|
|
93
|
+
const discovered = sources.flatMap((file) =>
|
|
94
|
+
discoverComponentsInSource(file.source, file.path, surfaces.get(file.path) ?? 'unknown'),
|
|
95
|
+
);
|
|
96
|
+
const rootEntries = await projectRootEntries(() =>
|
|
97
|
+
readFile(resolveManifestPath(projectRoot), 'utf8'),
|
|
98
|
+
);
|
|
99
|
+
return omitRootDocumentComponents(discovered, rootEntries).sort(compareProjectComponents);
|
|
100
|
+
}
|