@volter/sdk 0.0.0-stage → 0.5.204
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 +1168 -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 +329 -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 +669 -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,73 @@
|
|
|
1
|
+
import type { AuthoringAdapter } from '@volter/project/adapter';
|
|
2
|
+
import type { ShellStore } from '@volter/sdk/kit/shell-store';
|
|
3
|
+
import { adapterOnlyToolOwner, type ViewportToolOwner } from '@volter/sdk/kit/authoring/viewport-tool-owner';
|
|
4
|
+
import { CompositeAuthoringAdapter } from '@volter/sdk/kit/authoring/composite-authoring-adapter';
|
|
5
|
+
import { resolveThreeViewportRootId } from './three-root';
|
|
6
|
+
import { isRootHidden } from '@volter/sdk/kit/authoring/world-session-state';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The one native root whose viewport tools may claim the current selection.
|
|
10
|
+
*
|
|
11
|
+
* A composed game can contain several native surfaces at once, but editing
|
|
12
|
+
* chrome needs one unambiguous coordinate system and capability owner. Empty,
|
|
13
|
+
* organizational, and cross-root selections therefore resolve to `null`.
|
|
14
|
+
*/
|
|
15
|
+
export interface ViewportToolContext extends ViewportToolOwner {
|
|
16
|
+
readonly adapter: AuthoringAdapter;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function compositeContext(
|
|
20
|
+
composite: CompositeAuthoringAdapter,
|
|
21
|
+
selectedIds: readonly string[],
|
|
22
|
+
): ViewportToolContext | null {
|
|
23
|
+
const children = composite.childAdapters();
|
|
24
|
+
let owner: (typeof children)[number] | null = null;
|
|
25
|
+
|
|
26
|
+
for (const id of selectedIds) {
|
|
27
|
+
const child =
|
|
28
|
+
children.find((candidate) => composite.groupNodeId(candidate.worldId) === id) ??
|
|
29
|
+
children.find((candidate) => composite.ownerOf(id) === candidate.worldId);
|
|
30
|
+
// Kind/projection folders and stale ids do not claim native-world tools.
|
|
31
|
+
if (!child) return null;
|
|
32
|
+
// A heterogeneous selection has no single native editing context.
|
|
33
|
+
if (owner && owner.worldId !== child.worldId) return null;
|
|
34
|
+
owner = child;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return owner ? { worldId: owner.worldId, kind: owner.kind, adapter: owner.adapter } : null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Resolve viewport-tool ownership from selection, never from which roots
|
|
42
|
+
* merely exist or happen to be visible.
|
|
43
|
+
*/
|
|
44
|
+
export function resolveViewportToolContext(
|
|
45
|
+
adapter: AuthoringAdapter,
|
|
46
|
+
selectedIds: Iterable<string>,
|
|
47
|
+
): ViewportToolContext | null {
|
|
48
|
+
const ids = [...selectedIds];
|
|
49
|
+
if (ids.length === 0) return null;
|
|
50
|
+
if (adapter instanceof CompositeAuthoringAdapter) return compositeContext(adapter, ids);
|
|
51
|
+
|
|
52
|
+
// Legacy/single-adapter sessions have no manifest kind metadata, and that
|
|
53
|
+
// fallback is `adapterOnlyToolOwner` — it speaks only the adapter contract,
|
|
54
|
+
// so it lives below the shell (`viewport-authoring-policy.ts`) as the gizmo
|
|
55
|
+
// viewport's own default. One copy, read from both sides.
|
|
56
|
+
const owner = adapterOnlyToolOwner(adapter, ids);
|
|
57
|
+
return owner ? { ...owner, adapter } : null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Whether the selected owner is actually painted in this viewport. DOM
|
|
62
|
+
* layers follow their world eye; the manifest's sole Three root owns the 3D
|
|
63
|
+
* viewport chrome only while that root is visible.
|
|
64
|
+
*/
|
|
65
|
+
export function isViewportToolContextVisible(
|
|
66
|
+
store: ShellStore,
|
|
67
|
+
context: ViewportToolOwner | null,
|
|
68
|
+
): boolean {
|
|
69
|
+
if (!context) return false;
|
|
70
|
+
if (context.worldId !== null && isRootHidden(context.worldId)) return false;
|
|
71
|
+
if (context.kind !== 'three' || context.worldId === null) return true;
|
|
72
|
+
return resolveThreeViewportRootId(store) === context.worldId;
|
|
73
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { AuthoringAdapter } from '@volter/project/adapter';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The native root whose viewport tools may claim the current selection, as far
|
|
5
|
+
* as the viewport cares: its KIND (only `three` lets the 3D chrome claim the
|
|
6
|
+
* surface) and its manifest root id (`null` for a single-adapter session).
|
|
7
|
+
*
|
|
8
|
+
* `authoring/viewport-tool-context.ts`'s `ViewportToolContext` is this plus the
|
|
9
|
+
* adapter, and is structurally assignable to it.
|
|
10
|
+
*/
|
|
11
|
+
export interface ViewportToolOwner {
|
|
12
|
+
readonly worldId: string | null;
|
|
13
|
+
readonly kind: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Viewport-tool ownership for a SINGLE adapter — no composite, no manifest kind
|
|
18
|
+
* metadata to read.
|
|
19
|
+
*
|
|
20
|
+
* Structural and conservative, unchanged from where it was written
|
|
21
|
+
* (`authoring/viewport-tool-context.ts`, which now imports it): a rect-capable
|
|
22
|
+
* selection is DOM; a selection whose every node resolves to an `Object3D` is
|
|
23
|
+
* three; anything else advertises no kind-specific chrome rather than guessing.
|
|
24
|
+
* It speaks only the adapter contract, which is why it can be the default here.
|
|
25
|
+
*/
|
|
26
|
+
export function adapterOnlyToolOwner(
|
|
27
|
+
adapter: AuthoringAdapter,
|
|
28
|
+
selectedIds: Iterable<string>,
|
|
29
|
+
): ViewportToolOwner | null {
|
|
30
|
+
const ids = [...selectedIds];
|
|
31
|
+
if (ids.length === 0) return null;
|
|
32
|
+
if (ids.some((id) => adapter.hierarchy.node(id) === null)) return null;
|
|
33
|
+
if (adapter.rects) return { worldId: null, kind: 'dom' };
|
|
34
|
+
if (ids.every((id) => adapter.hierarchy.object3D?.(id) != null)) {
|
|
35
|
+
return { worldId: null, kind: 'three' };
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* World session state (B1) — a module-level subscribable singleton (same shape as
|
|
3
|
+
* `./mount-failure-report.ts`: a bare get/set slot, no subscribe of its own — every
|
|
4
|
+
* caller that mutates it follows up with `store.notifyIngestEdit()`, which every
|
|
5
|
+
* panel already re-renders off via `useSyncExternalStore(store.subscribe, …)`)
|
|
6
|
+
* holding THREE session-local, per-worldId toggles that are NEVER
|
|
7
|
+
* serialized/persisted (D9: "eye = session-local viewport visibility, never
|
|
8
|
+
* serialized" — generalized here to all three, none of which is an authored
|
|
9
|
+
* property):
|
|
10
|
+
*
|
|
11
|
+
* - `hidden` — the eye (A2/D9). LIFTED out of `GameHierarchy.tsx`'s former
|
|
12
|
+
* local `useState<Set<string>> hiddenRootIds` (module-private React state
|
|
13
|
+
* the design-time layer stack could never see) so `design-time-layers.ts`
|
|
14
|
+
* can hide/show a world's actual DOM layer, not just dim its hierarchy row.
|
|
15
|
+
* - `interactive` — forwards real pointer events to the layer (for testing
|
|
16
|
+
* hover/press states at design time); off by default (`pointer-events:none`
|
|
17
|
+
* is the layer's resting state — see `design-time-layers.ts`).
|
|
18
|
+
* - `pickLock` — stored here for B4 to consume (layered viewport picking,
|
|
19
|
+
* D12): a pick-locked layer is skipped by the topmost-first pick walk.
|
|
20
|
+
* B1 only stores/exposes the toggle; nothing reads it yet.
|
|
21
|
+
*
|
|
22
|
+
* Keyed by the RAW manifest world id (`CompositeChild.worldId` /
|
|
23
|
+
* `ResolvedAdapterRoot.id`) — the SAME id `design-time-layers.ts` gets from
|
|
24
|
+
* `composite.childAdapters()`, NOT the composite's synthetic `world:<id>`
|
|
25
|
+
* group-node id. `GameHierarchy.tsx` (whose rows ARE keyed by the group-node
|
|
26
|
+
* id) resolves the raw worldId via `compositeGroupBadge`'s `worldId` field
|
|
27
|
+
* before calling into this module — see that file's row component.
|
|
28
|
+
*
|
|
29
|
+
* A process-lifetime singleton (not project-scoped): switching projects
|
|
30
|
+
* within the same tab does not reset these toggles. That's a deliberate
|
|
31
|
+
* relaxation of the former per-mount-React-state behavior (which reset on
|
|
32
|
+
* every `GameHierarchy` remount) — "session-local" here means "this browser
|
|
33
|
+
* tab's session", matching D9's own framing; nothing depends on a
|
|
34
|
+
* project-switch reset.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
export interface RootSessionState {
|
|
38
|
+
readonly hidden: boolean;
|
|
39
|
+
readonly interactive: boolean;
|
|
40
|
+
readonly pickLock: boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const DEFAULT_STATE: RootSessionState = { hidden: false, interactive: false, pickLock: false };
|
|
44
|
+
|
|
45
|
+
const _states = new Map<string, RootSessionState>();
|
|
46
|
+
|
|
47
|
+
function get(worldId: string): RootSessionState {
|
|
48
|
+
return _states.get(worldId) ?? DEFAULT_STATE;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function patch(worldId: string, partial: Partial<RootSessionState>): void {
|
|
52
|
+
_states.set(worldId, { ...get(worldId), ...partial });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** The eye (A2/D9): true while `worldId`'s design-time layer is hidden. */
|
|
56
|
+
export function isRootHidden(worldId: string): boolean {
|
|
57
|
+
return get(worldId).hidden;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function setRootHidden(worldId: string, hidden: boolean): void {
|
|
61
|
+
patch(worldId, { hidden });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function toggleRootHidden(worldId: string): void {
|
|
65
|
+
setRootHidden(worldId, !isRootHidden(worldId));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** True while `worldId`'s layer forwards real pointer events (design-time
|
|
69
|
+
* hover/press testing) instead of its resting `pointer-events:none`. */
|
|
70
|
+
export function isRootInteractive(worldId: string): boolean {
|
|
71
|
+
return get(worldId).interactive;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function setRootInteractive(worldId: string, interactive: boolean): void {
|
|
75
|
+
patch(worldId, { interactive });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function toggleRootInteractive(worldId: string): void {
|
|
79
|
+
setRootInteractive(worldId, !isRootInteractive(worldId));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** B4 will read this to skip a layer in the topmost-first pick walk; B1 only
|
|
83
|
+
* stores/exposes the toggle. */
|
|
84
|
+
export function isRootPickLocked(worldId: string): boolean {
|
|
85
|
+
return get(worldId).pickLock;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function setRootPickLock(worldId: string, pickLock: boolean): void {
|
|
89
|
+
patch(worldId, { pickLock });
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function toggleRootPickLock(worldId: string): void {
|
|
93
|
+
setRootPickLock(worldId, !isRootPickLocked(worldId));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Test-only: drop every world's session state back to defaults so unit
|
|
97
|
+
* tests don't leak toggles across cases (this module is a process-lifetime
|
|
98
|
+
* singleton — see the header comment). */
|
|
99
|
+
export function _resetRootSessionStateForTest(): void {
|
|
100
|
+
_states.clear();
|
|
101
|
+
}
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One structural and operational answer for an AuthoringAdapter.
|
|
3
|
+
*
|
|
4
|
+
* This module does not call providers. It inventories their compiler-pinned
|
|
5
|
+
* shapes and combines those receipts with receipts produced by real consumers
|
|
6
|
+
* and conformance probes. Shape can reject a malformed carrier immediately;
|
|
7
|
+
* it can never manufacture an operational pass.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
AUTHORING_ADAPTER_SHAPE,
|
|
12
|
+
AUTHORING_PROVIDER_KEYS,
|
|
13
|
+
AUTHORING_PROVIDER_SHAPES,
|
|
14
|
+
type AuthoringAdapter,
|
|
15
|
+
type AuthoringProviderKey,
|
|
16
|
+
gradeSeamCarrier,
|
|
17
|
+
gradeSeamEvidence,
|
|
18
|
+
HIERARCHY_PROVIDER_SHAPE,
|
|
19
|
+
type HierarchyProvider,
|
|
20
|
+
inspectSeamShape,
|
|
21
|
+
type SeamEvidenceReceipt,
|
|
22
|
+
type SeamEvidenceVerdict,
|
|
23
|
+
type SeamProofStage,
|
|
24
|
+
type SeamShape,
|
|
25
|
+
type StructuralWriteOutcome,
|
|
26
|
+
type WriteAck,
|
|
27
|
+
} from '@volter/project/adapter';
|
|
28
|
+
import { liveSeamEvidence, recordLiveSeamEvidence } from '@volter/sdk/kit/live-seam-evidence';
|
|
29
|
+
|
|
30
|
+
const EPOCHS = new WeakMap<object, string>();
|
|
31
|
+
let nextEpoch = 1;
|
|
32
|
+
|
|
33
|
+
/** Stable only for the lifetime of this adapter object. A cold remount creates
|
|
34
|
+
* a new adapter and therefore cannot inherit receipts from the old one. */
|
|
35
|
+
export function authoringAdapterEpoch(adapter: AuthoringAdapter): string {
|
|
36
|
+
const object = adapter as object;
|
|
37
|
+
const existing = EPOCHS.get(object);
|
|
38
|
+
if (existing) return existing;
|
|
39
|
+
const epoch = `authoring-${nextEpoch++}`;
|
|
40
|
+
EPOCHS.set(object, epoch);
|
|
41
|
+
return epoch;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function recordAuthoringReceipt(options: {
|
|
45
|
+
readonly adapter: AuthoringAdapter;
|
|
46
|
+
readonly seam: string;
|
|
47
|
+
readonly stage: SeamProofStage;
|
|
48
|
+
readonly outcome: 'pass' | 'fail';
|
|
49
|
+
readonly detail: string;
|
|
50
|
+
}): void {
|
|
51
|
+
const epoch = authoringAdapterEpoch(options.adapter);
|
|
52
|
+
const record = (seam: string, detail: string): void =>
|
|
53
|
+
recordLiveSeamEvidence({
|
|
54
|
+
seam,
|
|
55
|
+
subject: 'authoring-adapter',
|
|
56
|
+
epoch,
|
|
57
|
+
stage: options.stage,
|
|
58
|
+
outcome: options.outcome,
|
|
59
|
+
source: 'consumer',
|
|
60
|
+
detail,
|
|
61
|
+
});
|
|
62
|
+
record(options.seam, options.detail);
|
|
63
|
+
const segments = options.seam.split('.');
|
|
64
|
+
if (segments.length < 3) return;
|
|
65
|
+
const parent = segments.slice(0, -1).join('.');
|
|
66
|
+
record(
|
|
67
|
+
parent,
|
|
68
|
+
options.outcome === 'pass'
|
|
69
|
+
? `${parent} served a real consumer ${options.stage}`
|
|
70
|
+
: `${parent} failed through its consumer: ${options.detail}`,
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function writeAck(value: unknown): WriteAck | null {
|
|
75
|
+
if (!value || typeof value !== 'object') return null;
|
|
76
|
+
const candidate = value as { destination?: unknown; persisted?: unknown };
|
|
77
|
+
return typeof candidate.destination === 'string' && typeof candidate.persisted === 'boolean'
|
|
78
|
+
? (candidate as WriteAck)
|
|
79
|
+
: null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Record one real consumer call against the exact adapter object it used.
|
|
83
|
+
*
|
|
84
|
+
* The epoch, not a display label, is the identity boundary: one root can be
|
|
85
|
+
* reported under its manifest id in status and under `root` in the ingest
|
|
86
|
+
* mount report, while both names refer to this same adapter instance. The
|
|
87
|
+
* receipt is therefore stored under the neutral subject and rebound to the
|
|
88
|
+
* report's subject in {@link inspectAuthoringAdapterSeams} below.
|
|
89
|
+
*
|
|
90
|
+
* Promise-returning provider methods keep their original timing and rejection;
|
|
91
|
+
* success is recorded only after they settle. A thrown/rejected call records a
|
|
92
|
+
* failing receipt and is rethrown unchanged.
|
|
93
|
+
*/
|
|
94
|
+
export function recordAuthoringConsumerUse<T>(options: {
|
|
95
|
+
readonly adapter: AuthoringAdapter;
|
|
96
|
+
readonly seam: string;
|
|
97
|
+
readonly stage: SeamProofStage;
|
|
98
|
+
readonly detail: string;
|
|
99
|
+
readonly run: () => T;
|
|
100
|
+
}): T {
|
|
101
|
+
const receipt = (outcome: 'pass' | 'fail', detail: string): void => {
|
|
102
|
+
recordAuthoringReceipt({ ...options, outcome, detail });
|
|
103
|
+
};
|
|
104
|
+
try {
|
|
105
|
+
const value = options.run();
|
|
106
|
+
if (value && typeof (value as { then?: unknown }).then === 'function') {
|
|
107
|
+
return Promise.resolve(value).then(
|
|
108
|
+
(settled) => {
|
|
109
|
+
receipt('pass', options.detail);
|
|
110
|
+
return settled;
|
|
111
|
+
},
|
|
112
|
+
(error) => {
|
|
113
|
+
receipt(
|
|
114
|
+
'fail',
|
|
115
|
+
`${options.detail} failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
116
|
+
);
|
|
117
|
+
throw error;
|
|
118
|
+
},
|
|
119
|
+
) as unknown as T;
|
|
120
|
+
}
|
|
121
|
+
receipt('pass', options.detail);
|
|
122
|
+
return value;
|
|
123
|
+
} catch (error) {
|
|
124
|
+
receipt(
|
|
125
|
+
'fail',
|
|
126
|
+
`${options.detail} failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
127
|
+
);
|
|
128
|
+
throw error;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** Record a write at the strength its own return value proves. A concrete
|
|
133
|
+
* WriteAck is a round trip even when it honestly says live-only; `void` proves
|
|
134
|
+
* only that the effect call returned. This keeps void-returning legacy lanes
|
|
135
|
+
* from manufacturing the stronger receipt their contract still owes. */
|
|
136
|
+
export function recordAuthoringWriteConsumerUse(options: {
|
|
137
|
+
readonly adapter: AuthoringAdapter;
|
|
138
|
+
readonly seam: string;
|
|
139
|
+
readonly detail: string;
|
|
140
|
+
readonly run: () => StructuralWriteOutcome;
|
|
141
|
+
}): StructuralWriteOutcome {
|
|
142
|
+
const success = (value: void | WriteAck): void | WriteAck => {
|
|
143
|
+
const ack = writeAck(value);
|
|
144
|
+
recordAuthoringReceipt({
|
|
145
|
+
adapter: options.adapter,
|
|
146
|
+
seam: options.seam,
|
|
147
|
+
stage: ack ? 'round-trip' : 'effect',
|
|
148
|
+
outcome: 'pass',
|
|
149
|
+
detail: ack
|
|
150
|
+
? `${options.detail}: ${ack.destination} (${ack.persisted ? 'persisted' : 'live-only'})`
|
|
151
|
+
: `${options.detail}; the provider returned no write acknowledgement`,
|
|
152
|
+
});
|
|
153
|
+
return value;
|
|
154
|
+
};
|
|
155
|
+
const failure = (error: unknown): never => {
|
|
156
|
+
recordAuthoringReceipt({
|
|
157
|
+
adapter: options.adapter,
|
|
158
|
+
seam: options.seam,
|
|
159
|
+
stage: 'round-trip',
|
|
160
|
+
outcome: 'fail',
|
|
161
|
+
detail: `${options.detail} failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
162
|
+
});
|
|
163
|
+
throw error;
|
|
164
|
+
};
|
|
165
|
+
try {
|
|
166
|
+
const value = options.run();
|
|
167
|
+
return value && typeof (value as { then?: unknown }).then === 'function'
|
|
168
|
+
? Promise.resolve(value).then(success, failure)
|
|
169
|
+
: success(value as void | WriteAck);
|
|
170
|
+
} catch (error) {
|
|
171
|
+
return failure(error);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export interface AuthoringSeamEvidence {
|
|
176
|
+
readonly subject: string;
|
|
177
|
+
readonly epoch: string;
|
|
178
|
+
readonly receipts: readonly SeamEvidenceReceipt[];
|
|
179
|
+
readonly providers: Readonly<Record<AuthoringProviderKey, SeamEvidenceVerdict>>;
|
|
180
|
+
/**
|
|
181
|
+
* The hierarchy CARRIER: well-formed, and every member it advertises proven
|
|
182
|
+
* at that member's own required stage. This is the door
|
|
183
|
+
* `authoring/active-adapter.ts` refuses a malformed adapter with — a missing
|
|
184
|
+
* or mis-kinded `roots`/`node` only ever shows up as a member verdict, so
|
|
185
|
+
* the refusal needs the carrier grade and not the seam's own.
|
|
186
|
+
*/
|
|
187
|
+
readonly hierarchy: SeamEvidenceVerdict;
|
|
188
|
+
/**
|
|
189
|
+
* The hierarchy WALK — the `editor.hierarchy` seam's own verdict, which is a
|
|
190
|
+
* different and weaker question than {@link hierarchy}: did a current-epoch
|
|
191
|
+
* operation walk this root's tree and find it finite, non-empty and
|
|
192
|
+
* reciprocal (`coverage/authoring-read-probe.ts`)?
|
|
193
|
+
*
|
|
194
|
+
* It exists because the CARRIER asks a strictly stronger question: every
|
|
195
|
+
* member the carrier advertises, proven at that member's own stage. It used
|
|
196
|
+
* to be an UNANSWERABLE one — `object3D` (required `operation`) and
|
|
197
|
+
* `idForObject3D` (then required `effect`) are optional-but-PRESENT on every
|
|
198
|
+
* three adapter, no production consumer records a receipt for either, and
|
|
199
|
+
* the read probe did not call them, so `gradeSeamCarrier` returned
|
|
200
|
+
* `unverified` on a perfectly reciprocal tree, forever. Both are pure
|
|
201
|
+
* lookups and are `operation` now, called and checked against the walk by
|
|
202
|
+
* `coverage/authoring-read-probe.ts`'s `objectLookupReceipts`, so the
|
|
203
|
+
* carrier answers its own question on a healthy adapter.
|
|
204
|
+
* The two grades stay separate regardless: this one is what
|
|
205
|
+
* `adapter-reach.ts`'s `captureEvidence` reads, and reading the CARRIER
|
|
206
|
+
* there once left the capture row's `ok` branch DEAD — a healthy
|
|
207
|
+
* root printed "no current-epoch hierarchy operation proves it projects
|
|
208
|
+
* this root's runtime" as `info` while the operation had in fact run and
|
|
209
|
+
* passed. MEASURED 2026-09-19 on a `--template game` scaffold: `info` with
|
|
210
|
+
* the reciprocity fix in, `gap` with the pre-fix adapter planted — the
|
|
211
|
+
* failure branch worked, the success branch could not be reached.
|
|
212
|
+
*
|
|
213
|
+
* Graded here, beside the carrier and off the SAME receipt set, so the two
|
|
214
|
+
* answers cannot drift apart in two modules.
|
|
215
|
+
*/
|
|
216
|
+
readonly hierarchyWalk: SeamEvidenceVerdict;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export function inspectAuthoringAdapterSeams(options: {
|
|
220
|
+
readonly adapter: AuthoringAdapter;
|
|
221
|
+
readonly subject: string;
|
|
222
|
+
readonly epoch?: string | undefined;
|
|
223
|
+
readonly receipts?: readonly SeamEvidenceReceipt[] | undefined;
|
|
224
|
+
}): AuthoringSeamEvidence {
|
|
225
|
+
const { adapter, subject } = options;
|
|
226
|
+
const epoch = options.epoch ?? authoringAdapterEpoch(adapter);
|
|
227
|
+
const receipts: SeamEvidenceReceipt[] = [
|
|
228
|
+
...inspectSeamShape<AuthoringAdapter>({
|
|
229
|
+
prefix: 'editor',
|
|
230
|
+
value: adapter,
|
|
231
|
+
shape: AUTHORING_ADAPTER_SHAPE,
|
|
232
|
+
subject,
|
|
233
|
+
epoch,
|
|
234
|
+
}),
|
|
235
|
+
...inspectSeamShape<HierarchyProvider>({
|
|
236
|
+
prefix: 'editor.hierarchy',
|
|
237
|
+
value: adapter.hierarchy,
|
|
238
|
+
shape: HIERARCHY_PROVIDER_SHAPE,
|
|
239
|
+
subject,
|
|
240
|
+
epoch,
|
|
241
|
+
}),
|
|
242
|
+
];
|
|
243
|
+
|
|
244
|
+
for (const [provider, shape] of Object.entries(AUTHORING_PROVIDER_SHAPES)) {
|
|
245
|
+
receipts.push(
|
|
246
|
+
...inspectSeamShape({
|
|
247
|
+
prefix: `editor.${provider}`,
|
|
248
|
+
value: (adapter as unknown as Record<string, unknown>)[provider],
|
|
249
|
+
shape: shape as SeamShape<object>,
|
|
250
|
+
subject,
|
|
251
|
+
epoch,
|
|
252
|
+
}),
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
// An adapter epoch already identifies one concrete carrier. Rebind its live
|
|
256
|
+
// consumer receipts to this report's display subject so the same operation
|
|
257
|
+
// closes both the per-root status row (`worldId`) and the ingest report
|
|
258
|
+
// (`root`) without duplicating or guessing names at the call site.
|
|
259
|
+
receipts.push(
|
|
260
|
+
...liveSeamEvidence.receipts({ epoch }).map((receipt) => ({ ...receipt, subject })),
|
|
261
|
+
);
|
|
262
|
+
if (options.receipts) receipts.push(...options.receipts);
|
|
263
|
+
|
|
264
|
+
const providers = {} as Record<AuthoringProviderKey, SeamEvidenceVerdict>;
|
|
265
|
+
for (const provider of AUTHORING_PROVIDER_KEYS) {
|
|
266
|
+
const nested = (AUTHORING_PROVIDER_SHAPES as Partial<Record<string, SeamShape<object>>>)[
|
|
267
|
+
provider
|
|
268
|
+
];
|
|
269
|
+
providers[provider] = gradeSeamCarrier({
|
|
270
|
+
seam: `editor.${provider}`,
|
|
271
|
+
required: AUTHORING_ADAPTER_SHAPE[provider].required,
|
|
272
|
+
shape: nested,
|
|
273
|
+
subject,
|
|
274
|
+
epoch,
|
|
275
|
+
receipts,
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
return {
|
|
280
|
+
subject,
|
|
281
|
+
epoch,
|
|
282
|
+
receipts,
|
|
283
|
+
providers,
|
|
284
|
+
hierarchy: gradeSeamCarrier({
|
|
285
|
+
seam: 'editor.hierarchy',
|
|
286
|
+
required: AUTHORING_ADAPTER_SHAPE.hierarchy.required,
|
|
287
|
+
shape: HIERARCHY_PROVIDER_SHAPE as SeamShape<object>,
|
|
288
|
+
subject,
|
|
289
|
+
epoch,
|
|
290
|
+
receipts,
|
|
291
|
+
}),
|
|
292
|
+
hierarchyWalk: gradeSeamEvidence({
|
|
293
|
+
seam: 'editor.hierarchy',
|
|
294
|
+
required: AUTHORING_ADAPTER_SHAPE.hierarchy.required,
|
|
295
|
+
subject,
|
|
296
|
+
epoch,
|
|
297
|
+
receipts,
|
|
298
|
+
}),
|
|
299
|
+
};
|
|
300
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ONE shared 250ms availability tick replacing the three independent
|
|
3
|
+
* `setInterval(…, 250)` pollers that W4 left behind (utility availability,
|
|
4
|
+
* the Dev utility's live-plane gate, and ConnectionStatus's networking-adapter
|
|
5
|
+
* poll).
|
|
6
|
+
*
|
|
7
|
+
* These gates all watch the SAME kind of out-of-band signal — a live play
|
|
8
|
+
* session's adapters appearing/disappearing without any store/registry
|
|
9
|
+
* notification — so they don't need three timers, three wakeups, and three
|
|
10
|
+
* interleaved re-render schedules; they need one heartbeat. The interval is
|
|
11
|
+
* refcounted: it starts with the first subscriber and stops with the last,
|
|
12
|
+
* so an idle editor (none of the three consumers mounted) runs no timer at
|
|
13
|
+
* all — strictly better than the three always-on intervals it replaces.
|
|
14
|
+
*
|
|
15
|
+
* `useSyncExternalStore`-shaped on purpose: consumers subscribe and SELECT
|
|
16
|
+
* the derived value they actually read (`getActiveDebug()` presence, a
|
|
17
|
+
* connection state, an availability fingerprint) — they re-render only when
|
|
18
|
+
* that value changes, never on the tick itself. The former version-counter
|
|
19
|
+
* hook (`useAvailabilityTick`) re-rendered every subscriber 4×/s
|
|
20
|
+
* unconditionally; with the workspace and every panel subscribed
|
|
21
|
+
* that measured ~27ms of React work per tick (~110ms/s) in an idle editor —
|
|
22
|
+
* found 2026-07-31 by the Profiler's long-animation-frame attribution.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { useSyncExternalStore } from 'react';
|
|
26
|
+
|
|
27
|
+
const TICK_MS = 250;
|
|
28
|
+
|
|
29
|
+
let _version = 0;
|
|
30
|
+
let _intervalId: ReturnType<typeof setInterval> | null = null;
|
|
31
|
+
const _listeners = new Set<() => void>();
|
|
32
|
+
|
|
33
|
+
function onTick(): void {
|
|
34
|
+
_version++;
|
|
35
|
+
for (const fn of _listeners) fn();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Subscribe to the shared 250ms tick. Starts the timer on first subscriber,
|
|
39
|
+
* stops it with the last. Returns unsubscribe. */
|
|
40
|
+
export function subscribeAvailabilityTick(fn: () => void): () => void {
|
|
41
|
+
_listeners.add(fn);
|
|
42
|
+
if (_intervalId === null) _intervalId = setInterval(onTick, TICK_MS);
|
|
43
|
+
return () => {
|
|
44
|
+
_listeners.delete(fn);
|
|
45
|
+
if (_listeners.size === 0 && _intervalId !== null) {
|
|
46
|
+
clearInterval(_intervalId);
|
|
47
|
+
_intervalId = null;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Monotonic tick counter — exposed for tests that assert the timer runs. */
|
|
53
|
+
export function availabilityTickVersion(): number {
|
|
54
|
+
return _version;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Re-evaluate `select` on every shared availability tick, re-rendering the
|
|
59
|
+
* caller ONLY when its result changes (`Object.is`). `select` must return a
|
|
60
|
+
* primitive or a stable reference (an adapter identity, a joined-id string,
|
|
61
|
+
* a bitmask) — a fresh object every call would defeat the point and re-render
|
|
62
|
+
* per tick. It runs 4×/s plus once per render, so keep it a cheap read.
|
|
63
|
+
*/
|
|
64
|
+
export function useAvailabilitySelector<T>(select: () => T): T {
|
|
65
|
+
return useSyncExternalStore(subscribeAvailabilityTick, select, select);
|
|
66
|
+
}
|