@volter/sdk 0.0.0-stage → 0.5.203
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/LICENSE +202 -0
- package/NOTICE +20 -0
- package/README.md +38 -3
- package/package.json +510 -4
- package/src/account.ts +210 -0
- package/src/chrome.ts +88 -0
- package/src/client.ts +1646 -0
- package/src/commands.ts +66 -0
- package/src/contributions.ts +619 -0
- package/src/css-numeric-style.ts +97 -0
- package/src/document-probe.ts +282 -0
- package/src/editor-view.ts +225 -0
- package/src/extension.ts +40 -0
- package/src/generations.ts +178 -0
- package/src/host.ts +1157 -0
- package/src/http-transport.browser.ts +14 -0
- package/src/http-transport.node.ts +19 -0
- package/src/index.ts +131 -0
- package/src/kit/CapabilityCoverageSection.tsx +185 -0
- package/src/kit/account-client.ts +333 -0
- package/src/kit/action-registry.ts +317 -0
- package/src/kit/active-product.ts +76 -0
- package/src/kit/active-project.ts +155 -0
- package/src/kit/adapter-editor-config.ts +25 -0
- package/src/kit/adapter-module.ts +7 -0
- package/src/kit/adapter-observation.ts +49 -0
- package/src/kit/animation/animation-clock.ts +479 -0
- package/src/kit/animation/stage-transport.ts +385 -0
- package/src/kit/api/assets.ts +365 -0
- package/src/kit/api/project-open.ts +355 -0
- package/src/kit/api/project-source.ts +180 -0
- package/src/kit/api/project-state.ts +110 -0
- package/src/kit/api/relay.ts +270 -0
- package/src/kit/api/themes.ts +45 -0
- package/src/kit/api-asset-library-wire.ts +45 -0
- package/src/kit/api-base.ts +10 -0
- package/src/kit/api-build.ts +99 -0
- package/src/kit/api-git-wire.ts +56 -0
- package/src/kit/api-logs.ts +92 -0
- package/src/kit/api-project-identity.ts +74 -0
- package/src/kit/api-settings.ts +36 -0
- package/src/kit/api-worktrees.ts +205 -0
- package/src/kit/asset-capabilities.ts +344 -0
- package/src/kit/asset-compare-core.ts +171 -0
- package/src/kit/asset-editor-context.tsx +101 -0
- package/src/kit/asset-events.ts +96 -0
- package/src/kit/asset-inspector-actions.ts +87 -0
- package/src/kit/asset-selection-viewer-registry.ts +113 -0
- package/src/kit/asset-selection.ts +146 -0
- package/src/kit/asset-thumbnails.ts +25 -0
- package/src/kit/asset-viewers.ts +115 -0
- package/src/kit/asset-workflow/asset-import-jobs.ts +106 -0
- package/src/kit/asset-workflow/asset-ledger-backend.ts +126 -0
- package/src/kit/asset-workflow/asset-ledger.ts +156 -0
- package/src/kit/asset-workflow/asset-materialization-report.ts +140 -0
- package/src/kit/asset-workflow/asset-pack-manifest.ts +320 -0
- package/src/kit/asset-workflow/asset-types.ts +142 -0
- package/src/kit/asset-workflow/audio-preview-player.ts +193 -0
- package/src/kit/asset-workflow/audio-waveform.ts +22 -0
- package/src/kit/asset-workflow/cloud-asset-client.ts +263 -0
- package/src/kit/asset-workflow/hosted-asset-materialization.ts +236 -0
- package/src/kit/asset-workflow/image-view-scale.ts +31 -0
- package/src/kit/asset-workflow/import-contract.ts +124 -0
- package/src/kit/asset-workflow/ledger-write-lock.ts +244 -0
- package/src/kit/asset-workflow/pixi-spritesheet.ts +197 -0
- package/src/kit/asset-workflow/preview-resource-lifetime.ts +44 -0
- package/src/kit/asset-workflow/project-asset-commands.ts +20 -0
- package/src/kit/asset-workflow/project-content.ts +288 -0
- package/src/kit/asset-workflow/project-source-index.ts +545 -0
- package/src/kit/asset-workflow/thumbnail-system.ts +256 -0
- package/src/kit/authoring/active-adapter.ts +200 -0
- package/src/kit/authoring/active-systems.ts +422 -0
- package/src/kit/authoring/adapter-key.ts +18 -0
- package/src/kit/authoring/authoring-asset-url.ts +27 -0
- package/src/kit/authoring/bootstrap-state.ts +49 -0
- package/src/kit/authoring/boundary-authoring-adapter.ts +189 -0
- package/src/kit/authoring/canvas-scene-guides.ts +84 -0
- package/src/kit/authoring/composite-authoring-adapter.ts +2109 -0
- package/src/kit/authoring/consumer-actions.ts +531 -0
- package/src/kit/authoring/design-time-layers.ts +852 -0
- package/src/kit/authoring/design-time-mount-registry.ts +244 -0
- package/src/kit/authoring/edit-mode-authoring.ts +637 -0
- package/src/kit/authoring/empty-project-authoring.ts +22 -0
- package/src/kit/authoring/instance-source-menu.ts +135 -0
- package/src/kit/authoring/layered-pick.ts +185 -0
- package/src/kit/authoring/mounted-root-subjects.ts +146 -0
- package/src/kit/authoring/no-authoring-adapter.ts +59 -0
- package/src/kit/authoring/object3d-document-persistence.ts +122 -0
- package/src/kit/authoring/panel-authoring.ts +121 -0
- package/src/kit/authoring/project-authoring-session.ts +105 -0
- package/src/kit/authoring/provenance.ts +99 -0
- package/src/kit/authoring/react-canvas-navigation.ts +259 -0
- package/src/kit/authoring/react-design-canvas-style.ts +20 -0
- package/src/kit/authoring/react-story-board.ts +917 -0
- package/src/kit/authoring/selection-scope.ts +195 -0
- package/src/kit/authoring/shell-document-ops.ts +169 -0
- package/src/kit/authoring/story-board-chrome-fit.ts +107 -0
- package/src/kit/authoring/story-board-presentation.ts +111 -0
- package/src/kit/authoring/three-root.ts +67 -0
- package/src/kit/authoring/viewport-tool-context.ts +73 -0
- package/src/kit/authoring/viewport-tool-owner.ts +38 -0
- package/src/kit/authoring/world-session-state.ts +101 -0
- package/src/kit/authoring-seam-evidence.ts +300 -0
- package/src/kit/availability-tick.ts +66 -0
- package/src/kit/bitmap-label.ts +120 -0
- package/src/kit/boot-routing.ts +392 -0
- package/src/kit/breakpoint-state.ts +43 -0
- package/src/kit/build-identity.ts +16 -0
- package/src/kit/bytes-codec.ts +62 -0
- package/src/kit/cancellation-reason.ts +58 -0
- package/src/kit/canvas-frames.ts +88 -0
- package/src/kit/capture-camera-pose.ts +77 -0
- package/src/kit/capture-size.ts +88 -0
- package/src/kit/chrome-registry.ts +159 -0
- package/src/kit/chrome-slot-registry.ts +91 -0
- package/src/kit/collaboration-client.ts +264 -0
- package/src/kit/collaboration-presence.ts +41 -0
- package/src/kit/command-dispatch.ts +19 -0
- package/src/kit/command-listener.ts +2182 -0
- package/src/kit/command-registry.ts +71 -0
- package/src/kit/component-board-registry.ts +205 -0
- package/src/kit/component-states-registry.ts +199 -0
- package/src/kit/components/AlignToolbar.tsx +204 -0
- package/src/kit/components/ApplicationMenus.tsx +372 -0
- package/src/kit/components/AssetEditorShell.tsx +216 -0
- package/src/kit/components/AssetInspectorToolSection.tsx +124 -0
- package/src/kit/components/BoardRulers.tsx +354 -0
- package/src/kit/components/CanvasAddNodeDialogs.tsx +529 -0
- package/src/kit/components/CanvasSceneViewport.tsx +1195 -0
- package/src/kit/components/ChromeSlot.tsx +20 -0
- package/src/kit/components/CodeView.tsx +470 -0
- package/src/kit/components/CompactInspectorShell.tsx +39 -0
- package/src/kit/components/ConsolePanel.tsx +273 -0
- package/src/kit/components/GameplaySessionTimeline.tsx +295 -0
- package/src/kit/components/InspectionProjection.tsx +932 -0
- package/src/kit/components/Inspector.tsx +270 -0
- package/src/kit/components/InspectorCanvasPreview.tsx +35 -0
- package/src/kit/components/InspectorFieldsSection.tsx +290 -0
- package/src/kit/components/InspectorStoriesSection.tsx +92 -0
- package/src/kit/components/InspectorToolSection.tsx +96 -0
- package/src/kit/components/InspectorTransformSection.tsx +245 -0
- package/src/kit/components/LightExplorerPanel.tsx +433 -0
- package/src/kit/components/MediaProperties.tsx +145 -0
- package/src/kit/components/ProjectHeader.tsx +328 -0
- package/src/kit/components/ReactCanvasControls.tsx +358 -0
- package/src/kit/components/RootSelectionOverlay.tsx +3688 -0
- package/src/kit/components/RootTextEditor.tsx +79 -0
- package/src/kit/components/SaveStatus.tsx +70 -0
- package/src/kit/components/SurfaceCrashBoundary.tsx +105 -0
- package/src/kit/components/SurfaceStateOverlay.tsx +24 -0
- package/src/kit/components/ToolContributionSurfaces.tsx +49 -0
- package/src/kit/components/ToolHost.tsx +380 -0
- package/src/kit/components/Toolbar.tsx +811 -0
- package/src/kit/components/TransientHint.tsx +44 -0
- package/src/kit/components/VersionControlSection.tsx +470 -0
- package/src/kit/components/ViewportOverlaysMenu.tsx +177 -0
- package/src/kit/components/VolterLogo.tsx +18 -0
- package/src/kit/components/WorktreeSwitcher.tsx +712 -0
- package/src/kit/components/account-documents.tsx +1162 -0
- package/src/kit/components/asset-documents.tsx +794 -0
- package/src/kit/components/asset-editor-persistence.ts +216 -0
- package/src/kit/components/asset-selection-section.tsx +545 -0
- package/src/kit/components/asset-thumbnails.tsx +307 -0
- package/src/kit/components/asset-viewers/AudioViewer.tsx +201 -0
- package/src/kit/components/asset-viewers/GenericJsonViewer.tsx +102 -0
- package/src/kit/components/asset-viewers/ImageViewer.tsx +300 -0
- package/src/kit/components/asset-viewers/JsonAssetDocument.tsx +98 -0
- package/src/kit/components/asset-viewers/OnlineAssetDetail.tsx +426 -0
- package/src/kit/components/asset-viewers/SourceAssetViewer.tsx +356 -0
- package/src/kit/components/asset-viewers/SpritesheetSpriteView.tsx +102 -0
- package/src/kit/components/asset-viewers/VideoViewer.tsx +101 -0
- package/src/kit/components/asset-viewers/shader-source.ts +144 -0
- package/src/kit/components/board-guides.ts +150 -0
- package/src/kit/components/canvas-scene-hotkeys.ts +37 -0
- package/src/kit/components/canvas-temporary-pivot.ts +34 -0
- package/src/kit/components/core-utilities.tsx +94 -0
- package/src/kit/components/inspector-preview-section.tsx +223 -0
- package/src/kit/components/inspector-revert-label.ts +20 -0
- package/src/kit/components/inspector-selection.ts +42 -0
- package/src/kit/components/inspector-stories-gating.ts +171 -0
- package/src/kit/components/inspector-transform-subject.ts +11 -0
- package/src/kit/components/inspector-transform.ts +88 -0
- package/src/kit/components/kind-documents.tsx +544 -0
- package/src/kit/components/primitives/DraftColorInput.tsx +74 -0
- package/src/kit/components/project-tool-documents.tsx +402 -0
- package/src/kit/components/scene-documents.tsx +221 -0
- package/src/kit/components/status-contributions.tsx +407 -0
- package/src/kit/components/tool-documents.tsx +302 -0
- package/src/kit/components/tool-schema-form.tsx +262 -0
- package/src/kit/components/use-after-paint.ts +41 -0
- package/src/kit/components/use-project-image-assets.ts +86 -0
- package/src/kit/components/workspace-history.ts +32 -0
- package/src/kit/components/world-documents.tsx +570 -0
- package/src/kit/components/world-overlay-gestures.ts +1939 -0
- package/src/kit/composite-screenshot.ts +2238 -0
- package/src/kit/content-entry-source-registry.ts +184 -0
- package/src/kit/contribution-surfaces.ts +48 -0
- package/src/kit/coverage/canvas-reveal.ts +192 -0
- package/src/kit/coverage/design-time-surfaces.ts +101 -0
- package/src/kit/coverage/ontology-invariants.ts +466 -0
- package/src/kit/coverage/session-vitals.ts +503 -0
- package/src/kit/crash-null-boundary.ts +36 -0
- package/src/kit/creation-site-edit.ts +1491 -0
- package/src/kit/creation-site-registry.ts +160 -0
- package/src/kit/delegate-harness-registry.ts +134 -0
- package/src/kit/document-areas.ts +70 -0
- package/src/kit/document-context-registry.ts +193 -0
- package/src/kit/document-open-registry.ts +200 -0
- package/src/kit/document-play-extension.ts +221 -0
- package/src/kit/document-preview-source.ts +20 -0
- package/src/kit/document-renderer-session.ts +138 -0
- package/src/kit/document-stage-sessions.ts +26 -0
- package/src/kit/document-viewports.ts +120 -0
- package/src/kit/editor-api.ts +46 -0
- package/src/kit/editor-chrome-capture.ts +136 -0
- package/src/kit/editor-commands.ts +176 -0
- package/src/kit/editor-console.ts +580 -0
- package/src/kit/editor-current-view.ts +56 -0
- package/src/kit/editor-document-probe.ts +1166 -0
- package/src/kit/editor-git-client.ts +115 -0
- package/src/kit/editor-hotkeys.ts +728 -0
- package/src/kit/editor-lease-view.ts +39 -0
- package/src/kit/editor-lease.ts +415 -0
- package/src/kit/editor-mode.ts +19 -0
- package/src/kit/editor-notifications.ts +140 -0
- package/src/kit/editor-presence.ts +563 -0
- package/src/kit/editor-presentation-activity.ts +58 -0
- package/src/kit/editor-presentation-notice.ts +42 -0
- package/src/kit/editor-runtime.tsx +147 -0
- package/src/kit/editor-server-response.ts +86 -0
- package/src/kit/editor-session-attribution.ts +85 -0
- package/src/kit/editor-session-mode.ts +54 -0
- package/src/kit/editor-state-facets.ts +74 -0
- package/src/kit/editor-view-presentation.ts +777 -0
- package/src/kit/environment-images.ts +58 -0
- package/src/kit/eyedropper-session.ts +60 -0
- package/src/kit/files/file-provider.ts +62 -0
- package/src/kit/files/project-files.ts +270 -0
- package/src/kit/finders/index.ts +137 -0
- package/src/kit/finders/scenes-from-entrypoint-selection.ts +387 -0
- package/src/kit/frame/frame-parts.ts +30 -0
- package/src/kit/framed-document-capture.ts +34 -0
- package/src/kit/game-globals-prelude.ts +143 -0
- package/src/kit/game-surface-defaults.ts +33 -0
- package/src/kit/gameplay-dom-recording.ts +318 -0
- package/src/kit/gameplay-export-state.ts +14 -0
- package/src/kit/gameplay-replay.ts +417 -0
- package/src/kit/gameplay-session-time.ts +9 -0
- package/src/kit/gameplay-sessions.ts +204 -0
- package/src/kit/hierarchy-component-marks.ts +298 -0
- package/src/kit/hierarchy-internals.ts +197 -0
- package/src/kit/hierarchy-kind-icon.ts +217 -0
- package/src/kit/hierarchy-menu-registry.ts +67 -0
- package/src/kit/hierarchy-node-rows.ts +307 -0
- package/src/kit/hierarchy-panel-view.ts +280 -0
- package/src/kit/hierarchy-projection.ts +76 -0
- package/src/kit/hierarchy-row-media.ts +45 -0
- package/src/kit/hierarchy-row-model.ts +308 -0
- package/src/kit/hierarchy-rows.ts +11 -0
- package/src/kit/hierarchy-walk.ts +86 -0
- package/src/kit/history/editor-session.ts +25 -0
- package/src/kit/history/history-commands.ts +147 -0
- package/src/kit/history/history-delegate.ts +187 -0
- package/src/kit/history/history-limit-notices.ts +43 -0
- package/src/kit/history/history-service.ts +1189 -0
- package/src/kit/history/persistence-coordinator.ts +35 -0
- package/src/kit/history/project-file-history.ts +386 -0
- package/src/kit/history/project-root-history-backends.ts +139 -0
- package/src/kit/history/resource-registry.ts +209 -0
- package/src/kit/history/snapshot-store.ts +103 -0
- package/src/kit/history/source-history-backend.ts +546 -0
- package/src/kit/history-types.ts +124 -0
- package/src/kit/hmr-registration-group.ts +67 -0
- package/src/kit/hmr-stable-react-context.ts +23 -0
- package/src/kit/hotkeys.ts +190 -0
- package/src/kit/inference-diagnostics.ts +69 -0
- package/src/kit/initial-project.ts +80 -0
- package/src/kit/inspection/active-subject.ts +571 -0
- package/src/kit/inspection/active-surface.ts +142 -0
- package/src/kit/inspection/compose-subject.ts +1055 -0
- package/src/kit/inspection/compose.ts +7 -0
- package/src/kit/inspection/display.ts +171 -0
- package/src/kit/inspection/document-subject.ts +109 -0
- package/src/kit/inspection/game-subject.ts +85 -0
- package/src/kit/inspection/null-subject.ts +119 -0
- package/src/kit/inspection/serialize.ts +357 -0
- package/src/kit/inspection/use-active-inspection.ts +180 -0
- package/src/kit/inspection-model.ts +542 -0
- package/src/kit/inspection-node-media.ts +58 -0
- package/src/kit/inspector-presentation.ts +203 -0
- package/src/kit/inspector-property-grouping.ts +64 -0
- package/src/kit/inspector-section-registry.ts +221 -0
- package/src/kit/instance-source-actions.ts +163 -0
- package/src/kit/js-heap.ts +71 -0
- package/src/kit/key-actions.ts +91 -0
- package/src/kit/keymap-presets.ts +428 -0
- package/src/kit/layout-policy.ts +31 -0
- package/src/kit/light-explorer-model.ts +134 -0
- package/src/kit/live-canvas-frame.ts +55 -0
- package/src/kit/live-document.ts +296 -0
- package/src/kit/live-gesture-lock.ts +50 -0
- package/src/kit/live-seam-evidence.ts +11 -0
- package/src/kit/live-session-registry.ts +220 -0
- package/src/kit/live-transition.ts +391 -0
- package/src/kit/manifest-project.ts +107 -0
- package/src/kit/module-fetch-diagnosis.ts +192 -0
- package/src/kit/mount-failure-report.ts +154 -0
- package/src/kit/native-selection-style.ts +497 -0
- package/src/kit/object3d-document-write-policy.ts +137 -0
- package/src/kit/packaged-runtime.ts +108 -0
- package/src/kit/palettes/maya.palette.json +57 -0
- package/src/kit/palettes/substance.palette.json +57 -0
- package/src/kit/performance-profiler.ts +367 -0
- package/src/kit/performance-sources.ts +69 -0
- package/src/kit/photograph-notice.ts +141 -0
- package/src/kit/play-boot-phase.ts +166 -0
- package/src/kit/play-camera-flight.ts +35 -0
- package/src/kit/png-encode.worker.ts +26 -0
- package/src/kit/presentation-surface.ts +248 -0
- package/src/kit/product-command.ts +90 -0
- package/src/kit/project-adapter.ts +1140 -0
- package/src/kit/project-asset-refresh.ts +23 -0
- package/src/kit/project-asset-roots.ts +68 -0
- package/src/kit/project-local-state.ts +151 -0
- package/src/kit/project-manager.ts +243 -0
- package/src/kit/project-module-changes.ts +201 -0
- package/src/kit/project-module-split.ts +270 -0
- package/src/kit/project-play-layers.ts +25 -0
- package/src/kit/project-provenance.ts +115 -0
- package/src/kit/project-ready.ts +42 -0
- package/src/kit/project-shape.ts +68 -0
- package/src/kit/project-tools.ts +107 -0
- package/src/kit/projection-types.ts +44 -0
- package/src/kit/readiness.ts +113 -0
- package/src/kit/renderer-resource-counts.ts +27 -0
- package/src/kit/reported-play-state.ts +90 -0
- package/src/kit/resolve-contributed-command.ts +14 -0
- package/src/kit/resolve-relative-specifier.ts +33 -0
- package/src/kit/retained-document-states.ts +91 -0
- package/src/kit/scene-document-plan.ts +320 -0
- package/src/kit/scene-live-open.ts +210 -0
- package/src/kit/scoped-game-css.ts +152 -0
- package/src/kit/served-url.ts +5 -0
- package/src/kit/session-close.ts +17 -0
- package/src/kit/session-tombstone.ts +127 -0
- package/src/kit/settings/settings-provider.ts +82 -0
- package/src/kit/settings-store.ts +348 -0
- package/src/kit/shell-document-state.ts +27 -0
- package/src/kit/shell-store-door.ts +45 -0
- package/src/kit/shell-store.ts +722 -0
- package/src/kit/source-conflict.ts +122 -0
- package/src/kit/stage-context.ts +377 -0
- package/src/kit/stage-invalidation.ts +25 -0
- package/src/kit/stage-store-registry.ts +69 -0
- package/src/kit/startup-failure.ts +80 -0
- package/src/kit/state-report-deferral.ts +73 -0
- package/src/kit/storage/host-files-storage.ts +97 -0
- package/src/kit/storage/http-storage.ts +174 -0
- package/src/kit/storage/index.ts +75 -0
- package/src/kit/storage/mem-storage.ts +158 -0
- package/src/kit/storage/path-lock.ts +44 -0
- package/src/kit/storage/paths.ts +26 -0
- package/src/kit/storage-types.ts +127 -0
- package/src/kit/stories/StoryPreviewMount.tsx +306 -0
- package/src/kit/stories/compose-project-stories.ts +255 -0
- package/src/kit/stories/prefabs-finder.ts +54 -0
- package/src/kit/stories/prefabs-from-stories.ts +182 -0
- package/src/kit/stories/project-story-regions.ts +24 -0
- package/src/kit/stories/story-capture.ts +579 -0
- package/src/kit/stories/story-declared-medium.ts +126 -0
- package/src/kit/stories/story-discovery.ts +176 -0
- package/src/kit/stories/story-dom-runtime.ts +78 -0
- package/src/kit/stories/story-grouping.ts +111 -0
- package/src/kit/stories/story-mount-turn.ts +27 -0
- package/src/kit/stories/story-presentation.ts +215 -0
- package/src/kit/stories/story-preview-component.ts +7 -0
- package/src/kit/stories/story-registry.ts +530 -0
- package/src/kit/stories-scope.ts +35 -0
- package/src/kit/story-document-openers.ts +36 -0
- package/src/kit/story-thumbnails.ts +47 -0
- package/src/kit/surface-keyboard.ts +101 -0
- package/src/kit/surface-state.ts +135 -0
- package/src/kit/system-seam-evidence.ts +72 -0
- package/src/kit/tab-census.ts +202 -0
- package/src/kit/tab-lifecycle-client.ts +227 -0
- package/src/kit/theme-library.ts +897 -0
- package/src/kit/theme-preference.ts +429 -0
- package/src/kit/three-viewport-presentation.ts +23 -0
- package/src/kit/tool-contribution-play.ts +74 -0
- package/src/kit/tool-loader.ts +1918 -0
- package/src/kit/transform-mode-request.ts +66 -0
- package/src/kit/transient-hint.ts +78 -0
- package/src/kit/transport-strip.tsx +174 -0
- package/src/kit/ui-source/adapter-region-includes.ts +238 -0
- package/src/kit/ui-source/file-region-resolver.ts +302 -0
- package/src/kit/ui-source/inspect.ts +775 -0
- package/src/kit/ui-source/source-write-backend.ts +605 -0
- package/src/kit/ui-source/tier-source-write-backend.ts +279 -0
- package/src/kit/user-local-state.ts +105 -0
- package/src/kit/viewport-activation-timings.ts +840 -0
- package/src/kit/viewport-editor-controls.ts +22 -0
- package/src/kit/viewport-presentation.ts +668 -0
- package/src/kit/viewport-surface-status.tsx +55 -0
- package/src/kit/wait-until.ts +37 -0
- package/src/kit/worker-call-metrics.ts +166 -0
- package/src/kit/workspace-areas.ts +191 -0
- package/src/kit/workspace-aux-commands.ts +11 -0
- package/src/kit/workspace-available-documents.ts +142 -0
- package/src/kit/workspace-core-utilities.ts +31 -0
- package/src/kit/workspace-document-ids.ts +59 -0
- package/src/kit/workspace-document-registry.ts +624 -0
- package/src/kit/workspace-document-restore.ts +146 -0
- package/src/kit/workspace-host-commands.ts +141 -0
- package/src/kit/workspace-persistence-gate.ts +40 -0
- package/src/kit/workspace-play-utilities.ts +44 -0
- package/src/kit/workspace-presets.ts +446 -0
- package/src/kit/workspace-regions.ts +276 -0
- package/src/kit/workspace-static-panels.ts +73 -0
- package/src/kit/workspace-status-registry.ts +121 -0
- package/src/kit/workspace-storage.ts +35 -0
- package/src/kit/workspace-style.ts +226 -0
- package/src/kit/workspace-utility-commands.ts +74 -0
- package/src/kit/workspace-utility-registry.ts +263 -0
- package/src/kit/world-adoption-event.ts +23 -0
- package/src/kit/world-adoption.ts +115 -0
- package/src/kit/world-canvas-viewport-state.ts +35 -0
- package/src/kit/world-document-routing.ts +104 -0
- package/src/kit/world-pan-state.ts +198 -0
- package/src/kit/write-pipe.ts +173 -0
- package/src/layout-arrangements.ts +5 -0
- package/src/layouts.tsx +108 -0
- package/src/looks.ts +16 -0
- package/src/project/output-roots.ts +73 -0
- package/src/project/tab-census.ts +155 -0
- package/src/project-tool-catalog.ts +104 -0
- package/src/selection.tsx +107 -0
- package/src/services.ts +18 -0
- package/src/session/build-report.ts +22 -0
- package/src/session/collaboration-types.ts +262 -0
- package/src/session/command-table.ts +327 -0
- package/src/session/discovery.ts +100 -0
- package/src/session/editor-brand.ts +48 -0
- package/src/session/editor-compatibility.ts +317 -0
- package/src/session/editor-control-lifecycle.ts +68 -0
- package/src/session/editor-control-protocol.ts +5 -0
- package/src/session/entrypoint-selection-readers.ts +66 -0
- package/src/session/entrypoint-selection-source.ts +120 -0
- package/src/session/game-css-scope.ts +30 -0
- package/src/session/hosted-attachment.ts +225 -0
- package/src/session/limited-view.ts +82 -0
- package/src/session/product-create.ts +24 -0
- package/src/session/product-locator.ts +478 -0
- package/src/session/project-module-url.ts +242 -0
- package/src/session/project-serving.ts +164 -0
- package/src/session/project-upgrade.ts +403 -0
- package/src/session/registry-format.ts +210 -0
- package/src/session/relative-path-guard.ts +56 -0
- package/src/session/scoped-game-css.ts +461 -0
- package/src/session/source-glob.ts +15 -0
- package/src/session/tool-contribution-convention.ts +123 -0
- package/src/session/workbench-locator.ts +712 -0
- package/src/session.ts +41 -0
- package/src/share.ts +160 -0
- package/src/source-analysis.ts +28 -0
- package/src/source-authoring.ts +439 -0
- package/src/tools/errors.ts +91 -0
- package/src/tools/provider-execution.ts +70 -0
- package/src/tools/registry.ts +341 -0
- package/src/tools/types.ts +159 -0
- package/src/transport.ts +100 -0
- package/src/types.ts +1693 -0
- package/src/views.ts +164 -0
- package/src/widgets/design-system.ts +93 -0
- package/src/widgets/editor-appearance.ts +151 -0
- package/src/widgets/editor-material.ts +83 -0
- package/src/widgets/icon-set-registry.ts +105 -0
- package/src/widgets/index.ts +71 -0
- package/src/widgets/inspector-widgets/AlignmentGrid.tsx +182 -0
- package/src/widgets/inspector-widgets/AssetSlotPicker.tsx +123 -0
- package/src/widgets/inspector-widgets/BorderEditor.tsx +309 -0
- package/src/widgets/inspector-widgets/ColorPicker.tsx +549 -0
- package/src/widgets/inspector-widgets/CurveEditor.tsx +359 -0
- package/src/widgets/inspector-widgets/FilterEditor.tsx +108 -0
- package/src/widgets/inspector-widgets/FontPicker.tsx +191 -0
- package/src/widgets/inspector-widgets/GradientEditor.tsx +623 -0
- package/src/widgets/inspector-widgets/ScrubbableInput.tsx +180 -0
- package/src/widgets/inspector-widgets/ShadowEditor.tsx +319 -0
- package/src/widgets/inspector-widgets/color-utils.ts +201 -0
- package/src/widgets/inspector-widgets/curve-utils.ts +212 -0
- package/src/widgets/inspector-widgets/index.ts +25 -0
- package/src/widgets/inspector-widgets/shared.tsx +140 -0
- package/src/widgets/interactive-edit-scope.ts +33 -0
- package/src/widgets/patterns/Dialog.tsx +140 -0
- package/src/widgets/patterns/Fields.tsx +44 -0
- package/src/widgets/patterns/List.tsx +25 -0
- package/src/widgets/patterns/StateSurface.tsx +40 -0
- package/src/widgets/patterns/Surfaces.tsx +122 -0
- package/src/widgets/patterns/Tabs.tsx +80 -0
- package/src/widgets/patterns/Toolbar.tsx +72 -0
- package/src/widgets/patterns/Tree.tsx +72 -0
- package/src/widgets/primitives/AnchoredMenu.tsx +260 -0
- package/src/widgets/primitives/Button.tsx +62 -0
- package/src/widgets/primitives/ColorInput.tsx +78 -0
- package/src/widgets/primitives/DraftTextInput.tsx +63 -0
- package/src/widgets/primitives/EditorIcon.tsx +157 -0
- package/src/widgets/primitives/FormControls.tsx +88 -0
- package/src/widgets/primitives/HoverPreview.tsx +96 -0
- package/src/widgets/primitives/JsonInput.tsx +113 -0
- package/src/widgets/primitives/Layout.tsx +100 -0
- package/src/widgets/primitives/Menu.tsx +161 -0
- package/src/widgets/primitives/NumberInput.tsx +169 -0
- package/src/widgets/primitives/Panel.tsx +80 -0
- package/src/widgets/primitives/SectionHeader.tsx +77 -0
- package/src/widgets/primitives/Text.tsx +54 -0
- package/src/widgets/primitives/ThemeRootPortal.tsx +52 -0
- package/src/widgets/primitives/Tooltip.tsx +204 -0
- package/src/widgets/primitives/Vec3Input.tsx +70 -0
- package/src/widgets/primitives/banner-tones.ts +32 -0
- package/src/widgets/primitives/clamp-to-viewport.ts +44 -0
- package/src/widgets/primitives/editor-icons.ts +254 -0
- package/src/widgets/primitives/panel-header-styles.ts +42 -0
- package/src/widgets/theme.ts +2841 -0
- package/src/widgets/z-index.ts +25 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime detection of the PACKAGED editor server (`packages/editor/server/
|
|
3
|
+
* packaged.ts` — a `@volter/editor-core` npm package with NO monorepo checkout on
|
|
4
|
+
* disk) from editor CLIENT code. Needed because a react world's mount
|
|
5
|
+
* (`react-mount-runtime.ts`'s `resolveReactRootMountRuntime`) must resolve its
|
|
6
|
+
* `react`/`react-dom/client` from the
|
|
7
|
+
* PROJECT's own module graph ONLY under this runtime — see that function's
|
|
8
|
+
* doc comment, and `packaged.ts`'s header doc comment ("React-world OID
|
|
9
|
+
* authoring parity"), for the dual-React-instance bug this closes. Under
|
|
10
|
+
* dev, this must resolve `false` so the existing static-import path
|
|
11
|
+
* stays byte-unchanged (one shared Vite instance already collapses both
|
|
12
|
+
* react copies via `resolve.dedupe`).
|
|
13
|
+
*
|
|
14
|
+
* Reads the server's own `packaged` flag off `/__editor/project`'s response
|
|
15
|
+
* (computed server-side via `isMonorepoScaffoldRoot`, `server-utils.ts`)
|
|
16
|
+
* rather than probing a URL that only resolves in packaged mode: an
|
|
17
|
+
* unconditional dynamic `import()` probe would 404 (and log an
|
|
18
|
+
* unsuppressible browser console error) on EVERY react-world mount under
|
|
19
|
+
* dev — the exact reasoning `binding-resolver.ts`'s
|
|
20
|
+
* `loadProjectUIRegistry` doc comment already recorded for `hasUiRegistry`
|
|
21
|
+
* ("the client must not probe /@fs for it").
|
|
22
|
+
*
|
|
23
|
+
* A plain inline `fetch()`, not `editor-api.ts`'s `getCurrentServerProject`
|
|
24
|
+
* — same reasoning `loadProjectUIRegistry` documents: this module (via
|
|
25
|
+
* `binding-resolver.ts`) must stay importable by headless Node/vitest
|
|
26
|
+
* suites, and `editor-api.ts`'s module top level pulls in `./storage`.
|
|
27
|
+
*
|
|
28
|
+
* A HOST THAT SERVES NO `/__editor/project` is answered locally rather than by
|
|
29
|
+
* a doomed fetch: it is never the packaged runtime, because "packaged" names a
|
|
30
|
+
* Node host serving a project's own module graph, and a 404's console error is
|
|
31
|
+
* unsuppressible on every doorway of every mount. Same guard, same reason, as
|
|
32
|
+
* `ui-source/tier-source-write-backend.ts`'s `serverSourceWriteRoutes`.
|
|
33
|
+
*
|
|
34
|
+
* ## What is memoized, and what a FAILED probe does
|
|
35
|
+
*
|
|
36
|
+
* An ANSWER is memoized for the page — the runtime a server process runs
|
|
37
|
+
* under cannot change without a restart, so a settled answer is settled. A
|
|
38
|
+
* probe that never got an answer is NOT memoized, and does NOT resolve: it
|
|
39
|
+
* drops the memo and REJECTS, so the next caller asks again.
|
|
40
|
+
*
|
|
41
|
+
* Both halves were bought by one measured failure. A `.catch(() => false)`
|
|
42
|
+
* latch turned a single unreachable fetch — a mount landing in the window
|
|
43
|
+
* while the editor's `edit` command restarts its dev server, which it does on any
|
|
44
|
+
* server-file change — into a page where EVERY doorway
|
|
45
|
+
* (`three-ingest-runtime`, `canvas-entry-runtime`, `r3f-entry-runtime`,
|
|
46
|
+
* the two story runtimes, `binding-resolver`'s react
|
|
47
|
+
* mount) silently resolved the SHELL's namespace for the rest of the
|
|
48
|
+
* session. Under the packaged runtime that is the wrong graph, and the cost
|
|
49
|
+
* lands 10–15 seconds later as a mount failure whose message blames the
|
|
50
|
+
* GAME ("bundles its own (un-shared) copy of three") for a defect in this
|
|
51
|
+
* host — the exact mis-attribution `three-ingest-runtime.ts`'s own
|
|
52
|
+
* loud-throw comment already refuses to make for the sibling case.
|
|
53
|
+
*
|
|
54
|
+
* So "I don't know" is never spent as "dev". Every doorway reads this with
|
|
55
|
+
* `await isPackagedRuntime()` and does nothing else with the answer, so the
|
|
56
|
+
* rejection propagates to the mount site unchanged: nothing mounts on a
|
|
57
|
+
* guessed graph, the message names this host, and because the memo is
|
|
58
|
+
* dropped the remedy it states — retry the mount — is a real one rather
|
|
59
|
+
* than advice.
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
import { editorServerJson } from '@volter/sdk/kit/editor-server-response';
|
|
63
|
+
|
|
64
|
+
let cachedIsPackaged: Promise<boolean> | null = null;
|
|
65
|
+
|
|
66
|
+
export function isPackagedRuntime(): Promise<boolean> {
|
|
67
|
+
if (!cachedIsPackaged) {
|
|
68
|
+
// The `fetch` call is INSIDE the chain so that a synchronous throw from it
|
|
69
|
+
// is a rejected probe like any other, rather than an exception thrown at
|
|
70
|
+
// whoever happened to ask first.
|
|
71
|
+
const probe: Promise<boolean> = Promise.resolve()
|
|
72
|
+
.then(() => fetch('/__editor/project'))
|
|
73
|
+
.then((res) =>
|
|
74
|
+
editorServerJson<{ project?: { packaged?: boolean } | null }>(
|
|
75
|
+
res,
|
|
76
|
+
'`/__editor/project` did not answer',
|
|
77
|
+
),
|
|
78
|
+
)
|
|
79
|
+
.then((data) => Boolean(data.project?.packaged))
|
|
80
|
+
.catch((err: unknown) => {
|
|
81
|
+
if (cachedIsPackaged === probe) cachedIsPackaged = null;
|
|
82
|
+
throw new Error(
|
|
83
|
+
"This editor session's runtime is unknown — `/__editor/project` did not answer, so " +
|
|
84
|
+
'which module graph a world mounts in (this shell’s, or the project’s) cannot be ' +
|
|
85
|
+
'decided and nothing was mounted on a guess. This is a fault in the editor host, ' +
|
|
86
|
+
'not in the game. The answer is not latched: retry the mount (reopen the project) ' +
|
|
87
|
+
`and the question is asked again. (${err instanceof Error ? err.message : String(err)})`,
|
|
88
|
+
{ cause: err },
|
|
89
|
+
);
|
|
90
|
+
});
|
|
91
|
+
cachedIsPackaged = probe;
|
|
92
|
+
}
|
|
93
|
+
return cachedIsPackaged;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Test-only: reset the memoized result between tests (mirrors
|
|
97
|
+
* `setCachedProjectUIRegistry`'s test-seam shape). */
|
|
98
|
+
export function resetPackagedRuntimeCacheForTest(): void {
|
|
99
|
+
cachedIsPackaged = null;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Test-only: pre-seed the probe's answer. jsdom has no `/__editor/project` to
|
|
103
|
+
* ask (vitest's MODE is not `web`, so the browser short-circuit does not
|
|
104
|
+
* apply), and the loud unknown-runtime refusal — correct in a live session —
|
|
105
|
+
* is pure noise in a suite that mounts portable stories. */
|
|
106
|
+
export function setPackagedRuntimeForTest(packaged: boolean): void {
|
|
107
|
+
cachedIsPackaged = Promise.resolve(packaged);
|
|
108
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 3,
|
|
3
|
+
"name": "Maya",
|
|
4
|
+
"theme": {
|
|
5
|
+
"id": "maya",
|
|
6
|
+
"color": {
|
|
7
|
+
"surface": {
|
|
8
|
+
"shell": "#2b2b2b",
|
|
9
|
+
"panel": "#444444",
|
|
10
|
+
"chrome": "#373737",
|
|
11
|
+
"raised": "#4b4b4b",
|
|
12
|
+
"inset": "#333333",
|
|
13
|
+
"overlay": "rgba(55,55,55,0.94)"
|
|
14
|
+
},
|
|
15
|
+
"boundary": {
|
|
16
|
+
"default": "#2b2b2b",
|
|
17
|
+
"strong": "#5a5a5a"
|
|
18
|
+
},
|
|
19
|
+
"content": {
|
|
20
|
+
"primary": "#cccccc",
|
|
21
|
+
"muted": "#a8a8a8",
|
|
22
|
+
"dim": "#858585",
|
|
23
|
+
"onAccent": "#ffffff",
|
|
24
|
+
"onBright": {
|
|
25
|
+
"primary": "#1c1c1c",
|
|
26
|
+
"muted": "rgba(28,28,28,0.82)",
|
|
27
|
+
"dim": "rgba(28,28,28,0.7)"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"accent": {
|
|
31
|
+
"default": "#5285a6",
|
|
32
|
+
"muted": "rgba(82,133,166,0.34)"
|
|
33
|
+
},
|
|
34
|
+
"semantic": {
|
|
35
|
+
"danger": "#d9534f",
|
|
36
|
+
"dangerMuted": "rgba(217,83,79,0.28)",
|
|
37
|
+
"dangerFaint": "rgba(217,83,79,0.12)",
|
|
38
|
+
"warning": "#e0a030",
|
|
39
|
+
"warningMuted": "rgba(224,160,48,0.28)",
|
|
40
|
+
"success": "#4fd85b",
|
|
41
|
+
"successMuted": "rgba(79,216,91,0.28)",
|
|
42
|
+
"dynamic": "#e6a6ff",
|
|
43
|
+
"dynamicMuted": "rgba(230,166,255,0.18)",
|
|
44
|
+
"instance": "#4fd85b"
|
|
45
|
+
},
|
|
46
|
+
"neutralOverlay": {
|
|
47
|
+
"hover": "rgba(255,255,255,0.07)",
|
|
48
|
+
"active": "rgba(255,255,255,0.12)"
|
|
49
|
+
},
|
|
50
|
+
"scrim": "rgba(0,0,0,0.55)"
|
|
51
|
+
},
|
|
52
|
+
"typography": {
|
|
53
|
+
"sans": "'Helvetica Neue', Arial, system-ui, sans-serif",
|
|
54
|
+
"mono": "Menlo, Consolas, monospace"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 3,
|
|
3
|
+
"name": "Substance",
|
|
4
|
+
"theme": {
|
|
5
|
+
"id": "substance",
|
|
6
|
+
"color": {
|
|
7
|
+
"surface": {
|
|
8
|
+
"shell": "#1e1e1e",
|
|
9
|
+
"panel": "#252525",
|
|
10
|
+
"chrome": "#2a2a2a",
|
|
11
|
+
"raised": "#2d2d2d",
|
|
12
|
+
"inset": "#1a1a1a",
|
|
13
|
+
"overlay": "rgba(37,37,37,0.94)"
|
|
14
|
+
},
|
|
15
|
+
"boundary": {
|
|
16
|
+
"default": "#3a3a3a",
|
|
17
|
+
"strong": "#4a4a4a"
|
|
18
|
+
},
|
|
19
|
+
"content": {
|
|
20
|
+
"primary": "#d9d9d9",
|
|
21
|
+
"muted": "#a6a6a6",
|
|
22
|
+
"dim": "#7f7f7f",
|
|
23
|
+
"onAccent": "#ffffff",
|
|
24
|
+
"onBright": {
|
|
25
|
+
"primary": "#1e1e1e",
|
|
26
|
+
"muted": "rgba(30,30,30,0.82)",
|
|
27
|
+
"dim": "rgba(30,30,30,0.7)"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"accent": {
|
|
31
|
+
"default": "#4aa3df",
|
|
32
|
+
"muted": "rgba(74,163,223,0.3)"
|
|
33
|
+
},
|
|
34
|
+
"semantic": {
|
|
35
|
+
"danger": "#e5534b",
|
|
36
|
+
"dangerMuted": "rgba(229,83,75,0.28)",
|
|
37
|
+
"dangerFaint": "rgba(229,83,75,0.12)",
|
|
38
|
+
"warning": "#e3a52f",
|
|
39
|
+
"warningMuted": "rgba(227,165,47,0.28)",
|
|
40
|
+
"success": "#5cc27a",
|
|
41
|
+
"successMuted": "rgba(92,194,122,0.28)",
|
|
42
|
+
"dynamic": "#4aa3df",
|
|
43
|
+
"dynamicMuted": "rgba(74,163,223,0.18)",
|
|
44
|
+
"instance": "#e98b3a"
|
|
45
|
+
},
|
|
46
|
+
"neutralOverlay": {
|
|
47
|
+
"hover": "rgba(255,255,255,0.06)",
|
|
48
|
+
"active": "rgba(255,255,255,0.11)"
|
|
49
|
+
},
|
|
50
|
+
"scrim": "rgba(0,0,0,0.62)"
|
|
51
|
+
},
|
|
52
|
+
"typography": {
|
|
53
|
+
"sans": "'Source Sans 3', 'Segoe UI', system-ui, sans-serif",
|
|
54
|
+
"mono": "'Source Code Pro', Menlo, monospace"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
export interface PerformanceTiming {
|
|
2
|
+
readonly name: string;
|
|
3
|
+
readonly ms: number;
|
|
4
|
+
/**
|
|
5
|
+
* Offset (ms) from THIS frame's start (`frameStart`) at which the timing
|
|
6
|
+
* began — a MEASURED value (e.g. a phase's `phaseStart - frameStart`), never
|
|
7
|
+
* synthesized. Present on per-frame phase timings (W4b, so a Chrome trace
|
|
8
|
+
* can place each phase span under its frame at the real offset). OMITTED on
|
|
9
|
+
* cross-frame aggregate rollups (`PerformanceSnapshot.phases`/`systems`/
|
|
10
|
+
* `components`), where no single start point exists — absent, never a
|
|
11
|
+
* fabricated 0.
|
|
12
|
+
*/
|
|
13
|
+
readonly startMs?: number;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* One MEASURED span within a frame (W4b) — a system or component invocation,
|
|
18
|
+
* with the phase it ran in and its measured start offset from `frameStart`.
|
|
19
|
+
* Distinct from {@link PerformanceTiming}: a span is a single timed
|
|
20
|
+
* invocation carrying `phase` + always-present `startMs` (the trace/flame
|
|
21
|
+
* unit), whereas a `PerformanceTiming` may be a cross-frame rollup.
|
|
22
|
+
*/
|
|
23
|
+
export interface PerformanceSpan {
|
|
24
|
+
readonly name: string;
|
|
25
|
+
readonly phase: string;
|
|
26
|
+
/** Measured offset (ms) from `frameStart` at which this span began. */
|
|
27
|
+
readonly startMs: number;
|
|
28
|
+
readonly ms: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Renderer counters accumulated over a frame (from `renderer.info`). */
|
|
32
|
+
export interface PerformanceRenderStats {
|
|
33
|
+
readonly gpuMs: number | null;
|
|
34
|
+
readonly drawCalls: number;
|
|
35
|
+
readonly triangles: number;
|
|
36
|
+
readonly geometries: number;
|
|
37
|
+
readonly textures: number;
|
|
38
|
+
/**
|
|
39
|
+
* How many top-level `renderer.render()` submissions the last presentation
|
|
40
|
+
* took (`renderer.info.render.frame`'s delta across one draw) — a composer
|
|
41
|
+
* chain, a shadow pass and a post stack each cost one. `null` (never a
|
|
42
|
+
* fabricated 0, same rule as `gpuMs`) when no reporter counted them: a
|
|
43
|
+
* reporter that omits `renderPasses` is saying it does not know, which is
|
|
44
|
+
* different from saying nothing was drawn.
|
|
45
|
+
*/
|
|
46
|
+
readonly renderPasses: number | null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface PerformanceFrame {
|
|
50
|
+
readonly id: number;
|
|
51
|
+
readonly timestamp: number;
|
|
52
|
+
readonly intervalMs: number;
|
|
53
|
+
readonly cpuMs: number;
|
|
54
|
+
readonly phases: readonly PerformanceTiming[];
|
|
55
|
+
/**
|
|
56
|
+
* Per-invocation system spans measured this frame (W4b). Ordered by
|
|
57
|
+
* `startMs` (execution order), NOT accumulated — a system that ran twice
|
|
58
|
+
* (two substeps) appears twice. Empty when the profiler saw no named
|
|
59
|
+
* systems this frame.
|
|
60
|
+
*/
|
|
61
|
+
readonly systems: readonly PerformanceSpan[];
|
|
62
|
+
/**
|
|
63
|
+
* Per-invocation component spans measured this frame (W4b) — populated ONLY
|
|
64
|
+
* while `recording` (component timing is gated on recording, matching
|
|
65
|
+
* `beginComponent`/`endComponent`). Empty otherwise.
|
|
66
|
+
*/
|
|
67
|
+
readonly components: readonly PerformanceSpan[];
|
|
68
|
+
/**
|
|
69
|
+
* Renderer counters reported during this frame (W4b) — a snapshot of the
|
|
70
|
+
* accumulated `reportRender` totals taken at `endFrame`. `gpuMs` is `null`
|
|
71
|
+
* when no GPU timer reported (headless/SwiftShader), never a fabricated 0.
|
|
72
|
+
*/
|
|
73
|
+
readonly render: PerformanceRenderStats;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface PerformanceSnapshot {
|
|
77
|
+
readonly enabled: boolean;
|
|
78
|
+
readonly recording: boolean;
|
|
79
|
+
readonly fps: number;
|
|
80
|
+
readonly cpuMs: number;
|
|
81
|
+
readonly p95Ms: number;
|
|
82
|
+
readonly p99Ms: number;
|
|
83
|
+
readonly frames: readonly PerformanceFrame[];
|
|
84
|
+
readonly phases: readonly PerformanceTiming[];
|
|
85
|
+
readonly systems: readonly PerformanceTiming[];
|
|
86
|
+
readonly components: readonly PerformanceTiming[];
|
|
87
|
+
readonly render: PerformanceRenderStats;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const now = () => globalThis.performance?.now() ?? Date.now();
|
|
91
|
+
|
|
92
|
+
function percentile(sorted: readonly number[], fraction: number): number {
|
|
93
|
+
if (sorted.length === 0) return 0;
|
|
94
|
+
return sorted[Math.min(sorted.length - 1, Math.floor((sorted.length - 1) * fraction))] ?? 0;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Game-owned, bounded external store for browser-native performance diagnostics. */
|
|
98
|
+
export function createPerformanceProfiler(initiallyEnabled = false) {
|
|
99
|
+
const listeners = new Set<() => void>();
|
|
100
|
+
const frames: PerformanceFrame[] = [];
|
|
101
|
+
const currentPhases = new Map<string, { ms: number; startMs: number }>();
|
|
102
|
+
const currentSystems = new Map<string, number>();
|
|
103
|
+
const currentComponents = new Map<string, number>();
|
|
104
|
+
// Per-frame span logs (W4b) — cleared each beginFrame, snapshotted into the
|
|
105
|
+
// frame at endFrame. Distinct from the accumulate-by-name aggregate maps
|
|
106
|
+
// above (which back the cross-frame snapshot rollups): these preserve every
|
|
107
|
+
// individual invocation and its measured start offset, for the trace.
|
|
108
|
+
let frameSystems: PerformanceSpan[] = [];
|
|
109
|
+
let frameComponents: PerformanceSpan[] = [];
|
|
110
|
+
let enabled = initiallyEnabled;
|
|
111
|
+
// The header's always-visible FPS sparkline needs frame INTERVALS without
|
|
112
|
+
// turning on the full profiler. Full profiling measures phases/systems,
|
|
113
|
+
// issues GPU timer queries at render sites, and intentionally warns about
|
|
114
|
+
// overhead; a glanceable heartbeat must not silently opt the user into all
|
|
115
|
+
// of that work. `telemetryEnabled` records only the frame envelope.
|
|
116
|
+
let telemetryEnabled = false;
|
|
117
|
+
let recording = false;
|
|
118
|
+
let frameId = 0;
|
|
119
|
+
let frameStart = 0;
|
|
120
|
+
let lastFrameStart = 0;
|
|
121
|
+
/**
|
|
122
|
+
* Phase start times, innermost last. A STACK rather than the single slot
|
|
123
|
+
* this used to be, because phases NEST: the three adapter brackets its CPU
|
|
124
|
+
* render submission as its own phase (`render.submit`,
|
|
125
|
+
* `dev/render-vitals.ts`) from inside the frame's enclosing `render` phase.
|
|
126
|
+
* With one slot the inner `beginPhase()` overwrote the outer's start, so the
|
|
127
|
+
* outer `endPhase('render')` measured only the tail after the inner phase —
|
|
128
|
+
* silently under-reporting the very phase the inner one was decomposing.
|
|
129
|
+
* Balanced callers are unaffected; `endPhase` with an empty stack falls back
|
|
130
|
+
* to `frameStart` rather than a stale start from a previous frame.
|
|
131
|
+
*/
|
|
132
|
+
const phaseStack: number[] = [];
|
|
133
|
+
let systemStart = 0;
|
|
134
|
+
let componentStart = 0;
|
|
135
|
+
let render: PerformanceRenderStats = {
|
|
136
|
+
gpuMs: null,
|
|
137
|
+
drawCalls: 0,
|
|
138
|
+
triangles: 0,
|
|
139
|
+
geometries: 0,
|
|
140
|
+
textures: 0,
|
|
141
|
+
renderPasses: null,
|
|
142
|
+
};
|
|
143
|
+
let snapshot: PerformanceSnapshot = {
|
|
144
|
+
enabled,
|
|
145
|
+
recording,
|
|
146
|
+
fps: 0,
|
|
147
|
+
cpuMs: 0,
|
|
148
|
+
p95Ms: 0,
|
|
149
|
+
p99Ms: 0,
|
|
150
|
+
frames: [],
|
|
151
|
+
phases: [],
|
|
152
|
+
systems: [],
|
|
153
|
+
components: [],
|
|
154
|
+
render,
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
function publish(): void {
|
|
158
|
+
const latest = frames.at(-1);
|
|
159
|
+
// Frame-only subscribers need no percentile work. Keep this window stable
|
|
160
|
+
// so a retained snapshot's first percentile read still describes its frames.
|
|
161
|
+
const snapshotFrames = frames.slice();
|
|
162
|
+
let sortedIntervals: number[] | undefined;
|
|
163
|
+
const readPercentile = (fraction: number): number => {
|
|
164
|
+
sortedIntervals ??= snapshotFrames
|
|
165
|
+
.map((frame) => frame.intervalMs)
|
|
166
|
+
.filter((value) => value > 0)
|
|
167
|
+
.sort((a, b) => a - b);
|
|
168
|
+
return percentile(sortedIntervals, fraction);
|
|
169
|
+
};
|
|
170
|
+
snapshot = {
|
|
171
|
+
enabled,
|
|
172
|
+
recording,
|
|
173
|
+
fps: latest?.intervalMs ? 1000 / latest.intervalMs : 0,
|
|
174
|
+
cpuMs: latest?.cpuMs ?? 0,
|
|
175
|
+
get p95Ms() {
|
|
176
|
+
return readPercentile(0.95);
|
|
177
|
+
},
|
|
178
|
+
get p99Ms() {
|
|
179
|
+
return readPercentile(0.99);
|
|
180
|
+
},
|
|
181
|
+
frames: snapshotFrames,
|
|
182
|
+
phases: latest?.phases ?? [],
|
|
183
|
+
systems: [...currentSystems].map(([name, ms]) => ({ name, ms })).sort((a, b) => b.ms - a.ms),
|
|
184
|
+
components: [...currentComponents]
|
|
185
|
+
.map(([name, ms]) => ({ name, ms }))
|
|
186
|
+
.sort((a, b) => b.ms - a.ms),
|
|
187
|
+
render,
|
|
188
|
+
};
|
|
189
|
+
for (const listener of listeners) listener();
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return {
|
|
193
|
+
get enabled() {
|
|
194
|
+
return enabled;
|
|
195
|
+
},
|
|
196
|
+
set enabled(value: boolean) {
|
|
197
|
+
if (enabled === value) return;
|
|
198
|
+
enabled = value;
|
|
199
|
+
if (value && !telemetryEnabled) lastFrameStart = 0;
|
|
200
|
+
publish();
|
|
201
|
+
},
|
|
202
|
+
get telemetryEnabled() {
|
|
203
|
+
return telemetryEnabled;
|
|
204
|
+
},
|
|
205
|
+
set telemetryEnabled(value: boolean) {
|
|
206
|
+
if (telemetryEnabled === value) return;
|
|
207
|
+
const wasInactive = !enabled && !telemetryEnabled;
|
|
208
|
+
telemetryEnabled = value;
|
|
209
|
+
if (value && wasInactive) lastFrameStart = 0;
|
|
210
|
+
publish();
|
|
211
|
+
},
|
|
212
|
+
get recording() {
|
|
213
|
+
return recording;
|
|
214
|
+
},
|
|
215
|
+
startRecording() {
|
|
216
|
+
const wasInactive = !enabled && !telemetryEnabled;
|
|
217
|
+
enabled = true;
|
|
218
|
+
if (wasInactive) lastFrameStart = 0;
|
|
219
|
+
recording = true;
|
|
220
|
+
frames.length = 0;
|
|
221
|
+
publish();
|
|
222
|
+
},
|
|
223
|
+
stopRecording() {
|
|
224
|
+
recording = false;
|
|
225
|
+
publish();
|
|
226
|
+
},
|
|
227
|
+
clear() {
|
|
228
|
+
frames.length = 0;
|
|
229
|
+
publish();
|
|
230
|
+
},
|
|
231
|
+
beginFrame() {
|
|
232
|
+
if (!enabled && !telemetryEnabled) return;
|
|
233
|
+
currentPhases.clear();
|
|
234
|
+
currentSystems.clear();
|
|
235
|
+
currentComponents.clear();
|
|
236
|
+
frameSystems = [];
|
|
237
|
+
frameComponents = [];
|
|
238
|
+
// A frame that threw mid-phase leaves entries on the stack; a fresh
|
|
239
|
+
// frame starts from nothing rather than inheriting them.
|
|
240
|
+
phaseStack.length = 0;
|
|
241
|
+
render = {
|
|
242
|
+
gpuMs: null,
|
|
243
|
+
drawCalls: 0,
|
|
244
|
+
triangles: 0,
|
|
245
|
+
geometries: 0,
|
|
246
|
+
textures: 0,
|
|
247
|
+
renderPasses: null,
|
|
248
|
+
};
|
|
249
|
+
frameStart = now();
|
|
250
|
+
},
|
|
251
|
+
beginPhase() {
|
|
252
|
+
if (!enabled) return;
|
|
253
|
+
phaseStack.push(now());
|
|
254
|
+
},
|
|
255
|
+
endPhase(name: string) {
|
|
256
|
+
if (!enabled) return;
|
|
257
|
+
// See `phaseStack`: pop restores the ENCLOSING phase's own start, so a
|
|
258
|
+
// nested bracket measures itself without truncating its parent.
|
|
259
|
+
const phaseStart = phaseStack.pop() ?? frameStart;
|
|
260
|
+
const elapsed = now() - phaseStart;
|
|
261
|
+
const existing = currentPhases.get(name);
|
|
262
|
+
// Accumulate ms across re-entries of the same phase, but keep the FIRST
|
|
263
|
+
// measured start offset (earliest entry) as the span's startMs.
|
|
264
|
+
currentPhases.set(name, {
|
|
265
|
+
ms: (existing?.ms ?? 0) + elapsed,
|
|
266
|
+
startMs: existing?.startMs ?? phaseStart - frameStart,
|
|
267
|
+
});
|
|
268
|
+
if (recording)
|
|
269
|
+
performance.measure(`volter.phase.${name}`, { start: phaseStart, duration: elapsed });
|
|
270
|
+
},
|
|
271
|
+
systemObserver: {
|
|
272
|
+
beginSystem() {
|
|
273
|
+
if (!enabled) return;
|
|
274
|
+
systemStart = now();
|
|
275
|
+
},
|
|
276
|
+
endSystem(scope: string, phase: string, name: string) {
|
|
277
|
+
if (!enabled) return;
|
|
278
|
+
const end = now();
|
|
279
|
+
const key = `${scope} / ${phase} / ${name}`;
|
|
280
|
+
currentSystems.set(key, (currentSystems.get(key) ?? 0) + end - systemStart);
|
|
281
|
+
frameSystems.push({
|
|
282
|
+
name: key,
|
|
283
|
+
phase,
|
|
284
|
+
startMs: systemStart - frameStart,
|
|
285
|
+
ms: end - systemStart,
|
|
286
|
+
});
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
beginComponent() {
|
|
290
|
+
if (!recording) return;
|
|
291
|
+
componentStart = now();
|
|
292
|
+
},
|
|
293
|
+
endComponent(name: string, phase = '') {
|
|
294
|
+
if (!recording) return;
|
|
295
|
+
const end = now();
|
|
296
|
+
currentComponents.set(name, (currentComponents.get(name) ?? 0) + end - componentStart);
|
|
297
|
+
frameComponents.push({
|
|
298
|
+
name,
|
|
299
|
+
phase,
|
|
300
|
+
startMs: componentStart - frameStart,
|
|
301
|
+
ms: end - componentStart,
|
|
302
|
+
});
|
|
303
|
+
},
|
|
304
|
+
reportRender(stats: {
|
|
305
|
+
gpuMs: number | null;
|
|
306
|
+
drawCalls: number;
|
|
307
|
+
triangles: number;
|
|
308
|
+
geometries: number;
|
|
309
|
+
textures: number;
|
|
310
|
+
/** Omit when this reporter does not count passes — see
|
|
311
|
+
* {@link PerformanceRenderStats.renderPasses}. */
|
|
312
|
+
renderPasses?: number;
|
|
313
|
+
}) {
|
|
314
|
+
if (!enabled) return;
|
|
315
|
+
render = {
|
|
316
|
+
gpuMs: stats.gpuMs ?? render.gpuMs,
|
|
317
|
+
drawCalls: render.drawCalls + stats.drawCalls,
|
|
318
|
+
triangles: render.triangles + stats.triangles,
|
|
319
|
+
geometries: render.geometries + stats.geometries,
|
|
320
|
+
textures: render.textures + stats.textures,
|
|
321
|
+
renderPasses:
|
|
322
|
+
stats.renderPasses === undefined
|
|
323
|
+
? render.renderPasses
|
|
324
|
+
: (render.renderPasses ?? 0) + stats.renderPasses,
|
|
325
|
+
};
|
|
326
|
+
},
|
|
327
|
+
endFrame() {
|
|
328
|
+
if (!enabled && !telemetryEnabled) return;
|
|
329
|
+
const timestamp = now();
|
|
330
|
+
const intervalMs = lastFrameStart === 0 ? 0 : frameStart - lastFrameStart;
|
|
331
|
+
lastFrameStart = frameStart;
|
|
332
|
+
const frame: PerformanceFrame = {
|
|
333
|
+
id: ++frameId,
|
|
334
|
+
timestamp,
|
|
335
|
+
intervalMs,
|
|
336
|
+
cpuMs: timestamp - frameStart,
|
|
337
|
+
phases: [...currentPhases]
|
|
338
|
+
.map(([name, { ms, startMs }]) => ({ name, ms, startMs }))
|
|
339
|
+
.sort((a, b) => b.ms - a.ms),
|
|
340
|
+
systems: frameSystems.slice(),
|
|
341
|
+
components: frameComponents.slice(),
|
|
342
|
+
render: { ...render },
|
|
343
|
+
};
|
|
344
|
+
frames.push(frame);
|
|
345
|
+
if (frames.length > 600) frames.splice(0, frames.length - 600);
|
|
346
|
+
if (recording)
|
|
347
|
+
performance.measure('volter.frame', { start: frameStart, duration: frame.cpuMs });
|
|
348
|
+
publish();
|
|
349
|
+
},
|
|
350
|
+
subscribe(listener: () => void) {
|
|
351
|
+
listeners.add(listener);
|
|
352
|
+
return () => {
|
|
353
|
+
listeners.delete(listener);
|
|
354
|
+
};
|
|
355
|
+
},
|
|
356
|
+
getSnapshot() {
|
|
357
|
+
return snapshot;
|
|
358
|
+
},
|
|
359
|
+
exportJSON() {
|
|
360
|
+
// version 2 (W4b): frames now carry per-frame `systems`/`components`
|
|
361
|
+
// spans, per-frame `render` counters, and `startMs` on phase timings.
|
|
362
|
+
return JSON.stringify({ version: 2, capturedAt: new Date().toISOString(), frames }, null, 2);
|
|
363
|
+
},
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
export type PerformanceProfiler = ReturnType<typeof createPerformanceProfiler>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { PerformanceProfiler } from './performance-profiler';
|
|
2
|
+
|
|
3
|
+
export interface EditorPerformanceSource {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly label: string;
|
|
6
|
+
readonly kind: 'scene' | 'source' | 'asset' | 'game';
|
|
7
|
+
readonly profiler: PerformanceProfiler;
|
|
8
|
+
/** Mount identity for a Game runtime source. Document identity stays
|
|
9
|
+
* `workspace:game`; this disambiguates the runtime inspected inside it. */
|
|
10
|
+
readonly instanceId?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const sources = new Map<string, EditorPerformanceSource>();
|
|
14
|
+
const listeners = new Set<() => void>();
|
|
15
|
+
let version = 0;
|
|
16
|
+
|
|
17
|
+
function notify(): void {
|
|
18
|
+
version++;
|
|
19
|
+
for (const listener of listeners) listener();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Register one real render loop as a profiler source. */
|
|
23
|
+
export function registerPerformanceSource(source: EditorPerformanceSource): () => void {
|
|
24
|
+
sources.set(source.id, source);
|
|
25
|
+
notify();
|
|
26
|
+
return () => {
|
|
27
|
+
if (sources.get(source.id) !== source) return;
|
|
28
|
+
sources.delete(source.id);
|
|
29
|
+
notify();
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function performanceSourceForDocument(
|
|
34
|
+
documentId: string | null,
|
|
35
|
+
): EditorPerformanceSource | null {
|
|
36
|
+
return documentId ? (sources.get(documentId) ?? null) : null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Every registered render loop. The self-vitals checks
|
|
40
|
+
* (`coverage/session-vitals.ts`) ask "did the thing that is running draw a
|
|
41
|
+
* frame", which is a question about whichever loop exists, not about the
|
|
42
|
+
* document the user happens to be looking at. */
|
|
43
|
+
export function allPerformanceSources(): readonly EditorPerformanceSource[] {
|
|
44
|
+
return [...sources.values()];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function performanceSourceForGameInstance(
|
|
48
|
+
instanceId: string | null,
|
|
49
|
+
): EditorPerformanceSource | null {
|
|
50
|
+
if (instanceId === null) return null;
|
|
51
|
+
for (const source of sources.values()) {
|
|
52
|
+
if (source.kind === 'game' && source.instanceId === instanceId) return source;
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function subscribePerformanceSources(listener: () => void): () => void {
|
|
58
|
+
listeners.add(listener);
|
|
59
|
+
return () => listeners.delete(listener);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function performanceSourcesVersion(): number {
|
|
63
|
+
return version;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function __resetPerformanceSourcesForTest(): void {
|
|
67
|
+
sources.clear();
|
|
68
|
+
notify();
|
|
69
|
+
}
|