@vgai/editor 0.2.0 → 0.4.0-canary.20260715.0
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/README.md +24 -0
- package/dist/assets/axe-C7YBtOuM.js +30 -0
- package/dist/assets/browserAll-DDtGGE48.js +1 -0
- package/dist/assets/create-runtime-DbTlBlKG.js +1 -0
- package/dist/assets/{game-BI111o5f.js → game-BE0r7DMI.js} +3 -3
- package/dist/assets/game-BdTHR2_X.js +1 -0
- package/dist/assets/{game-pt_1lQLv.js → game-C3iQGSqo.js} +1 -1
- package/dist/assets/game-CcHfYxjP.js +1 -0
- package/dist/assets/game-Cqzj_lpD.js +1 -0
- package/dist/assets/game-DSZdeCHu.js +1 -0
- package/dist/assets/game-Dch9sAPc.js +1 -0
- package/dist/assets/{game-xsOho_wg.js → game-SAFn90pA.js} +3 -3
- package/dist/assets/game-loop-DMIgSMV-.js +1 -0
- package/dist/assets/{game-source-CvidN7AB.js → game-source-Dk83w26t.js} +1 -1
- package/dist/assets/{index-Bp5cecD6.js → index-4idIsHHJ.js} +2 -2
- package/dist/assets/{index-DL7RcQ0n.js → index-C-LhOTBN.js} +1 -1
- package/dist/assets/{index-Cs8xwv3e.js → index-CDkxceqE.js} +1 -1
- package/dist/assets/index-CQEfi217.js +15412 -0
- package/dist/assets/index-Dvi-V0NE.css +1 -0
- package/dist/assets/ingest-siblings-s0P5I1Ub.js +1 -0
- package/dist/assets/mount-manifest-DXMOlF79.js +1 -0
- package/dist/assets/react-18-C9eHn8x1.js +1 -0
- package/dist/assets/webworkerAll-Fn0e-ouF.js +1 -0
- package/dist/assets/world-documents-GM0a9Kv7.js +1 -0
- package/dist/index.html +15 -13
- package/dist/ingest/racing-game/vgai.game.json +5 -4
- package/dist/ingest/simcity/vgai.game.json +5 -4
- package/dist/ingest/tanks/vgai.game.json +5 -4
- package/dist/project-scripts.bundle.js +3917 -0
- package/dist/scenes/untitled.vscn.json +2 -0
- package/dist-server/packaged.mjs +7697 -3435
- package/package.json +31 -4
- package/scripts/probe-reporter.ts +349 -0
- package/scripts/run-probe.ts +2260 -0
- package/server/asset-catalog-audit.ts +268 -0
- package/server/asset-catalog-v2.ts +146 -0
- package/server/asset-library-routes.ts +276 -58
- package/server/canonical-path.ts +1 -1
- package/server/dev.ts +148 -44
- package/server/editor-server.ts +888 -61
- package/server/editor-sse.ts +115 -4
- package/server/harness-chat-service.ts +796 -0
- package/server/local-asset-catalog.ts +157 -22
- package/server/packaged.ts +51 -21
- package/server/process-shutdown.ts +136 -0
- package/server/prod.ts +9 -6
- package/server/project-hmr-files.ts +41 -0
- package/server/project-operations.ts +343 -0
- package/server/project-optimize-deps-entries.ts +4 -4
- package/server/project-output-writer.ts +156 -0
- package/server/project-validation.ts +140 -0
- package/server/project-view.ts +8 -50
- package/server/server-utils.ts +75 -10
- package/server/session-registry.ts +12 -0
- package/src/EditorContext.tsx +107 -3
- package/src/action-registry.ts +115 -17
- package/src/adapter-resolver.ts +213 -478
- package/src/asset-events.ts +64 -1
- package/src/asset-preview.ts +906 -0
- package/src/asset-selection.ts +121 -0
- package/src/asset-workflow/asset-capabilities.ts +259 -0
- package/src/asset-workflow/asset-editor-errors.ts +46 -0
- package/src/asset-workflow/asset-import-pipeline.ts +176 -0
- package/src/asset-workflow/asset-library-query.ts +107 -0
- package/src/asset-workflow/asset-types.ts +192 -0
- package/src/asset-workflow/asset-workflow-quality.ts +65 -0
- package/src/asset-workflow/import-contract.ts +113 -0
- package/src/asset-workflow/model-conversion.ts +126 -0
- package/src/asset-workflow/model-inspection.ts +185 -0
- package/src/asset-workflow/project-asset-commands.ts +23 -0
- package/src/asset-workflow/project-asset-health.ts +153 -0
- package/src/asset-workflow/project-asset-operations.ts +119 -0
- package/src/asset-workflow/thumbnail-system.ts +172 -0
- package/src/authoring/active-systems.ts +15 -0
- package/src/authoring/boundary-authoring-adapter.ts +16 -5
- package/src/authoring/composite-authoring-adapter.ts +305 -124
- package/src/authoring/design-time-layers.ts +300 -117
- package/src/authoring/edit-mode-authoring.ts +278 -293
- package/src/authoring/embed-only-adapter.ts +4 -2
- package/src/authoring/first-party-hierarchy-menu.ts +7 -2
- package/src/authoring/first-party-inspector/AddSectionMenu.tsx +5 -12
- package/src/authoring/first-party-inspector/EnvironmentSection.tsx +53 -126
- package/src/authoring/first-party-inspector/HeaderSection.tsx +54 -65
- package/src/authoring/first-party-inspector/is-first-party-selection.ts +30 -11
- package/src/authoring/first-party-inspector/register.tsx +13 -2
- package/src/authoring/ingest-authoring-adapter.ts +142 -45
- package/src/authoring/mount-failure-report.ts +5 -5
- package/src/authoring/provenance.ts +41 -0
- package/src/authoring/react-dom-authoring-adapter.ts +92 -92
- package/src/authoring/react-inspector-section.tsx +489 -51
- package/src/authoring/react-world-authoring-adapter.ts +541 -306
- package/src/authoring/story-overlay.ts +1 -1
- package/src/authoring/story-types.ts +11 -0
- package/src/authoring/vgai-scene-authoring-adapter.ts +54 -25
- package/src/authoring/viewport-tool-context.ts +78 -0
- package/src/authoring/world-canvas-viewport-state.ts +35 -0
- package/src/authoring/world-hidden-viewport.ts +186 -0
- package/src/authoring/world-pan-state.ts +33 -17
- package/src/authoring/world-session-state.ts +1 -1
- package/src/authoring/world2d-authoring-adapter.ts +109 -52
- package/src/availability-tick.ts +56 -0
- package/src/browser-play-entry.ts +5 -5
- package/src/browser-project-scripts.ts +1 -0
- package/src/build-identity.ts +15 -0
- package/src/command-listener.ts +893 -19
- package/src/components/AlignToolbar.tsx +74 -63
- package/src/components/AppRoot.tsx +193 -26
- package/src/components/ApplicationMenus.tsx +272 -0
- package/src/components/AssetBrowser.tsx +1450 -293
- package/src/components/AssetEditorShell.tsx +141 -0
- package/src/components/AssetImportDetails.tsx +218 -0
- package/src/components/AssetLibraryPanel.tsx +14 -0
- package/src/components/CameraInfo.tsx +11 -20
- package/src/components/CenterDocuments.tsx +585 -0
- package/src/components/CommandPalette.tsx +75 -30
- package/src/components/ConsolePanel.css +55 -0
- package/src/components/ConsolePanel.tsx +57 -112
- package/src/components/DebugConsolePanel.tsx +461 -0
- package/src/components/DebuggerPanel.tsx +165 -0
- package/src/components/DefaultEditorLayout.tsx +167 -231
- package/src/components/GameHierarchy.tsx +873 -290
- package/src/components/GamePerformanceOverlay.tsx +46 -0
- package/src/components/HarnessChatPanel.tsx +2352 -0
- package/src/components/HistoryPanel.tsx +226 -0
- package/src/components/Inspector.tsx +153 -99
- package/src/components/InspectorToolSection.tsx +6 -4
- package/src/components/MountFailureBanner.tsx +31 -48
- package/src/components/NetworkSection.tsx +25 -14
- package/src/components/OnlineAssetBrowser.tsx +794 -343
- package/src/components/OverlayReportBanner.tsx +38 -64
- package/src/components/PerformancePanel.tsx +206 -0
- package/src/components/PlayBar.tsx +93 -263
- package/src/components/PrefabSaveDialog.tsx +55 -127
- package/src/components/ProjectHeader.css +60 -0
- package/src/components/ProjectHeader.tsx +170 -105
- package/src/components/ProjectScreen.tsx +246 -184
- package/src/components/ReactCanvasControls.tsx +185 -0
- package/src/components/ResolutionPicker.tsx +85 -0
- package/src/components/RootActivateDialog.tsx +39 -68
- package/src/components/SaveDialog.tsx +55 -127
- package/src/components/SaveStatus.tsx +11 -29
- package/src/components/StartupLoadingScreen.tsx +96 -0
- package/src/components/StateWatchPanel.tsx +302 -0
- package/src/components/StatsOverlay.tsx +12 -5
- package/src/components/StatusBar.tsx +64 -0
- package/src/components/ThemeManagerDialog.css +89 -0
- package/src/components/ThemeManagerDialog.tsx +371 -0
- package/src/components/ToolHost.tsx +26 -15
- package/src/components/Toolbar.tsx +117 -214
- package/src/components/VgaiVoxelLogo.tsx +89 -0
- package/src/components/ViewportOverlay.tsx +97 -172
- package/src/components/ViewportPanel.tsx +130 -31
- package/src/components/WorkspaceDock.tsx +891 -0
- package/src/components/WorldSelectionOverlay.tsx +51 -63
- package/src/components/WorldTextEditor.tsx +9 -5
- package/src/components/asset-documents.tsx +390 -0
- package/src/components/asset-editor-persistence.ts +44 -0
- package/src/components/asset-selection-section.tsx +338 -0
- package/src/components/asset-viewers/AudioViewer.tsx +73 -21
- package/src/components/asset-viewers/GenericJsonViewer.tsx +26 -11
- package/src/components/asset-viewers/ImageViewer.tsx +43 -11
- package/src/components/asset-viewers/InputMapViewer.tsx +512 -134
- package/src/components/asset-viewers/MaterialAssetEditor.tsx +540 -0
- package/src/components/asset-viewers/ModelViewer.tsx +805 -121
- package/src/components/asset-viewers/OnlineAssetDetail.tsx +177 -60
- package/src/components/asset-viewers/SourceAssetViewer.tsx +121 -0
- package/src/components/asset-workflow.css +506 -0
- package/src/components/build-documents.tsx +696 -0
- package/src/components/core-utilities.tsx +75 -0
- package/src/components/data-documents.tsx +364 -0
- package/src/components/{DataPanel.tsx → data-editor.tsx} +138 -288
- package/src/components/debugger-panel-state.ts +57 -0
- package/src/components/inspector-widgets/AlignmentGrid.tsx +8 -14
- package/src/components/inspector-widgets/BorderEditor.tsx +41 -33
- package/src/components/inspector-widgets/ColorPicker.tsx +39 -39
- package/src/components/inspector-widgets/FontPicker.tsx +13 -21
- package/src/components/inspector-widgets/GradientEditor.tsx +11 -19
- package/src/components/inspector-widgets/ScrubbableInput.tsx +6 -3
- package/src/components/inspector-widgets/ShadowEditor.tsx +20 -33
- package/src/components/inspector-widgets/shared.tsx +90 -49
- package/src/components/inspectors/AnimationSection.tsx +39 -40
- package/src/components/inspectors/AudioSection.tsx +28 -39
- package/src/components/inspectors/BoneAttachmentSection.tsx +19 -24
- package/src/components/inspectors/CameraSection.tsx +14 -23
- package/src/components/inspectors/ComponentsSection.tsx +39 -43
- package/src/components/inspectors/JointsSection.tsx +34 -43
- package/src/components/inspectors/LightSection.tsx +90 -35
- package/src/components/inspectors/MaterialSection.tsx +137 -174
- package/src/components/inspectors/MeshSection.tsx +9 -17
- package/src/components/inspectors/NavigationSection.tsx +8 -15
- package/src/components/inspectors/ParticleSection.tsx +91 -76
- package/src/components/inspectors/PhysicsSection.tsx +42 -46
- package/src/components/inspectors/PostProcessingSection.tsx +28 -36
- package/src/components/inspectors/RenderingSection.tsx +12 -20
- package/src/components/inspectors/ShadowSection.tsx +7 -8
- package/src/components/inspectors/SplineSection.tsx +31 -42
- package/src/components/inspectors/TransformSection.tsx +14 -22
- package/src/components/patterns/Dialog.tsx +95 -0
- package/src/components/patterns/Fields.tsx +44 -0
- package/src/components/patterns/List.tsx +25 -0
- package/src/components/patterns/StateSurface.tsx +40 -0
- package/src/components/patterns/Surfaces.tsx +115 -0
- package/src/components/patterns/Tabs.tsx +80 -0
- package/src/components/patterns/Toolbar.tsx +51 -0
- package/src/components/patterns/Tree.tsx +72 -0
- package/src/components/primitives/Button.tsx +46 -0
- package/src/components/primitives/ColorInput.tsx +11 -47
- package/src/components/primitives/EditorIcon.tsx +99 -0
- package/src/components/primitives/FormControls.tsx +71 -0
- package/src/components/primitives/JsonInput.tsx +15 -2
- package/src/components/primitives/Layout.tsx +100 -0
- package/src/components/primitives/Menu.tsx +105 -0
- package/src/components/primitives/NumberInput.tsx +8 -35
- package/src/components/primitives/Panel.tsx +49 -44
- package/src/components/primitives/SectionHeader.tsx +10 -28
- package/src/components/primitives/Text.tsx +46 -0
- package/src/components/primitives/Tooltip.tsx +20 -12
- package/src/components/primitives/Vec3Input.tsx +3 -0
- package/src/components/primitives/banner-tones.ts +33 -0
- package/src/components/primitives/editor-icons.ts +102 -0
- package/src/components/primitives/panel-header-styles.ts +30 -0
- package/src/components/project-operation-documents.tsx +226 -0
- package/src/components/status-contributions.tsx +175 -0
- package/src/components/story-documents-register.ts +15 -0
- package/src/components/story-documents.tsx +1185 -0
- package/src/components/tool-documents.tsx +110 -0
- package/src/components/workspace-dock.css +293 -0
- package/src/components/workspace-history.ts +33 -0
- package/src/components/world-documents.tsx +145 -0
- package/src/components/xstate-documents.tsx +209 -0
- package/src/composite-screenshot.ts +248 -0
- package/src/design-system/index.ts +70 -0
- package/src/design-system-stories/Foundation.stories.tsx +183 -0
- package/src/design-system-stories/Patterns.stories.tsx +251 -0
- package/src/design-system-stories/Workspace.stories.tsx +538 -0
- package/src/doctor/report.ts +57 -13
- package/src/editor-api.ts +295 -31
- package/src/editor-compatibility.ts +200 -0
- package/src/editor-console.ts +35 -17
- package/src/editor-hotkeys.ts +85 -33
- package/src/editor-store.ts +538 -233
- package/src/editor-viewport.ts +160 -34
- package/src/entity-factory.ts +14 -3
- package/src/gizmo-registry.ts +21 -5
- package/src/harness-chat-editor-context.ts +37 -0
- package/src/harness-chat-indicator.ts +68 -0
- package/src/harness-chat-layout.ts +53 -0
- package/src/harness-chat-lifecycle.ts +170 -0
- package/src/harness-chat-reconnect.ts +85 -0
- package/src/harness-chat-types.ts +409 -0
- package/src/hierarchy-drop.ts +50 -0
- package/src/hierarchy-expansion-state.ts +100 -0
- package/src/hierarchy-menu-registry.ts +1 -1
- package/src/hierarchy-projection.ts +76 -0
- package/src/history/editor-session.ts +21 -0
- package/src/history/history-commands.ts +147 -0
- package/src/history/history-service.ts +904 -0
- package/src/history/json-history-resource.ts +165 -0
- package/src/history/persistence-coordinator.ts +35 -0
- package/src/history/project-file-history.ts +266 -0
- package/src/history/project-root-history-backends.ts +53 -0
- package/src/history/resource-registry.ts +209 -0
- package/src/history/snapshot-store.ts +108 -0
- package/src/history/source-history-backend.ts +374 -0
- package/src/history/types.ts +100 -0
- package/src/hmr-registration-group.ts +67 -0
- package/src/hmr-stable-react-context.ts +23 -0
- package/src/hosted-example.ts +12 -2
- package/src/hotkeys.ts +89 -18
- package/src/ingest/discovery-react.ts +9 -10
- package/src/ingest/discovery.ts +4 -4
- package/src/ingest/discovery2d.ts +5 -5
- package/src/ingest/games/bloom-composer/vgai.game.json +3 -3
- package/src/ingest/games/embed-bundle/vgai.game.json +3 -3
- package/src/ingest/games/games-fps/vgai.game.json +3 -3
- package/src/ingest/games/iframe-reachable/vgai.game.json +3 -3
- package/src/ingest/games/interactive-cubes/vgai.game.json +3 -3
- package/src/ingest/games/mismatched-three/vgai.game.json +3 -3
- package/src/ingest/games/own-three-bundled/vgai.game.json +3 -3
- package/src/ingest/games/pointerlock-maze/vgai.game.json +7 -4
- package/src/ingest/games-2d/bubbo-bubbo/vgai.game.json +3 -3
- package/src/ingest/games-2d/bunnymark/vgai.game.json +3 -3
- package/src/ingest/games-2d/flappy/vgai.game.json +3 -3
- package/src/ingest/games-2d/flappy-pixi/vgai.game.json +3 -3
- package/src/ingest/games-2d/puzzling-potions/vgai.game.json +3 -3
- package/src/ingest/games-2d/tilemap-camera/vgai.game.json +3 -3
- package/src/ingest/games-react/react-rpg/vgai.game.json +3 -3
- package/src/ingest/types.ts +1 -1
- package/src/ingest-mode.ts +47 -52
- package/src/ingest-siblings.ts +23 -33
- package/src/initial-scene.ts +1 -2
- package/src/main.tsx +16 -8
- package/src/manifest-project.ts +10 -12
- package/src/model-thumbnail.ts +261 -26
- package/src/module-mode.ts +44 -50
- package/src/play-log-events.ts +26 -0
- package/src/play-mode.ts +495 -401
- package/src/play-scene-adoption.ts +23 -0
- package/src/playground/main.ts +68 -24
- package/src/playwright-shim.ts +473 -0
- package/src/project-manager.ts +90 -10
- package/src/project-operations.ts +112 -0
- package/src/project-story-discovery.ts +25 -0
- package/src/project-tool-discovery.ts +43 -0
- package/src/scene-serializer.ts +0 -6
- package/src/scene-sync.ts +7 -2
- package/src/script-loader.ts +3 -3
- package/src/skeleton-helper.ts +57 -0
- package/src/storage/seed.ts +68 -8
- package/src/stories/StoryPreviewMount.tsx +265 -0
- package/src/stories/action-stories.fixture.tsx +44 -0
- package/src/stories/button-stories.fixture.tsx +50 -0
- package/src/stories/compose-project-stories.ts +182 -0
- package/src/stories/loader-stories.fixture.tsx +53 -0
- package/src/stories/story-discovery.ts +130 -0
- package/src/stories/story-registry.ts +146 -0
- package/src/theme-css.ts +1049 -0
- package/src/theme-library.ts +238 -0
- package/src/theme-preference.ts +130 -0
- package/src/theme.ts +527 -0
- package/src/tool-loader.ts +80 -24
- package/src/ui-source/inspect.ts +27 -4
- package/src/ui-source/source-write-backend.ts +83 -22
- package/src/widgets/index.ts +9 -18
- package/src/workspace-aux-commands.ts +11 -0
- package/src/workspace-dock-controller.ts +64 -0
- package/src/workspace-document-ids.ts +5 -0
- package/src/workspace-document-registry.ts +367 -0
- package/src/workspace-state-persistence.ts +455 -0
- package/src/workspace-status-registry.ts +110 -0
- package/src/workspace-utility-commands.ts +49 -0
- package/src/workspace-utility-registry.ts +161 -0
- package/src/world-document-routing.ts +16 -0
- package/src/xstate-inspect/XStateMachineInspector.tsx +544 -0
- package/src/xstate-inspect/character-animation-machine.fixture.ts +74 -0
- package/src/xstate-inspect/use-live-actor-state.ts +39 -0
- package/src/xstate-inspect/xstate-graph.ts +265 -0
- package/src/xstate-inspect/xstate-layout.ts +76 -0
- package/src/z-index.ts +26 -0
- package/template/.claude/skills/editor/SKILL.md +129 -90
- package/template/AGENTS.md +1110 -0
- package/template/CLAUDE.md +1 -512
- package/template/IDIOMS.md +50 -0
- package/template/check-idioms.ts +706 -0
- package/template/manifest-entry-modules-plugin.ts +53 -0
- package/template/package.json +13 -4
- package/template/public/scenes/default.scn2d.json +6 -0
- package/template/public/scenes/default.vscn.json +7 -1
- package/template/public/scenes/untitled.vscn.json +10 -0
- package/template/scripts/playtest.ts +40 -0
- package/template/server/loopback.ts +75 -0
- package/template/server/rooms/arena-room.ts +69 -1
- package/template/server/rooms/game-room.ts +68 -1
- package/template/src/data/README.md +9 -4
- package/template/src/data/data-ref.ts +35 -0
- package/template/src/data/tuning.schema.ts +1 -1
- package/template/src/main.ts +41 -62
- package/template/src/manifest-entry-modules.d.ts +3 -0
- package/template/src/operations/README.md +88 -0
- package/template/src/runtime/pixi-adapter.ts +24 -0
- package/template/src/scripts/components/data-spinner.ts +43 -2
- package/template/src/scripts/components/spin-lap-math.ts +27 -0
- package/template/src/tools/README.md +5 -3
- package/template/src/tools/example.tool.tsx +13 -7
- package/template/src/ui/Button.stories.tsx +66 -0
- package/template/src/ui/RebindPanel.tsx +2 -6
- package/template/src/ui/game.tsx +17 -0
- package/template/tests/acceptance/example.spec.ts +64 -0
- package/template/tests/logic/example.test.ts +31 -0
- package/template/tests/logic/room.test.ts +100 -0
- package/template/tests/tsconfig.json +30 -0
- package/template/validate-manifest.ts +5 -5
- package/template/validate-scenes.ts +50 -18
- package/template/vgai.game.json +20 -13
- package/template/vite.config.ts +77 -16
- package/vite-plugin-ui-oid.ts +261 -17
- package/dist/assets/CCDIKSolver-Dz-ysxZF.js +0 -1
- package/dist/assets/SelectionBox-BXsv_6aH.js +0 -1
- package/dist/assets/browser-project-scripts-DOru4L1x.js +0 -2
- package/dist/assets/browserAll-CEkWYlFk.js +0 -1
- package/dist/assets/create-runtime-DYIWr3va.js +0 -1
- package/dist/assets/data-asset-Bb9sIM7i.js +0 -5
- package/dist/assets/game-8SDZPPgH.js +0 -1
- package/dist/assets/game-CevorxyV.js +0 -1
- package/dist/assets/game-Di7XlywD.js +0 -1
- package/dist/assets/game-DjnCaw8R.js +0 -1
- package/dist/assets/game-Q9A0aXSV.js +0 -1
- package/dist/assets/index-CPVV6pjw.js +0 -1
- package/dist/assets/index-CpOnYyeD.js +0 -213
- package/dist/assets/index-Dr8H_6Rl.js +0 -1
- package/dist/assets/index-_bCaipUk.js +0 -13650
- package/dist/assets/ingest-siblings-Dz8eEqrV.js +0 -1
- package/dist/assets/mount-manifest-Bhk0ohsl.js +0 -1
- package/dist/assets/scene-query-BivAHhJu.js +0 -1
- package/dist/assets/webworkerAll-BLrH0F6F.js +0 -1
- package/dist/assets/xstate-animation-binding-1NGLmw6y.js +0 -1
- package/dist/assets/xstate.esm-BgUD33nl.js +0 -3
- package/src/authoring/scene-ui-layer.ts +0 -485
- package/src/authoring/ui-authoring-adapter.ts +0 -325
- package/src/authoring/ui-hierarchy-menu.ts +0 -40
- package/src/authoring/ui-inspector-sections.tsx +0 -156
- package/src/authoring/undo-timeline.ts +0 -145
- package/src/components/BottomPanel.tsx +0 -326
- package/src/components/BuildPanel.tsx +0 -455
- package/src/components/FolderTree.tsx +0 -179
- package/src/components/RightPanel.tsx +0 -166
- package/src/components/WorldContextMenu.tsx +0 -257
- package/src/components/asset-viewers/AssetViewer.tsx +0 -38
- package/src/ingest/games-react/react-rpg/src/ui/game-state.tsx +0 -129
- package/src/scene-ui-mode/active-scene-ui.ts +0 -58
- package/src/scene-ui-mode/scene-ui-palette-panel.tsx +0 -152
- package/src/scene-ui-mode/scene-ui-timeline-tab.tsx +0 -29
- package/src/scene-ui-mode/ui-prefab-dialog-host.tsx +0 -74
- package/src/scene-ui-mode/ui-prefab-hierarchy-menu.ts +0 -49
- package/src/scene-ui-mode/ui-prefab-io.ts +0 -76
- package/src/ui-editor/inspector.tsx +0 -563
- package/src/ui-editor/node-ops.ts +0 -266
- package/src/ui-editor/overlay.tsx +0 -380
- package/src/ui-editor/palette.tsx +0 -114
- package/src/ui-editor/react-store.ts +0 -78
- package/src/ui-editor/timeline-panel.tsx +0 -443
- package/src/ui-editor/ui-edit-store.ts +0 -552
- package/src/ui-editor/ui-prefab.ts +0 -95
- package/template/project.json +0 -9
- package/template/src/scripts/main.ts +0 -94
- package/template/src/ui/DefaultHud.tsx +0 -40
- package/template/src/ui/game-state.tsx +0 -37
- package/template/src/ui/mount-default-hud.tsx +0 -19
- package/template/src/ui/mount-ui.ts +0 -15
- package/vite-plugin-react-world-provider.ts +0 -81
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The editor's built-in DRAWER utilities, registered through the same
|
|
3
|
+
* W0 workspace-utility registry every other utility uses, so Dockview's
|
|
4
|
+
* bottom edge group is registry-driven end to end:
|
|
5
|
+
*
|
|
6
|
+
* - **Console** (B3): always available; its error/warn count becomes the
|
|
7
|
+
* registry `badge()` (rendered on the collapsed tab — the badge, never
|
|
8
|
+
* an auto-open, is how log entries call for attention; only actionable
|
|
9
|
+
* save failures reveal it automatically).
|
|
10
|
+
* - **Debugger**: persistent instrument container. Profiler, State,
|
|
11
|
+
* Network, Machines, and Commands remain discoverable; views without a
|
|
12
|
+
* live source show an honest empty state.
|
|
13
|
+
*
|
|
14
|
+
* PROBLEMS (§4.1 mock's `Problems` tab) is deliberately NOT registered —
|
|
15
|
+
* the W4 decision, recorded in the inventory: no truthful problem SOURCE
|
|
16
|
+
* exists today (there is no in-editor typecheck surface; scene-validation
|
|
17
|
+
* failures already surface as console errors + the MountFailureBanner), and
|
|
18
|
+
* §4.3's spirit forbids fabricating a surface with nothing real to feed it.
|
|
19
|
+
* The status bar's error count (`status-contributions.tsx`) reads the
|
|
20
|
+
* console counts — the truthful signal that does exist. A real Problems
|
|
21
|
+
* utility lands when a real diagnostics source does.
|
|
22
|
+
*
|
|
23
|
+
* Idempotent-ensure idiom mirrors `build-documents.tsx`'s
|
|
24
|
+
* `ensureBuildContributionsRegistered`.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { editorConsole } from '../editor-console';
|
|
28
|
+
import { createHmrRegistrationGroup } from '../hmr-registration-group';
|
|
29
|
+
import {
|
|
30
|
+
registerWorkspaceUtility,
|
|
31
|
+
type WorkspaceUtilityBadge,
|
|
32
|
+
} from '../workspace-utility-registry';
|
|
33
|
+
import { ConsolePanel } from './ConsolePanel';
|
|
34
|
+
import { DebuggerPanel } from './DebuggerPanel';
|
|
35
|
+
|
|
36
|
+
const registrationGroup = createHmrRegistrationGroup(import.meta.hot, 'core-utilities');
|
|
37
|
+
|
|
38
|
+
/** The Console tab's attention badge: error count (error severity) else
|
|
39
|
+
* warn count (warn severity) else none. Exported for tests. */
|
|
40
|
+
export function consoleUtilityBadge(): WorkspaceUtilityBadge | null {
|
|
41
|
+
const { error, warn } = editorConsole.counts;
|
|
42
|
+
if (error > 0) return { count: error + warn, severity: 'error' };
|
|
43
|
+
if (warn > 0) return { count: warn, severity: 'warn' };
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Idempotent one-time registration of the built-in workspace utilities. */
|
|
48
|
+
export function ensureCoreUtilitiesRegistered(): void {
|
|
49
|
+
registrationGroup.ensure((track) => {
|
|
50
|
+
track(
|
|
51
|
+
registerWorkspaceUtility({
|
|
52
|
+
id: 'console',
|
|
53
|
+
title: 'Console',
|
|
54
|
+
order: -100, // first utility tab, matching the §4.1 mock's tab order
|
|
55
|
+
Content: ConsolePanel,
|
|
56
|
+
badge: consoleUtilityBadge,
|
|
57
|
+
subscribeBadge: editorConsole.subscribe,
|
|
58
|
+
badgeSnapshot: editorConsole.getSnapshot,
|
|
59
|
+
}),
|
|
60
|
+
);
|
|
61
|
+
track(
|
|
62
|
+
registerWorkspaceUtility({
|
|
63
|
+
id: 'debugger',
|
|
64
|
+
title: 'Debugger',
|
|
65
|
+
order: 20,
|
|
66
|
+
Content: DebuggerPanel,
|
|
67
|
+
}),
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Test-only: allow re-registration after a registry reset. */
|
|
73
|
+
export function __resetCoreUtilitiesForTest(): void {
|
|
74
|
+
registrationGroup.reset();
|
|
75
|
+
}
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
import { themeVars } from '../design-system';
|
|
2
|
+
/**
|
|
3
|
+
* Data DOCUMENTS (W3, docs/EDITOR-WORKSPACE-SHELL-TODO.md §5/§9 W3 —
|
|
4
|
+
* inventory row B5): each `src/data/*.data.json` opens as a NAMED center
|
|
5
|
+
* form/table document (kind `'data'`, title = the file's own name per §8,
|
|
6
|
+
* e.g. `tuning.data.json`), replacing the permanent bottom DATA tab. The
|
|
7
|
+
* editing machinery itself is unchanged (`data-editor.tsx`, formerly
|
|
8
|
+
* `DataPanel.tsx`) — same emitted-schema widget pipeline, same D1
|
|
9
|
+
* write-immediately semantics through the SAME write path (history-service
|
|
10
|
+
* `write` when available, raw `/__editor/data-file` POST otherwise), same
|
|
11
|
+
* `$schema`-first key-order-preserving serialization. DATA-TOOLS-DESIGN's
|
|
12
|
+
* transaction rules stay authoritative.
|
|
13
|
+
*
|
|
14
|
+
* DISCOVERY (the B5 "record which" decision): the old tab's master file list
|
|
15
|
+
* folds into existing navigation — the COMMAND PALETTE lists one
|
|
16
|
+
* `Open Data Asset: <name>` action per discovered file (live folder-scan
|
|
17
|
+
* store, refreshed at editor init + on W6a's add/unlink SSE events), plus a
|
|
18
|
+
* static `Data Assets` action opening a small navigation/teaching document
|
|
19
|
+
* (the file list; the W6d empty state when the project has none). Data is a
|
|
20
|
+
* typed project resource, not a permanent navigator tab; these named center
|
|
21
|
+
* documents remain its authoring surface.
|
|
22
|
+
*
|
|
23
|
+
* Loaded-file state is a module-scope store (house `useSyncExternalStore`
|
|
24
|
+
* shape) rather than per-component state so every data document, the guide
|
|
25
|
+
* document, and the palette actions read ONE folder-scan truth — exactly the
|
|
26
|
+
* D3 "discovery IS the folder scan" physics the panel had, shared.
|
|
27
|
+
*
|
|
28
|
+
* Selected-row-details-in-Inspector (§5's "may") is deliberately NOT built
|
|
29
|
+
* this wave — the wide center grid already gives every cell a real widget;
|
|
30
|
+
* a second Inspector-hosted detail form would be a new master-detail
|
|
31
|
+
* mechanism with no demand signal yet. Recorded as a deferral, not a gap.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
import { useEffect, useSyncExternalStore } from 'react';
|
|
35
|
+
import type { EditorAction } from '../action-registry';
|
|
36
|
+
import { connectDataFileEvents } from '../asset-events';
|
|
37
|
+
import { EditorListButton } from '../design-system';
|
|
38
|
+
import { getProjectFileHistory, type ProjectFileHistory } from '../history/project-file-history';
|
|
39
|
+
import { getDataHistoryBackend } from '../history/project-root-history-backends';
|
|
40
|
+
import {
|
|
41
|
+
openWorkspaceDocument,
|
|
42
|
+
type WorkspaceDocumentContentProps,
|
|
43
|
+
} from '../workspace-document-registry';
|
|
44
|
+
import {
|
|
45
|
+
DataEmptyState,
|
|
46
|
+
DataFileEditor,
|
|
47
|
+
type LoadedDataFile,
|
|
48
|
+
nextKeyOrder,
|
|
49
|
+
parseServerFile,
|
|
50
|
+
RefOptionsContext,
|
|
51
|
+
type ServerDataFile,
|
|
52
|
+
serializeDataFile,
|
|
53
|
+
} from './data-editor';
|
|
54
|
+
import { workspaceHistoryService } from './workspace-history';
|
|
55
|
+
|
|
56
|
+
// --- The shared loaded-files store (one folder-scan truth) -----------------
|
|
57
|
+
|
|
58
|
+
let _files: LoadedDataFile[] = [];
|
|
59
|
+
let _version = 0;
|
|
60
|
+
const _listeners = new Set<() => void>();
|
|
61
|
+
|
|
62
|
+
function notifyChanged(): void {
|
|
63
|
+
_version++;
|
|
64
|
+
for (const fn of _listeners) fn();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Subscribe to loaded-data-file changes. Returns unsubscribe. */
|
|
68
|
+
export function subscribeDataFiles(fn: () => void): () => void {
|
|
69
|
+
_listeners.add(fn);
|
|
70
|
+
return () => {
|
|
71
|
+
_listeners.delete(fn);
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Monotonic change counter — the `getSnapshot` for `useSyncExternalStore`. */
|
|
76
|
+
export function dataFilesVersion(): number {
|
|
77
|
+
return _version;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** The currently loaded data files (stable reference between changes). */
|
|
81
|
+
export function loadedDataFiles(): readonly LoadedDataFile[] {
|
|
82
|
+
return _files;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Re-run the folder scan (`GET /__editor/data-files`) — D3: discovery IS
|
|
86
|
+
* the folder scan, never a cached manifest. Server unreachable keeps the
|
|
87
|
+
* last snapshot (same physics as the old panel's `refresh`). */
|
|
88
|
+
export async function refreshDataFiles(): Promise<void> {
|
|
89
|
+
try {
|
|
90
|
+
const res = await fetch('/__editor/data-files');
|
|
91
|
+
if (!res.ok) return;
|
|
92
|
+
const { files: raw } = (await res.json()) as { files: ServerDataFile[] };
|
|
93
|
+
_files = raw.map(parseServerFile);
|
|
94
|
+
notifyChanged();
|
|
95
|
+
} catch {
|
|
96
|
+
/* server unreachable — keep whatever we last had */
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Editor-init discovery lifecycle (same B13 physics as project-tool
|
|
102
|
+
* discovery): initial scan + re-scan on W6a's add/unlink SSE events (a
|
|
103
|
+
* `change` event is deliberately not broadcast by the server — it would echo
|
|
104
|
+
* this module's own POST writes back into a refetch, clobbering in-flight
|
|
105
|
+
* drafts). Returns a cleanup that detaches the SSE listener.
|
|
106
|
+
*/
|
|
107
|
+
export function startDataAssetDiscovery(): () => void {
|
|
108
|
+
void refreshDataFiles();
|
|
109
|
+
return connectDataFileEvents(() => void refreshDataFiles());
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Test-only reset. */
|
|
113
|
+
export function __resetDataFilesForTest(): void {
|
|
114
|
+
_files = [];
|
|
115
|
+
notifyChanged();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// --- Writes (the D1 path, verbatim from the old panel) ---------------------
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* D1 (spec §2.5): commit → write the file IMMEDIATELY, no buffering. The
|
|
122
|
+
* local store copy is updated in the same tick so widgets stay live; disk is
|
|
123
|
+
* the document. D5 resolution: this deliberately BYPASSES the play-mode
|
|
124
|
+
* overlay (scene-entity-only) — a running game receives the change through
|
|
125
|
+
* the shipped `.data.json` HMR path instead. `nextKeyOrder` folds the
|
|
126
|
+
* commit's keys into the file's current on-disk order once, and the result
|
|
127
|
+
* becomes this file's `keyOrder` going forward, so a whole session of edits
|
|
128
|
+
* keeps the original key order (integer-like keys included) stable.
|
|
129
|
+
*/
|
|
130
|
+
export function commitDataFile(
|
|
131
|
+
file: LoadedDataFile,
|
|
132
|
+
nextData: Record<string, unknown>,
|
|
133
|
+
fileHistory: ProjectFileHistory | null,
|
|
134
|
+
): void {
|
|
135
|
+
const order = nextKeyOrder(file.keyOrder, nextData);
|
|
136
|
+
const content = serializeDataFile(nextData, order);
|
|
137
|
+
_files = _files.map((f) =>
|
|
138
|
+
f.path === file.path ? { ...f, data: nextData, keyOrder: order } : f,
|
|
139
|
+
);
|
|
140
|
+
notifyChanged();
|
|
141
|
+
if (!fileHistory) {
|
|
142
|
+
void fetch('/__editor/data-file', {
|
|
143
|
+
method: 'POST',
|
|
144
|
+
headers: { 'Content-Type': 'application/json' },
|
|
145
|
+
body: JSON.stringify({ path: file.path, content }),
|
|
146
|
+
});
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
void fileHistory
|
|
150
|
+
.write(file.path, content, {
|
|
151
|
+
label: `Edit ${file.path.split('/').pop() ?? 'Data'}`,
|
|
152
|
+
kind: 'data',
|
|
153
|
+
contentType: 'application/json',
|
|
154
|
+
})
|
|
155
|
+
.catch(() => void refreshDataFiles());
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// --- Documents --------------------------------------------------------------
|
|
159
|
+
|
|
160
|
+
/** The narrow store surface data documents need (T6.3 gate hand-off — same
|
|
161
|
+
* contract as `asset-documents.tsx`). */
|
|
162
|
+
export interface DataDocumentStore {
|
|
163
|
+
setActiveViewportTab(tab: 'scene' | 'game'): void;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Stable §7.1 identity for one data-asset document. */
|
|
167
|
+
export function dataDocumentId(path: string): string {
|
|
168
|
+
return `data:${path}`;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** The navigation/teaching `Data Assets` document's id. */
|
|
172
|
+
export const DATA_ASSETS_DOCUMENT_ID = 'workspace:data-assets';
|
|
173
|
+
|
|
174
|
+
/** §8 source-owned title: the file's own basename (`tuning.data.json`). */
|
|
175
|
+
export function dataDocumentTitle(path: string): string {
|
|
176
|
+
return path.split('/').pop() ?? path;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Open (or activate) the center form/table document for one data asset.
|
|
181
|
+
* Never fabricates: the document renders a plain "no longer on disk" message
|
|
182
|
+
* if the file disappears after opening (delete/rename — the SSE rescan
|
|
183
|
+
* updates the store; the document does not pretend the file still exists).
|
|
184
|
+
*/
|
|
185
|
+
export function openDataDocument(store: DataDocumentStore, path: string): string {
|
|
186
|
+
return openWorkspaceDocument({
|
|
187
|
+
id: dataDocumentId(path),
|
|
188
|
+
title: dataDocumentTitle(path),
|
|
189
|
+
kind: 'data',
|
|
190
|
+
provenance: { sourcePath: path },
|
|
191
|
+
Content: DataDocumentContent,
|
|
192
|
+
closeable: true,
|
|
193
|
+
onActivate: () => store.setActiveViewportTab('scene'),
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/** Open the `Data Assets` navigation/teaching document (file list, or the
|
|
198
|
+
* W6d empty state when the project has no data assets yet). */
|
|
199
|
+
export function openDataAssetsDocument(store: DataDocumentStore): string {
|
|
200
|
+
return openWorkspaceDocument({
|
|
201
|
+
id: DATA_ASSETS_DOCUMENT_ID,
|
|
202
|
+
title: 'Data Assets',
|
|
203
|
+
kind: 'data',
|
|
204
|
+
Content: DataAssetsDocumentContent,
|
|
205
|
+
closeable: true,
|
|
206
|
+
onActivate: () => store.setActiveViewportTab('scene'),
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Command-palette discovery (the B5 fold): one `Open Data Asset` action per
|
|
212
|
+
* discovered file plus the static `Data Assets` navigation document. Reads
|
|
213
|
+
* the live store snapshot — the palette rebuilds its list on every open.
|
|
214
|
+
*/
|
|
215
|
+
export function buildDataAssetActions(store: DataDocumentStore): EditorAction[] {
|
|
216
|
+
const perFile: EditorAction[] = _files.map((f) => ({
|
|
217
|
+
id: `data-asset:${f.path}`,
|
|
218
|
+
label: `Open Data Asset: ${dataDocumentTitle(f.path)}`,
|
|
219
|
+
category: 'action' as const,
|
|
220
|
+
execute: () => void openDataDocument(store, f.path),
|
|
221
|
+
}));
|
|
222
|
+
return [
|
|
223
|
+
{
|
|
224
|
+
id: 'data.assets',
|
|
225
|
+
label: 'Data Assets',
|
|
226
|
+
category: 'action' as const,
|
|
227
|
+
execute: () => void openDataAssetsDocument(store),
|
|
228
|
+
},
|
|
229
|
+
...perFile,
|
|
230
|
+
];
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// --- Content hosts ----------------------------------------------------------
|
|
234
|
+
|
|
235
|
+
/** `'ref'` widget picker options (§2.2): loaded files reduced to
|
|
236
|
+
* `stem -> key[]` — same derivation the old panel memoized. */
|
|
237
|
+
function refOptionsByStem(files: readonly LoadedDataFile[]): ReadonlyMap<string, string[]> {
|
|
238
|
+
const map = new Map<string, string[]>();
|
|
239
|
+
for (const f of files) {
|
|
240
|
+
if (!f.data) continue;
|
|
241
|
+
const stem = f.path.replace(/^src\/data\//, '').replace(/\.data\.json$/, '');
|
|
242
|
+
map.set(
|
|
243
|
+
stem,
|
|
244
|
+
Object.keys(f.data).filter((k) => k !== '$schema'),
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
return map;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** Shared per-content wiring: live store + history-aware commit + a refresh
|
|
251
|
+
* on history writes from OTHER surfaces (undo/redo, project-tool
|
|
252
|
+
* `writeData`) — the same subscription the old panel held. */
|
|
253
|
+
function useDataFilesWithHistory(): {
|
|
254
|
+
files: readonly LoadedDataFile[];
|
|
255
|
+
writeFile: (file: LoadedDataFile, nextData: Record<string, unknown>) => void;
|
|
256
|
+
} {
|
|
257
|
+
useSyncExternalStore(subscribeDataFiles, dataFilesVersion);
|
|
258
|
+
// The session history service arrives through the workspace-history bridge
|
|
259
|
+
// (NOT EditorContext — see workspace-history.ts's doc comment); the
|
|
260
|
+
// per-(service, namespace) manager is cached inside getProjectFileHistory.
|
|
261
|
+
const history = workspaceHistoryService();
|
|
262
|
+
const fileHistory = history
|
|
263
|
+
? getProjectFileHistory(history, getDataHistoryBackend(), 'project-data')
|
|
264
|
+
: null;
|
|
265
|
+
useEffect(() => {
|
|
266
|
+
void refreshDataFiles();
|
|
267
|
+
return (
|
|
268
|
+
fileHistory?.subscribeAll((path) => {
|
|
269
|
+
if (path.startsWith('src/data/') && path.endsWith('.data.json')) {
|
|
270
|
+
void refreshDataFiles();
|
|
271
|
+
}
|
|
272
|
+
}) ?? (() => {})
|
|
273
|
+
);
|
|
274
|
+
}, [fileHistory]);
|
|
275
|
+
return {
|
|
276
|
+
files: _files,
|
|
277
|
+
writeFile: (file, nextData) => commitDataFile(file, nextData, fileHistory),
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/** One data asset's center form/table document. */
|
|
282
|
+
export function DataDocumentContent({ documentId }: WorkspaceDocumentContentProps) {
|
|
283
|
+
const { files, writeFile } = useDataFilesWithHistory();
|
|
284
|
+
const path = documentId.startsWith('data:') ? documentId.slice('data:'.length) : documentId;
|
|
285
|
+
const file = files.find((f) => f.path === path) ?? null;
|
|
286
|
+
return (
|
|
287
|
+
<div
|
|
288
|
+
data-testid={`data-document:${path}`}
|
|
289
|
+
style={{
|
|
290
|
+
flex: 1,
|
|
291
|
+
minHeight: 0,
|
|
292
|
+
overflow: 'auto',
|
|
293
|
+
pointerEvents: 'auto',
|
|
294
|
+
padding: 12,
|
|
295
|
+
}}
|
|
296
|
+
>
|
|
297
|
+
{file ? (
|
|
298
|
+
<RefOptionsContext.Provider value={refOptionsByStem(files)}>
|
|
299
|
+
<DataFileEditor file={file} writeFile={writeFile} />
|
|
300
|
+
</RefOptionsContext.Provider>
|
|
301
|
+
) : (
|
|
302
|
+
<div style={{ fontSize: 12, color: themeVars.content.muted, maxWidth: 480 }}>
|
|
303
|
+
{path} is no longer on disk (deleted or renamed) — close this document.
|
|
304
|
+
</div>
|
|
305
|
+
)}
|
|
306
|
+
</div>
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/** The `Data Assets` navigation/teaching document: the discovered file list
|
|
311
|
+
* (click → open that asset's document), or the W6d empty state. */
|
|
312
|
+
export function DataAssetsDocumentContent(_props: WorkspaceDocumentContentProps) {
|
|
313
|
+
const { files } = useDataFilesWithHistory();
|
|
314
|
+
const store = useDataDocumentStoreBridge();
|
|
315
|
+
if (files.length === 0) {
|
|
316
|
+
return (
|
|
317
|
+
<div style={{ flex: 1, minHeight: 0, overflow: 'auto', pointerEvents: 'auto' }}>
|
|
318
|
+
<DataEmptyState />
|
|
319
|
+
</div>
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
return (
|
|
323
|
+
<div
|
|
324
|
+
data-testid="data-assets-document"
|
|
325
|
+
style={{ flex: 1, minHeight: 0, overflow: 'auto', pointerEvents: 'auto', padding: 12 }}
|
|
326
|
+
>
|
|
327
|
+
<div style={{ fontSize: 11, color: themeVars.content.muted, marginBottom: 8 }}>
|
|
328
|
+
Each data asset opens as its own center document (docs/DATA-TOOLS-DESIGN.md §2).
|
|
329
|
+
</div>
|
|
330
|
+
<div style={{ maxWidth: 360, border: `1px solid ${themeVars.boundary.default}` }}>
|
|
331
|
+
{files.map((f) => (
|
|
332
|
+
<EditorListButton
|
|
333
|
+
key={f.path}
|
|
334
|
+
data-testid={`data-asset-row-${dataDocumentTitle(f.path)}`}
|
|
335
|
+
onClick={() => void openDataDocument(store, f.path)}
|
|
336
|
+
title={f.path}
|
|
337
|
+
style={{ padding: '5px 10px', fontSize: 12 }}
|
|
338
|
+
>
|
|
339
|
+
{dataDocumentTitle(f.path)}
|
|
340
|
+
</EditorListButton>
|
|
341
|
+
))}
|
|
342
|
+
</div>
|
|
343
|
+
</div>
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// The guide document's rows open sibling documents; they only need the T6.3
|
|
348
|
+
// tab hand-off. Route through the SAME store contract the open functions
|
|
349
|
+
// take — supplied by the layout via `configureDataDocumentStore` (set once,
|
|
350
|
+
// alongside `startDataAssetDiscovery`).
|
|
351
|
+
let _storeBridge: DataDocumentStore | null = null;
|
|
352
|
+
|
|
353
|
+
/** Wire the store the guide document's rows open sibling documents through.
|
|
354
|
+
* Returns a cleanup that clears it. */
|
|
355
|
+
export function configureDataDocumentStore(store: DataDocumentStore): () => void {
|
|
356
|
+
_storeBridge = store;
|
|
357
|
+
return () => {
|
|
358
|
+
if (_storeBridge === store) _storeBridge = null;
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
function useDataDocumentStoreBridge(): DataDocumentStore {
|
|
363
|
+
return _storeBridge ?? { setActiveViewportTab: () => {} };
|
|
364
|
+
}
|