@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,134 @@
|
|
|
1
|
+
import type { AuthoringAdapter, EditorNode, PropertyDescriptor } from '@volter/project/adapter';
|
|
2
|
+
import { setAuthoringInspectorField } from './authoring/consumer-actions';
|
|
3
|
+
import { forEachHierarchyNode } from './hierarchy-walk';
|
|
4
|
+
|
|
5
|
+
export const LIGHT_EXPLORER_PATHS = {
|
|
6
|
+
enabled: 'visible',
|
|
7
|
+
color: 'light.color',
|
|
8
|
+
intensity: 'light.intensity',
|
|
9
|
+
range: 'light.distance',
|
|
10
|
+
shadows: 'shadow.cast',
|
|
11
|
+
} as const;
|
|
12
|
+
|
|
13
|
+
export type LightExplorerField = keyof typeof LIGHT_EXPLORER_PATHS;
|
|
14
|
+
|
|
15
|
+
export interface LightExplorerCell<T> {
|
|
16
|
+
readonly supported: boolean;
|
|
17
|
+
readonly writable: boolean;
|
|
18
|
+
readonly value: T | null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface LightExplorerRow {
|
|
22
|
+
readonly id: string;
|
|
23
|
+
readonly name: string;
|
|
24
|
+
readonly type: string;
|
|
25
|
+
readonly enabled: LightExplorerCell<boolean>;
|
|
26
|
+
readonly color: LightExplorerCell<string>;
|
|
27
|
+
readonly intensity: LightExplorerCell<number>;
|
|
28
|
+
readonly range: LightExplorerCell<number>;
|
|
29
|
+
readonly shadows: LightExplorerCell<boolean>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface HierarchyWithInternals {
|
|
33
|
+
/** Optional editor-side hierarchy projection used by component-owning
|
|
34
|
+
* adapters. These are still real adapter nodes; they are merely folded out
|
|
35
|
+
* of the ordinary tree until a person asks to reveal implementation parts. */
|
|
36
|
+
internalChildren?(id: string): EditorNode[] | undefined;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function lightNodes(adapter: AuthoringAdapter): EditorNode[] {
|
|
40
|
+
const result: EditorNode[] = [];
|
|
41
|
+
const hierarchyWithInternals = adapter as AuthoringAdapter & HierarchyWithInternals;
|
|
42
|
+
forEachHierarchyNode(
|
|
43
|
+
adapter.hierarchy,
|
|
44
|
+
(node) => {
|
|
45
|
+
if (node.kind === 'light') result.push(node);
|
|
46
|
+
},
|
|
47
|
+
{ extraChildren: (id) => hierarchyWithInternals.internalChildren?.(id) },
|
|
48
|
+
);
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function activeLightCount(adapter: AuthoringAdapter): number {
|
|
53
|
+
return lightNodes(adapter).length;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function descriptorFor(
|
|
57
|
+
descriptors: readonly PropertyDescriptor[],
|
|
58
|
+
field: LightExplorerField,
|
|
59
|
+
): PropertyDescriptor | null {
|
|
60
|
+
return descriptors.find((descriptor) => descriptor.path === LIGHT_EXPLORER_PATHS[field]) ?? null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function cell<T>(
|
|
64
|
+
adapter: AuthoringAdapter,
|
|
65
|
+
id: string,
|
|
66
|
+
descriptors: readonly PropertyDescriptor[],
|
|
67
|
+
field: LightExplorerField,
|
|
68
|
+
accept: (value: unknown) => value is T,
|
|
69
|
+
): LightExplorerCell<T> {
|
|
70
|
+
const descriptor = descriptorFor(descriptors, field);
|
|
71
|
+
if (!descriptor || !adapter.inspector) {
|
|
72
|
+
return { supported: false, writable: false, value: null };
|
|
73
|
+
}
|
|
74
|
+
let value: unknown;
|
|
75
|
+
try {
|
|
76
|
+
value = adapter.inspector.get(id, descriptor.path);
|
|
77
|
+
} catch {
|
|
78
|
+
value = undefined;
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
supported: true,
|
|
82
|
+
writable: descriptor.readonly !== true,
|
|
83
|
+
value: accept(value) ? value : null,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const isBoolean = (value: unknown): value is boolean => typeof value === 'boolean';
|
|
88
|
+
const isString = (value: unknown): value is string => typeof value === 'string';
|
|
89
|
+
const isNumber = (value: unknown): value is number =>
|
|
90
|
+
typeof value === 'number' && Number.isFinite(value);
|
|
91
|
+
|
|
92
|
+
export function lightExplorerRows(adapter: AuthoringAdapter): LightExplorerRow[] {
|
|
93
|
+
return lightNodes(adapter).map((node) => {
|
|
94
|
+
let descriptors: readonly PropertyDescriptor[] = [];
|
|
95
|
+
try {
|
|
96
|
+
descriptors = adapter.inspector?.properties(node.id) ?? [];
|
|
97
|
+
} catch {
|
|
98
|
+
// A broken per-node inspector must not take the scene-wide inventory down.
|
|
99
|
+
}
|
|
100
|
+
const nativeType = (adapter.hierarchy.object3D?.(node.id) as { readonly type?: string } | null | undefined)?.type;
|
|
101
|
+
return {
|
|
102
|
+
id: node.id,
|
|
103
|
+
name: node.label,
|
|
104
|
+
type: node.typeLabel ?? nativeType ?? 'Light',
|
|
105
|
+
enabled: cell(adapter, node.id, descriptors, 'enabled', isBoolean),
|
|
106
|
+
color: cell(adapter, node.id, descriptors, 'color', isString),
|
|
107
|
+
intensity: cell(adapter, node.id, descriptors, 'intensity', isNumber),
|
|
108
|
+
range: cell(adapter, node.id, descriptors, 'range', isNumber),
|
|
109
|
+
shadows: cell(adapter, node.id, descriptors, 'shadows', isBoolean),
|
|
110
|
+
};
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function setLightExplorerField(
|
|
115
|
+
adapter: AuthoringAdapter,
|
|
116
|
+
ids: readonly string[],
|
|
117
|
+
field: LightExplorerField,
|
|
118
|
+
value: unknown,
|
|
119
|
+
): number {
|
|
120
|
+
if (!adapter.inspector) return 0;
|
|
121
|
+
let changed = 0;
|
|
122
|
+
for (const id of ids) {
|
|
123
|
+
let descriptor: PropertyDescriptor | null = null;
|
|
124
|
+
try {
|
|
125
|
+
descriptor = descriptorFor(adapter.inspector.properties(id), field);
|
|
126
|
+
} catch {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (!descriptor || descriptor.readonly) continue;
|
|
130
|
+
setAuthoringInspectorField(adapter, id, descriptor.path, value);
|
|
131
|
+
changed++;
|
|
132
|
+
}
|
|
133
|
+
return changed;
|
|
134
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ONE `canvasFrame` seam (`composite-screenshot.ts`), for every pixel door.
|
|
3
|
+
*
|
|
4
|
+
* ## Why this exists
|
|
5
|
+
*
|
|
6
|
+
* A canvas is only `drawImage`-able after its frame when its WebGL context was
|
|
7
|
+
* created with `preserveDrawingBuffer: true`. Every canvas the volter RUNTIME
|
|
8
|
+
* mounts sets it; a canvas a GAME created is the game's own and almost never
|
|
9
|
+
* does. Two different mechanisms recover those pixels, one per substrate:
|
|
10
|
+
*
|
|
11
|
+
* - a lane whose render pass owns the canvas (a three ingest) copies the
|
|
12
|
+
* drawing buffer INSIDE that pass, asked through the live registry
|
|
13
|
+
* (`LiveSession.snapshotFrame`, `ingest/ingest-frame-snapshot.ts`);
|
|
14
|
+
* - a Pixi surface re-renders the stage through the renderer's own extractor
|
|
15
|
+
* ({@link presentedPixiFrame}, `stories/story-pixi-preview.ts`).
|
|
16
|
+
*
|
|
17
|
+
* Both already existed. What did not was a single place that tries both, and
|
|
18
|
+
* that gap was VISIBLE AS A LIE: `command-listener.ts`'s `bridge-screenshot`
|
|
19
|
+
* passed only the three one and `editor-view-presentation.ts`'s
|
|
20
|
+
* `capture-active-document` passed only the Pixi one, so each door photographed
|
|
21
|
+
* one lane correctly and the other one BLANK — and a blank frame is the worst
|
|
22
|
+
* failure a look verb has, because nothing about it says it failed.
|
|
23
|
+
*
|
|
24
|
+
* Composing them is safe by construction: each half answers `null` — the seam's
|
|
25
|
+
* documented "read the canvas directly" — for a canvas it does not own, so a
|
|
26
|
+
* first-party runtime canvas still takes the ordinary path.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import { presentedCanvasFrame } from '@volter/sdk/kit/canvas-frames';
|
|
30
|
+
import { snapshotLiveFrame } from '@volter/sdk/kit/live-session-registry';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Same-frame pixels for `canvas`, whichever live surface owns it, or `null`
|
|
34
|
+
* when none does.
|
|
35
|
+
*
|
|
36
|
+
* Order is the cheap test first: the registry's claim is an identity read
|
|
37
|
+
* against the mounted lane's canvas, while the Pixi leg walks the presented
|
|
38
|
+
* set and, on a hit, costs a real render.
|
|
39
|
+
*/
|
|
40
|
+
export async function liveCanvasFrame(
|
|
41
|
+
canvas: HTMLCanvasElement,
|
|
42
|
+
): Promise<CanvasImageSource | null> {
|
|
43
|
+
const live = snapshotLiveFrame(canvas);
|
|
44
|
+
if (live) return live;
|
|
45
|
+
return presentedCanvasFrame(canvas);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** A `CanvasImageSource` that can be read back as a PNG on its own — what the
|
|
49
|
+
* canvas-only capture leg needs when it has no compositor to draw into.
|
|
50
|
+
* Pixi's extractor hands back a real `HTMLCanvasElement`, but the seam's type
|
|
51
|
+
* is the wider `CanvasImageSource`, so the door asks rather than casts. */
|
|
52
|
+
export function readablePngSource(source: CanvasImageSource | null): HTMLCanvasElement | null {
|
|
53
|
+
const candidate = source as HTMLCanvasElement | null;
|
|
54
|
+
return candidate && typeof candidate.toDataURL === 'function' ? candidate : null;
|
|
55
|
+
}
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE LIVE DOCUMENT's lifetime — the host's one center document for running
|
|
3
|
+
* content (`workspace:game`, titled `Game`). When nothing runs there is no
|
|
4
|
+
* live document at all — no tab, no panel, no hidden-but-mounted host.
|
|
5
|
+
*
|
|
6
|
+
* The editor's standing center documents are the authoring ones (Scene / the
|
|
7
|
+
* world documents, `UI`, `3D`). The live document is not one of them: it is
|
|
8
|
+
* the running lane's own surface, so it EXISTS exactly as long as a runtime
|
|
9
|
+
* does. It is installed when a runtime is about to mount and closed when
|
|
10
|
+
* that runtime ends, through the ordinary `workspace-document-registry`
|
|
11
|
+
* path every other document uses — never a parallel host, never a
|
|
12
|
+
* permanently-mounted panel whose tab is hidden.
|
|
13
|
+
*
|
|
14
|
+
* ## Resource ownership (stated here, once)
|
|
15
|
+
*
|
|
16
|
+
* This module OWNS the open/close of `workspace:game`, the focus it borrows,
|
|
17
|
+
* and the CONTAINER element every lane mounts into. Sharers:
|
|
18
|
+
* `components/CenterDocuments.tsx` binds the session's tab hook
|
|
19
|
+
* ({@link bindLiveDocument}) and reports play-state edges
|
|
20
|
+
* ({@link syncLiveDocumentPlayState}); the package that runs things registers
|
|
21
|
+
* what the document DRAWS ({@link registerLiveDocumentContent}, through
|
|
22
|
+
* `@volter/sdk/host`'s `workspace.liveDocument`) and its panel reports
|
|
23
|
+
* the container's attach/detach ({@link setLiveDocumentContainer} /
|
|
24
|
+
* {@link releaseLiveDocumentContainer}); the runtimes that {@link
|
|
25
|
+
* acquireLiveDocument} are exactly the ones that MOUNT INTO the container —
|
|
26
|
+
* Play, the module lane's two enter paths, and each per-surface ingest mount
|
|
27
|
+
* — each acquiring immediately before it reads {@link liveDocumentContainer}.
|
|
28
|
+
* A dispatcher above them (`ingest/mount-ingest-root.ts`) never acquires: a
|
|
29
|
+
* second, earlier acquire there could only refuse ahead of the mount that
|
|
30
|
+
* owns the answer. {@link releaseLiveDocument} is the ONE teardown path and
|
|
31
|
+
* it is idempotent — a failed play calls it directly, and every ordinary stop
|
|
32
|
+
* reaches it through the playing → stopped edge.
|
|
33
|
+
*
|
|
34
|
+
* ## Why acquiring is asynchronous
|
|
35
|
+
*
|
|
36
|
+
* A runtime mounts into the document's own DOM (the registered content's
|
|
37
|
+
* panel), so the element only exists once React has committed the panel
|
|
38
|
+
* that this module just opened. `acquireLiveDocument` therefore opens the
|
|
39
|
+
* document and then waits for that commit, which the panel reports through
|
|
40
|
+
* {@link setLiveDocumentContainer}.
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
import type { LiveDocumentContent, LiveDocumentContentProps } from '@volter/sdk/host';
|
|
44
|
+
import type { ComponentType } from 'react';
|
|
45
|
+
import { GAME_DOCUMENT_ID } from '@volter/sdk/kit/workspace-document-ids';
|
|
46
|
+
import {
|
|
47
|
+
activateWorkspaceDocument,
|
|
48
|
+
activeWorkspaceDocumentId,
|
|
49
|
+
closeWorkspaceDocument,
|
|
50
|
+
openWorkspaceDocument,
|
|
51
|
+
openWorkspaceDocuments,
|
|
52
|
+
supersedeRestoredActivation,
|
|
53
|
+
type WorkspaceDocumentDescriptor,
|
|
54
|
+
} from '@volter/sdk/kit/workspace-document-registry';
|
|
55
|
+
|
|
56
|
+
/** How long an acquire waits for the panel's first commit before giving up.
|
|
57
|
+
* The caller's failure message ("the game container is not mounted…") is the
|
|
58
|
+
* honest report; hanging forever would be worse than a bounded refusal. */
|
|
59
|
+
const CONTAINER_MOUNT_TIMEOUT_MS = 4000;
|
|
60
|
+
|
|
61
|
+
/** The editor session's binding: the live document exists only while one is bound. */
|
|
62
|
+
interface LiveDocumentHooks {
|
|
63
|
+
readonly session: true;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let _hooks: LiveDocumentHooks | null = null;
|
|
67
|
+
let _content: LiveDocumentContent | null = null;
|
|
68
|
+
let _container: HTMLElement | null = null;
|
|
69
|
+
let _containerMounted = false;
|
|
70
|
+
let _restoreDocumentId: string | null = null;
|
|
71
|
+
let _wasLive = false;
|
|
72
|
+
/** A runtime acquired the live document and has not released it. */
|
|
73
|
+
let _held = false;
|
|
74
|
+
const _mountWaiters = new Set<() => void>();
|
|
75
|
+
|
|
76
|
+
/** Reached only when a lane acquires the document before any package
|
|
77
|
+
* registered content — a build that mounts nothing never opens it. */
|
|
78
|
+
const NoLiveContent: ComponentType<LiveDocumentContentProps> = () => null;
|
|
79
|
+
|
|
80
|
+
function descriptor(): WorkspaceDocumentDescriptor | null {
|
|
81
|
+
const hooks = _hooks;
|
|
82
|
+
if (!hooks) return null;
|
|
83
|
+
const content = _content;
|
|
84
|
+
return {
|
|
85
|
+
id: GAME_DOCUMENT_ID,
|
|
86
|
+
title: 'Game',
|
|
87
|
+
kind: 'game',
|
|
88
|
+
workspaceRole: 'authored-subject',
|
|
89
|
+
Content: content?.Content ?? NoLiveContent,
|
|
90
|
+
// The document-local toolbar — the lane's own — appears only while the
|
|
91
|
+
// live document is active (§6.3).
|
|
92
|
+
...(content?.Toolbar ? { Toolbar: content.Toolbar } : {}),
|
|
93
|
+
closeable: false,
|
|
94
|
+
presentation: () => ({ kind: 'workspace', id: GAME_DOCUMENT_ID }),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Bind this editor session. `useCenterDocuments` calls this in
|
|
100
|
+
* the same effect that installs the other center documents, and the returned
|
|
101
|
+
* cleanup releases the document with the session.
|
|
102
|
+
*/
|
|
103
|
+
export function bindLiveDocument(): () => void {
|
|
104
|
+
const hooks: LiveDocumentHooks = { session: true };
|
|
105
|
+
_hooks = hooks;
|
|
106
|
+
return () => {
|
|
107
|
+
if (_hooks !== hooks) return;
|
|
108
|
+
releaseLiveDocument();
|
|
109
|
+
_hooks = null;
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** The package that runs things registers what the document draws. While
|
|
114
|
+
* the document is open, re-registering refreshes its mount slots. */
|
|
115
|
+
export function registerLiveDocumentContent(content: LiveDocumentContent): () => void {
|
|
116
|
+
_content = content;
|
|
117
|
+
if (liveDocumentOpen()) {
|
|
118
|
+
const next = descriptor();
|
|
119
|
+
if (next) openWorkspaceDocument(next, { activate: false });
|
|
120
|
+
}
|
|
121
|
+
return () => {
|
|
122
|
+
if (_content === content) _content = null;
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Whether a runtime holds the live document: acquired for Play and not yet
|
|
128
|
+
* released. Documents a project installs while it is held open behind it
|
|
129
|
+
* rather than in front of it — the person asked for the game.
|
|
130
|
+
*/
|
|
131
|
+
export function liveDocumentHeld(): boolean {
|
|
132
|
+
return _held && liveDocumentOpen();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** Whether the live document is currently open. */
|
|
136
|
+
export function liveDocumentOpen(): boolean {
|
|
137
|
+
return openWorkspaceDocuments().some((d) => d.descriptor.id === GAME_DOCUMENT_ID);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Bring the live document to the front, if it is open. Answers whether it was.
|
|
142
|
+
*
|
|
143
|
+
* ▶ IS A DELIBERATE ACT ON THE GAME, and this is the half a BOOT-MOUNTED
|
|
144
|
+
* ingest was missing. `landIngestBootInEdit` puts the authoring Scene in front
|
|
145
|
+
* at mount — correctly, because that mount IS edit mode — and until 2026-09-20
|
|
146
|
+
* nothing moved it back: the ingest transport's ▶ released content time and
|
|
147
|
+
* left the person looking at the Scene, which for `three-points-waves` is the
|
|
148
|
+
* honest "No renderable content" card while the points ran unseen behind it
|
|
149
|
+
* (walk 3, beat 19). A play-time mount already does this for itself
|
|
150
|
+
* (`deferred-ingest-play.ts` activates this document).
|
|
151
|
+
*
|
|
152
|
+
* It activates rather than writing the viewport tab because THIS module owns
|
|
153
|
+
* `workspace:game`: activation fires the descriptor's `onActivate`, which is
|
|
154
|
+
* the one place that writes `activeViewportTab = 'play'` — so the tab, the
|
|
155
|
+
* registry and the input gate cannot drift apart. A caller with no store in
|
|
156
|
+
* hand (the ingest play control is a pure control surface) needs exactly this.
|
|
157
|
+
*/
|
|
158
|
+
export function activateLiveDocument(): boolean {
|
|
159
|
+
if (!liveDocumentOpen()) return false;
|
|
160
|
+
supersedeRestoredActivation();
|
|
161
|
+
return activateWorkspaceDocument(GAME_DOCUMENT_ID);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** The container element every lane mounts into, or null while no panel is
|
|
165
|
+
* committed. */
|
|
166
|
+
export function liveDocumentContainer(): HTMLElement | null {
|
|
167
|
+
return _container;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** The panel's ATTACH half. */
|
|
171
|
+
export function setLiveDocumentContainer(el: HTMLElement): void {
|
|
172
|
+
_container = el;
|
|
173
|
+
_containerMounted = true;
|
|
174
|
+
for (const waiter of [..._mountWaiters]) waiter();
|
|
175
|
+
_mountWaiters.clear();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* The panel's DETACH half, keyed by the element it is letting go of — never
|
|
180
|
+
* a bare "set null".
|
|
181
|
+
*
|
|
182
|
+
* Two panel instances briefly coexist whenever the live document closes and
|
|
183
|
+
* reopens in one gesture (every ingest mount's `exitActiveIngest()` →
|
|
184
|
+
* `acquireLiveDocument()` sequence), and React gives no cross-component
|
|
185
|
+
* ordering promise between the old panel's cleanup ref and the new panel's
|
|
186
|
+
* attach ref. Measured on bubbo-bubbo (2026-08-21, probe in the mount path):
|
|
187
|
+
* the acquire resolved `true` in 36ms — the NEW panel's element had attached
|
|
188
|
+
* — and the container was null anyway, because the OLD panel's cleanup ran
|
|
189
|
+
* after the attach and clobbered the singleton. Keying the release on the
|
|
190
|
+
* element makes a stale panel's cleanup a no-op: only the panel that still
|
|
191
|
+
* OWNS the slot may empty it.
|
|
192
|
+
*/
|
|
193
|
+
export function releaseLiveDocumentContainer(el: HTMLElement): void {
|
|
194
|
+
if (_container !== el) return;
|
|
195
|
+
_container = null;
|
|
196
|
+
_containerMounted = false;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Install the live document and resolve once its container has mounted.
|
|
201
|
+
*
|
|
202
|
+
* Called by every runtime that mounts into that container — play, ingest and
|
|
203
|
+
* module mode — BEFORE it reads {@link liveDocumentContainer}. Resolves `false` when no
|
|
204
|
+
* session has bound a descriptor, or when the panel did not commit in time; the
|
|
205
|
+
* caller reports that as its own start failure rather than mounting into
|
|
206
|
+
* nothing.
|
|
207
|
+
*
|
|
208
|
+
* Opening ACTIVATES the document (entering a runtime is a deliberate act on the
|
|
209
|
+
* game), and remembers whichever document had focus so
|
|
210
|
+
* {@link releaseLiveDocument} can hand it back.
|
|
211
|
+
*/
|
|
212
|
+
export async function acquireLiveDocument(
|
|
213
|
+
timeoutMs = CONTAINER_MOUNT_TIMEOUT_MS,
|
|
214
|
+
): Promise<boolean> {
|
|
215
|
+
const next = descriptor();
|
|
216
|
+
if (!next) return false;
|
|
217
|
+
supersedeRestoredActivation();
|
|
218
|
+
_held = true;
|
|
219
|
+
if (!liveDocumentOpen()) {
|
|
220
|
+
_restoreDocumentId = activeWorkspaceDocumentId();
|
|
221
|
+
openWorkspaceDocument(next);
|
|
222
|
+
} else {
|
|
223
|
+
activateWorkspaceDocument(next.id);
|
|
224
|
+
}
|
|
225
|
+
if (_containerMounted) return true;
|
|
226
|
+
return new Promise<boolean>((resolve) => {
|
|
227
|
+
const waiter = () => {
|
|
228
|
+
clearTimeout(timer);
|
|
229
|
+
resolve(true);
|
|
230
|
+
};
|
|
231
|
+
const timer = setTimeout(() => {
|
|
232
|
+
_mountWaiters.delete(waiter);
|
|
233
|
+
resolve(_containerMounted);
|
|
234
|
+
}, timeoutMs);
|
|
235
|
+
_mountWaiters.add(waiter);
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* The ONE teardown path: close the live document and give focus back to
|
|
241
|
+
* whatever held it before the runtime borrowed it. Idempotent — safe from a
|
|
242
|
+
* failed start and from an ordinary stop, both of which reach it.
|
|
243
|
+
*/
|
|
244
|
+
export function releaseLiveDocument(): void {
|
|
245
|
+
_held = false;
|
|
246
|
+
if (!_hooks || !liveDocumentOpen()) {
|
|
247
|
+
_restoreDocumentId = null;
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
const restore = _restoreDocumentId;
|
|
251
|
+
_restoreDocumentId = null;
|
|
252
|
+
// THE LATCH GOES STALE-FALSE HERE, EAGERLY — before React has flushed the
|
|
253
|
+
// panel's unmount. Closing the document makes "the container is mounted"
|
|
254
|
+
// untrue at THIS line, but the panel's own detach only
|
|
255
|
+
// lands on the next React commit, so between here and that commit the latch
|
|
256
|
+
// used to still say true. A caller that tears a runtime down and
|
|
257
|
+
// immediately re-acquires (every ingest mount's `exitActiveIngest()` →
|
|
258
|
+
// `acquireLiveDocument()` sequence) then got an instant `true` from the
|
|
259
|
+
// stale latch, read the container in the unmount gap, and refused
|
|
260
|
+
// with "Game container not mounted" — measured on bubbo-bubbo (2026-08-21):
|
|
261
|
+
// every ▶ after a creation-site write failed this way, because the write is
|
|
262
|
+
// what first materializes the held ingest session the next play must tear
|
|
263
|
+
// down. Clearing the latch first makes the re-acquire genuinely WAIT for
|
|
264
|
+
// the reopened panel's commit, which is the contract its doc claims.
|
|
265
|
+
_containerMounted = false;
|
|
266
|
+
// `discardDirty` because the live document is never an authored draft — it
|
|
267
|
+
// has nothing to save and a close must never be refused.
|
|
268
|
+
closeWorkspaceDocument(GAME_DOCUMENT_ID, { discardDirty: true });
|
|
269
|
+
// Closing already activated a neighbour (the registry's own "there is always
|
|
270
|
+
// an active center document" fallback); restoring the pre-play document is
|
|
271
|
+
// only a correction of WHICH one, never a rescue from having none.
|
|
272
|
+
if (restore) activateWorkspaceDocument(restore);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Report the store's live/stopped state on every notify. A runtime ENDING is
|
|
277
|
+
* the edge that closes the document; the stopped state on its own must not,
|
|
278
|
+
* because {@link acquireLiveDocument} deliberately runs while the store still
|
|
279
|
+
* says stopped (a runtime needs the container before it can start).
|
|
280
|
+
*/
|
|
281
|
+
export function syncLiveDocumentPlayState(live: boolean): void {
|
|
282
|
+
if (_wasLive && !live) releaseLiveDocument();
|
|
283
|
+
_wasLive = live;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/** Test-only reset — drops the binding and every latch WITHOUT closing. */
|
|
287
|
+
export function __resetLiveDocumentForTest(): void {
|
|
288
|
+
_hooks = null;
|
|
289
|
+
_content = null;
|
|
290
|
+
_container = null;
|
|
291
|
+
_containerMounted = false;
|
|
292
|
+
_restoreDocumentId = null;
|
|
293
|
+
_wasLive = false;
|
|
294
|
+
_held = false;
|
|
295
|
+
_mountWaiters.clear();
|
|
296
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "A continuous viewport gesture is happening right now" — the one fact the
|
|
3
|
+
* absorb-by-remount cycle needs from the gizmo.
|
|
4
|
+
*
|
|
5
|
+
* A source write remounts the world; a drag that is STILL RUNNING when the
|
|
6
|
+
* swap lands moves old-scene objects, and the adopted scene snaps them back
|
|
7
|
+
* to the written values — a human moving a three-cube selection "bit by bit"
|
|
8
|
+
* watched one member stay behind on every quick successive drag (runhuman
|
|
9
|
+
* passes 49/54, both ranked it their #1 fix). The design session builds the
|
|
10
|
+
* new world in parallel but awaits {@link whenLiveGestureIdle} before the
|
|
11
|
+
* swap, so a drag always completes on the objects it started on.
|
|
12
|
+
*
|
|
13
|
+
* Deliberately module-scoped and frameworkless: the setter is the viewport's
|
|
14
|
+
* `dragging-changed` handler and the consumer is the design session — no
|
|
15
|
+
* React context reaches both.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
let active = 0;
|
|
19
|
+
let waiters: Array<() => void> = [];
|
|
20
|
+
|
|
21
|
+
export function beginLiveGesture(): void {
|
|
22
|
+
active += 1;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function endLiveGesture(): void {
|
|
26
|
+
active = Math.max(0, active - 1);
|
|
27
|
+
if (active === 0) {
|
|
28
|
+
const resolved = waiters;
|
|
29
|
+
waiters = [];
|
|
30
|
+
for (const resolve of resolved) resolve();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Whether any gesture (a drag, or a gesture's still-landing write) holds
|
|
35
|
+
* the lock right now — the swap's settle loop re-checks this after each
|
|
36
|
+
* wait, because a lock taken in the same task that released the previous
|
|
37
|
+
* one can race a waiter that already resolved. */
|
|
38
|
+
export function liveGestureActive(): boolean {
|
|
39
|
+
return active > 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Resolves immediately when no gesture is running, else on the current
|
|
43
|
+
* gesture's end. */
|
|
44
|
+
export function whenLiveGestureIdle(): Promise<void> {
|
|
45
|
+
return active === 0
|
|
46
|
+
? Promise.resolve()
|
|
47
|
+
: new Promise((resolve) => {
|
|
48
|
+
waiters.push(resolve);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** One current-process evidence ledger shared by panels, relay consumers,
|
|
2
|
+
* coverage, status, and Doctor. It is intentionally ephemeral: project source
|
|
3
|
+
* remains truth and no Volter evidence sidecar is invented. */
|
|
4
|
+
|
|
5
|
+
import { SeamEvidenceLedger, type SeamEvidenceReceipt } from '@volter/project/adapter';
|
|
6
|
+
|
|
7
|
+
export const liveSeamEvidence = new SeamEvidenceLedger();
|
|
8
|
+
|
|
9
|
+
export function recordLiveSeamEvidence(receipt: SeamEvidenceReceipt): void {
|
|
10
|
+
liveSeamEvidence.record(receipt);
|
|
11
|
+
}
|