@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,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A PHOTOGRAPH IS SEEN WHERE IT WAS TAKEN. Owner, 2026-09-28: "when a screenshot is takem in
|
|
3
|
+
* blender, let's show that image in the corner for a little time (like how it happens on macosx)
|
|
4
|
+
* and let's also do the 'camera flash'".
|
|
5
|
+
*
|
|
6
|
+
* So every photograph of the active document (the capture door an agent's
|
|
7
|
+
* `get_viewport_screenshot`, the CLI's `screenshot` and `editor.captureActiveDocument` share)
|
|
8
|
+
* flashes the document's box white and slides the picture into the page's bottom-right corner
|
|
9
|
+
* for a few seconds, the way macOS shows a screenshot it has just taken. Clicking the picture
|
|
10
|
+
* puts it away.
|
|
11
|
+
*
|
|
12
|
+
* Both elements sit OUTSIDE the document's box, in its theme root: a capture photographs the
|
|
13
|
+
* document, so a second photograph taken while the first is still showing cannot contain it.
|
|
14
|
+
* They start only after the capture resolved, so the photograph never holds its own flash.
|
|
15
|
+
*
|
|
16
|
+
* The editor-chrome capture (`cyclotron capture`) shows it too. Its `page` region photographs the
|
|
17
|
+
* whole page, corner included, so it puts away what is showing first (`withdrawPhotograph`). A
|
|
18
|
+
* capture can be named (`cyclotron capture --name "aim up"`); the name is the picture's caption,
|
|
19
|
+
* so a person watching knows what each one was for.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { activeDocumentContainer } from '@volter/sdk/kit/editor-document-probe';
|
|
23
|
+
import { activeWorkspaceDocumentId } from '@volter/sdk/kit/workspace-document-registry';
|
|
24
|
+
|
|
25
|
+
/** How long the picture stays in the corner; macOS keeps its own for about five seconds. */
|
|
26
|
+
const SHOWN_MS = 5_000;
|
|
27
|
+
const FLASH_MS = 350;
|
|
28
|
+
const SLIDE_MS = 240;
|
|
29
|
+
|
|
30
|
+
let showing: HTMLElement | null = null;
|
|
31
|
+
let flashing: HTMLElement | null = null;
|
|
32
|
+
|
|
33
|
+
/** Take the corner picture and the flash off the page at once, before the page is photographed. */
|
|
34
|
+
export function withdrawPhotograph(): void {
|
|
35
|
+
showing?.remove();
|
|
36
|
+
showing = null;
|
|
37
|
+
flashing?.remove();
|
|
38
|
+
flashing = null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function announcePhotograph(base64: string, name?: string): void {
|
|
42
|
+
if (typeof document === 'undefined') return;
|
|
43
|
+
const id = activeWorkspaceDocumentId();
|
|
44
|
+
const box = id === null ? null : activeDocumentContainer(id);
|
|
45
|
+
const root =
|
|
46
|
+
box?.closest<HTMLElement>('.volter-editor-theme') ??
|
|
47
|
+
document.querySelector<HTMLElement>('.volter-editor-theme') ??
|
|
48
|
+
document.body;
|
|
49
|
+
const still = window.matchMedia?.('(prefers-reduced-motion: reduce)').matches ?? false;
|
|
50
|
+
|
|
51
|
+
if (box && !still) {
|
|
52
|
+
const rect = box.getBoundingClientRect();
|
|
53
|
+
const flash = document.createElement('div');
|
|
54
|
+
flash.dataset['testid'] = 'photograph-flash';
|
|
55
|
+
Object.assign(flash.style, {
|
|
56
|
+
position: 'fixed',
|
|
57
|
+
left: `${rect.left}px`,
|
|
58
|
+
top: `${rect.top}px`,
|
|
59
|
+
width: `${rect.width}px`,
|
|
60
|
+
height: `${rect.height}px`,
|
|
61
|
+
background: '#ffffff',
|
|
62
|
+
pointerEvents: 'none',
|
|
63
|
+
zIndex: 'var(--volter-z-toast)',
|
|
64
|
+
});
|
|
65
|
+
flashing?.remove();
|
|
66
|
+
flashing = flash;
|
|
67
|
+
root.append(flash);
|
|
68
|
+
flash
|
|
69
|
+
.animate([{ opacity: 0.85 }, { opacity: 0 }], { duration: FLASH_MS, easing: 'ease-out' })
|
|
70
|
+
.finished.finally(() => {
|
|
71
|
+
flash.remove();
|
|
72
|
+
if (flashing === flash) flashing = null;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
showing?.remove();
|
|
77
|
+
const card = document.createElement('button');
|
|
78
|
+
card.type = 'button';
|
|
79
|
+
card.dataset['testid'] = 'photograph-notice';
|
|
80
|
+
card.title = `${name ? `${name}: photograph` : 'Photograph'} taken. Click to put it away.`;
|
|
81
|
+
card.setAttribute('aria-label', name ? `Photograph taken: ${name}` : 'Photograph taken');
|
|
82
|
+
Object.assign(card.style, {
|
|
83
|
+
position: 'fixed',
|
|
84
|
+
right: 'var(--volter-space-4)',
|
|
85
|
+
bottom: '40px',
|
|
86
|
+
width: '220px',
|
|
87
|
+
padding: '0',
|
|
88
|
+
border: '1px solid var(--volter-selection-border)',
|
|
89
|
+
borderRadius: 'var(--volter-radius-md)',
|
|
90
|
+
background: 'var(--volter-surface-raised)',
|
|
91
|
+
boxShadow: 'var(--volter-shadow-lg)',
|
|
92
|
+
overflow: 'hidden',
|
|
93
|
+
cursor: 'pointer',
|
|
94
|
+
zIndex: 'var(--volter-z-toast)',
|
|
95
|
+
});
|
|
96
|
+
const image = document.createElement('img');
|
|
97
|
+
image.src = `data:image/png;base64,${base64}`;
|
|
98
|
+
image.alt = 'The photograph just taken of the document';
|
|
99
|
+
Object.assign(image.style, { display: 'block', width: '100%', height: 'auto' });
|
|
100
|
+
card.append(image);
|
|
101
|
+
if (name) {
|
|
102
|
+
const caption = document.createElement('div');
|
|
103
|
+
caption.dataset['testid'] = 'photograph-name';
|
|
104
|
+
caption.textContent = name;
|
|
105
|
+
Object.assign(caption.style, {
|
|
106
|
+
padding: 'var(--volter-space-1) var(--volter-space-2)',
|
|
107
|
+
font: 'var(--volter-font-ui-sm, 12px system-ui)',
|
|
108
|
+
color: 'var(--volter-text)',
|
|
109
|
+
textAlign: 'left',
|
|
110
|
+
whiteSpace: 'nowrap',
|
|
111
|
+
overflow: 'hidden',
|
|
112
|
+
textOverflow: 'ellipsis',
|
|
113
|
+
});
|
|
114
|
+
card.append(caption);
|
|
115
|
+
}
|
|
116
|
+
root.append(card);
|
|
117
|
+
showing = card;
|
|
118
|
+
|
|
119
|
+
const away = () => {
|
|
120
|
+
if (showing === card) showing = null;
|
|
121
|
+
if (!card.isConnected) return;
|
|
122
|
+
if (still) {
|
|
123
|
+
card.remove();
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
card
|
|
127
|
+
.animate([{ transform: 'translateX(0)' }, { transform: 'translateX(130%)' }], {
|
|
128
|
+
duration: SLIDE_MS,
|
|
129
|
+
easing: 'ease-in',
|
|
130
|
+
fill: 'forwards',
|
|
131
|
+
})
|
|
132
|
+
.finished.finally(() => card.remove());
|
|
133
|
+
};
|
|
134
|
+
card.addEventListener('click', away, { once: true });
|
|
135
|
+
if (!still)
|
|
136
|
+
card.animate([{ transform: 'translateX(130%)' }, { transform: 'translateX(0)' }], {
|
|
137
|
+
duration: SLIDE_MS,
|
|
138
|
+
easing: 'ease-out',
|
|
139
|
+
});
|
|
140
|
+
window.setTimeout(away, SHOWN_MS);
|
|
141
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WHAT PLAY WAS DOING WHEN IT STOPPED ANSWERING.
|
|
3
|
+
*
|
|
4
|
+
* ## The measurement this exists for
|
|
5
|
+
*
|
|
6
|
+
* 2026-08-20, `packages/editor/scripts/scale-harness` at N=20000 on the canvas
|
|
7
|
+
* lane. the editor's `play` command burned its whole 120s budget and was refused with
|
|
8
|
+
*
|
|
9
|
+
* Command timed out — the tab is present (last heartbeat 0.8s ago) and
|
|
10
|
+
* did not respond.
|
|
11
|
+
*
|
|
12
|
+
* then `screenshot` (15s) and `stop` (30s) were refused with the same sentence.
|
|
13
|
+
* Every one of those statements was TRUE and none of them was the answer: the
|
|
14
|
+
* heartbeat is a WORKER, so it kept beating at 0.4s while the page's main
|
|
15
|
+
* thread sat inside one 199.5-second synchronous block. Four consecutive runs,
|
|
16
|
+
* three silent timeouts each, against a session every reader called healthy.
|
|
17
|
+
*
|
|
18
|
+
* The defect the fix closed was a quadratic name derivation
|
|
19
|
+
* (`@volter/editor-game/runtime/pixi/authoring`). The defect THIS closes is that nothing anywhere
|
|
20
|
+
* could say which of play's eight steps the page was in — the relay knows only
|
|
21
|
+
* that it asked, the tab table knows only that the tab exists, and the page
|
|
22
|
+
* itself, being wedged, is the one party that cannot speak.
|
|
23
|
+
*
|
|
24
|
+
* ## The mechanism
|
|
25
|
+
*
|
|
26
|
+
* A phase is published BEFORE its work starts, on the control channel, as its
|
|
27
|
+
* own tiny message — never folded into the state snapshot, which is the
|
|
28
|
+
* expensive derivation a wedged page cannot produce and which is exactly the
|
|
29
|
+
* thing that goes silent. So the server always holds the phase the page was
|
|
30
|
+
* ENTERING when it went quiet, and the relay's refusal can name it.
|
|
31
|
+
*
|
|
32
|
+
* This module is the page's half and is deliberately pure apart from one
|
|
33
|
+
* injected reporter: the latch, the phase vocabulary, and the sentence are all
|
|
34
|
+
* unit-testable without a browser.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The steps of a play boot, in the order `play-mode.ts` runs them.
|
|
39
|
+
*
|
|
40
|
+
* The vocabulary is shared with `play-boot-stall.ts`: the three network-shaped
|
|
41
|
+
* steps it already guards use the SAME wording here, so the hidden-tab stall
|
|
42
|
+
* message and a stuck-play refusal cannot describe the same step differently.
|
|
43
|
+
* The steps that guard does not wrap — the runtime mount and the authoring
|
|
44
|
+
* install, which must never be abandoned mid-flight — are the ones that had no
|
|
45
|
+
* name at all, and they are where the 199.5s block was measured.
|
|
46
|
+
*/
|
|
47
|
+
export const PLAY_BOOT_PHASES = [
|
|
48
|
+
'waiting for the editor to bind Play',
|
|
49
|
+
'waiting for the project bootstrap to settle',
|
|
50
|
+
'starting the play log session',
|
|
51
|
+
'opening the Game document',
|
|
52
|
+
'fetching the project manifest',
|
|
53
|
+
"resolving the project's root entries",
|
|
54
|
+
'mounting the runtime roots',
|
|
55
|
+
'installing play authoring for each root',
|
|
56
|
+
'binding the editor to the running game',
|
|
57
|
+
] as const;
|
|
58
|
+
|
|
59
|
+
export type PlayBootPhase = (typeof PLAY_BOOT_PHASES)[number];
|
|
60
|
+
|
|
61
|
+
/** The page's standing answer to "what is play doing right now". */
|
|
62
|
+
/** Any main-thread work the page announces before starting it: a play boot
|
|
63
|
+
* step, or a document's `building src/models/x.ts`. */
|
|
64
|
+
export type PagePhase = string;
|
|
65
|
+
|
|
66
|
+
export interface PlayBootPhaseState {
|
|
67
|
+
/** The phase being ENTERED, or `null` once the boot settled either way. */
|
|
68
|
+
readonly phase: PagePhase | null;
|
|
69
|
+
/** Epoch ms the page entered it (or left the last one). */
|
|
70
|
+
readonly at: number;
|
|
71
|
+
/** This play attempt's ordinal, so a stale report is recognizable as stale. */
|
|
72
|
+
readonly run: number;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let _state: PlayBootPhaseState = { phase: null, at: 0, run: 0 };
|
|
76
|
+
let _base = _state;
|
|
77
|
+
const work = new Map<symbol, { phase: string; at: number }>();
|
|
78
|
+
let _report: ((state: PlayBootPhaseState) => void) | null = null;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Install the upstream reporter. Wired once at editor boot; left unset in
|
|
82
|
+
* tests, where the latch is read directly.
|
|
83
|
+
*/
|
|
84
|
+
export function setPlayBootPhaseReporter(
|
|
85
|
+
report: ((state: PlayBootPhaseState) => void) | null,
|
|
86
|
+
): void {
|
|
87
|
+
_report = report;
|
|
88
|
+
// A document may have entered work before the command listener attached.
|
|
89
|
+
publish(_state);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function publish(next: PlayBootPhaseState): void {
|
|
93
|
+
_state = next;
|
|
94
|
+
// A reporter that throws must never break a play boot — the phase is
|
|
95
|
+
// diagnostics, and diagnostics that can fail the thing they describe are
|
|
96
|
+
// worse than none.
|
|
97
|
+
try {
|
|
98
|
+
_report?.(next);
|
|
99
|
+
} catch {
|
|
100
|
+
/* the boot continues; the reader loses one phase line */
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function publishCurrent(): void {
|
|
105
|
+
const current = [...work.values()].at(-1);
|
|
106
|
+
const next = current ? { ...current, run: _base.run } : _base;
|
|
107
|
+
if (next.phase === _state.phase && next.at === _state.at && next.run === _state.run) return;
|
|
108
|
+
publish(next);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Begin a play attempt. Returns its run ordinal. */
|
|
112
|
+
export function beginPlayBoot(now: number = Date.now()): number {
|
|
113
|
+
_base = { phase: null, at: now, run: _base.run + 1 };
|
|
114
|
+
publishCurrent();
|
|
115
|
+
return _state.run;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Enter one phase. Called BEFORE the phase's work, never after it. */
|
|
119
|
+
export function markPlayBootPhase(phase: PlayBootPhase, now: number = Date.now()): void {
|
|
120
|
+
_base = { phase, at: now, run: _base.run };
|
|
121
|
+
publishCurrent();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* The boot settled — started, failed, or was superseded. Clearing the phase is
|
|
126
|
+
* what makes a LATER stuck command ("stop", "screenshot") report honestly that
|
|
127
|
+
* play was not booting rather than blaming the last phase of a boot that
|
|
128
|
+
* finished minutes ago.
|
|
129
|
+
*/
|
|
130
|
+
export function endPlayBoot(now: number = Date.now()): void {
|
|
131
|
+
_base = { phase: null, at: now, run: _base.run };
|
|
132
|
+
publishCurrent();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Announce main-thread work that is NOT a play boot — a model document about
|
|
137
|
+
* to run a module's `build()` — so a command that times out while the page is
|
|
138
|
+
* inside it is refused by name ("the page is still inside building
|
|
139
|
+
* src/models/mushroom.ts") instead of "never answered". A blind session on a
|
|
140
|
+
* swapped box read the generic refusal as its own module hanging and bisected
|
|
141
|
+
* a parameter for five minutes (2026-09-06). Returns an idempotent end call.
|
|
142
|
+
* Overlapping work has distinct tokens, even with identical labels: a late
|
|
143
|
+
* completion must not erase a newer call, or leave a completed child blamed.
|
|
144
|
+
* Labels name operations only, never model contents, scripts or credentials.
|
|
145
|
+
*/
|
|
146
|
+
export function beginPageWork(label: string, now: number = Date.now()): () => void {
|
|
147
|
+
const token = Symbol();
|
|
148
|
+
work.set(token, { phase: label.slice(0, 160), at: now });
|
|
149
|
+
publishCurrent();
|
|
150
|
+
return () => {
|
|
151
|
+
if (!work.delete(token)) return;
|
|
152
|
+
publishCurrent();
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function currentPlayBootPhase(): PlayBootPhaseState {
|
|
157
|
+
return _state;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** Test-only reset — drops the latch and the reporter. */
|
|
161
|
+
export function __resetPlayBootPhaseForTest(): void {
|
|
162
|
+
_state = { phase: null, at: 0, run: 0 };
|
|
163
|
+
_base = _state;
|
|
164
|
+
work.clear();
|
|
165
|
+
_report = null;
|
|
166
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The camera half of Play's immersive entry (`host.viewport.transition`): the viewport flies from
|
|
3
|
+
* its preview pose to the authored game camera while the chrome dissolves, converges on the
|
|
4
|
+
* game's live camera once it boots, and restores the preview pose when Play ends. The kit's
|
|
5
|
+
* transition owns the phases and the chrome; the Three integration registers the flight.
|
|
6
|
+
*/
|
|
7
|
+
import type { EditorHostLiveTransition } from '../host';
|
|
8
|
+
|
|
9
|
+
/** The game's live render camera, handed over when its runtime is ready. */
|
|
10
|
+
export type LiveCameraLookup = NonNullable<Parameters<EditorHostLiveTransition['ready']>[0]>;
|
|
11
|
+
|
|
12
|
+
export interface PlayCameraFlight {
|
|
13
|
+
/** Resolve the authored camera and start flying; `false` when there is nothing to fly to (no
|
|
14
|
+
* viewport, no authored camera). `onLanded` runs once, when the flight reaches its target. */
|
|
15
|
+
begin(onLanded: () => void): boolean;
|
|
16
|
+
/** Converge on the game's live camera from now on. */
|
|
17
|
+
track(liveCamera: LiveCameraLookup): void;
|
|
18
|
+
/** The game is on screen: stop driving the camera and leave orbit usable at the landed pose. */
|
|
19
|
+
settle(): void;
|
|
20
|
+
/** Play ended: restore the pose the viewport had before the flight. */
|
|
21
|
+
end(): void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let registered: PlayCameraFlight | null = null;
|
|
25
|
+
|
|
26
|
+
export function registerPlayCameraFlight(flight: PlayCameraFlight): () => void {
|
|
27
|
+
registered = flight;
|
|
28
|
+
return () => {
|
|
29
|
+
if (registered === flight) registered = null;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function playCameraFlight(): PlayCameraFlight | null {
|
|
34
|
+
return registered;
|
|
35
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** One owned screenshot bitmap; encode away from the live document's frame loop. */
|
|
2
|
+
const worker = self as unknown as {
|
|
3
|
+
onmessage: ((event: MessageEvent<ImageBitmap>) => void) | null;
|
|
4
|
+
postMessage(message: unknown): void;
|
|
5
|
+
close(): void;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
worker.onmessage = async ({ data: bitmap }) => {
|
|
9
|
+
const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
|
|
10
|
+
try {
|
|
11
|
+
const context = canvas.getContext('2d');
|
|
12
|
+
if (!context) throw new Error('PNG encoding has no 2d canvas context');
|
|
13
|
+
context.drawImage(bitmap, 0, 0);
|
|
14
|
+
const blob = await canvas.convertToBlob({ type: 'image/png' });
|
|
15
|
+
worker.postMessage({ blob });
|
|
16
|
+
} catch (error) {
|
|
17
|
+
worker.postMessage({ error: error instanceof Error ? error.message : String(error) });
|
|
18
|
+
} finally {
|
|
19
|
+
bitmap.close();
|
|
20
|
+
canvas.width = 0;
|
|
21
|
+
canvas.height = 0;
|
|
22
|
+
worker.close();
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE DECLARED PRESENTATION SURFACE — the one door for "what is this game
|
|
3
|
+
* presented on, and which element carries its pixels".
|
|
4
|
+
*
|
|
5
|
+
* ARCHITECTURE-CORE §The editor protocol, "Zero inference": read a declaration,
|
|
6
|
+
* walk ground truth, or diagnose declared-vs-measured drift — never guess a
|
|
7
|
+
* fact the game's author (or, here, the HOST'S OWN MOUNT) already stated. Three
|
|
8
|
+
* capture-side readers were guessing:
|
|
9
|
+
*
|
|
10
|
+
* · `composite-screenshot.ts` counted `<canvas>` children to decide whether
|
|
11
|
+
* the subject is a DOM-only medium and therefore needs the compositor
|
|
12
|
+
* settle window;
|
|
13
|
+
* · `play-mode.ts`'s `getPlayCanvas` took the FIRST `<canvas>` in DOM order
|
|
14
|
+
* as "the game canvas" — a guess about authoring order that a game with a
|
|
15
|
+
* minimap, an offscreen buffer, or a 2D overlay quietly loses;
|
|
16
|
+
* · `command-listener.ts`'s screenshot staleness gate skipped itself when no
|
|
17
|
+
* canvas was found, i.e. inferred "React-only root" from a DOM absence.
|
|
18
|
+
*
|
|
19
|
+
* Every one of those facts is DECLARED somewhere already:
|
|
20
|
+
*
|
|
21
|
+
* · the MEDIUM is the adapter's region table (`project-adapter.ts`) — a
|
|
22
|
+
* region's `surface` is a first-party statement about what the host hands
|
|
23
|
+
* that root;
|
|
24
|
+
* · a HOST-MOUNTED root's canvas is stamped with its root id by the mount
|
|
25
|
+
* that created it (`create-runtime.ts`, `data-volter-root-id`);
|
|
26
|
+
* · a SELF-BOOTING game's canvas is its own, so its contract declares it
|
|
27
|
+
* (`window.volterGame.presentation`), and the ingest mount records it here.
|
|
28
|
+
*
|
|
29
|
+
* The measured answers all remain, because a game that declares nothing must
|
|
30
|
+
* keep working — but they are REPORTED as measured (`source`), so "nobody
|
|
31
|
+
* stated this" is a visible fact instead of an invisible default.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
import {
|
|
35
|
+
type AdapterRegion,
|
|
36
|
+
type AdapterRegionBasis,
|
|
37
|
+
NATIVE_REGION_BASIS,
|
|
38
|
+
} from '@volter/project/adapter/adapter-module';
|
|
39
|
+
|
|
40
|
+
/** Where an answer came from. `none` = there is no answer at all, which is
|
|
41
|
+
* deliberately distinct from a measured one. */
|
|
42
|
+
export type PresentationSource = 'declared' | 'measured' | 'none';
|
|
43
|
+
|
|
44
|
+
/** What the game is presented ON. `unknown` means no adapter table has loaded
|
|
45
|
+
* yet — "nobody looked", never "it has no canvas". */
|
|
46
|
+
export type PresentationMedium = 'canvas' | 'dom' | 'unknown';
|
|
47
|
+
|
|
48
|
+
export interface PresentationSurfaceReading {
|
|
49
|
+
/** The element carrying the game's pixels, or `null` for a DOM-only game (or
|
|
50
|
+
* before anything mounted). */
|
|
51
|
+
readonly canvas: HTMLCanvasElement | null;
|
|
52
|
+
/** How {@link canvas} was answered. */
|
|
53
|
+
readonly source: PresentationSource;
|
|
54
|
+
/** The root the surface belongs to, when the answer named one. */
|
|
55
|
+
readonly rootId: string | null;
|
|
56
|
+
/** What the ADAPTER declares this project is presented on. */
|
|
57
|
+
readonly medium: PresentationMedium;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** The host stamp `create-runtime.ts` writes on every surface it mounts. */
|
|
61
|
+
const ROOT_ID_ATTRIBUTE = 'data-volter-root-id';
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Presentation elements a SELF-BOOTING game owns, keyed by root id — the
|
|
65
|
+
* ingest mount records one per mounted game and drops it on teardown. Most are
|
|
66
|
+
* canvases; CSS3DRenderer truthfully contributes a DOM element and `canvas: null`.
|
|
67
|
+
*
|
|
68
|
+
* RESOURCE OWNERSHIP: the ingest mount path that recorded an entry
|
|
69
|
+
* (`authoring/ingest-root-adapter.ts`) is the only party that clears it, in its
|
|
70
|
+
* own teardown. Nothing else writes this map, and a stale entry cannot outlive
|
|
71
|
+
* its mount, because the reading below also requires the canvas to still be
|
|
72
|
+
* inside the container it is asked about.
|
|
73
|
+
*/
|
|
74
|
+
const _selfBooting = new Map<
|
|
75
|
+
string,
|
|
76
|
+
{
|
|
77
|
+
element: HTMLElement;
|
|
78
|
+
canvas: HTMLCanvasElement | null;
|
|
79
|
+
source: 'declared' | 'measured';
|
|
80
|
+
}
|
|
81
|
+
>();
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Record the element a self-booting game presents on.
|
|
85
|
+
*
|
|
86
|
+
* `source` is the honesty: `declared` when the game's own contract named it
|
|
87
|
+
* (`window.volterGame.presentation`), `measured` when the host took the captured
|
|
88
|
+
* renderer's `domElement` — which is a real measurement off the render trap,
|
|
89
|
+
* not a DOM-order guess, but still not a statement by the game.
|
|
90
|
+
*/
|
|
91
|
+
export function recordPresentationSurface(
|
|
92
|
+
rootId: string,
|
|
93
|
+
element: HTMLElement,
|
|
94
|
+
source: 'declared' | 'measured',
|
|
95
|
+
): void {
|
|
96
|
+
const canvas = element.tagName === 'CANVAS' ? (element as HTMLCanvasElement) : null;
|
|
97
|
+
_selfBooting.set(rootId, { element, canvas, source });
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Drop one mount's recorded surface — what its teardown calls. */
|
|
101
|
+
export function clearPresentationSurface(rootId: string): void {
|
|
102
|
+
_selfBooting.delete(rootId);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Test seam: drop every recorded surface and the published region table. */
|
|
106
|
+
export function __resetPresentationSurfacesForTest(): void {
|
|
107
|
+
_selfBooting.clear();
|
|
108
|
+
_regions = [];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* The loaded adapter's regions, PUSHED here by their one owner rather than
|
|
113
|
+
* pulled from it.
|
|
114
|
+
*
|
|
115
|
+
* `project-adapter.ts` publishes the resolved table and calls this from the
|
|
116
|
+
* same `publish`, so there is still exactly one place regions are decided. The
|
|
117
|
+
* direction matters: this module is read from inside the ingest mount and from
|
|
118
|
+
* `play-mode.ts`, and importing the adapter loader would drag its whole
|
|
119
|
+
* transitive graph (editor API, project manager, story registry, the ingest
|
|
120
|
+
* registry) into both. A one-line push keeps this module dependency-free apart
|
|
121
|
+
* from an engine TYPE — which is also what makes it testable without standing
|
|
122
|
+
* up a project.
|
|
123
|
+
*/
|
|
124
|
+
let _regions: readonly AdapterRegion[] = [];
|
|
125
|
+
|
|
126
|
+
export function setPresentationRegions(regions: readonly AdapterRegion[]): void {
|
|
127
|
+
_regions = regions;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** The adapter's regions — the manifest allows at most one per medium. */
|
|
131
|
+
function contentRegions(): readonly AdapterRegion[] {
|
|
132
|
+
return _regions;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* The world basis the loaded adapter declares for `surface`'s CONTENT region —
|
|
137
|
+
* "which way is up in this game, and where is its ground". The gizmo viewport's
|
|
138
|
+
* ground-plane raycast (asset drop, nav probe) reads it instead of the `y = 0`
|
|
139
|
+
* constant it used to compile in (ARCHITECTURE-CORE §The editor protocol,
|
|
140
|
+
* "Zero inference").
|
|
141
|
+
*
|
|
142
|
+
* It lives HERE, on the pushed region table, and not on the loader that fills
|
|
143
|
+
* it, for the same reason {@link presentationSurface} does: the viewport is a
|
|
144
|
+
* surface below the shell, and importing `project-adapter.ts` to ask one
|
|
145
|
+
* question about one region drags the whole loader graph (editor API, project
|
|
146
|
+
* manager, story registry, the ingest registry) into it — measured at 121 files
|
|
147
|
+
* for a two-line read. The push already delivered the answer; this is the
|
|
148
|
+
* reader beside it.
|
|
149
|
+
*
|
|
150
|
+
* Before the first load, and for a region that declares no basis, the answer is
|
|
151
|
+
* {@link NATIVE_REGION_BASIS} — the declared native default, which
|
|
152
|
+
* `regionsFromManifestRoots` publishes outright.
|
|
153
|
+
*/
|
|
154
|
+
export function presentationRegionBasis(surface: AdapterRegion['surface']): AdapterRegionBasis {
|
|
155
|
+
return _regions.find((entry) => entry.surface === surface)?.basis ?? NATIVE_REGION_BASIS;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* What the ADAPTER declares this project is presented on.
|
|
160
|
+
*
|
|
161
|
+
* `three` and `canvas` regions are handed a canvas by the host; a `dom` region
|
|
162
|
+
* is handed a DOM container. A project with both is `canvas` — the canvas is
|
|
163
|
+
* where the game's pixels are, and the HUD rides over it.
|
|
164
|
+
*/
|
|
165
|
+
function presentationMedium(container: HTMLElement | null): PresentationMedium {
|
|
166
|
+
const regions = contentRegions();
|
|
167
|
+
if (regions.length === 0) return 'unknown';
|
|
168
|
+
return regions.some((region) => {
|
|
169
|
+
if (region.surface === 'dom') return false;
|
|
170
|
+
const measured = _selfBooting.get(region.id);
|
|
171
|
+
return (
|
|
172
|
+
!measured || measured.canvas !== null || !container || !holds(container, measured.element)
|
|
173
|
+
);
|
|
174
|
+
})
|
|
175
|
+
? 'canvas'
|
|
176
|
+
: 'dom';
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* A container is only queryable if it really is an element.
|
|
181
|
+
*
|
|
182
|
+
* The play container reaches here from several routes, and the relay's own
|
|
183
|
+
* harnesses hand in stand-ins that implement exactly the members the old reader
|
|
184
|
+
* touched. Every DOM read below is therefore capability-checked rather than
|
|
185
|
+
* assumed: a container that cannot answer a question contributes nothing to the
|
|
186
|
+
* reading, which lands on `source: 'none'` — the honest answer, and the one that
|
|
187
|
+
* leaves each caller's own degrade path (the canvas-only capture leg, the
|
|
188
|
+
* screenshot's named refusal) exactly where it was.
|
|
189
|
+
*/
|
|
190
|
+
function holds(container: HTMLElement, element: HTMLElement): boolean {
|
|
191
|
+
return typeof container.contains === 'function' && container.contains(element);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** The declared-canvas legs, in precedence order, or `null` when none answers. */
|
|
195
|
+
function declaredCanvas(
|
|
196
|
+
container: HTMLElement,
|
|
197
|
+
): { canvas: HTMLCanvasElement; rootId: string } | null {
|
|
198
|
+
// 1. A self-booting game's own declaration wins outright.
|
|
199
|
+
for (const [rootId, entry] of _selfBooting) {
|
|
200
|
+
if (entry.canvas && entry.source === 'declared' && holds(container, entry.canvas)) {
|
|
201
|
+
return { canvas: entry.canvas, rootId };
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
// 2. A host-mounted root's canvas carries the id of the root it presents —
|
|
205
|
+
// stamped by the mount that made it, so this is a read, not a search for
|
|
206
|
+
// something canvas-shaped.
|
|
207
|
+
const stamped =
|
|
208
|
+
typeof container.querySelectorAll === 'function'
|
|
209
|
+
? Array.from(container.querySelectorAll<HTMLCanvasElement>(`canvas[${ROOT_ID_ATTRIBUTE}]`))
|
|
210
|
+
: [];
|
|
211
|
+
for (const region of contentRegions()) {
|
|
212
|
+
if (region.surface === 'dom') continue;
|
|
213
|
+
const match = stamped.find((canvas) => canvas.dataset['volterRootId'] === region.id);
|
|
214
|
+
if (match) return { canvas: match, rootId: region.id };
|
|
215
|
+
}
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Resolve the presentation surface inside `container`.
|
|
221
|
+
*
|
|
222
|
+
* Declaration first, measured fallback SECOND AND LABELLED. The fallback is
|
|
223
|
+
* still first-canvas-in-DOM-order — deliberately unchanged, because a game that
|
|
224
|
+
* declares nothing must behave exactly as it did — but it now arrives as
|
|
225
|
+
* `source: 'measured'` wherever it is reported, so the guess is legible.
|
|
226
|
+
*/
|
|
227
|
+
export function presentationSurface(container: HTMLElement | null): PresentationSurfaceReading {
|
|
228
|
+
const medium = presentationMedium(container);
|
|
229
|
+
if (!container) return { canvas: null, source: 'none', rootId: null, medium };
|
|
230
|
+
const declared = declaredCanvas(container);
|
|
231
|
+
if (declared) {
|
|
232
|
+
return { canvas: declared.canvas, source: 'declared', rootId: declared.rootId, medium };
|
|
233
|
+
}
|
|
234
|
+
// A self-booting game whose contract declared nothing: the host's own
|
|
235
|
+
// measurement (the captured renderer's element) still beats a DOM sweep.
|
|
236
|
+
for (const [rootId, entry] of _selfBooting) {
|
|
237
|
+
if (entry.canvas && holds(container, entry.canvas)) {
|
|
238
|
+
return { canvas: entry.canvas, source: 'measured', rootId, medium };
|
|
239
|
+
}
|
|
240
|
+
if (holds(container, entry.element)) {
|
|
241
|
+
return { canvas: null, source: entry.source, rootId, medium };
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
const first =
|
|
245
|
+
typeof container.querySelector === 'function' ? container.querySelector('canvas') : null;
|
|
246
|
+
if (first) return { canvas: first, source: 'measured', rootId: null, medium };
|
|
247
|
+
return { canvas: null, source: 'none', rootId: null, medium };
|
|
248
|
+
}
|