@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,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backend-agnostic file interface for the editor.
|
|
3
|
+
*
|
|
4
|
+
* The editor and engine read/write project files through one `StorageBackend`
|
|
5
|
+
* and never learn which implementation is behind it — the session's own
|
|
6
|
+
* `/__editor/*` routes, the frame's file door over them, or the design
|
|
7
|
+
* system's in-memory fixture.
|
|
8
|
+
*
|
|
9
|
+
* Scope — this interface deliberately covers ONLY what reduces to file
|
|
10
|
+
* operations. Three editor concerns do not, and are handled elsewhere:
|
|
11
|
+
* - native folder dialogs / "reveal in OS file manager" → `HostCapabilities`
|
|
12
|
+
* - the `volter` CLI control channel (SSE + command RPC) → server-only, dropped
|
|
13
|
+
* in a pure-browser editor
|
|
14
|
+
* - `export` / packaging (spawns a build) → a client-side bundler in-browser
|
|
15
|
+
*
|
|
16
|
+
* `watch` is part of the interface but its semantics are backend-specific: a
|
|
17
|
+
* server backend reports real filesystem events (chokidar); a browser backend
|
|
18
|
+
* has no OS file-change notifications, so it derives events from its OWN writes
|
|
19
|
+
* (in a server-less editor the editor is the only writer — which is exactly the
|
|
20
|
+
* signal HMR needs).
|
|
21
|
+
*
|
|
22
|
+
* Paths are POSIX-style, project-root-relative, '/'-separated, no leading slash
|
|
23
|
+
* (e.g. `src/scripts/components/spin.ts`).
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
export type NodeType = 'file' | 'dir';
|
|
27
|
+
|
|
28
|
+
export interface Stat {
|
|
29
|
+
/** Normalized, root-relative path. */
|
|
30
|
+
path: string;
|
|
31
|
+
type: NodeType;
|
|
32
|
+
/** Byte length for files; 0 for directories. */
|
|
33
|
+
size: number;
|
|
34
|
+
/** Last-modified time, epoch ms (0 if the backend cannot report it). */
|
|
35
|
+
mtime: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface DirEntry {
|
|
39
|
+
/** Base name (no slashes). */
|
|
40
|
+
name: string;
|
|
41
|
+
/** Normalized, root-relative path. */
|
|
42
|
+
path: string;
|
|
43
|
+
type: NodeType;
|
|
44
|
+
/** Byte length for files (omitted for directories). */
|
|
45
|
+
size?: number;
|
|
46
|
+
/** Last-modified time, epoch ms (omitted if the backend cannot report it). */
|
|
47
|
+
mtime?: number;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type WatchEventType = 'create' | 'update' | 'remove';
|
|
51
|
+
|
|
52
|
+
export interface WatchEvent {
|
|
53
|
+
type: WatchEventType;
|
|
54
|
+
/** Normalized, root-relative path of the affected node. */
|
|
55
|
+
path: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export type WatchCallback = (event: WatchEvent) => void;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The one file interface every storage backend implements. All methods take and
|
|
62
|
+
* return normalized, root-relative POSIX paths.
|
|
63
|
+
*/
|
|
64
|
+
export interface StorageBackend {
|
|
65
|
+
/** Stable identifier for the active backend (for diagnostics/feature flags). */
|
|
66
|
+
readonly id: string;
|
|
67
|
+
|
|
68
|
+
/** Read a UTF-8 text file. Rejects if the path is missing or is a directory. */
|
|
69
|
+
read(path: string): Promise<string>;
|
|
70
|
+
/** Read raw bytes. Rejects if the path is missing or is a directory. */
|
|
71
|
+
readBytes(path: string): Promise<Uint8Array>;
|
|
72
|
+
|
|
73
|
+
/** Write a file, creating parent directories as needed. Emits a watch event. */
|
|
74
|
+
write(path: string, data: string | Uint8Array): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Create a new file without replacing an existing one. Returns false when
|
|
77
|
+
* the path already exists. Browser handle APIs have no OS-level O_EXCL;
|
|
78
|
+
* HandleStorage serializes same-origin writers and rechecks at handle
|
|
79
|
+
* acquisition, while an external process may still win the final race.
|
|
80
|
+
*/
|
|
81
|
+
writeIfAbsent(path: string, data: string | Uint8Array): Promise<boolean>;
|
|
82
|
+
|
|
83
|
+
/** Shallow directory listing. Rejects if the path is missing or is a file. */
|
|
84
|
+
list(dir: string): Promise<DirEntry[]>;
|
|
85
|
+
|
|
86
|
+
/** Stat a node, or resolve to `null` if it does not exist. */
|
|
87
|
+
stat(path: string): Promise<Stat | null>;
|
|
88
|
+
|
|
89
|
+
/** Convenience existence check. */
|
|
90
|
+
exists(path: string): Promise<boolean>;
|
|
91
|
+
|
|
92
|
+
/** Recursively create a directory (no-op if it already exists). */
|
|
93
|
+
mkdir(path: string): Promise<void>;
|
|
94
|
+
|
|
95
|
+
/** Recursively remove a file or directory (no-op if missing). Emits an event. */
|
|
96
|
+
remove(path: string): Promise<void>;
|
|
97
|
+
|
|
98
|
+
/** Subscribe to change events. Returns an unsubscribe function. */
|
|
99
|
+
watch(callback: WatchCallback): () => void;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Non-file host capabilities, kept separate from `StorageBackend` because they
|
|
104
|
+
* do not reduce to path operations. A backend may implement none of these.
|
|
105
|
+
*/
|
|
106
|
+
export interface HostCapabilities {
|
|
107
|
+
/**
|
|
108
|
+
* Prompt the user to choose a project root and return a backend rooted there.
|
|
109
|
+
* Browser: `showDirectoryPicker()` (Chromium). Resolves to `null` if the user
|
|
110
|
+
* cancels. Absent entirely where unsupported.
|
|
111
|
+
*/
|
|
112
|
+
pickProjectRoot?(): Promise<StorageBackend | null>;
|
|
113
|
+
|
|
114
|
+
/** Reveal a path in the OS file manager. Absent in the browser. */
|
|
115
|
+
reveal?(path: string): Promise<void>;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Is `backend` rooted at the project's `public/` folder rather than the project
|
|
120
|
+
* root? The session's HTTP tier (`http`) is, and so is the Code-OSS frame's
|
|
121
|
+
* file door (`frame:<tier>`), which is always the `public/` view. A reader of
|
|
122
|
+
* project-root files (`volter.project.json`, `.volter/`) reaches them through the
|
|
123
|
+
* dev server's own routes when this is true.
|
|
124
|
+
*/
|
|
125
|
+
export function isPublicRootedBackend(backend: StorageBackend): boolean {
|
|
126
|
+
return backend.id === 'http' || backend.id.startsWith('frame:');
|
|
127
|
+
}
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Isolated story preview mount — C3 (spec §9 "A story may be opened in an
|
|
3
|
+
* isolated editor preview"). Renders one composed story (`ComposedProjectStory`
|
|
4
|
+
* from `compose-project-stories.ts`) into a SEPARATE `react-dom/client` root,
|
|
5
|
+
* not a child of the editor's own React tree: the preview container div is
|
|
6
|
+
* handed to its own `createRoot`, so a story's own React version/context/
|
|
7
|
+
* error state can never leak into (or be affected by) the editor shell's
|
|
8
|
+
* tree — the same isolation a Storybook iframe gives you, achieved here with
|
|
9
|
+
* a dedicated root instead (this editor has no existing iframe-preview
|
|
10
|
+
* pattern to reuse — see the module doc comment on `StoriesPanel.tsx`).
|
|
11
|
+
*
|
|
12
|
+
* Error handling (spec §9 "Errors identify the source module and story
|
|
13
|
+
* export"): a story that throws while rendering is caught by
|
|
14
|
+
* `StoryPreviewErrorBoundary` (mirrors `ToolHost.tsx`'s `ToolErrorBoundary`)
|
|
15
|
+
* and reported with BOTH the module path and the story export name — one
|
|
16
|
+
* throwing story never takes down the panel or another story's preview.
|
|
17
|
+
*
|
|
18
|
+
* Play functions (spec §9 "supported play functions mount... optional but
|
|
19
|
+
* nice"): `runPlay` below calls the composed story's own `.play()` (Storybook
|
|
20
|
+
* populates it via `composeStories` when the CSF export declares one) inside
|
|
21
|
+
* the SAME error containment, so a throwing play function reports the same
|
|
22
|
+
* module+export naming instead of crashing the preview. `play()` is called
|
|
23
|
+
* with `{ canvasElement }` set to the isolated preview root's own container —
|
|
24
|
+
* without it, Storybook's portable-story `play()` defaults `canvasElement` to
|
|
25
|
+
* `document.body` (confirmed in `storybook/dist/preview-api/index.cjs`'s
|
|
26
|
+
* `composeStory`: `g.canvasElement ??= globalThis?.document?.body`), which
|
|
27
|
+
* would let a story's play() query/interact with the ENTIRE page instead of
|
|
28
|
+
* just its own isolated preview.
|
|
29
|
+
*
|
|
30
|
+
* Loaders (spec §9 "loaders ... mount through Storybook portable-story
|
|
31
|
+
* APIs"): a composed story only runs its `loaders` when `.load()` is
|
|
32
|
+
* explicitly awaited before render. Confirmed directly in Storybook 9's own
|
|
33
|
+
* `composeStory` (`storybook/dist/preview-api/index.cjs`): the render
|
|
34
|
+
* function reads a module-closure variable (`x`) for `loaded` data, and that
|
|
35
|
+
* variable is populated ONLY inside `load: async () => { ...; f.loaded =
|
|
36
|
+
* await c.applyLoaders(f); ...; x = f; }` — i.e. `applyLoaders` (which runs
|
|
37
|
+
* every `loaders` entry) never runs unless `.load()` itself runs first.
|
|
38
|
+
* Rendering the composed component directly (no `.load()`) leaves `loaded`
|
|
39
|
+
* as `{}`. `mountIsolatedStory` below is therefore async and awaits
|
|
40
|
+
* `StoryComponent.load()` before calling `root.render(...)`.
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
import { markGameCssScope } from '@volter/sdk/session/game-css-scope';
|
|
44
|
+
import { themeVars } from '@volter/sdk/widgets';
|
|
45
|
+
import { Component, type ErrorInfo, type ReactNode } from 'react';
|
|
46
|
+
import type { Root } from 'react-dom/client';
|
|
47
|
+
import type { ComposedStoryFn } from 'storybook/internal/types';
|
|
48
|
+
import { getCurrentProject } from '@volter/sdk/kit/project-manager';
|
|
49
|
+
import { ensureScopedGameStyles } from '@volter/sdk/kit/scoped-game-css';
|
|
50
|
+
import { resolveStoryDomRuntime } from '@volter/sdk/kit/stories/story-dom-runtime';
|
|
51
|
+
|
|
52
|
+
interface StoryPreviewErrorBoundaryProps {
|
|
53
|
+
modulePath: string;
|
|
54
|
+
storyName: string;
|
|
55
|
+
children: ReactNode;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
interface StoryPreviewErrorBoundaryState {
|
|
59
|
+
error: Error | null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Crash containment for one mounted story — names both the source module
|
|
63
|
+
* AND the story export in the fallback UI and the console, per spec §9. */
|
|
64
|
+
export class StoryPreviewErrorBoundary extends Component<
|
|
65
|
+
StoryPreviewErrorBoundaryProps,
|
|
66
|
+
StoryPreviewErrorBoundaryState
|
|
67
|
+
> {
|
|
68
|
+
override state: StoryPreviewErrorBoundaryState = { error: null };
|
|
69
|
+
|
|
70
|
+
static getDerivedStateFromError(error: Error): StoryPreviewErrorBoundaryState {
|
|
71
|
+
return { error };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
override componentDidCatch(error: Error, info: ErrorInfo): void {
|
|
75
|
+
// biome-ignore lint/suspicious/noConsole: deliberate, greppable — a crashed story preview must be diagnosable from the console (spec §9 "errors identify the source module and story export"), mirroring ToolHost.tsx's ToolErrorBoundary
|
|
76
|
+
console.error(
|
|
77
|
+
`[stories] ${this.props.modulePath} — story "${this.props.storyName}" crashed while rendering:`,
|
|
78
|
+
error,
|
|
79
|
+
info.componentStack,
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
override render(): ReactNode {
|
|
84
|
+
if (this.state.error) {
|
|
85
|
+
return (
|
|
86
|
+
<div style={{ padding: 12, fontSize: 12, color: themeVars.semantic.danger, maxWidth: 640 }}>
|
|
87
|
+
<div style={{ fontWeight: 600, marginBottom: 4 }}>
|
|
88
|
+
Story crashed: <code>{this.props.modulePath}</code> — export{' '}
|
|
89
|
+
<code>{this.props.storyName}</code>
|
|
90
|
+
</div>
|
|
91
|
+
<div style={{ whiteSpace: 'pre-wrap' }}>{String(this.state.error)}</div>
|
|
92
|
+
</div>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
return this.props.children;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** One container's isolated root plus a generation counter — see
|
|
100
|
+
* `mountIsolatedStory` below for why the counter (not just the `Root`
|
|
101
|
+
* object's identity) is what a stale `unmount()` must check. `root` is
|
|
102
|
+
* `undefined` for the brief window between a mount call CLAIMING a
|
|
103
|
+
* generation (synchronously) and that same call's `await
|
|
104
|
+
* StoryComponent.load()` resolving — no `Root` exists yet for a container
|
|
105
|
+
* that has never been rendered into before (the very first mount), so the
|
|
106
|
+
* reservation itself can't supply one. */
|
|
107
|
+
interface ContainerMount {
|
|
108
|
+
root: Root | undefined;
|
|
109
|
+
generation: number;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// One isolated `react-dom/client` root per container, reused across repeated
|
|
113
|
+
// `mountIsolatedStory` calls (e.g. a story switch: `StoriesPanel.tsx`'s
|
|
114
|
+
// `StoryPreviewHost` effect re-fires for the SAME DOM node with a new
|
|
115
|
+
// `StoryComponent`). Calling `createRoot` twice on the SAME node is a hard
|
|
116
|
+
// react-dom warning ("already been passed to createRoot() before") — this
|
|
117
|
+
// map is the guard: a second `mountIsolatedStory` on the same container
|
|
118
|
+
// `.render()`s onto the EXISTING root instead of creating a new one, exactly
|
|
119
|
+
// react-dom's own documented fix for that warning.
|
|
120
|
+
const mountsByContainer = new WeakMap<HTMLElement, ContainerMount>();
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Mount one composed story into `container` via its OWN `createRoot` —
|
|
124
|
+
* isolated from whatever React root `container` itself lives inside.
|
|
125
|
+
* Returns an `unmount` the caller runs on cleanup (e.g. story switch or
|
|
126
|
+
* panel close) — same lifecycle discipline every other editor mount point
|
|
127
|
+
* (`ToolHost`) uses. Safe to
|
|
128
|
+
* call again on the same `container` before a previous `unmount()` has
|
|
129
|
+
* landed (see `mountsByContainer` above) — the isolated root is reused, and
|
|
130
|
+
* `unmount()` (below) removes it from the container entirely rather than
|
|
131
|
+
* merely clearing its content, so callers who intend a REAL teardown (panel
|
|
132
|
+
* close) still get one.
|
|
133
|
+
*
|
|
134
|
+
* Async: awaits `StoryComponent.load()` (runs the story's `loaders`, per the
|
|
135
|
+
* module doc comment above) BEFORE the first render. The generation counter
|
|
136
|
+
* is claimed SYNCHRONOUSLY (before the `await`), exactly like the sync
|
|
137
|
+
* version did — so a second `mountIsolatedStory` call on the same container
|
|
138
|
+
* (e.g. the user switches stories again while this one's `.load()` is still
|
|
139
|
+
* in flight) still bumps the generation immediately and makes it visible to
|
|
140
|
+
* this in-flight call. After the await, this call re-reads the container's
|
|
141
|
+
* CURRENT generation and bails out (never creates/renders a root, never
|
|
142
|
+
* touches `mountsByContainer`) if it's no longer the current one — so a
|
|
143
|
+
* stale `.load()` resolving late can never win a render race against a
|
|
144
|
+
* newer story switch, even though nothing was mounted yet for it to
|
|
145
|
+
* unmount.
|
|
146
|
+
*/
|
|
147
|
+
export async function mountIsolatedStory(
|
|
148
|
+
container: HTMLElement,
|
|
149
|
+
modulePath: string,
|
|
150
|
+
storyName: string,
|
|
151
|
+
StoryComponent: ComposedStoryFn,
|
|
152
|
+
// W2 (story documents): optional per-mount prop overrides. Portable
|
|
153
|
+
// stories are plain React components whose composed args are DEFAULTS —
|
|
154
|
+
// Storybook's own documented portable-story contract lets a caller pass
|
|
155
|
+
// partial props over them (`<Story label="…" />`). The story-document
|
|
156
|
+
// Inspector's editable args and its action-logging spies ride this;
|
|
157
|
+
// omitted (every pre-W2 caller) the render is byte-identical to before.
|
|
158
|
+
overrideProps?: Record<string, unknown>,
|
|
159
|
+
): Promise<{ root: Root; unmount: () => void } | null> {
|
|
160
|
+
const existing = mountsByContainer.get(container);
|
|
161
|
+
// Bumped on EVERY mount, including a reuse of the same `Root` object (a
|
|
162
|
+
// story switch) — this is the piece a same-root reuse needs that plain
|
|
163
|
+
// `Root`-identity checking (an earlier version of this function) doesn't
|
|
164
|
+
// give you: reusing the root means two DIFFERENT stories' mounts can share
|
|
165
|
+
// the exact same `Root` instance, so a stale `unmount()` comparing
|
|
166
|
+
// `Root`s would see "yes, that's still the registered root" and tear down
|
|
167
|
+
// the NEWER story's render a moment after it landed. Comparing the
|
|
168
|
+
// generation this specific `mountIsolatedStory` call captured against the
|
|
169
|
+
// container's CURRENT generation instead correctly recognizes "a newer
|
|
170
|
+
// mount has since claimed this container" even when the root itself
|
|
171
|
+
// didn't change. Claimed HERE, synchronously, before the `load()` await
|
|
172
|
+
// below — so a newer call arriving while this one awaits sees (and bumps
|
|
173
|
+
// past) this generation immediately, rather than racing to claim the same
|
|
174
|
+
// number once both awaits resolve.
|
|
175
|
+
const generation = (existing?.generation ?? 0) + 1;
|
|
176
|
+
mountsByContainer.set(container, { root: existing?.root, generation });
|
|
177
|
+
|
|
178
|
+
// THE STORY'S OWN PAGE CSS, if its project has any. A story of a foreign
|
|
179
|
+
// game's HUD component is a plain React component whose entire layout lives
|
|
180
|
+
// in that game's page-level stylesheet — without it the card renders real
|
|
181
|
+
// DOM with zero layout, which reads as wreckage rather than as a component.
|
|
182
|
+
// This is the ONE seam every story surface passes through (the UI board's
|
|
183
|
+
// cards, the story documents, the editor's `screenshot <file>.stories.tsx` command), so
|
|
184
|
+
// marking the container here styles all of them; the sheet itself is
|
|
185
|
+
// installed once per project, never per card (`scoped-game-css.ts`).
|
|
186
|
+
// Deliberately awaited BEFORE the first render so a card never flashes
|
|
187
|
+
// unstyled, and deliberately non-fatal: a project with no declared
|
|
188
|
+
// stylesheet mounts exactly as it did before.
|
|
189
|
+
markGameCssScope(container);
|
|
190
|
+
const currentProject = getCurrentProject();
|
|
191
|
+
if (currentProject) await ensureScopedGameStyles(currentProject.rootPath);
|
|
192
|
+
|
|
193
|
+
// Loaders (spec §9): must run — and their `loaded` data become part of the
|
|
194
|
+
// composed story's render-time context — before the story is ever
|
|
195
|
+
// rendered. See the module doc comment for why this can't be skipped.
|
|
196
|
+
await StoryComponent.load();
|
|
197
|
+
|
|
198
|
+
// WHICH graph's react-dom mounts the story is the packaged-runtime seam
|
|
199
|
+
// (`story-dom-runtime.ts`): the CSF component's hooks resolve against the
|
|
200
|
+
// project's react, so the mounting `createRoot` must come from that same
|
|
201
|
+
// graph or the render dies on "Invalid hook call". Resolved BEFORE the
|
|
202
|
+
// generation re-check below, so the stale-call guard covers every await
|
|
203
|
+
// this call performs. (The error-boundary wrapper stays this bundle's own
|
|
204
|
+
// React deliberately: it is a class component — no hooks, no dispatcher —
|
|
205
|
+
// and React elements are cross-instance by design via Symbol.for.)
|
|
206
|
+
const { createRoot, flushSync } = await resolveStoryDomRuntime();
|
|
207
|
+
|
|
208
|
+
// Re-check AFTER the await: if a newer `mountIsolatedStory` call (story
|
|
209
|
+
// switch) has since claimed this container, its generation will have
|
|
210
|
+
// moved past `generation` above — this stale call must not create a root
|
|
211
|
+
// or render into a container a newer story already owns (or is about to).
|
|
212
|
+
const afterLoad = mountsByContainer.get(container);
|
|
213
|
+
if (!afterLoad || afterLoad.generation !== generation) return null;
|
|
214
|
+
|
|
215
|
+
const root = existing?.root ?? createRoot(container);
|
|
216
|
+
mountsByContainer.set(container, { root, generation });
|
|
217
|
+
|
|
218
|
+
// A resolved mount is a COMMITTED mount. The UI/2D boards await this
|
|
219
|
+
// function before announcing their document ready, and Doctor photographs
|
|
220
|
+
// that document immediately afterward. Leaving `root.render()` on React's
|
|
221
|
+
// scheduler produced a perfectly plausible empty board: its synchronous
|
|
222
|
+
// frame chrome existed, but every authored story was still absent. Use the
|
|
223
|
+
// `flushSync` from the SAME project-owned React graph as `createRoot` (the
|
|
224
|
+
// ordinary React design-time entry mount has the identical contract in
|
|
225
|
+
// `design-time-layers.ts`). This is not capture-specific waiting: every
|
|
226
|
+
// caller now receives the honest lifecycle guarantee its return value
|
|
227
|
+
// implies.
|
|
228
|
+
flushSync(() => {
|
|
229
|
+
root.render(
|
|
230
|
+
<StoryPreviewErrorBoundary modulePath={modulePath} storyName={storyName}>
|
|
231
|
+
{/* `ComposedStoryFn` is a callable React function component
|
|
232
|
+
(Storybook's portable-story contract) — its own composed
|
|
233
|
+
args/decorators are already baked in by `composeStories`;
|
|
234
|
+
`overrideProps` (when given) override individual args per that same
|
|
235
|
+
contract. */}
|
|
236
|
+
<StoryComponent {...(overrideProps ?? {})} />
|
|
237
|
+
</StoryPreviewErrorBoundary>,
|
|
238
|
+
);
|
|
239
|
+
});
|
|
240
|
+
return {
|
|
241
|
+
root,
|
|
242
|
+
// Deferred to a microtask, deliberately NOT called synchronously:
|
|
243
|
+
// `unmount` is returned as `StoryPreviewHost`'s effect cleanup, and
|
|
244
|
+
// React runs an effect's cleanup SYNCHRONOUSLY as part of its own
|
|
245
|
+
// render/commit pass whenever the OUTER tree unmounts (e.g. the whole
|
|
246
|
+
// Stories panel closing). React tracks "is any root currently
|
|
247
|
+
// rendering" as a single GLOBAL flag for the whole call stack
|
|
248
|
+
// (`executionContext`, react-dom-client.development.js) — so calling
|
|
249
|
+
// THIS (independent, inner) root's `.unmount()` synchronously from
|
|
250
|
+
// inside that outer pass trips "Attempted to synchronously unmount a
|
|
251
|
+
// root while React was already rendering" even though the inner root
|
|
252
|
+
// itself has nothing in flight. Queuing the call for the next microtask
|
|
253
|
+
// runs it once the outer commit has fully finished and cleared that
|
|
254
|
+
// flag, which is the documented fix for exactly this nested-root
|
|
255
|
+
// pattern (no functional delay — the isolated root is still torn down
|
|
256
|
+
// effectively immediately).
|
|
257
|
+
unmount: () => {
|
|
258
|
+
queueMicrotask(() => {
|
|
259
|
+
// Only the mount that's STILL the container's current generation
|
|
260
|
+
// actually tears the root down — see the `generation` doc comment
|
|
261
|
+
// above for why this can't just compare `Root` identity.
|
|
262
|
+
const current = mountsByContainer.get(container);
|
|
263
|
+
if (!current || current.generation !== generation || !current.root) return;
|
|
264
|
+
mountsByContainer.delete(container);
|
|
265
|
+
current.root.unmount();
|
|
266
|
+
});
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Run a composed story's `.play()` if it declared one, inside the same
|
|
273
|
+
* module+export-naming error containment as render crashes. Returns whether
|
|
274
|
+
* a play function existed and ran ok — the caller (`StoriesPanel`) uses this
|
|
275
|
+
* to show a "no play function" state distinctly from a failure.
|
|
276
|
+
*
|
|
277
|
+
* `canvasElement` is passed through to `.play({ canvasElement })` — the
|
|
278
|
+
* composed story's own `play` accepts `Partial<StoryContext>` (confirmed in
|
|
279
|
+
* `storybook/dist/types/index.d.ts`: `play?: (context?: Partial<StoryContext<...>>)
|
|
280
|
+
* => Promise<void>`, and `StoryContext.canvasElement: TRenderer['canvasElement']`).
|
|
281
|
+
* Without it, Storybook's `composeStory` defaults `canvasElement` to
|
|
282
|
+
* `globalThis.document.body` (`storybook/dist/preview-api/index.cjs`:
|
|
283
|
+
* `g.canvasElement ??= globalThis?.document?.body`), which would let a
|
|
284
|
+
* story's play() query/interact with the WHOLE page instead of just its own
|
|
285
|
+
* isolated preview root.
|
|
286
|
+
*/
|
|
287
|
+
export async function runStoryPlay(
|
|
288
|
+
modulePath: string,
|
|
289
|
+
storyName: string,
|
|
290
|
+
StoryComponent: ComposedStoryFn,
|
|
291
|
+
canvasElement: HTMLElement,
|
|
292
|
+
): Promise<{ ran: boolean; error?: string }> {
|
|
293
|
+
if (typeof StoryComponent.play !== 'function') return { ran: false };
|
|
294
|
+
try {
|
|
295
|
+
await StoryComponent.play({ canvasElement });
|
|
296
|
+
return { ran: true };
|
|
297
|
+
} catch (err) {
|
|
298
|
+
const message = String(err instanceof Error ? err.message : err);
|
|
299
|
+
// biome-ignore lint/suspicious/noConsole: deliberate, greppable — a throwing play() must be diagnosable from the console, same naming discipline as a render crash
|
|
300
|
+
console.error(`[stories] ${modulePath} — story "${storyName}"'s play() threw:`, err);
|
|
301
|
+
return {
|
|
302
|
+
ran: true,
|
|
303
|
+
error: `[stories] ${modulePath} — story "${storyName}"'s play() failed: ${message}`,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
}
|