@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,387 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FINDER — scenes from the entrypoint's active-scene selection.
|
|
3
|
+
*
|
|
4
|
+
* ARCHITECTURE-CORE §The editor protocol, "Zero inference": discovery may be a
|
|
5
|
+
* LIBRARY, and this is one. It only ever runs because an adapter SELECTED it
|
|
6
|
+
* (`{ finder: 'scenesFromEntrypointSelection', … }`); the engine never runs a
|
|
7
|
+
* finder nobody selected, which `packages/engine/test/finder-import-boundary.test.ts`
|
|
8
|
+
* enforces mechanically rather than by policy.
|
|
9
|
+
*
|
|
10
|
+
* Why the ENTRYPOINT and not a folder: it is a LOAD-BEARING source — a
|
|
11
|
+
* reference the game itself executes. The review test is "would the game break
|
|
12
|
+
* if this fact lied?", and here it would: change the entrypoint's selection
|
|
13
|
+
* table and the game changes with it. A `src/scenes/` convention can drift
|
|
14
|
+
* silently; this cannot.
|
|
15
|
+
*
|
|
16
|
+
* Two answers, and the difference is declared rather than sniffed:
|
|
17
|
+
* - the adapter names a `selection` identifier ⇒ read that module-level
|
|
18
|
+
* table and answer one entry per key, each reachable through it — plus
|
|
19
|
+
* WHICH key the entrypoint indexes it with right now (`scenes[activeScene]`
|
|
20
|
+
* → `const activeScene = 'main'`), marked `reach.active`. That reference is
|
|
21
|
+
* load-bearing for the same reason the table is: the running world renders
|
|
22
|
+
* exactly that key's composition, which is why the host can treat the
|
|
23
|
+
* active entry as the region's own standing document rather than a second
|
|
24
|
+
* tab beside it;
|
|
25
|
+
* - the adapter names none ⇒ the entrypoint mounts ONE composition, and the
|
|
26
|
+
* answer is the single-scene DEGENERATE table: the region's own
|
|
27
|
+
* composition, opened by mounting the region.
|
|
28
|
+
*
|
|
29
|
+
* ON `typescript`: this module parses the entrypoint's own TSX with the
|
|
30
|
+
* TypeScript compiler API — the same parser `packages/sdk/src/kit/ui-source/
|
|
31
|
+
* oid-transform.ts` and `packages/sdk/src/kit/asset-workflow/project-content.ts`
|
|
32
|
+
* already use for exactly this kind of question (volter has `typescript`; it does
|
|
33
|
+
* NOT have @babel/*). It is a HOST-SIDE-ONLY dependency: finders are importable
|
|
34
|
+
* only by the adapter loader, `adapter-module.ts` imports nothing from this
|
|
35
|
+
* directory, and a game's `editor/volter.adapter.ts` therefore never pulls a parser into
|
|
36
|
+
* its own bundle.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
import {
|
|
40
|
+
indexingIdentifier,
|
|
41
|
+
propertyKey,
|
|
42
|
+
selectionTable,
|
|
43
|
+
} from '@volter/sdk/session/entrypoint-selection-readers';
|
|
44
|
+
import type {
|
|
45
|
+
DocumentEntry,
|
|
46
|
+
SceneSource,
|
|
47
|
+
ScenesFromEntrypointSelectionParams,
|
|
48
|
+
} from '@volter/project/adapter/adapter-module';
|
|
49
|
+
import { EXPORTED_COMPOSITION_REGIONS } from '@volter/project/adapter/adapter-module';
|
|
50
|
+
import type { FinderResult } from '@volter/project/adapter/finders/finder-result';
|
|
51
|
+
import ts from 'typescript';
|
|
52
|
+
|
|
53
|
+
/** One region's entrypoint, as the host reads it off the manifest + disk. */
|
|
54
|
+
export interface EntrypointSource {
|
|
55
|
+
/** The region (== manifest root) id. */
|
|
56
|
+
readonly regionId: string;
|
|
57
|
+
/** Project-relative path of the root's `entry` module. */
|
|
58
|
+
readonly path: string;
|
|
59
|
+
/** The module's bytes; `null` when they could not be read. */
|
|
60
|
+
readonly source: string | null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface ScenesFromEntrypointSelectionInput {
|
|
64
|
+
/**
|
|
65
|
+
* Every region the host mounts from an exported composition (a root with an
|
|
66
|
+
* `entry`), in manifest order.
|
|
67
|
+
*/
|
|
68
|
+
readonly entrypoints: readonly EntrypointSource[];
|
|
69
|
+
/**
|
|
70
|
+
* Resolve one of the entrypoint's own import specifiers to a project-relative
|
|
71
|
+
* path. Supplied by the host because extension/index resolution is a
|
|
72
|
+
* filesystem question and this function is pure. Absent, or answering `null`,
|
|
73
|
+
* means the produced entry carries no `source` — an honest omission rather
|
|
74
|
+
* than a guessed path.
|
|
75
|
+
*/
|
|
76
|
+
readonly resolveModule?: (specifier: string, fromPath: string) => string | null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Strip the directory and extension from a project-relative path. */
|
|
80
|
+
function basename(path: string): string {
|
|
81
|
+
const file = path.replaceAll('\\', '/').split('/').pop() ?? path;
|
|
82
|
+
return file.replace(/\.[jt]sx?$/, '');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function parse(path: string, source: string): ts.SourceFile {
|
|
86
|
+
return ts.createSourceFile(path, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The name the module's own default export carries — the game's own word for
|
|
91
|
+
* this composition, so the editor's tab reads `World`, not `world.tsx`.
|
|
92
|
+
* `undefined` when the default export is anonymous or absent.
|
|
93
|
+
*/
|
|
94
|
+
function defaultExportName(sf: ts.SourceFile): string | undefined {
|
|
95
|
+
for (const statement of sf.statements) {
|
|
96
|
+
if (ts.isExportAssignment(statement) && !statement.isExportEquals) {
|
|
97
|
+
const expression = statement.expression;
|
|
98
|
+
if (ts.isIdentifier(expression)) return expression.text;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const modifiers = ts.canHaveModifiers(statement) ? ts.getModifiers(statement) : undefined;
|
|
102
|
+
const isDefault = modifiers?.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword);
|
|
103
|
+
if (!isDefault) continue;
|
|
104
|
+
if (ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement)) {
|
|
105
|
+
return statement.name?.text;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Local identifier -> the import it came from. */
|
|
112
|
+
interface ImportedBinding {
|
|
113
|
+
readonly specifier: string;
|
|
114
|
+
/** The exported name this binding reads; `undefined` for a default import. */
|
|
115
|
+
readonly exported?: string;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function recordClauseBindings(
|
|
119
|
+
clause: ts.ImportClause,
|
|
120
|
+
specifier: string,
|
|
121
|
+
bindings: Map<string, ImportedBinding>,
|
|
122
|
+
): void {
|
|
123
|
+
if (clause.name) bindings.set(clause.name.text, { specifier });
|
|
124
|
+
const named = clause.namedBindings;
|
|
125
|
+
if (!named || !ts.isNamedImports(named)) return;
|
|
126
|
+
for (const element of named.elements) {
|
|
127
|
+
bindings.set(element.name.text, {
|
|
128
|
+
specifier,
|
|
129
|
+
exported: (element.propertyName ?? element.name).text,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function importedBindings(sf: ts.SourceFile): Map<string, ImportedBinding> {
|
|
135
|
+
const bindings = new Map<string, ImportedBinding>();
|
|
136
|
+
for (const statement of sf.statements) {
|
|
137
|
+
if (!ts.isImportDeclaration(statement) || !statement.importClause) continue;
|
|
138
|
+
if (!ts.isStringLiteral(statement.moduleSpecifier)) continue;
|
|
139
|
+
recordClauseBindings(statement.importClause, statement.moduleSpecifier.text, bindings);
|
|
140
|
+
}
|
|
141
|
+
return bindings;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* The string a module-level `const <name> = '…'` binds, or `undefined`.
|
|
146
|
+
*
|
|
147
|
+
* `const` and a STRING LITERAL are both required: a `let` can be reassigned and
|
|
148
|
+
* a computed initializer is not a fact the source states, so neither can be
|
|
149
|
+
* reported as the key the game executes. A type annotation
|
|
150
|
+
* (`const activeScene: keyof typeof scenes = 'main'`) is irrelevant here — the
|
|
151
|
+
* initializer is what runs.
|
|
152
|
+
*/
|
|
153
|
+
function moduleLevelString(sf: ts.SourceFile, name: string): string | undefined {
|
|
154
|
+
for (const statement of sf.statements) {
|
|
155
|
+
if (!ts.isVariableStatement(statement)) continue;
|
|
156
|
+
if ((statement.declarationList.flags & ts.NodeFlags.Const) === 0) continue;
|
|
157
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
158
|
+
if (!ts.isIdentifier(declaration.name) || declaration.name.text !== name) continue;
|
|
159
|
+
const initializer = declaration.initializer;
|
|
160
|
+
if (initializer && ts.isStringLiteral(initializer)) return initializer.text;
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return undefined;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* WHICH key the entrypoint mounts at its slot right now, read off the source
|
|
169
|
+
* the game itself executes.
|
|
170
|
+
*
|
|
171
|
+
* Every failure is a NOTE and answers `undefined`: an unread active key costs
|
|
172
|
+
* a retitle, while a guessed one would open the wrong composition as the
|
|
173
|
+
* region's own document.
|
|
174
|
+
*/
|
|
175
|
+
function activeSelectionKey(
|
|
176
|
+
entrypoint: EntrypointSource,
|
|
177
|
+
sf: ts.SourceFile,
|
|
178
|
+
selection: string,
|
|
179
|
+
keys: readonly string[],
|
|
180
|
+
notes: string[],
|
|
181
|
+
): string | undefined {
|
|
182
|
+
const identifier = indexingIdentifier(sf, selection);
|
|
183
|
+
if (identifier === undefined) {
|
|
184
|
+
notes.push(
|
|
185
|
+
`scenesFromEntrypointSelection: ${entrypoint.path} never indexes \`${selection}\`, so ` +
|
|
186
|
+
'which of its compositions the entrypoint mounts is not stated in the source and no ' +
|
|
187
|
+
'entry is settled as the active one.',
|
|
188
|
+
);
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
191
|
+
if (identifier === null) {
|
|
192
|
+
notes.push(
|
|
193
|
+
`scenesFromEntrypointSelection: ${entrypoint.path} indexes \`${selection}\` with ` +
|
|
194
|
+
'something other than one single identifier, so the key it mounts cannot be read ' +
|
|
195
|
+
'statically.',
|
|
196
|
+
);
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
const key = moduleLevelString(sf, identifier);
|
|
200
|
+
if (key === undefined) {
|
|
201
|
+
notes.push(
|
|
202
|
+
`scenesFromEntrypointSelection: ${entrypoint.path} indexes \`${selection}\` with ` +
|
|
203
|
+
`\`${identifier}\`, which is not a module-level \`const\` bound to a string literal, ` +
|
|
204
|
+
'so the key it mounts cannot be read statically.',
|
|
205
|
+
);
|
|
206
|
+
return undefined;
|
|
207
|
+
}
|
|
208
|
+
if (!keys.includes(key)) {
|
|
209
|
+
notes.push(
|
|
210
|
+
`scenesFromEntrypointSelection: ${entrypoint.path} mounts \`${selection}\` under ` +
|
|
211
|
+
`"${key}", which is not a key of that table. The entrypoint and its own selection ` +
|
|
212
|
+
'table disagree.',
|
|
213
|
+
);
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
216
|
+
return key;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** The identifier a selection entry's value names, if it names one at all. */
|
|
220
|
+
function propertyIdentifier(property: ts.ObjectLiteralElementLike): string | undefined {
|
|
221
|
+
if (ts.isShorthandPropertyAssignment(property)) return property.name.text;
|
|
222
|
+
if (ts.isPropertyAssignment(property) && ts.isIdentifier(property.initializer)) {
|
|
223
|
+
return property.initializer.text;
|
|
224
|
+
}
|
|
225
|
+
return undefined;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function sourceFor(
|
|
229
|
+
binding: ImportedBinding | undefined,
|
|
230
|
+
fromPath: string,
|
|
231
|
+
resolveModule: ScenesFromEntrypointSelectionInput['resolveModule'],
|
|
232
|
+
): SceneSource | undefined {
|
|
233
|
+
if (!binding || !resolveModule) return undefined;
|
|
234
|
+
const path = resolveModule(binding.specifier, fromPath);
|
|
235
|
+
if (!path) return undefined;
|
|
236
|
+
return binding.exported === undefined ? { path } : { path, export: binding.exported };
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Which entrypoints this selection targets.
|
|
241
|
+
*
|
|
242
|
+
* The RULE form is every exported-composition region. A named region with no
|
|
243
|
+
* matching entrypoint becomes a note, not a silent omission.
|
|
244
|
+
*/
|
|
245
|
+
function targetedEntrypoints(
|
|
246
|
+
params: ScenesFromEntrypointSelectionParams,
|
|
247
|
+
entrypoints: readonly EntrypointSource[],
|
|
248
|
+
notes: string[],
|
|
249
|
+
): EntrypointSource[] {
|
|
250
|
+
if (params.regions === EXPORTED_COMPOSITION_REGIONS) {
|
|
251
|
+
return [...entrypoints];
|
|
252
|
+
}
|
|
253
|
+
const found: EntrypointSource[] = [];
|
|
254
|
+
for (const regionId of params.regions) {
|
|
255
|
+
const match = entrypoints.find((entry) => entry.regionId === regionId);
|
|
256
|
+
if (match) found.push(match);
|
|
257
|
+
else {
|
|
258
|
+
notes.push(
|
|
259
|
+
`scenesFromEntrypointSelection: region "${regionId}" is selected but the project ` +
|
|
260
|
+
'declares no root with that id and an entry.',
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return found;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/** DEGENERATE: the entrypoint mounts one composition, and mounting the region
|
|
268
|
+
* IS opening it. Labelled by the module's own default export — the game's own
|
|
269
|
+
* word for this composition. */
|
|
270
|
+
function degenerateEntry(entrypoint: EntrypointSource, sf: ts.SourceFile): DocumentEntry {
|
|
271
|
+
return {
|
|
272
|
+
id: entrypoint.regionId,
|
|
273
|
+
label: defaultExportName(sf) ?? basename(entrypoint.path),
|
|
274
|
+
kind: 'scene',
|
|
275
|
+
region: entrypoint.regionId,
|
|
276
|
+
authorable: true,
|
|
277
|
+
reach: { kind: 'root-mount' },
|
|
278
|
+
source: { path: entrypoint.path },
|
|
279
|
+
finder: 'scenesFromEntrypointSelection',
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* One entry per key of the entrypoint's own selection table, plus WHICH of
|
|
285
|
+
* them the entrypoint currently mounts at the slot (`active`).
|
|
286
|
+
*/
|
|
287
|
+
function selectionEntries(
|
|
288
|
+
entrypoint: EntrypointSource,
|
|
289
|
+
sf: ts.SourceFile,
|
|
290
|
+
selection: string,
|
|
291
|
+
resolveModule: ScenesFromEntrypointSelectionInput['resolveModule'],
|
|
292
|
+
notes: string[],
|
|
293
|
+
): { entries: DocumentEntry[]; active: string | undefined } {
|
|
294
|
+
const table = selectionTable(sf, selection);
|
|
295
|
+
if (!table) {
|
|
296
|
+
notes.push(
|
|
297
|
+
`scenesFromEntrypointSelection: ${entrypoint.path} declares no module-level ` +
|
|
298
|
+
`\`const ${selection} = { … }\` selection table. Nothing is assumed in its ` +
|
|
299
|
+
'place — fix the adapter’s `selection` or the entrypoint.',
|
|
300
|
+
);
|
|
301
|
+
return { entries: [], active: undefined };
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const bindings = importedBindings(sf);
|
|
305
|
+
const keys: string[] = [];
|
|
306
|
+
const built: { key: string; label: string; source: SceneSource | undefined }[] = [];
|
|
307
|
+
for (const property of table.properties) {
|
|
308
|
+
const key = propertyKey(property);
|
|
309
|
+
if (key === undefined) {
|
|
310
|
+
notes.push(
|
|
311
|
+
`scenesFromEntrypointSelection: ${entrypoint.path}'s \`${selection}\` has an ` +
|
|
312
|
+
'entry whose key is computed, so it cannot be named statically.',
|
|
313
|
+
);
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
const identifier = propertyIdentifier(property);
|
|
317
|
+
keys.push(key);
|
|
318
|
+
built.push({
|
|
319
|
+
key,
|
|
320
|
+
label: identifier ?? key,
|
|
321
|
+
source: sourceFor(
|
|
322
|
+
identifier ? bindings.get(identifier) : undefined,
|
|
323
|
+
entrypoint.path,
|
|
324
|
+
resolveModule,
|
|
325
|
+
),
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const active = activeSelectionKey(entrypoint, sf, selection, keys, notes);
|
|
330
|
+
const entries = built.map(({ key, label, source }) => ({
|
|
331
|
+
id: key,
|
|
332
|
+
label,
|
|
333
|
+
kind: 'scene' as const,
|
|
334
|
+
region: entrypoint.regionId,
|
|
335
|
+
authorable: true,
|
|
336
|
+
reach: {
|
|
337
|
+
kind: 'entrypoint-selection' as const,
|
|
338
|
+
selection,
|
|
339
|
+
key,
|
|
340
|
+
...(key === active ? { active: true } : {}),
|
|
341
|
+
},
|
|
342
|
+
...(source ? { source } : {}),
|
|
343
|
+
finder: 'scenesFromEntrypointSelection' as const,
|
|
344
|
+
}));
|
|
345
|
+
return { entries, active };
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Answer the scene table this finder's selection describes.
|
|
350
|
+
*
|
|
351
|
+
* Pure: every input is passed in, nothing is read from disk, and an
|
|
352
|
+
* unanswerable question becomes a NOTE rather than a fabricated entry.
|
|
353
|
+
*/
|
|
354
|
+
export function scenesFromEntrypointSelection(
|
|
355
|
+
params: ScenesFromEntrypointSelectionParams,
|
|
356
|
+
input: ScenesFromEntrypointSelectionInput,
|
|
357
|
+
): FinderResult {
|
|
358
|
+
const notes: string[] = [];
|
|
359
|
+
const entries: DocumentEntry[] = [];
|
|
360
|
+
const active: string[] = [];
|
|
361
|
+
|
|
362
|
+
for (const entrypoint of targetedEntrypoints(params, input.entrypoints, notes)) {
|
|
363
|
+
if (entrypoint.source === null) {
|
|
364
|
+
notes.push(
|
|
365
|
+
`scenesFromEntrypointSelection: could not read ${entrypoint.path} (region ` +
|
|
366
|
+
`"${entrypoint.regionId}"), so its scenes are unknown — not empty.`,
|
|
367
|
+
);
|
|
368
|
+
continue;
|
|
369
|
+
}
|
|
370
|
+
const sf = parse(entrypoint.path, entrypoint.source);
|
|
371
|
+
if (params.selection === undefined) {
|
|
372
|
+
entries.push(degenerateEntry(entrypoint, sf));
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
const found = selectionEntries(entrypoint, sf, params.selection, input.resolveModule, notes);
|
|
376
|
+
entries.push(...found.entries);
|
|
377
|
+
if (found.active !== undefined) active.push(found.active);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// The ACTIVE key settles the default outright: the entrypoint states which
|
|
381
|
+
// composition it mounts, so this is the finder READING an answer rather than
|
|
382
|
+
// choosing between candidates. Failing that, one candidate settles it; two or
|
|
383
|
+
// more is a choice, and a choice belongs to the adapter author.
|
|
384
|
+
const settled =
|
|
385
|
+
active.length === 1 ? active[0] : entries.length === 1 ? entries[0]?.id : undefined;
|
|
386
|
+
return settled !== undefined ? { entries, default: settled, notes } : { entries, notes };
|
|
387
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WHETHER THE WORKBENCH IS SHOWING A PART — the one fact about the Code-OSS frame's layout a page
|
|
3
|
+
* module needs without importing the bridge. The bridge records each part as the workbench offers
|
|
4
|
+
* or withdraws it (`bridge.tsx`'s `offerVolterPart`); `null` means there is no frame, and the
|
|
5
|
+
* editor's panels are in the page.
|
|
6
|
+
*/
|
|
7
|
+
let framed = false;
|
|
8
|
+
const shown = new Set<string>();
|
|
9
|
+
const listeners = new Set<() => void>();
|
|
10
|
+
|
|
11
|
+
/** The bridge: a part was offered (`true`) or withdrawn (`false`). */
|
|
12
|
+
export function setFramePartShown(part: string, isShown: boolean): void {
|
|
13
|
+
framed = true;
|
|
14
|
+
if (shown.has(part) === isShown) return;
|
|
15
|
+
if (isShown) shown.add(part);
|
|
16
|
+
else shown.delete(part);
|
|
17
|
+
for (const listener of listeners) listener();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Whether the frame shows `part`; `null` without a frame. */
|
|
21
|
+
export function framePartShown(part: string): boolean | null {
|
|
22
|
+
return framed ? shown.has(part) : null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function subscribeFrameParts(listener: () => void): () => void {
|
|
26
|
+
listeners.add(listener);
|
|
27
|
+
return () => {
|
|
28
|
+
listeners.delete(listener);
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A document whose subject runs in a same-origin frame (the Build Player runs
|
|
3
|
+
* the project's own build in one) registers that frame here, so the capture
|
|
4
|
+
* door photographs what runs inside it: the composite of the frame's own
|
|
5
|
+
* document, not the editor's DOM around an `<iframe>` it cannot see into.
|
|
6
|
+
*
|
|
7
|
+
* `canvasFrame` is the composite's same-frame seam (`CaptureOptions`): the
|
|
8
|
+
* frame's canvases are its game's, created without `preserveDrawingBuffer`,
|
|
9
|
+
* so only the frame can copy them right after it renders.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export interface FramedCapture {
|
|
13
|
+
/** The element of the frame's document to composite. */
|
|
14
|
+
readonly container: () => HTMLElement | null;
|
|
15
|
+
readonly canvasFrame: (canvas: HTMLCanvasElement) => Promise<CanvasImageSource | null>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const framed = new WeakMap<HTMLIFrameElement, FramedCapture>();
|
|
19
|
+
|
|
20
|
+
export function registerFramedCapture(frame: HTMLIFrameElement, capture: FramedCapture): void {
|
|
21
|
+
framed.set(frame, capture);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** The framed subject inside a document's content, when it has one. */
|
|
25
|
+
export function framedCapture(
|
|
26
|
+
content: HTMLElement,
|
|
27
|
+
): { readonly container: HTMLElement; readonly canvasFrame: FramedCapture['canvasFrame'] } | null {
|
|
28
|
+
for (const frame of Array.from(content.querySelectorAll('iframe'))) {
|
|
29
|
+
const capture = framed.get(frame);
|
|
30
|
+
const container = capture?.container();
|
|
31
|
+
if (capture && container) return { container, canvasFrame: capture.canvasFrame };
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The lexical shadow prepended to every project/game module so `globalThis`,
|
|
3
|
+
* `window`, and `document` resolve to the mount's game realm instead of the
|
|
4
|
+
* real host objects. This is how raw listeners, timers, storage calls, and
|
|
5
|
+
* game-global properties stay attributable without touching editor globals.
|
|
6
|
+
*
|
|
7
|
+
* It lives in its own module, apart from `gated-globals.ts`, because it has THREE
|
|
8
|
+
* consumers spanning two TypeScript programs:
|
|
9
|
+
* - `gated-globals.ts` (browser) re-exports it, and installs the proxies;
|
|
10
|
+
* - `browser-transpile.ts` (browser) prepends it to client-transpiled source;
|
|
11
|
+
* - `vite-plugin-game-globals.ts` (Node) prepends it at transform time, and is
|
|
12
|
+
* reachable from `tsconfig.server.json` via `server/dev.ts`.
|
|
13
|
+
*
|
|
14
|
+
* That last one is the constraint: the server program compiles without the DOM
|
|
15
|
+
* lib, so it cannot pull in `gated-globals.ts` (whose proxy code names `window`,
|
|
16
|
+
* `document`, and `EventListenerOrEventListenerObject`). This module names none
|
|
17
|
+
* of them, so both programs can import the ONE definition. The dev server used to
|
|
18
|
+
* keep a hand-copied duplicate policed by a source-text sync test; extracting the
|
|
19
|
+
* constant deletes the copy and the test with it.
|
|
20
|
+
*
|
|
21
|
+
* Safe ahead of a module's own `import` statements: ESM imports are hoisted, so a
|
|
22
|
+
* leading `const window = …` still shadows for the whole module body. See
|
|
23
|
+
* `gated-globals.ts` for the proxy semantics it reaches.
|
|
24
|
+
*
|
|
25
|
+
* S-5 (the SimCity ingest ledger) added the SCHEDULING half. Shadowing `window`
|
|
26
|
+
* alone never reached a bare `setInterval(this.simulate, 1000)` — that resolves
|
|
27
|
+
* to the global binding, not to `window.setInterval` — which is exactly how a
|
|
28
|
+
* "gated" SimCity mount kept simulating after pause. The scheduling names are
|
|
29
|
+
* shadowed onto the same-realm loop gate
|
|
30
|
+
* (`ingest/same-realm-loop-gate.ts`, installed by `gated-globals.ts`), which is
|
|
31
|
+
* a pure pass-through until something holds it, so an ungated session's timing
|
|
32
|
+
* is unchanged. `.bind` is not optional: these are window methods and a bare
|
|
33
|
+
* call would hand them an `undefined` receiver ("Illegal invocation"), the same
|
|
34
|
+
* trap the `set` proxy's receiver comment records.
|
|
35
|
+
*/
|
|
36
|
+
/**
|
|
37
|
+
* MULTI-INSTANCE: the prelude for a module belonging to mount `mountId`.
|
|
38
|
+
*
|
|
39
|
+
* The mount id is BAKED IN at transform time rather than discovered at runtime
|
|
40
|
+
* from `import.meta.url`. Reading the module's own url would have worked —
|
|
41
|
+
* every project module under a mount already carries `?volter-mount=<id>` — and
|
|
42
|
+
* it needed no parameter. It was rejected because it silently constrains the
|
|
43
|
+
* prelude to ES-MODULE evaluation forever: `import.meta` is a SyntaxError in a
|
|
44
|
+
* `new Function` body, so any future non-module evaluation path would break at
|
|
45
|
+
* runtime with a message naming neither this file nor the reason. A test
|
|
46
|
+
* evaluating the prelude that way is what surfaced it. The transform already
|
|
47
|
+
* knows the mount id, so baking it costs one argument and keeps the prelude
|
|
48
|
+
* evaluable anywhere.
|
|
49
|
+
*
|
|
50
|
+
* With no mount id the same resolver selects the default realm. Hosted/client
|
|
51
|
+
* transpile paths therefore receive the same isolation semantics rather than
|
|
52
|
+
* a weaker fallback realm.
|
|
53
|
+
*/
|
|
54
|
+
export function gameGlobalsPrelude(mountId?: string): string {
|
|
55
|
+
const realm = `(__volterHost.__volterGameRealm?__volterHost.__volterGameRealm(${JSON.stringify(mountId ?? '')}):null)`;
|
|
56
|
+
return PRELUDE_HEAD.replace('__VOLTER_REALM__', realm);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The page's real global object, as an expression that names no identifier a project can shadow
|
|
61
|
+
* and compiles no code from a string.
|
|
62
|
+
*
|
|
63
|
+
* A module may itself declare `globalThis` (the prelude does), so reading the host through that
|
|
64
|
+
* identifier before its declaration would hit the declaration's TDZ. The expression instead puts
|
|
65
|
+
* a getter on `Object.prototype` for a moment and reads it as a bare name: a bare name that no
|
|
66
|
+
* scope declares is looked up on the global object, which inherits from `Object.prototype`, so the
|
|
67
|
+
* getter runs with the global object as `this`. It is the published `globalThis` polyfill
|
|
68
|
+
* (mathiasbynens.be/notes/globalthis), with `Object` itself reached through a literal. When
|
|
69
|
+
* `Object.prototype` will not take the getter (a project froze it), the global is read as `self`
|
|
70
|
+
* or `global` instead, so one project's freeze does not break every module that loads after it.
|
|
71
|
+
*
|
|
72
|
+
* It replaced a call of the Function constructor on the string 'return globalThis', which a
|
|
73
|
+
* content security policy without 'unsafe-eval' refuses: under such a policy every project module
|
|
74
|
+
* failed on its first line.
|
|
75
|
+
*
|
|
76
|
+
* This is lifecycle instrumentation, not a security sandbox: arbitrary same-realm code can reach
|
|
77
|
+
* the same object, which is why the architecture does not claim a browsing-context boundary.
|
|
78
|
+
*/
|
|
79
|
+
export const HOST_GLOBAL_EXPRESSION =
|
|
80
|
+
"(()=>{const O=({}).constructor;try{O.defineProperty(O.prototype,'__volterHostOf',{get(){return this},configurable:true});" +
|
|
81
|
+
'try{return __volterHostOf}finally{delete O.prototype.__volterHostOf}}' +
|
|
82
|
+
// A project may have frozen Object.prototype, and then the getter cannot be put there. The
|
|
83
|
+
// global is then read by a name the prelude itself does not declare: `self` (a window or a
|
|
84
|
+
// worker), then `global` (Node). Each is tried alone, because a project that declares the
|
|
85
|
+
// name makes even `typeof` of it throw until its declaration runs. `window` and `globalThis`
|
|
86
|
+
// are not tried: the prelude declares both in this same statement.
|
|
87
|
+
"catch(d){try{if(typeof self!=='undefined')return self}catch(s){}" +
|
|
88
|
+
"try{if(typeof global!=='undefined')return global}catch(g){}throw d}})()";
|
|
89
|
+
|
|
90
|
+
/** How every prelude begins: the text a transform looks for to know a module already has one. */
|
|
91
|
+
export const GAME_GLOBALS_PRELUDE_START = `const __volterHost=${HOST_GLOBAL_EXPRESSION},`;
|
|
92
|
+
|
|
93
|
+
const PRELUDE_HEAD =
|
|
94
|
+
GAME_GLOBALS_PRELUDE_START +
|
|
95
|
+
'__volterR=__VOLTER_REALM__,' +
|
|
96
|
+
'__volterGlobal=((__volterR&&__volterR.globalThis)||__volterHost.__volterGameWindow||__volterHost),' +
|
|
97
|
+
'globalThis=__volterGlobal,' +
|
|
98
|
+
'__volterSched=((__volterR&&__volterR.timers)||__volterHost.__volterGameTimers||__volterHost),' +
|
|
99
|
+
// Bind or pass through UNCHANGED. `.bind` is not optional for a real window
|
|
100
|
+
// method — a bare call would hand it an `undefined` receiver ("Illegal
|
|
101
|
+
// invocation"), the same trap `gated-globals.ts`'s `set` trap records — but
|
|
102
|
+
// an environment missing the API entirely (a Node-side transpile test, a
|
|
103
|
+
// worker) must degrade at the CALL site, not explode at module load.
|
|
104
|
+
'__volterBind=function(n){var f=__volterSched[n];' +
|
|
105
|
+
"return typeof f==='function'?f.bind(__volterSched):f;}," +
|
|
106
|
+
'console=((__volterR&&__volterR.console)||__volterHost.__volterGameConsole||__volterHost.console),' +
|
|
107
|
+
'window=((__volterR&&__volterR.window)||__volterHost.__volterGameWindow||__volterGlobal.window),' +
|
|
108
|
+
'document=((__volterR&&__volterR.document)||__volterHost.__volterGameDocument||__volterGlobal.document),' +
|
|
109
|
+
'__volterWindowBind=function(n){var f=window&&window[n];' +
|
|
110
|
+
"return typeof f==='function'?f.bind(window):f;}," +
|
|
111
|
+
'localStorage=(window&&window.localStorage),' +
|
|
112
|
+
'sessionStorage=(window&&window.sessionStorage),' +
|
|
113
|
+
'location=(window&&window.location),' +
|
|
114
|
+
"addEventListener=__volterWindowBind('addEventListener')," +
|
|
115
|
+
"removeEventListener=__volterWindowBind('removeEventListener')," +
|
|
116
|
+
"dispatchEvent=__volterWindowBind('dispatchEvent')," +
|
|
117
|
+
// PROJECT-SCOPED fetch: `__volterProjectFetch`, when a host installs one,
|
|
118
|
+
// answers a root-absolute `fetch('/shaders/…')` from project code against
|
|
119
|
+
// the project's own files; everywhere else this binds the host's own fetch (bound
|
|
120
|
+
// to the REAL global: native fetch called on a proxied window receiver
|
|
121
|
+
// throws "Illegal invocation"). The browser twin of the dev server's
|
|
122
|
+
// `vite-plugin-project-root-absolute-assets` rule: a root-absolute request
|
|
123
|
+
// made BY PROJECT CODE resolves inside the project.
|
|
124
|
+
// RESOLVED AT CALL TIME, not at module evaluation. Binding the hook once,
|
|
125
|
+
// when the module evaluated, captured whatever existed THEN: a canvas
|
|
126
|
+
// project's world evaluated on RELOAD before the bridge had installed the
|
|
127
|
+
// hook, so Pixi's atlas fetch of `/sprites/survivor.json` went to the host
|
|
128
|
+
// and got the SPA's index.html — `Unexpected token '<'`, the scene gutted to
|
|
129
|
+
// one row (build-45 gate, 2026-09-02); and after a library download the
|
|
130
|
+
// bridge mints a NEW hook over a new url map, which an already-evaluated
|
|
131
|
+
// module would never see. Reading the host's property on every call keeps
|
|
132
|
+
// every module on the current bridge, with the same host-fetch fallback.
|
|
133
|
+
'fetch=function(){var f=__volterHost.__volterProjectFetch;' +
|
|
134
|
+
'return f?f.apply(null,arguments):__volterHost.fetch.apply(__volterHost,arguments)},' +
|
|
135
|
+
"setTimeout=__volterBind('setTimeout')," +
|
|
136
|
+
"clearTimeout=__volterBind('clearTimeout')," +
|
|
137
|
+
"setInterval=__volterBind('setInterval')," +
|
|
138
|
+
"clearInterval=__volterBind('clearInterval')," +
|
|
139
|
+
"requestAnimationFrame=__volterBind('requestAnimationFrame')," +
|
|
140
|
+
"cancelAnimationFrame=__volterBind('cancelAnimationFrame');\n";
|
|
141
|
+
|
|
142
|
+
/** The no-mount prelude — the constant every existing consumer already uses. */
|
|
143
|
+
export const GAME_GLOBALS_PRELUDE = gameGlobalsPrelude();
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A game's DOM surface starts from a page's text defaults, as the game's
|
|
3
|
+
* `<body>` does when it ships: otherwise the editor's own typography (11px, its
|
|
4
|
+
* line height and colour) inherits into the game's DOM.
|
|
5
|
+
*
|
|
6
|
+
* The defaults are a ZERO-specificity rule (`:where(...)`), not inline style, so
|
|
7
|
+
* the game's own page rules win over them as they do in its build: a game's
|
|
8
|
+
* `html`/`body` rules arrive scoped as `:scope` (`scoped-game-css.ts`), on this
|
|
9
|
+
* same element, and an inline `font: initial` beat them — a game that sets its
|
|
10
|
+
* font on `body` rendered in the browser's default serif in the editor.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** The attribute that marks an element as a game's page surface. */
|
|
14
|
+
export const GAME_SURFACE_ATTRIBUTE = 'data-volter-game-surface';
|
|
15
|
+
|
|
16
|
+
const DEFAULTS_STYLE_MARK = 'data-volter-game-surface-defaults';
|
|
17
|
+
|
|
18
|
+
const DEFAULTS_CSS =
|
|
19
|
+
`:where([${GAME_SURFACE_ATTRIBUTE}]){font:initial;color:initial;letter-spacing:normal;` +
|
|
20
|
+
'word-spacing:normal;text-align:start;text-indent:0;text-transform:none;' +
|
|
21
|
+
'white-space:normal;direction:ltr;cursor:auto}';
|
|
22
|
+
|
|
23
|
+
/** Mark `element` as a game surface, installing the defaults rule once per document. */
|
|
24
|
+
export function markGameSurface(element: HTMLElement): void {
|
|
25
|
+
const document = element.ownerDocument;
|
|
26
|
+
if (!document.querySelector(`style[${DEFAULTS_STYLE_MARK}]`)) {
|
|
27
|
+
const style = document.createElement('style');
|
|
28
|
+
style.setAttribute(DEFAULTS_STYLE_MARK, '');
|
|
29
|
+
style.textContent = DEFAULTS_CSS;
|
|
30
|
+
(document.head ?? document.documentElement).prepend(style);
|
|
31
|
+
}
|
|
32
|
+
element.setAttribute(GAME_SURFACE_ATTRIBUTE, '');
|
|
33
|
+
}
|