@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,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A DESIGN-TIME MOUNT IS REGISTERED, NOT DISPATCHED — the fifth registry in
|
|
3
|
+
* the family of `workspace-document-restore.ts` (a kind owns its persisted
|
|
4
|
+
* state), `document-open-registry.ts` (a kind owns how it opens),
|
|
5
|
+
* `chrome-slot-registry.ts` (the host owns the place, a package owns what
|
|
6
|
+
* sits there) and `content-entry-source-registry.ts` (the host owns the
|
|
7
|
+
* Content scope, a package owns why a component is content). Here: the host
|
|
8
|
+
* owns the design-time layer STACK and a package owns how a medium MOUNTS
|
|
9
|
+
* into it.
|
|
10
|
+
*
|
|
11
|
+
* WHY IT EXISTS. `design-time-layers.ts` dispatched the two media in ONE
|
|
12
|
+
* expression — `candidate.kind === 'canvas' ? mountCanvasLayer(…) :
|
|
13
|
+
* mountReactLayer(…)` — against a single `LayerMountResult` contract whose
|
|
14
|
+
* own docblock said the failure/teardown/play lifecycle is "the SAME for both
|
|
15
|
+
* media". A contract two implementations already share, chosen by a literal
|
|
16
|
+
* the host spells, is a registry that has not been written yet. Past the
|
|
17
|
+
* dispatch it hard-coded two more per-medium facts: canvas REMOUNTS when a
|
|
18
|
+
* write lands with no HMR channel, dom RE-PROJECTS when the story registry
|
|
19
|
+
* publishes, and canvas layers are always interactive because the 2D scene IS
|
|
20
|
+
* the document's subject. Each is a statement about a MEDIUM, made in the
|
|
21
|
+
* host (WORK.md §The open-source launch item 12, §Stories leave the host edge
|
|
22
|
+
* 9).
|
|
23
|
+
*
|
|
24
|
+
* THE SHAPE is transcribed from `content-entry-source-registry.ts:96-134`:
|
|
25
|
+
* register / list / subscribe, with the same owner-replaces-owner rule so an
|
|
26
|
+
* HMR re-evaluation leaves one mount and not two. Two deliberate differences,
|
|
27
|
+
* each with its reason:
|
|
28
|
+
*
|
|
29
|
+
* - NO VERSION COUNTER. That registry publishes one because a React panel
|
|
30
|
+
* reads it through `useSyncExternalStore`; this one's only reader is the
|
|
31
|
+
* layer stack, which subscribes and re-reads. A counter with no caller is
|
|
32
|
+
* a name that gets built because it was named.
|
|
33
|
+
* - THE INVALIDATION HOOKS ARE NOT RE-FANNED into `subscribeDesignTimeMounts`
|
|
34
|
+
* (the content registry re-fans its sources' `subscribe` into one signal).
|
|
35
|
+
* A staleness signal is not a registration change: it must reach the ONE
|
|
36
|
+
* layer stack that mounted that medium, carrying which action to take
|
|
37
|
+
* (remount, which tears down first, or re-project, which keeps the old
|
|
38
|
+
* layer up until the new one settles). The stack binds them itself, per
|
|
39
|
+
* mount, and unbinds on teardown.
|
|
40
|
+
*
|
|
41
|
+
* WHAT THE HOST STILL OWNS, and why it is not a leak: the layer ELEMENT and
|
|
42
|
+
* everything about its place in the stack — the mount epoch that supersedes
|
|
43
|
+
* an in-flight mount, the z-order, the pan transform, the eye, the play
|
|
44
|
+
* handoff and Stop's rebuild, and the `BoundaryAuthoringAdapter` disclosure a
|
|
45
|
+
* failed or unregistered mount degrades to. A mount is handed a layer and
|
|
46
|
+
* asked to fill it; it never decides when it exists.
|
|
47
|
+
*
|
|
48
|
+
* NOTHING REGISTERED IS A REAL ANSWER. A build whose package list carries no
|
|
49
|
+
* mount for a medium leaves that world's Boundary node standing with a reason
|
|
50
|
+
* that names the kind and says no package registered a mount for it — the
|
|
51
|
+
* same honest emptiness a document kind with no registered opener gives, and
|
|
52
|
+
* the reason the stack waits rather than fails: contributions load
|
|
53
|
+
* asynchronously (`project-tool-discovery.ts` defers the pass behind the
|
|
54
|
+
* first viewport frame), so "not registered yet" and "not registered at all"
|
|
55
|
+
* are different answers and only the second is worth showing.
|
|
56
|
+
*/
|
|
57
|
+
|
|
58
|
+
import type * as THREE from 'three';
|
|
59
|
+
import type { EditorShellStore } from '../editor-shell-store';
|
|
60
|
+
import type { CompositeAuthoringAdapter } from './composite-authoring-adapter';
|
|
61
|
+
import type { DesignTimeRootDescriptor, LayerMountResult } from './design-time-layers';
|
|
62
|
+
import type { RootViewController } from './world-pan-state';
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Everything a mount reads from the HOST, and deliberately nothing more — the
|
|
66
|
+
* stack does not hand over itself. Measured against the two mount functions
|
|
67
|
+
* as they stood: `mountReactLayer` read the project root, the shell store and
|
|
68
|
+
* the activation document id; `mountCanvasLayer` read those three plus the
|
|
69
|
+
* presentation's view controller.
|
|
70
|
+
*/
|
|
71
|
+
export interface DesignTimeMountContext {
|
|
72
|
+
/** The open project's absolute root path — resolved once by the stack, and
|
|
73
|
+
* the reason it refuses to mount anything when there is no project. */
|
|
74
|
+
readonly projectRootPath: string;
|
|
75
|
+
/** The ONE format-neutral shell store (selection, history handle, play
|
|
76
|
+
* state) every authoring adapter is constructed against. */
|
|
77
|
+
readonly store: EditorShellStore;
|
|
78
|
+
/** Present only when the document this layer belongs to presents its own
|
|
79
|
+
* independent editor camera and viewport renderer rather than the shared
|
|
80
|
+
* artboard (`mountDesignTimeLayers`' `presentation`). A mount that has no
|
|
81
|
+
* camera of its own ignores it. */
|
|
82
|
+
readonly view?: RootViewController;
|
|
83
|
+
/** When set, first-mount work writes named segments onto this document's
|
|
84
|
+
* activation clock (`viewport-activation-timings`). */
|
|
85
|
+
readonly activationDocumentId?: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* A medium that mounts into a LAYER of the design-time stack, over the shared
|
|
90
|
+
* artboard: `dom` and `canvas`.
|
|
91
|
+
*/
|
|
92
|
+
export type DesignTimeLayerKind = DesignTimeRootDescriptor['kind'];
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* A medium that mounts onto the WORLD ROOT's 3D stage instead of into a layer
|
|
96
|
+
* over it: `three`. Its design session adopts the stage's own renderer and
|
|
97
|
+
* scene rather than being handed an element to fill — the same question ("how
|
|
98
|
+
* does this medium mount at design time?"), answered on a different surface,
|
|
99
|
+
* which is why it is this registry's second shape and not a second registry.
|
|
100
|
+
*/
|
|
101
|
+
export type DesignTimeStageKind = 'three';
|
|
102
|
+
|
|
103
|
+
export type DesignTimeMountKind = DesignTimeLayerKind | DesignTimeStageKind;
|
|
104
|
+
|
|
105
|
+
/** What every registration carries, whichever surface it mounts on. */
|
|
106
|
+
interface DesignTimeMountBase {
|
|
107
|
+
/** The medium this mounts, in the descriptor's own vocabulary. */
|
|
108
|
+
readonly kind: DesignTimeMountKind;
|
|
109
|
+
/** Which module registered it. Re-registering the same owner+kind REPLACES,
|
|
110
|
+
* so an HMR re-evaluation leaves one mount, not two. */
|
|
111
|
+
readonly owner: string;
|
|
112
|
+
/**
|
|
113
|
+
* This medium's mounted worlds are STALE and must be torn down and mounted
|
|
114
|
+
* again from current source. The mount owns the condition (which tier, which
|
|
115
|
+
* watch, which debounce); the stack owns whether it may act right now (not
|
|
116
|
+
* while play is running, not after teardown). Returns its teardown.
|
|
117
|
+
*/
|
|
118
|
+
readonly remountWhen?: (invalidate: () => void) => () => void;
|
|
119
|
+
/**
|
|
120
|
+
* The same staleness, for a medium that can mount the NEW world before
|
|
121
|
+
* taking the old one down — no visible reload flash. Returns its teardown.
|
|
122
|
+
*/
|
|
123
|
+
readonly reprojectWhen?: (invalidate: () => void) => () => void;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface DesignTimeLayerMount extends DesignTimeMountBase {
|
|
127
|
+
readonly kind: DesignTimeLayerKind;
|
|
128
|
+
/** The resolved adapter identity a mount failure is reported under
|
|
129
|
+
* (`MountFailureReport['identity']`, e.g. `default-react`/`default-pixi`).
|
|
130
|
+
* It lives here because it is a fact about the mount; the host used to
|
|
131
|
+
* spell both literals in its own catch block. */
|
|
132
|
+
readonly identity: string;
|
|
133
|
+
/** This medium's layer always forwards pointer events: its content IS the
|
|
134
|
+
* document's subject (a click on it is how you select in it), so the
|
|
135
|
+
* `interactive` toggle — which exists for a medium whose design-time
|
|
136
|
+
* hover/press testing competes with authoring gestures — does not apply. */
|
|
137
|
+
readonly alwaysInteractive?: boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Fill `layer` with this medium's design-time world and report what the
|
|
140
|
+
* stack should publish for it. Throwing is the sanctioned failure: the
|
|
141
|
+
* stack degrades that world to its Boundary disclosure node with the
|
|
142
|
+
* thrown message, exactly as it always did.
|
|
143
|
+
*/
|
|
144
|
+
readonly mount: (
|
|
145
|
+
candidate: DesignTimeRootDescriptor,
|
|
146
|
+
layer: HTMLElement,
|
|
147
|
+
context: DesignTimeMountContext,
|
|
148
|
+
) => Promise<LayerMountResult>;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** Everything the world root's stage hands its medium's design session. It is
|
|
152
|
+
* the stage's own three handles: nothing here is a layer, a candidate or a
|
|
153
|
+
* project path, because the session resolves its world from the manifest
|
|
154
|
+
* itself. Measured against `mountR3FDesignSession` as it stood. */
|
|
155
|
+
export interface WorldRootSessionContext {
|
|
156
|
+
/** The ONE format-neutral shell store the session's adapter is built over. */
|
|
157
|
+
readonly store: EditorShellStore;
|
|
158
|
+
/** The edit-mode composite the session swaps its own child adapter into. */
|
|
159
|
+
readonly composite: CompositeAuthoringAdapter;
|
|
160
|
+
/** The stage's renderer — the session adopts it rather than building one. */
|
|
161
|
+
readonly renderer: THREE.WebGLRenderer;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export interface DesignTimeStageMount extends DesignTimeMountBase {
|
|
165
|
+
readonly kind: DesignTimeStageKind;
|
|
166
|
+
/**
|
|
167
|
+
* Mount this medium's design session onto the world root's stage. Returns
|
|
168
|
+
* its teardown. Throwing is the sanctioned failure, the same as a layer
|
|
169
|
+
* mount's.
|
|
170
|
+
*/
|
|
171
|
+
readonly mountWorldRootSession: (context: WorldRootSessionContext) => Promise<() => void>;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export type DesignTimeMount = DesignTimeLayerMount | DesignTimeStageMount;
|
|
175
|
+
|
|
176
|
+
const _mounts: DesignTimeMount[] = [];
|
|
177
|
+
const listeners = new Set<() => void>();
|
|
178
|
+
|
|
179
|
+
function publish(): void {
|
|
180
|
+
for (const listener of listeners) listener();
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** Install a mount for one medium. Returns the teardown. */
|
|
184
|
+
export function registerDesignTimeMount(mount: DesignTimeMount): () => void {
|
|
185
|
+
const stale = _mounts.findIndex((item) => item.owner === mount.owner && item.kind === mount.kind);
|
|
186
|
+
if (stale >= 0) _mounts.splice(stale, 1);
|
|
187
|
+
_mounts.push(mount);
|
|
188
|
+
publish();
|
|
189
|
+
return () => {
|
|
190
|
+
const at = _mounts.indexOf(mount);
|
|
191
|
+
if (at < 0) return;
|
|
192
|
+
_mounts.splice(at, 1);
|
|
193
|
+
publish();
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const EMPTY: readonly DesignTimeMount[] = [];
|
|
198
|
+
|
|
199
|
+
/** Everything registered, in registration order. A stable array while nothing
|
|
200
|
+
* changes, so a reader can compare identities across a notification. */
|
|
201
|
+
export function designTimeMounts(): readonly DesignTimeMount[] {
|
|
202
|
+
return _mounts.length === 0 ? EMPTY : _mounts;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** The mount for one medium, or `null` — "no package registered one", which
|
|
206
|
+
* is a real answer and never an error. The LAST registration wins, the same
|
|
207
|
+
* way a later chrome-slot filler of the same order does. The overloads are
|
|
208
|
+
* how a caller that knows its surface gets the shape that surface mounts
|
|
209
|
+
* with, without narrowing at the call site. */
|
|
210
|
+
export function designTimeMountFor(kind: DesignTimeLayerKind): DesignTimeLayerMount | null;
|
|
211
|
+
export function designTimeMountFor(kind: DesignTimeStageKind): DesignTimeStageMount | null;
|
|
212
|
+
export function designTimeMountFor(kind: DesignTimeMountKind): DesignTimeMount | null;
|
|
213
|
+
export function designTimeMountFor(kind: DesignTimeMountKind): DesignTimeMount | null {
|
|
214
|
+
for (let i = _mounts.length - 1; i >= 0; i--) {
|
|
215
|
+
const mount = _mounts[i];
|
|
216
|
+
if (mount && mount.kind === kind) return mount;
|
|
217
|
+
}
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** Registration changes only. A mounted layer's own staleness travels through
|
|
222
|
+
* that mount's `remountWhen`/`reprojectWhen` instead — see the module note. */
|
|
223
|
+
export function subscribeDesignTimeMounts(listener: () => void): () => void {
|
|
224
|
+
listeners.add(listener);
|
|
225
|
+
return () => {
|
|
226
|
+
listeners.delete(listener);
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/** Test-only reset (mirrors the restore, open, chrome-slot and content-source
|
|
231
|
+
* registries'). */
|
|
232
|
+
export function __resetDesignTimeMountsForTest(): void {
|
|
233
|
+
_mounts.length = 0;
|
|
234
|
+
publish();
|
|
235
|
+
}
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE DESIGN-TIME SETTLE, and the only place its constants are spelled.
|
|
3
|
+
*
|
|
4
|
+
* This is deliberately NOT an interactive-document boot step. Scene and Asset
|
|
5
|
+
* Lab documents show authored state immediately and advance content only when
|
|
6
|
+
* the user starts an explicit simulation or animation transport. A hidden
|
|
7
|
+
* settle before reveal violated Edit ≠ Play and made a complex local scene wait
|
|
8
|
+
* up to four seconds for construction quiescence plus 90 invisible steps.
|
|
9
|
+
*
|
|
10
|
+
* The remaining callers are deliberate off-screen preview/capture operations
|
|
11
|
+
* that ask for a derived rest pose. That is why {@link settleDesignWorld} takes
|
|
12
|
+
* a {@link SettleTarget} rather than a viewport type: the seam is "a world with
|
|
13
|
+
* a host-driven tick," while the caller owns the decision to simulate.
|
|
14
|
+
*
|
|
15
|
+
* **The settle is a PURE FUNCTION OF SOURCE.** It never reads accumulated
|
|
16
|
+
* state, never persists a result, and is never a second truth beside the
|
|
17
|
+
* source: every mount re-derives the world from the file and re-runs the same
|
|
18
|
+
* bounded simulation from the same authored spawn. That is what makes the two
|
|
19
|
+
* interaction contracts hold — a gizmo commit writes the JSX literal, the
|
|
20
|
+
* session re-derives from source, and the settle re-runs from the EDIT's
|
|
21
|
+
* position (the edit wins, nothing snaps back); and two mounts of identical
|
|
22
|
+
* source produce the same rest state.
|
|
23
|
+
*
|
|
24
|
+
* ## THE SEAM IT DRIVES, and why it is not a physics API
|
|
25
|
+
*
|
|
26
|
+
* `MountedThreeRoot.update(dt)` — the world's own host-driven tick, the exact
|
|
27
|
+
* one `runFrameImpl` (`@vgai/game-runtime/runtime/game`) calls at play time. For an R3F
|
|
28
|
+
* world that is `world3d-react/r3f-adapter.tsx`'s `update()`: it runs the
|
|
29
|
+
* engine phases and then `advance(elapsed, true, state)`, which under
|
|
30
|
+
* `frameloop: 'never'` is what runs every `useFrame` subscriber.
|
|
31
|
+
*
|
|
32
|
+
* A physics integration is one of those subscribers, so driving `update()`
|
|
33
|
+
* drives the world's physics THROUGH THE WORLD'S OWN DECLARATION — including
|
|
34
|
+
* whatever gravity/iterations/solver props its own `<Physics>` element
|
|
35
|
+
* carries. Worked example, `@react-three/cannon@6.6.0`: its provider registers
|
|
36
|
+
* `useFrame(loop)` (`node_modules/@react-three/cannon/dist/index.js:12166`)
|
|
37
|
+
* and `loop` posts `worker.step({ maxSubSteps, stepSize, timeSinceLastCalled })`
|
|
38
|
+
* (`:12032`) to its own Web Worker. Nothing here knows any of that, and
|
|
39
|
+
* nothing here should: the editor reaching for a named physics library's step
|
|
40
|
+
* API would be an editor that only settles the physics engines it has heard
|
|
41
|
+
* of.
|
|
42
|
+
*
|
|
43
|
+
* ## WHY IT IS ASYNC, and why it steps in ROUNDS
|
|
44
|
+
*
|
|
45
|
+
* That worker is OFF-THREAD. `worker.step()` posts a message; the resulting
|
|
46
|
+
* pose arrives on a later task and is applied to `object.matrix` from the
|
|
47
|
+
* worker's own `frame` handler (`:12120`). A synchronous burst of `update()`
|
|
48
|
+
* calls would therefore measure nothing but the spawn pose. So the settle
|
|
49
|
+
* yields to the event loop, and it does so once per ROUND of
|
|
50
|
+
* {@link SETTLE_STEPS_PER_ROUND} steps rather than once per step: the worker
|
|
51
|
+
* queue is FIFO, so a round's steps pipeline and its frames land together,
|
|
52
|
+
* which costs one event-loop turn per round instead of one per step.
|
|
53
|
+
*
|
|
54
|
+
* ## WHY REST IS ONLY DECLARED AFTER MOTION
|
|
55
|
+
*
|
|
56
|
+
* The naive rest test — "the scene did not move this round, so we are done" —
|
|
57
|
+
* is TRUE at round one for the exact reason the settle exists: an off-thread
|
|
58
|
+
* physics engine has not answered yet, so nothing has moved YET. Declaring
|
|
59
|
+
* rest there would settle to the spawn pose and call it a rest state. Rest is
|
|
60
|
+
* therefore gated on having OBSERVED motion first; a world that never moves
|
|
61
|
+
* under simulation ends at {@link SETTLE_MAX_ROUNDS} with reason `'still'`,
|
|
62
|
+
* which costs it that many event-loop turns and nothing else.
|
|
63
|
+
*
|
|
64
|
+
* Non-finite poses are the same class of not-yet-answered and are handled the
|
|
65
|
+
* same way: `@react-three/cannon` writes `object.matrix` from worker buffers
|
|
66
|
+
* that are unwritten at frame zero, so two of racing-game's meshes are
|
|
67
|
+
* measurably `NaN` before the first frame lands (see `content-bounds.ts`'s own
|
|
68
|
+
* measurement of exactly this). A round whose sample is non-finite is
|
|
69
|
+
* NOT COMPARABLE: it resets the rest run and is never counted as motion.
|
|
70
|
+
*/
|
|
71
|
+
|
|
72
|
+
import type * as THREE from 'three';
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* What a settle needs from a world, and nothing more: the graph to measure and
|
|
76
|
+
* the world's OWN host-driven tick to advance. `MountedThreeRoot` satisfies it
|
|
77
|
+
* structurally, and so does every other design-time surface's source (a story
|
|
78
|
+
* mount's `advance`, a project contribution's `build().update`) — which is the
|
|
79
|
+
* point: one settle, one shape, no per-surface copy.
|
|
80
|
+
*/
|
|
81
|
+
export interface SettleTarget {
|
|
82
|
+
/** The subtree whose motion is measured. A whole `THREE.Scene` for a mounted
|
|
83
|
+
* root; a story's own wrapper group for an off-screen story mount. */
|
|
84
|
+
readonly scene: THREE.Object3D;
|
|
85
|
+
/** The world's own tick. Absent ⇒ nothing to advance (`'unsupported'`). */
|
|
86
|
+
readonly update?: ((dt: number) => void) | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* Whether this mount has an off-thread physics stepper subscribed (a
|
|
89
|
+
* `<Physics>` provider, a cannon worker, a first-party adapter).
|
|
90
|
+
*
|
|
91
|
+
* The quiet-wait and still-rounds exist because that stepper is SILENT at
|
|
92
|
+
* spawn: declaring rest before it answers would freeze a vehicle at a pose
|
|
93
|
+
* the game never has. A tree, a jump pad, a mesh with no physics has
|
|
94
|
+
* nothing that can move later, so both waits are wasted — pass `false` and
|
|
95
|
+
* the settle returns immediately. Omitted is the SAFE default (settle):
|
|
96
|
+
* callers that have not looked must not skip a rigid body.
|
|
97
|
+
*/
|
|
98
|
+
readonly hasPhysicsSubscriber?: boolean;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** The simulated timestep each settle step advances — the engine's own fixed
|
|
102
|
+
* timestep (`core/game-loop.ts`'s `fixedTimestep ?? 1/60`), so a settle step
|
|
103
|
+
* is the same quantum a play frame is. */
|
|
104
|
+
export const SETTLE_STEP_SECONDS = 1 / 60;
|
|
105
|
+
|
|
106
|
+
/** Steps advanced between event-loop yields. 6 steps = 0.1 simulated second —
|
|
107
|
+
* enough that an off-thread physics worker's frames for the round have
|
|
108
|
+
* something to show, small enough that rest is detected within 0.1s of it
|
|
109
|
+
* happening. */
|
|
110
|
+
export const SETTLE_STEPS_PER_ROUND = 6;
|
|
111
|
+
|
|
112
|
+
/** Hard budget: 15 rounds = 90 steps = **1.5 simulated seconds**. A body
|
|
113
|
+
* dropped onto its own suspension or resolved out of an interpenetration
|
|
114
|
+
* reaches rest well inside that; a world that is still moving at 1.5s is
|
|
115
|
+
* animating rather than settling, and Edit mode owes it a freeze, not a
|
|
116
|
+
* longer run. */
|
|
117
|
+
export const SETTLE_MAX_ROUNDS = 15;
|
|
118
|
+
|
|
119
|
+
/** Rest threshold: world units moved by the FASTEST-moving node across one
|
|
120
|
+
* round. 1e-4 units per 0.1s is 1 millimetre per second in a metres-scaled
|
|
121
|
+
* world — below it, nothing a viewer or a capture can distinguish is
|
|
122
|
+
* happening. */
|
|
123
|
+
export const SETTLE_REST_EPSILON = 1e-4;
|
|
124
|
+
|
|
125
|
+
/** Consecutive quiet rounds required before rest is declared, so a body
|
|
126
|
+
* pausing at the top of a bounce is not mistaken for a rest state. */
|
|
127
|
+
export const SETTLE_REST_ROUNDS = 2;
|
|
128
|
+
|
|
129
|
+
/** After the last step, event-loop turns awaited for an off-thread physics
|
|
130
|
+
* engine's in-flight frames to land. This is what makes "then FREEZES" true
|
|
131
|
+
* rather than asserted: the settle does not return while a pose it caused is
|
|
132
|
+
* still on its way. */
|
|
133
|
+
export const SETTLE_DRAIN_TURNS = 10;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* How long the scene graph must stop CHANGING SHAPE before the settle starts
|
|
137
|
+
* stepping, and the hard ceiling on waiting for that.
|
|
138
|
+
*
|
|
139
|
+
* WHY THIS EXISTS, measured. A world's `mount()` resolves at fiber's first
|
|
140
|
+
* commit, which is NOT the end of construction: suspended asset loads
|
|
141
|
+
* (racing-game's Draco chassis/track GLBs and its HDR environment) add nodes —
|
|
142
|
+
* including physics bodies — for as long as they take. Step the world during
|
|
143
|
+
* that window and a body created at round 3 gets 12 fewer steps than one
|
|
144
|
+
* created at round 0, so the SAME source settles differently depending on how
|
|
145
|
+
* warm the HTTP cache was. Measured directly: two boots of unchanged
|
|
146
|
+
* racing-game source produced chassis Y = 0.7549 and 0.7927.
|
|
147
|
+
*
|
|
148
|
+
* So the settle waits for the world to stop being BUILT before it simulates.
|
|
149
|
+
* Node count is the signal (an asset resolving adds nodes; a texture arriving
|
|
150
|
+
* does not change the count and does not change physics either). Both bounds
|
|
151
|
+
* are wall-clock because what is being waited on is I/O, not frames.
|
|
152
|
+
*/
|
|
153
|
+
export const SETTLE_BUILD_STABLE_MS = 250;
|
|
154
|
+
export const SETTLE_BUILD_TIMEOUT_MS = 4000;
|
|
155
|
+
|
|
156
|
+
/** Why the settle ended. */
|
|
157
|
+
export type SettleOutcome =
|
|
158
|
+
/** The world moved and then came to rest. */
|
|
159
|
+
| 'rest'
|
|
160
|
+
/** The world was still moving when the step budget ran out. */
|
|
161
|
+
| 'budget'
|
|
162
|
+
/** Nothing in the world ever moved under simulation. */
|
|
163
|
+
| 'still'
|
|
164
|
+
/** The world is not host-driven — there is no `update(dt)` to advance. */
|
|
165
|
+
| 'unsupported';
|
|
166
|
+
|
|
167
|
+
export interface SettleReport {
|
|
168
|
+
readonly outcome: SettleOutcome;
|
|
169
|
+
/** Simulation steps actually advanced. */
|
|
170
|
+
readonly steps: number;
|
|
171
|
+
/** World units the fastest node moved across the final measured round. */
|
|
172
|
+
readonly lastMotion: number;
|
|
173
|
+
/** Milliseconds spent waiting for the world to stop being BUILT, and whether
|
|
174
|
+
* that wait ended because the graph went quiet (`true`) or because it hit
|
|
175
|
+
* {@link SETTLE_BUILD_TIMEOUT_MS} (`false` — the settle then runs against a
|
|
176
|
+
* world still loading, and its result is honestly not reproducible). */
|
|
177
|
+
readonly buildWaitMs: number;
|
|
178
|
+
readonly buildSettled: boolean;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** Injectables. Real callers pass nothing; a test drives the loop and the
|
|
182
|
+
* clock so the wall-clock bounds above cost it no wall clock. */
|
|
183
|
+
export interface SettleHooks {
|
|
184
|
+
yieldTurn?: () => Promise<void>;
|
|
185
|
+
now?: () => number;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** Every node's world position, flattened. Length changes (an async model
|
|
189
|
+
* resolving mid-settle) make two samples NOT COMPARABLE, which is the honest
|
|
190
|
+
* answer rather than a wrong distance. */
|
|
191
|
+
function samplePositions(scene: THREE.Object3D): number[] {
|
|
192
|
+
scene.updateMatrixWorld(true);
|
|
193
|
+
const out: number[] = [];
|
|
194
|
+
scene.traverse((object) => {
|
|
195
|
+
const e = object.matrixWorld.elements;
|
|
196
|
+
out.push(e[12] as number, e[13] as number, e[14] as number);
|
|
197
|
+
});
|
|
198
|
+
return out;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/** How many nodes the world currently has — the build-quiesce signal. */
|
|
202
|
+
function countNodes(scene: THREE.Object3D): number {
|
|
203
|
+
let n = 0;
|
|
204
|
+
scene.traverse(() => {
|
|
205
|
+
n++;
|
|
206
|
+
});
|
|
207
|
+
return n;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* The largest distance any node moved between two samples, or `NaN` when the
|
|
212
|
+
* two are not comparable (different node counts, or a pose that is not a
|
|
213
|
+
* number yet).
|
|
214
|
+
*/
|
|
215
|
+
function maxMotion(before: number[], after: number[]): number {
|
|
216
|
+
if (before.length !== after.length) return Number.NaN;
|
|
217
|
+
let max = 0;
|
|
218
|
+
for (let i = 0; i < after.length; i += 3) {
|
|
219
|
+
const dx = (after[i] as number) - (before[i] as number);
|
|
220
|
+
const dy = (after[i + 1] as number) - (before[i + 1] as number);
|
|
221
|
+
const dz = (after[i + 2] as number) - (before[i + 2] as number);
|
|
222
|
+
const d = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
223
|
+
if (!Number.isFinite(d)) return Number.NaN;
|
|
224
|
+
if (d > max) max = d;
|
|
225
|
+
}
|
|
226
|
+
return max;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/** One event-loop turn — a MACROtask, because an off-thread worker's message
|
|
230
|
+
* cannot land in a microtask drain. */
|
|
231
|
+
const nextTurn = (): Promise<void> => new Promise((resolve) => setTimeout(resolve, 0));
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Block until the world's node count has held still for
|
|
235
|
+
* {@link SETTLE_BUILD_STABLE_MS}, or {@link SETTLE_BUILD_TIMEOUT_MS} runs out.
|
|
236
|
+
* See those constants for the measurement that put this phase here.
|
|
237
|
+
*/
|
|
238
|
+
async function awaitConstructionQuiesced(
|
|
239
|
+
scene: THREE.Object3D,
|
|
240
|
+
yieldTurn: () => Promise<void>,
|
|
241
|
+
now: () => number,
|
|
242
|
+
): Promise<{ buildWaitMs: number; buildSettled: boolean }> {
|
|
243
|
+
const start = now();
|
|
244
|
+
let nodes = countNodes(scene);
|
|
245
|
+
let quietSince = start;
|
|
246
|
+
let buildSettled = false;
|
|
247
|
+
while (now() - start < SETTLE_BUILD_TIMEOUT_MS) {
|
|
248
|
+
if (now() - quietSince >= SETTLE_BUILD_STABLE_MS) {
|
|
249
|
+
buildSettled = true;
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
await yieldTurn();
|
|
253
|
+
const next = countNodes(scene);
|
|
254
|
+
if (next !== nodes) {
|
|
255
|
+
nodes = next;
|
|
256
|
+
quietSince = now();
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return { buildWaitMs: now() - start, buildSettled };
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function idleSettleReport(outcome: 'unsupported' | 'still'): SettleReport {
|
|
263
|
+
return { outcome, steps: 0, lastMotion: 0, buildWaitMs: 0, buildSettled: true };
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* The narrow skip: no physics subscriber means nothing can move after spawn,
|
|
268
|
+
* so the construction quiet-wait and the still-rounds are both wasted. Omitted
|
|
269
|
+
* is treated as "yes, settle" — a caller that has not looked must not skip a
|
|
270
|
+
* rigid body. The predicate lives here so a revert (always-skip, or treating
|
|
271
|
+
* omitted as skip) reds the physics rest test.
|
|
272
|
+
*/
|
|
273
|
+
export function designWorldHasPhysicsSubscriber(root: SettleTarget): boolean {
|
|
274
|
+
return root.hasPhysicsSubscriber !== false;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Derive a rest pose for a caller that explicitly requested one, then leave the
|
|
279
|
+
* world frozen. Advances the world's OWN `update(dt)` — see this module's
|
|
280
|
+
* header for why that is the seam and why the loop is shaped the way it is.
|
|
281
|
+
*/
|
|
282
|
+
export async function settleDesignWorld(
|
|
283
|
+
root: SettleTarget,
|
|
284
|
+
hooks: SettleHooks = {},
|
|
285
|
+
): Promise<SettleReport> {
|
|
286
|
+
const yieldTurn = hooks.yieldTurn ?? nextTurn;
|
|
287
|
+
const now = hooks.now ?? (() => Date.now());
|
|
288
|
+
const update = root.update?.bind(root);
|
|
289
|
+
if (!update) return idleSettleReport('unsupported');
|
|
290
|
+
if (!designWorldHasPhysicsSubscriber(root)) return idleSettleReport('still');
|
|
291
|
+
|
|
292
|
+
// ---- 1. wait for the world to stop being BUILT
|
|
293
|
+
const { buildWaitMs, buildSettled } = await awaitConstructionQuiesced(root.scene, yieldTurn, now);
|
|
294
|
+
|
|
295
|
+
// ---- 2. the bounded settle itself
|
|
296
|
+
let previous = samplePositions(root.scene);
|
|
297
|
+
let steps = 0;
|
|
298
|
+
let quietRounds = 0;
|
|
299
|
+
let observedMotion = false;
|
|
300
|
+
let lastMotion = 0;
|
|
301
|
+
let outcome: SettleOutcome = 'still';
|
|
302
|
+
|
|
303
|
+
for (let round = 0; round < SETTLE_MAX_ROUNDS; round++) {
|
|
304
|
+
for (let step = 0; step < SETTLE_STEPS_PER_ROUND; step++) {
|
|
305
|
+
update(SETTLE_STEP_SECONDS);
|
|
306
|
+
steps++;
|
|
307
|
+
}
|
|
308
|
+
await yieldTurn();
|
|
309
|
+
const current = samplePositions(root.scene);
|
|
310
|
+
const motion = maxMotion(previous, current);
|
|
311
|
+
previous = current;
|
|
312
|
+
if (!Number.isFinite(motion)) {
|
|
313
|
+
// Not comparable — the world is mid-answer. Never rest, never motion.
|
|
314
|
+
quietRounds = 0;
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
lastMotion = motion;
|
|
318
|
+
if (motion > SETTLE_REST_EPSILON) {
|
|
319
|
+
observedMotion = true;
|
|
320
|
+
quietRounds = 0;
|
|
321
|
+
outcome = 'budget';
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
quietRounds++;
|
|
325
|
+
if (observedMotion && quietRounds >= SETTLE_REST_ROUNDS) {
|
|
326
|
+
outcome = 'rest';
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// ---- 3. FREEZE. Nothing is stepped from here; the drain only waits out
|
|
332
|
+
// poses this settle already caused, so the scene the editor draws from now
|
|
333
|
+
// on is a real rest state rather than one still being written into.
|
|
334
|
+
for (let turn = 0; turn < SETTLE_DRAIN_TURNS; turn++) {
|
|
335
|
+
await yieldTurn();
|
|
336
|
+
const current = samplePositions(root.scene);
|
|
337
|
+
const motion = maxMotion(previous, current);
|
|
338
|
+
previous = current;
|
|
339
|
+
if (Number.isFinite(motion) && motion <= SETTLE_REST_EPSILON) break;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
return { outcome, steps, lastMotion, buildWaitMs, buildSettled };
|
|
343
|
+
}
|