@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,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE EDITOR RUNTIME CONTEXT — the light half of what `EditorContext.tsx`
|
|
3
|
+
* used to be: the `EditorRuntime` shape (store, stats, init promise,
|
|
4
|
+
* session), the React context that carries it, `EditorRuntimeProvider`,
|
|
5
|
+
* and every `use*` hook that reads it. Nothing here starts a lifecycle:
|
|
6
|
+
* no project discovery, no command listener, no save wiring. That is the
|
|
7
|
+
* point of the split — a connected component's only dependency on the
|
|
8
|
+
* editor is this module (closure: the shell store, the history session and
|
|
9
|
+
* two context helpers), so a bounded host (a document mounted alone,
|
|
10
|
+
* Storybook, a component test) mounts the same components without the
|
|
11
|
+
* application's whole boot graph. `EditorContext.tsx` keeps the
|
|
12
|
+
* application-level `EditorProvider` that owns those lifecycles.
|
|
13
|
+
*
|
|
14
|
+
* Measured 2026-09-03 (`scripts/validate-editor-closure.mjs --rank`): the
|
|
15
|
+
* bounded entry's closure was 505 files, 500 of them through
|
|
16
|
+
* `EditorContext.tsx`'s lifecycle imports, and the web build put 6.5 MB of
|
|
17
|
+
* the editor into that page for one Provider. This module is the cut.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { type InteractiveEditScope, InteractiveEditScopeContext } from '@volter/sdk/widgets';
|
|
21
|
+
import { type ReactNode, Suspense, useContext, useMemo, useSyncExternalStore } from 'react';
|
|
22
|
+
import type { ShellStore } from '@volter/sdk/kit/shell-store';
|
|
23
|
+
import type { EditorSession } from '@volter/sdk/kit/history/editor-session';
|
|
24
|
+
import type { HistoryCommandSnapshot, HistoryCommands } from '@volter/sdk/kit/history/history-commands';
|
|
25
|
+
import type { HistoryService, HistorySnapshot } from '@volter/sdk/kit/history/history-service';
|
|
26
|
+
import { createHmrStableReactContext } from '@volter/sdk/kit/hmr-stable-react-context';
|
|
27
|
+
|
|
28
|
+
export interface EditorStats {
|
|
29
|
+
fps: number;
|
|
30
|
+
frameTime: number;
|
|
31
|
+
drawCalls: number;
|
|
32
|
+
triangles: number;
|
|
33
|
+
cameraPosition: { x: number; y: number; z: number };
|
|
34
|
+
cameraTarget: { x: number; y: number; z: number };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface EditorRuntime {
|
|
38
|
+
store: ShellStore;
|
|
39
|
+
stats: EditorStats;
|
|
40
|
+
initPromise: Promise<void>;
|
|
41
|
+
session: EditorSession;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const EditorContext = createHmrStableReactContext<EditorRuntime | null>(
|
|
45
|
+
// Vite's HMR data when a dev server serves this module; the SDK carries no bundler types.
|
|
46
|
+
(import.meta as ImportMeta & { hot?: { data: Record<string, unknown> } }).hot?.data,
|
|
47
|
+
'EditorContext',
|
|
48
|
+
null,
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Provide an already-constructed editor runtime without starting project
|
|
53
|
+
* discovery, filesystem initialization, command listeners, or global bridges.
|
|
54
|
+
*
|
|
55
|
+
* The application-level {@link EditorProvider} below owns those lifecycles.
|
|
56
|
+
* Bounded production hosts (Storybook, component tests, embedded tools) use
|
|
57
|
+
* this provider so they render the same connected components against explicit
|
|
58
|
+
* dependencies instead of cloning the UI or accidentally booting a project.
|
|
59
|
+
*/
|
|
60
|
+
export function EditorRuntimeProvider({
|
|
61
|
+
runtime,
|
|
62
|
+
children,
|
|
63
|
+
}: {
|
|
64
|
+
readonly runtime: EditorRuntime;
|
|
65
|
+
readonly children: ReactNode;
|
|
66
|
+
}) {
|
|
67
|
+
// The shell's interactive-edit scope is INERT by design: coalescing a drag
|
|
68
|
+
// into one undo entry is each adapter's own business, done next to the
|
|
69
|
+
// writes it owns, so nothing here needs to bracket them.
|
|
70
|
+
const editScope = useMemo<InteractiveEditScope>(() => ({ begin: () => {}, end: () => {} }), []);
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<EditorContext.Provider value={runtime}>
|
|
74
|
+
<InteractiveEditScopeContext.Provider value={editScope}>
|
|
75
|
+
<Suspense>{children}</Suspense>
|
|
76
|
+
</InteractiveEditScopeContext.Provider>
|
|
77
|
+
</EditorContext.Provider>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function useEditorStore(): ShellStore {
|
|
82
|
+
const ctx = useContext(EditorContext);
|
|
83
|
+
if (!ctx) throw new Error('useEditorStore must be used within <EditorProvider>');
|
|
84
|
+
return ctx.store;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function useEditorStats(): EditorStats {
|
|
88
|
+
const ctx = useContext(EditorContext);
|
|
89
|
+
if (!ctx) throw new Error('useEditorStats must be used within <EditorProvider>');
|
|
90
|
+
return ctx.stats;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function useEditorInit(): Promise<void> {
|
|
94
|
+
const ctx = useContext(EditorContext);
|
|
95
|
+
if (!ctx) throw new Error('useEditorInit must be used within <EditorProvider>');
|
|
96
|
+
return ctx.initPromise;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function useHistoryService(): HistoryService {
|
|
100
|
+
const ctx = useContext(EditorContext);
|
|
101
|
+
if (!ctx) throw new Error('useHistoryService must be used within <EditorProvider>');
|
|
102
|
+
return ctx.session.history;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** History-aware panels may still be rendered in isolated component tests. */
|
|
106
|
+
export function useOptionalHistoryService(): HistoryService | null {
|
|
107
|
+
return useContext(EditorContext)?.session.history ?? null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* The shell store WHEN THERE IS A SHELL — `null` in a bounded host.
|
|
112
|
+
*
|
|
113
|
+
* Same contract as {@link useOptionalHistoryService}, and it exists for the
|
|
114
|
+
* same reason: the surfaces `scripts/validate-editor-closure.mjs` pins are
|
|
115
|
+
* exactly the ones a bounded host mounts with no `EditorProvider` above them
|
|
116
|
+
* (`@volter/editor-blender`'s Model document mounts `ToolObject3DAuthoring` that way).
|
|
117
|
+
* A stage asking what the WORKSPACE is showing must be able to hear "there is
|
|
118
|
+
* no workspace" instead of throwing the host's own document off the screen.
|
|
119
|
+
*/
|
|
120
|
+
export function useOptionalEditorStore(): ShellStore | null {
|
|
121
|
+
return useContext(EditorContext)?.store ?? null;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** The shell's frame/camera readout WHEN THERE IS A SHELL — same contract as
|
|
125
|
+
* {@link useOptionalEditorStore}, for the stage host: the world root's stage
|
|
126
|
+
* writes this every frame and the shell's own readouts (`CameraInfo`,
|
|
127
|
+
* `StatsOverlay`) read it, while a bounded host has neither. */
|
|
128
|
+
export function useOptionalEditorStats(): EditorStats | null {
|
|
129
|
+
return useContext(EditorContext)?.stats ?? null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function useHistoryCommands(): HistoryCommands {
|
|
133
|
+
const ctx = useContext(EditorContext);
|
|
134
|
+
if (!ctx) throw new Error('useHistoryCommands must be used within <EditorProvider>');
|
|
135
|
+
return ctx.session.historyCommands;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export function useHistoryCommandSnapshot(): HistoryCommandSnapshot {
|
|
139
|
+
const history = useHistoryCommands();
|
|
140
|
+
return useSyncExternalStore(history.subscribe, history.getSnapshot, history.getSnapshot);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function useHistorySnapshot(): HistorySnapshot {
|
|
144
|
+
const history = useHistoryService();
|
|
145
|
+
return useSyncExternalStore(history.subscribe, history.getSnapshot, history.getSnapshot);
|
|
146
|
+
}
|
|
147
|
+
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One reader for "did the EDITOR SERVER answer this, and what did it say?"
|
|
3
|
+
*
|
|
4
|
+
* ## Why `response.ok` is not that question
|
|
5
|
+
*
|
|
6
|
+
* Every editor route lives under `/__editor/*` on the same origin as the
|
|
7
|
+
* editor page. When no editor server is in front of that origin — a static
|
|
8
|
+
* preview of `dist/`, a misconfigured deployment — the host still answers:
|
|
9
|
+
* with the SPA FALLBACK, which is `200 OK` and
|
|
10
|
+
* `text/html`. So `response.ok` is TRUE for a request nothing handled.
|
|
11
|
+
*
|
|
12
|
+
* That turned into two different fabrications, depending on what the caller did
|
|
13
|
+
* next:
|
|
14
|
+
*
|
|
15
|
+
* - callers that PARSED died inside `res.json()` on `Unexpected token '<'`, an
|
|
16
|
+
* error naming neither the route nor the cause, usually into a bare `catch`
|
|
17
|
+
* that returned an empty value the UI then reported as a fact about the
|
|
18
|
+
* project ("No project tools registered", "no portable CSF previews");
|
|
19
|
+
* - callers that did NOT parse — a POST whose only interest is "did it work?"
|
|
20
|
+
* — read the fallback as SUCCESS. Marking a generation job read, forgetting
|
|
21
|
+
* one, reconciling providers: each reported done, having reached nothing.
|
|
22
|
+
*
|
|
23
|
+
* The second is the worse half, and it is invisible: there is no exception to
|
|
24
|
+
* catch, so the only symptom is state that never actually changed.
|
|
25
|
+
*
|
|
26
|
+
* ## The rule
|
|
27
|
+
*
|
|
28
|
+
* A response is from the editor server when its content type is JSON. Every
|
|
29
|
+
* `/__editor/*` route answers JSON — including its FAILURES, which carry
|
|
30
|
+
* `{ error }` — while the page fallback never does, so the check has no false
|
|
31
|
+
* negatives to trade against. Callers that already guard the REALM
|
|
32
|
+
* (`getEditorMode()`) still use this: the realm guard says "don't ask", this
|
|
33
|
+
* says "that answer isn't ours", and a deployment can put a page fallback in
|
|
34
|
+
* front of a mode the client believes is served.
|
|
35
|
+
*
|
|
36
|
+
* The header's question is really two, so there are two entry points:
|
|
37
|
+
*
|
|
38
|
+
* - {@link assertEditorServerAnswered} — "did the editor server answer this?"
|
|
39
|
+
* alone, for the many callers that then read the server's OWN `{ error }`
|
|
40
|
+
* body on a non-OK status. Asserting `ok` for them would replace a real,
|
|
41
|
+
* user-facing server message ("Insufficient credits") with a bare status
|
|
42
|
+
* code, so they get the fallback check and keep their own status handling.
|
|
43
|
+
* - {@link assertEditorServerResponse} / {@link editorServerJson} — answered
|
|
44
|
+
* AND OK, for callers with no interest in the failure body.
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
/** The single sentence a page-fallback answer gets, so the reader is sent to
|
|
48
|
+
* the host rather than to their own project. */
|
|
49
|
+
function fallbackMessage(what: string, contentType: string): string {
|
|
50
|
+
return (
|
|
51
|
+
`${what}: this origin answered with its page fallback (${contentType || 'no content-type'}) ` +
|
|
52
|
+
'rather than JSON, so no editor server handled the request.'
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Throw unless `response` came from the editor server AT ALL — ignoring its
|
|
58
|
+
* status, which is the caller's own business.
|
|
59
|
+
*
|
|
60
|
+
* For callers that read the route's `{ error }` body on failure: run this
|
|
61
|
+
* BEFORE `response.json()`, so a page fallback reports itself instead of dying
|
|
62
|
+
* as `Unexpected token '<'` in the parse.
|
|
63
|
+
*/
|
|
64
|
+
export function assertEditorServerAnswered(response: Response, what: string): void {
|
|
65
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
66
|
+
if (!contentType.includes('application/json')) {
|
|
67
|
+
throw new Error(fallbackMessage(what, contentType));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Throw unless `response` really came from the editor server AND succeeded.
|
|
73
|
+
*
|
|
74
|
+
* For callers whose only question is whether the call took effect (POST/DELETE
|
|
75
|
+
* routes with no interesting body).
|
|
76
|
+
*/
|
|
77
|
+
export function assertEditorServerResponse(response: Response, what: string): void {
|
|
78
|
+
if (!response.ok) throw new Error(`${what} (${response.status}).`);
|
|
79
|
+
assertEditorServerAnswered(response, what);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** {@link assertEditorServerResponse}, then the parsed body. */
|
|
83
|
+
export async function editorServerJson<T>(response: Response, what: string): Promise<T> {
|
|
84
|
+
assertEditorServerResponse(response, what);
|
|
85
|
+
return (await response.json()) as T;
|
|
86
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WHO THIS EDITOR SESSION IS, AND WHAT REVISION IT LAST SAW — the stamp every
|
|
3
|
+
* host source write carries.
|
|
4
|
+
*
|
|
5
|
+
* Three facts, all of them the page's own:
|
|
6
|
+
* - the PARTICIPANT ID this tab writes under, seeded by the server's
|
|
7
|
+
* bootstrap global and otherwise persisted per browser. `editor-presence.ts`
|
|
8
|
+
* re-exports it as `EDITOR_PARTICIPANT_ID`, which is the name the rest of
|
|
9
|
+
* the host knows it by.
|
|
10
|
+
* - the session's GUEST flag: this page reached the editor through a shared
|
|
11
|
+
* tunnel, so three host surfaces disable what a guest may not do
|
|
12
|
+
* (`account.ts`, `components/ProjectHeader.tsx`,
|
|
13
|
+
* `components/WorktreeSwitcher.tsx`).
|
|
14
|
+
* - the last source REVISION this page observed, which every write sends as
|
|
15
|
+
* `expectedRevision` so the server can refuse a stale one. That is
|
|
16
|
+
* optimistic concurrency on the storage seam, not a feature: the readers
|
|
17
|
+
* are `storage/http-storage.ts`, `ui-source/source-write-backend.ts`,
|
|
18
|
+
* `history/project-root-history-backends.ts`,
|
|
19
|
+
* `authoring/edit-mode-authoring.ts` and `source-conflict.ts`.
|
|
20
|
+
*
|
|
21
|
+
* IT WAS CALLED `collaboration-attribution.ts` UNTIL THE FINAL AUDIT, and the
|
|
22
|
+
* name was the only thing that ever made it an opinion — two audits filed it
|
|
23
|
+
* under 'collaboration and presence' and named a door for it that the host
|
|
24
|
+
* does not need, because nothing here is a lane's: a page identifies itself
|
|
25
|
+
* and stamps its writes whether or not anyone else is connected. TWO sibling
|
|
26
|
+
* packages read it (the collaboration package takes the guest flag,
|
|
27
|
+
* `@volter/editor-game` takes the write stamp), which by the rule `@volter/editor-game` was
|
|
28
|
+
* landed on means it lives in neither. `WORK.md` §THE FINAL AUDIT.
|
|
29
|
+
*/
|
|
30
|
+
const participantKey = 'volter.collaboration.participant.v1';
|
|
31
|
+
const remoteShareKey = 'volter.collaboration.remote-share.v1';
|
|
32
|
+
const bootstrap = (
|
|
33
|
+
globalThis as typeof globalThis & {
|
|
34
|
+
__VOLTER_EDITOR_PRESENCE_BOOTSTRAP__?: {
|
|
35
|
+
participantId?: string;
|
|
36
|
+
displayName?: string;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
).__VOLTER_EDITOR_PRESENCE_BOOTSTRAP__;
|
|
40
|
+
|
|
41
|
+
function storedParticipantId(): string {
|
|
42
|
+
if (bootstrap?.participantId) return bootstrap.participantId;
|
|
43
|
+
const generated = globalThis.crypto?.randomUUID?.() ?? `participant-${Date.now()}`;
|
|
44
|
+
try {
|
|
45
|
+
const stored = globalThis.localStorage?.getItem(participantKey);
|
|
46
|
+
if (stored) return stored;
|
|
47
|
+
globalThis.localStorage?.setItem(participantKey, generated);
|
|
48
|
+
} catch {
|
|
49
|
+
// Storage can be blocked; page-lifetime identity is still usable.
|
|
50
|
+
}
|
|
51
|
+
return generated;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const COLLABORATION_PARTICIPANT_ID = storedParticipantId();
|
|
55
|
+
export const COLLABORATION_REMOTE_SHARE = (() => {
|
|
56
|
+
try {
|
|
57
|
+
return globalThis.localStorage?.getItem(remoteShareKey) === '1';
|
|
58
|
+
} catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
})();
|
|
62
|
+
export const COLLABORATION_PARTICIPANT_NAME = bootstrap?.displayName || 'Local editor';
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The source revision this page has seen, held on the PAGE, not in this module: the shell's
|
|
66
|
+
* bundled copy of this file and a declared package's source-served copy are two module instances
|
|
67
|
+
* on one page, and only the shell's collaboration client hears the revision stream. A module-local
|
|
68
|
+
* `let` left every other copy at 0, so a declared package's first write after anyone else's edit
|
|
69
|
+
* was refused as stale.
|
|
70
|
+
*/
|
|
71
|
+
const REVISION_SLOT = Symbol.for('volter.collaboration.revision');
|
|
72
|
+
const revisionSlot = ((globalThis as unknown as Record<symbol, { value: number } | undefined>)[REVISION_SLOT] ??= {
|
|
73
|
+
value: 0,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
export function setCollaborationRevision(value: number): void {
|
|
77
|
+
if (Number.isInteger(value) && value >= revisionSlot.value) revisionSlot.value = value;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function sourceMutationAttribution(): {
|
|
81
|
+
participantId: string;
|
|
82
|
+
expectedRevision: number;
|
|
83
|
+
} {
|
|
84
|
+
return { participantId: COLLABORATION_PARTICIPANT_ID, expectedRevision: revisionSlot.value };
|
|
85
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WHICH MODE THE EDITOR IS IN — one predicate, in a leaf module.
|
|
3
|
+
*
|
|
4
|
+
* It lives here rather than beside its first reader because it has two kinds of
|
|
5
|
+
* reader now, and they must never drift: `coverage/session-vitals.ts` asks so
|
|
6
|
+
* the `edit-mode-static` invariant can judge the session, and the ingest mount
|
|
7
|
+
* paths ask so a freshly-loaded game can be HELD at design time
|
|
8
|
+
* (`ingest/ingest-play-control.ts`'s `ingestContentTimeForMode`). An instrument
|
|
9
|
+
* must not be an import of the thing it measures, so neither owns it.
|
|
10
|
+
*
|
|
11
|
+
* MODE IS A SESSION, NOT A LOOP — and reading it off the loops is the one
|
|
12
|
+
* mistake that would make the Edit-static check unable to fire.
|
|
13
|
+
*
|
|
14
|
+
* A first-party play, deferred-ingest play, module session, or explicit ingest
|
|
15
|
+
* ▶ exists because somebody asked the host to run content; that is the editor
|
|
16
|
+
* being in Play. An ingest loop merely TURNING is still not a mode — it is the
|
|
17
|
+
* condition "ingested games autoplay in Edit" describes. `ingestPlaying()` is
|
|
18
|
+
* safe to use here because it is NOT inferred from a moving loop: it is the
|
|
19
|
+
* host play-control latch, written only when that control releases or holds the
|
|
20
|
+
* required ingest pause surface. A game advancing behind the host's back cannot
|
|
21
|
+
* set it and therefore remains visible to the Edit-static invariant.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { anyLiveSessionPlaying } from '@volter/sdk/kit/live-session-registry';
|
|
25
|
+
|
|
26
|
+
/** The editor is in Play when any registered lane is playing
|
|
27
|
+
* (`live-session-registry.ts`): first-party Play, a deferred-ingest play, an
|
|
28
|
+
* ingest ▶ held by the host play-control latch, a module session. */
|
|
29
|
+
export function editorIsPlaying(): boolean {
|
|
30
|
+
return anyLiveSessionPlaying();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Whether a gesture closed RIGHT NOW is an AUTHORING edit — the question every
|
|
35
|
+
* source-write backend asks before it moves a byte
|
|
36
|
+
* (`authoring/source-persistence-backend.ts` and the two backends behind it).
|
|
37
|
+
*
|
|
38
|
+
* What an edit means is decided by the surface it is made on: a HELD world is
|
|
39
|
+
* being authored and the gesture belongs in the game's own source; a RUNNING
|
|
40
|
+
* one is being played, and a play-time edit is session-local.
|
|
41
|
+
* {@link editorIsPlaying} owns that whole answer, including the ingest play
|
|
42
|
+
* control, rather than making every caller remember a second condition. Play
|
|
43
|
+
* adoption normally hands its adapters no source backend at all, but not every
|
|
44
|
+
* world in a play session gets that treatment (`play-mode.ts` composes
|
|
45
|
+
* non-presented worlds with `structuralThree`, which carries one), so the
|
|
46
|
+
* mode is asked here rather than trusted to the composition.
|
|
47
|
+
*
|
|
48
|
+
* The converse case is what decides the shape: an ingest boot-mounted into the
|
|
49
|
+
* Game document and HELD on its title screen is being AUTHORED. So the test is
|
|
50
|
+
* the loop's state, never which document the mount happens to live in.
|
|
51
|
+
*/
|
|
52
|
+
export function editorIsAuthoring(): boolean {
|
|
53
|
+
return !editorIsPlaying();
|
|
54
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE STATE REPORT'S CONTRIBUTED FIELDS — what a lane adds to `collectState`
|
|
3
|
+
* (`command-listener.ts`: the editor's `status` command, the SDK's `editor.state`). The host
|
|
4
|
+
* reports the session; a lane reports what only it knows (its loop's time
|
|
5
|
+
* scale and liveness, its seed, whether a restart is required) through
|
|
6
|
+
* `@volter/sdk/host`'s `session.reportFacet`. Keys are spread in the
|
|
7
|
+
* order of registration; a lane never overrides a host key.
|
|
8
|
+
*
|
|
9
|
+
* ## A FACET MAY BE REUSABLE, and that is what let coverage leave the host
|
|
10
|
+
*
|
|
11
|
+
* `collectState` takes a previous full snapshot whose expensive facets it may
|
|
12
|
+
* COPY instead of re-deriving, and the list of copyable keys used to be a
|
|
13
|
+
* host constant (`command-listener.ts`'s `REUSABLE_DERIVED_FACETS`). That is
|
|
14
|
+
* the reason the four capability-GRADING families stayed host fields long
|
|
15
|
+
* after everything around them had left: their derivation costs 76ms–1.3s and
|
|
16
|
+
* a facet's collect ran on EVERY report, interaction path included, so
|
|
17
|
+
* registering them from a package would have put that cost back on the
|
|
18
|
+
* critical path this mechanism exists to keep it off.
|
|
19
|
+
*
|
|
20
|
+
* So a registration carries its own reusable key names, and the collect is
|
|
21
|
+
* handed the `reuse` snapshot. A reusing collect returns the copied values (or
|
|
22
|
+
* skips the work outright); {@link reusableFacetKeys} is what the host strips
|
|
23
|
+
* from an interaction PATCH by name. The choice stays the caller's — only
|
|
24
|
+
* `collectState`'s caller knows whether it is on a user's critical path — and
|
|
25
|
+
* a package never has to invent a cache of its own to approximate it.
|
|
26
|
+
*/
|
|
27
|
+
export interface EditorStateFacetOptions {
|
|
28
|
+
/**
|
|
29
|
+
* The keys this facet's collect may serve from `reuse` rather than
|
|
30
|
+
* re-deriving. They join the host's own reusable set: an interaction-path
|
|
31
|
+
* PATCH omits them (the server still holds the last full snapshot), and the
|
|
32
|
+
* deferred full collect that always follows makes them current again.
|
|
33
|
+
*/
|
|
34
|
+
readonly reusableKeys?: readonly string[];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
type FacetCollect = (reuse: Record<string, unknown> | null) => Record<string, unknown>;
|
|
38
|
+
|
|
39
|
+
interface RegisteredFacet {
|
|
40
|
+
readonly collect: FacetCollect;
|
|
41
|
+
readonly reusableKeys: readonly string[];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const facets = new Set<RegisteredFacet>();
|
|
45
|
+
|
|
46
|
+
export function registerEditorStateFacet(
|
|
47
|
+
collect: FacetCollect,
|
|
48
|
+
options?: EditorStateFacetOptions,
|
|
49
|
+
): () => void {
|
|
50
|
+
const facet: RegisteredFacet = { collect, reusableKeys: options?.reusableKeys ?? [] };
|
|
51
|
+
facets.add(facet);
|
|
52
|
+
return () => {
|
|
53
|
+
facets.delete(facet);
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function collectEditorStateFacets(
|
|
58
|
+
/** A previous full snapshot a registered collect may copy its own reusable
|
|
59
|
+
* keys from, or `null` for a full collect. */
|
|
60
|
+
reuse: Record<string, unknown> | null = null,
|
|
61
|
+
): Record<string, unknown> {
|
|
62
|
+
const out: Record<string, unknown> = {};
|
|
63
|
+
for (const facet of facets) Object.assign(out, facet.collect(reuse));
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Every reusable key any registered facet declares — the contributed half of
|
|
68
|
+
* the host's `REUSABLE_DERIVED_FACETS`, read fresh because a contribution
|
|
69
|
+
* pass adds and removes facets while the session runs. */
|
|
70
|
+
export function reusableFacetKeys(): readonly string[] {
|
|
71
|
+
const keys: string[] = [];
|
|
72
|
+
for (const facet of facets) keys.push(...facet.reusableKeys);
|
|
73
|
+
return keys;
|
|
74
|
+
}
|