@volter/editor-game 0.5.65 → 0.5.67
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/contributions/audio-unlock.service.ts +2 -2
- package/contributions/autoplay.service.ts +1 -1
- package/contributions/bridge.command.ts +3 -3
- package/contributions/canvas/component-board.service.ts +16 -0
- package/contributions/canvas/design-time-mount.service.ts +45 -0
- package/contributions/canvas-story-capture.service.ts +12 -0
- package/contributions/edit-mode-audio.service.ts +2 -2
- package/contributions/edit-mode-networking.service.ts +1 -1
- package/contributions/gameplay.command.ts +4 -4
- package/contributions/generation.service.ts +3 -3
- package/contributions/generations.status.tsx +1 -1
- package/contributions/godot.palette.json +99 -0
- package/contributions/godot.style.ts +82 -0
- package/contributions/godot.view.ts +75 -0
- package/contributions/ingest.service.ts +4 -4
- package/contributions/instances.command.ts +1 -1
- package/contributions/navmesh.menu.ts +1 -1
- package/contributions/network-observer.service.ts +14 -0
- package/contributions/play.command.ts +11 -5
- package/contributions/react/component-board.service.ts +1 -1
- package/contributions/react/design-time-mount.service.ts +1 -1
- package/contributions/react/react-inspector.service.ts +2 -2
- package/contributions/scene-document.service.ts +5 -5
- package/contributions/state-watch.menu.ts +1 -1
- package/contributions/state-watch.utility.tsx +1 -1
- package/contributions/team-playtest.service.ts +4 -4
- package/contributions/three/component-board.service.ts +1 -1
- package/contributions/three/component-verbs.command.ts +8 -8
- package/contributions/three/three-authoring.service.ts +8 -5
- package/contributions/three-story-capture.service.ts +12 -0
- package/contributions/unity.palette.json +102 -0
- package/contributions/unity.style.ts +72 -0
- package/contributions/unity.view.ts +82 -0
- package/contributions/unreal.palette.json +105 -0
- package/contributions/unreal.style.ts +66 -0
- package/contributions/unreal.view.ts +93 -0
- package/dist-node/serving.mjs +16 -0
- package/package.json +33 -16
- package/serving/index.ts +27 -0
- package/src/asset-budget/AssetBudgetPanel.tsx +1 -1
- package/src/asset-budget/asset-budget-model.ts +4 -4
- package/src/asset-budget/optimize-apply.ts +7 -7
- package/src/audio/AudioDebuggerPanel.tsx +1 -1
- package/src/bridge/dispatch.ts +16 -16
- package/src/bridge/live-frames.ts +1 -1
- package/src/bridge/screenshot.ts +6 -6
- package/src/build/BuildProfilesPanel.tsx +3 -3
- package/src/canvas/canvas-board/CanvasBoardDocument.tsx +676 -0
- package/src/canvas/canvas-board/canvas-board-model.ts +407 -0
- package/src/canvas/canvas-board/canvas-component-board.ts +56 -0
- package/src/canvas/canvas-design-mount.ts +524 -0
- package/src/canvas/design-time-canvas-mount.ts +79 -0
- package/src/coverage/live-authoring-surface.ts +6 -6
- package/src/coverage/live-project-verbs.ts +2 -2
- package/src/coverage/native-system-coverage.ts +6 -6
- package/src/coverage/root-coverage.ts +1 -1
- package/src/coverage/session-coverage.ts +5 -5
- package/src/design-system-stories/ApplicationChrome.stories.tsx +5 -5
- package/src/design-system-stories/InspectorNarrowBodies.stories.tsx +13 -53
- package/src/edit-mode/edit-mode-audio.ts +4 -4
- package/src/edit-mode/edit-mode-networking.ts +2 -2
- package/src/game-document/GameCaptureFrameButton.tsx +2 -2
- package/src/game-document/GameDocument.tsx +2 -2
- package/src/game-document/GamePanel.tsx +8 -8
- package/src/game-document/InstanceInspectorPicker.tsx +2 -2
- package/src/game-document/crowd-debug.ts +1 -1
- package/src/game-document/device-preview.ts +10 -11
- package/src/game-document/physics-debug.ts +1 -1
- package/src/generation/GenerationActivity.tsx +6 -8
- package/src/generation/generation-documents.tsx +8 -8
- package/src/generation/generation-jobs.ts +2 -2
- package/src/generation/generation-presentation.ts +1 -1
- package/src/host/adapter-reach.ts +1 -1
- package/src/host/adapter-runtime-bindings.ts +97 -6
- package/src/host/api/configurations.ts +2 -2
- package/src/host/authoring/babylon-authoring-adapter.ts +8 -8
- package/src/host/authoring/contract-hierarchy-authoring.ts +1 -1
- package/src/host/authoring/contract-scenes-stories.ts +1 -1
- package/src/host/authoring/creation-site-related.ts +2 -2
- package/src/host/authoring/ephemeral-persistence.ts +1 -1
- package/src/host/authoring/gesture-persist.ts +2 -2
- package/src/host/authoring/ingest-data-writer.ts +1 -1
- package/src/host/authoring/ingest-source-persistence.ts +8 -8
- package/src/host/authoring/mount-isolated-pixi-screen.ts +1 -1
- package/src/host/authoring/mounted-authoring.ts +4 -4
- package/src/host/authoring/phaser-live-authoring-adapter.ts +4 -4
- package/src/host/authoring/pixi-authoring-adapter.ts +42 -17
- package/src/host/authoring/pixi-creation-site-write-target.ts +2 -2
- package/src/host/authoring/pixi-live-write-target.ts +7 -7
- package/src/host/authoring/pixi-source-identity.ts +3 -3
- package/src/host/authoring/pixi-source-write-target.ts +1614 -0
- package/src/host/authoring/pixi-still-presentation.ts +2 -2
- package/src/host/authoring/pixi-structure-history.ts +3 -3
- package/src/host/authoring/pixi-transform-channels.ts +16 -14
- package/src/host/authoring/source-persistence-backend.ts +6 -6
- package/src/host/authoring/struct-write-pipe.ts +3 -3
- package/src/host/binding-resolver.ts +8 -9
- package/src/host/browser-transpile.ts +2 -2
- package/src/host/canvas-entry-runtime.ts +59 -48
- package/src/host/canvas-preview-frames.ts +482 -0
- package/src/host/components/CameraAuthoringOverlay.tsx +1 -1
- package/src/host/components/HeaderTelemetry.tsx +9 -16
- package/src/host/components/PixiIsolationSceneContent.tsx +17 -16
- package/src/host/components/ThreeIsolationSceneContent.tsx +5 -5
- package/src/host/components/frame-debugger-model.ts +2 -2
- package/src/host/components/header-telemetry-model.ts +2 -2
- package/src/host/components/scene-document.tsx +29 -61
- package/src/host/components/utility-view-state.ts +1 -1
- package/src/host/components/world-root-stage-binding.tsx +17 -26
- package/src/host/components/world-root-stage.ts +130 -63
- package/src/host/coverage/capability-coverage.ts +13 -1
- package/src/host/coverage/game-contract-seam-evidence.ts +1 -1
- package/src/host/coverage/project-verb-coverage.ts +2 -17
- package/src/host/coverage/system-adapter-coverage.ts +4 -5
- package/src/host/design-system-stories/fixtures/editor-runtime.tsx +14 -8
- package/src/host/document-preview-three.ts +2 -2
- package/src/host/entry-adjudication.ts +6 -6
- package/src/host/game-css-scope-transform.ts +4 -0
- package/src/host/game-module-access.ts +1 -1
- package/src/host/game-realm-page.ts +16 -8
- package/src/host/game-realm-reclaim.ts +1 -1
- package/src/host/gameplay-export.ts +25 -14
- package/src/host/gameplay-recording.ts +5 -5
- package/src/host/gated-globals.ts +6 -6
- package/src/host/history/json-history-resource.ts +3 -3
- package/src/host/instance-extract-actions.ts +1 -1
- package/src/host/instance-fork-actions.ts +1 -1
- package/src/host/projection/dom.ts +2 -2
- package/src/host/projection/pixi.ts +25 -3
- package/src/host/r3f-entry-runtime.ts +65 -34
- package/src/host/react-mount-runtime.ts +8 -49
- package/src/host/realm-services.ts +2 -2
- package/src/host/roots/canvas-root.tsx +361 -0
- package/src/host/roots/module-root.ts +1 -1
- package/src/host/roots/r3f-root.tsx +473 -0
- package/src/host/roots/react-root.ts +9 -43
- package/src/host/scene-view-drawability.ts +2 -2
- package/src/host/served-bundle-runtime-modules.ts +1 -19
- package/src/host/server-log-bridge.ts +3 -3
- package/src/host/stories/mounted-story-viewport-source.ts +1 -1
- package/src/host/stories/pixi-story-model.ts +30 -0
- package/src/host/stories/story-media-captures.ts +46 -0
- package/src/host/stories/story-media-presence.ts +3 -3
- package/src/host/stories/story-pixi-preview.ts +408 -0
- package/src/host/stories/story-three-preview.ts +806 -0
- package/src/host/stories/three-story-captures.ts +35 -0
- package/src/host/story-three-preview-runtime.ts +56 -0
- package/src/host/three-ingest-runtime.ts +1 -1
- package/src/host/use-active-performance-source.ts +3 -3
- package/src/host/viewport-pose-memory.ts +1 -1
- package/src/host/viewport-root-presentation.ts +6 -5
- package/src/ingest/active-ingest.ts +2 -2
- package/src/ingest/authoring/ingest-dom-surface-authoring.ts +4 -4
- package/src/ingest/authoring/ingest-root-adapter.ts +13 -13
- package/src/ingest/capture-wait-report.ts +1 -1
- package/src/ingest/deferred-ingest-play.ts +11 -10
- package/src/ingest/discovery-public-ingest.ts +2 -2
- package/src/ingest/ingest-boot-viewport.ts +6 -8
- package/src/ingest/ingest-canvas-scene-document.tsx +17 -16
- package/src/ingest/ingest-canvas-scene.ts +5 -8
- package/src/ingest/ingest-evidence-hook.ts +1 -1
- package/src/ingest/ingest-frame-snapshot.ts +1 -1
- package/src/ingest/ingest-play-control.ts +4 -4
- package/src/ingest/ingest-render-debug.ts +11 -11
- package/src/ingest/ingest-siblings.ts +16 -28
- package/src/ingest/module-mode.ts +18 -19
- package/src/ingest/mount-canvas-ingest-root.ts +27 -27
- package/src/ingest/mount-coverage.ts +4 -4
- package/src/ingest/mount-dom-ingest-root.ts +16 -16
- package/src/ingest/mount-ingest-root.ts +14 -14
- package/src/ingest/mount-three-ingest-root.ts +12 -12
- package/src/ingest/resolve-canvas.ts +1 -1
- package/src/ingest/served-html-boot.ts +1 -1
- package/src/ingest/surface-canvas.ts +1 -1
- package/src/ingest/unmount-ingest-root.ts +7 -7
- package/src/navmesh/navmesh-handler.ts +24 -16
- package/src/network/NetworkInspectorPanel.tsx +449 -14
- package/src/network/network-inspector-model.ts +14 -2
- package/src/play/play-log-events.ts +1 -1
- package/src/play/play-mode.ts +99 -142
- package/src/play/play-recording.ts +2 -2
- package/src/play/react-play-live-authoring.ts +3 -3
- package/src/play/run-selection.ts +93 -0
- package/src/play-bar/PlayBar.tsx +20 -39
- package/src/profiler/FrameDebuggerPanel.tsx +1 -1
- package/src/profiler/PerformancePanel.tsx +4 -4
- package/src/react/design-time-react-mount.ts +37 -85
- package/src/react/dom-authoring-adapter.ts +11 -11
- package/src/react/react-inspector-section.tsx +13 -13
- package/src/react/react-world-authoring-adapter.ts +31 -143
- package/src/react/story-documents/story-documents.tsx +18 -22
- package/src/react/ui-board-document.tsx +10 -11
- package/src/react/ui-component-board.ts +5 -5
- package/src/runtime/adapter/audio-meter.ts +21 -0
- package/src/runtime/adapter/first-party-audio-system.ts +230 -0
- package/src/runtime/adapter/ingest/contract-debug-adapter.ts +114 -0
- package/src/runtime/adapter/ingest/contract-system-adapters.ts +256 -0
- package/src/runtime/adapter/ingest/merge-debug-adapters.ts +197 -0
- package/src/runtime/adapter/ingest/observation-debug-adapter.ts +162 -0
- package/src/runtime/adapter/ingest/upstream-pin.ts +51 -0
- package/src/runtime/adapter/native-debug-module.ts +498 -0
- package/src/runtime/audio/bus-mixer.ts +161 -0
- package/src/runtime/audio/pose-guard.ts +80 -0
- package/src/runtime/core/frame-pacing.ts +126 -0
- package/src/runtime/core/game-loop.ts +225 -0
- package/src/runtime/core/game-scoped-slot.ts +28 -0
- package/src/runtime/core/seeded-random.ts +162 -0
- package/src/runtime/core/sim-clock.ts +391 -0
- package/src/runtime/core/system-runner.ts +269 -0
- package/src/runtime/core/types.ts +104 -0
- package/src/runtime/create-runtime.ts +1128 -0
- package/src/runtime/debug-bridge.ts +570 -0
- package/src/runtime/debug-registry.ts +899 -0
- package/src/runtime/dev/chrome-trace.ts +153 -0
- package/src/runtime/dev/instruments.ts +403 -0
- package/src/runtime/dev/logger.ts +119 -0
- package/src/runtime/dev/performance-profiler.ts +367 -0
- package/src/runtime/dev/register-render-vitals.ts +276 -0
- package/src/runtime/dev/render-census.ts +354 -0
- package/src/runtime/dev/render-debug-adapter.ts +218 -0
- package/src/runtime/dev/render-memory.ts +226 -0
- package/src/runtime/dev/render-vitals.ts +338 -0
- package/src/runtime/dev/static-batch-advisor.ts +188 -0
- package/src/runtime/dev/webgl-frame-capture.ts +366 -0
- package/src/runtime/dev/webgl-gpu-timer.ts +53 -0
- package/src/runtime/dev-build.ts +47 -0
- package/src/runtime/game.ts +1636 -0
- package/src/runtime/gameplay-rng-trap.ts +135 -0
- package/src/runtime/host-context.ts +64 -0
- package/src/runtime/input-router.ts +169 -0
- package/src/runtime/mount-manifest.ts +480 -0
- package/src/runtime/pixi/authoring.ts +706 -0
- package/src/runtime/pixi/ingest.ts +116 -0
- package/src/runtime/pixi/physics-registry.ts +49 -0
- package/src/runtime/pixi/render-pass-bracket.ts +117 -0
- package/src/runtime/pixi/scene-capture.ts +179 -0
- package/src/runtime/pixi/system-adapters.ts +69 -0
- package/src/runtime/playtest.ts +22 -0
- package/src/runtime/presentation.ts +141 -0
- package/src/runtime/render-control.ts +642 -0
- package/src/runtime/render-seed.ts +77 -0
- package/src/runtime/run-ticks-settled.ts +73 -0
- package/src/runtime/setup/setup-audio.ts +72 -0
- package/src/services/audio-pose-guard.ts +2 -2
- package/src/services/game-audio.ts +152 -0
- package/src/services/game-network.ts +657 -0
- package/src/services/game-physics.ts +334 -0
- package/src/state-watch/StateWatchPanel.tsx +1 -1
- package/src/three/authoring/camera-runtime-inspector-section.tsx +4 -3
- package/src/three/authoring/constraint-inspector-section.tsx +8 -7
- package/src/three/authoring/model-asset-inspector-section.tsx +14 -17
- package/src/three/authoring/oid-source-persistence.ts +13 -13
- package/src/three/authoring/r3f-design-session.ts +79 -61
- package/src/three/authoring/r3f-source-authoring-adapter.ts +112 -108
- package/src/three/authoring/reflection-probe-inspector-section.tsx +5 -4
- package/src/three/authoring/spatial-joint-handles.ts +1 -1
- package/src/three/authoring/spatial-lod-handles.ts +1 -1
- package/src/three/authoring/spatial-particle-handles.ts +1 -1
- package/src/three/authoring/three-authoring-adapter.ts +33 -33
- package/src/three/component-verbs/extract-menu.ts +8 -7
- package/src/three/component-verbs/fork-menu.ts +8 -7
- package/src/three/component-verbs/internals-menu.ts +3 -3
- package/src/three/drei-asset-caches.ts +13 -0
- package/src/three/story-documents/three-story-documents.tsx +24 -34
- package/src/three/three-board/ThreeBoardDocument.tsx +25 -25
- package/src/three/three-board/board-scene.ts +7 -7
- package/src/three/three-board/three-component-board.ts +5 -5
- package/contributions/react/pasteboard.action.ts +0 -41
- package/contributions/xstate-behavior.action.ts +0 -42
- package/contributions/xstate-behavior.document.tsx +0 -73
- package/contributions/xstate-behavior.inspector.tsx +0 -28
- package/contributions/xstate-behavior.menu.ts +0 -23
- package/src/react/pasteboard-materialize.ts +0 -154
- package/src/services/game-audio-unlock.ts +0 -48
- package/src/xstate/XStateBehaviorSection.tsx +0 -130
- package/src/xstate/XStateMachineInspector.tsx +0 -566
- package/src/xstate/character-animation-machine.fixture.ts +0 -74
- package/src/xstate/live-behaviors.ts +0 -106
- package/src/xstate/use-live-actor-state.ts +0 -44
- package/src/xstate/xstate-graph.ts +0 -235
- package/src/xstate/xstate-layout.ts +0 -76
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { threeObject } from '@volter/editor-threejs/adapter/three-contract';
|
|
2
|
+
import { registerAvailableWorkspaceDocument } from '@volter/editor-sdk/kit/workspace-available-documents';
|
|
2
3
|
/**
|
|
3
4
|
* The 3D COMPONENTS board — a generated, never-persisted 3D scene laying out
|
|
4
5
|
* every qualifying `three` story's mounted `Object3D` at TRUE SCALE, so a
|
|
@@ -52,43 +53,43 @@ import { registerAvailableWorkspaceDocument } from '@volter/editor-core/workspac
|
|
|
52
53
|
* degradation). Same sentences, same clipboard path, never a silent no-op.
|
|
53
54
|
*/
|
|
54
55
|
|
|
55
|
-
import { object3DDocumentSession } from '@volter/editor-
|
|
56
|
-
import { Object3DDocumentViewport } from '@volter/editor-
|
|
57
|
-
import { STANDARD_COMPONENT_CAMERA_DIRECTION } from '@volter/editor-
|
|
58
|
-
import { threeBoardBuildingCopy } from '@volter/editor-
|
|
59
|
-
import { openRegisteredDocument } from '@volter/editor-
|
|
60
|
-
import { listProjectComponents } from '@volter/editor-
|
|
61
|
-
import { editorConsole } from '@volter/editor-
|
|
62
|
-
import { createHmrRegistrationGroup } from '@volter/editor-
|
|
63
|
-
import { CONTRIBUTED_SECTION_ORDER } from '@volter/editor-
|
|
56
|
+
import { object3DDocumentSession } from '@volter/editor-threejs/kit/authoring/object3d-document-session-registry';
|
|
57
|
+
import { Object3DDocumentViewport } from '@volter/editor-threejs/kit/components/Object3DDocumentViewport';
|
|
58
|
+
import { STANDARD_COMPONENT_CAMERA_DIRECTION } from '@volter/editor-threejs/kit/components/standard-viewport-dressing';
|
|
59
|
+
import { threeBoardBuildingCopy } from '@volter/editor-sdk/kit/viewport-surface-status';
|
|
60
|
+
import { openRegisteredDocument } from '@volter/editor-sdk/kit/document-open-registry';
|
|
61
|
+
import { listProjectComponents } from '@volter/editor-sdk/kit/editor-api';
|
|
62
|
+
import { editorConsole } from '@volter/editor-sdk/kit/editor-console';
|
|
63
|
+
import { createHmrRegistrationGroup } from '@volter/editor-sdk/kit/hmr-registration-group';
|
|
64
|
+
import { CONTRIBUTED_SECTION_ORDER } from '@volter/editor-sdk/kit/inspection-model';
|
|
64
65
|
import {
|
|
65
66
|
type InspectorSectionProps,
|
|
66
67
|
registerInspectorSections,
|
|
67
|
-
} from '@volter/editor-
|
|
68
|
-
import { type ClipboardWriter, runInstanceSourceAction } from '@volter/editor-
|
|
69
|
-
import { getProjectStoryRegions } from '@volter/editor-
|
|
70
|
-
import { declaredStoryMedium } from '@volter/editor-
|
|
71
|
-
import { THREE_STORY_DOCUMENT_OPENER } from '@volter/editor-
|
|
68
|
+
} from '@volter/editor-sdk/kit/inspector-section-registry';
|
|
69
|
+
import { type ClipboardWriter, runInstanceSourceAction } from '@volter/editor-sdk/kit/instance-source-actions';
|
|
70
|
+
import { getProjectStoryRegions } from '@volter/editor-sdk/kit/stories/project-story-regions';
|
|
71
|
+
import { declaredStoryMedium } from '@volter/editor-sdk/kit/stories/story-declared-medium';
|
|
72
|
+
import { THREE_STORY_DOCUMENT_OPENER } from '@volter/editor-sdk/kit/story-document-openers';
|
|
72
73
|
import {
|
|
73
74
|
getProjectStoryModules,
|
|
74
75
|
type ProjectStoryModule,
|
|
75
76
|
subscribeProjectStoryModules,
|
|
76
77
|
whenProjectStoriesReady,
|
|
77
|
-
} from '@volter/editor-
|
|
78
|
-
import { showTransientHint } from '@volter/editor-
|
|
78
|
+
} from '@volter/editor-sdk/kit/stories/story-registry';
|
|
79
|
+
import { showTransientHint } from '@volter/editor-sdk/kit/transient-hint';
|
|
79
80
|
import {
|
|
80
81
|
beginViewportBreakdown,
|
|
81
82
|
cancelViewportBreakdown,
|
|
82
83
|
markViewportBoardReady,
|
|
83
84
|
markViewportReactActive,
|
|
84
85
|
markViewportSegment,
|
|
85
|
-
} from '@volter/editor-
|
|
86
|
-
import { THREE_COMPONENTS_DOCUMENT_ID } from '@volter/editor-
|
|
86
|
+
} from '@volter/editor-sdk/kit/viewport-activation-timings';
|
|
87
|
+
import { THREE_COMPONENTS_DOCUMENT_ID } from '@volter/editor-sdk/kit/workspace-document-ids';
|
|
87
88
|
import {
|
|
88
89
|
activeWorkspaceDocument,
|
|
89
90
|
type WorkspaceDocumentContentProps,
|
|
90
|
-
} from '@volter/editor-
|
|
91
|
-
import type { WorkspaceStateStore } from '@volter/editor-
|
|
91
|
+
} from '@volter/editor-sdk/kit/workspace-document-registry';
|
|
92
|
+
import type { WorkspaceStateStore } from '@volter/editor-sdk/kit/workspace-document-restore';
|
|
92
93
|
import { faCircleInfo } from '@fortawesome/free-solid-svg-icons';
|
|
93
94
|
import { themeVars } from '@volter/editor-sdk/widgets';
|
|
94
95
|
import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from 'react';
|
|
@@ -737,7 +738,7 @@ export function BoardExhibitSection({ adapter, nodeId }: InspectorSectionProps)
|
|
|
737
738
|
useSyncExternalStore(subscribeThreeBoard, threeBoardVersion);
|
|
738
739
|
const candidateIds = [...(nodeId ? [nodeId] : []), ...(adapter.selection?.get() ?? [])];
|
|
739
740
|
const exhibit = candidateIds.reduce<BoardExhibit | null>(
|
|
740
|
-
(found, id) => found ?? findExhibitIn(_scene, adapter.hierarchy
|
|
741
|
+
(found, id) => found ?? findExhibitIn(_scene, threeObject(adapter.hierarchy, id)),
|
|
741
742
|
null,
|
|
742
743
|
);
|
|
743
744
|
return (
|
|
@@ -814,7 +815,7 @@ const threeBoardPreview = {
|
|
|
814
815
|
revision: () => JSON.stringify(getProjectStoryModules().map((module_) => module_.modulePath)),
|
|
815
816
|
subscribe: subscribeProjectStoryModules,
|
|
816
817
|
capture: async (
|
|
817
|
-
request: import('@volter/editor-
|
|
818
|
+
request: import('@volter/editor-sdk/kit/document-preview-source').DocumentPreviewCaptureRequest,
|
|
818
819
|
) => {
|
|
819
820
|
await whenProjectStoriesReady();
|
|
820
821
|
const regions = getProjectStoryRegions();
|
|
@@ -829,7 +830,7 @@ const threeBoardPreview = {
|
|
|
829
830
|
const { captureAuthoredThreeScenePreview } = await import('../../host/document-preview-three');
|
|
830
831
|
const { createStandardEnvironment } = await import('@volter/editor-threejs/viewport/environment');
|
|
831
832
|
const { applyStandardViewportDressing } = await import(
|
|
832
|
-
'@volter/editor-
|
|
833
|
+
'@volter/editor-threejs/kit/components/standard-viewport-dressing'
|
|
833
834
|
);
|
|
834
835
|
const { isEditorOwnedObject } = await import('@volter/editor-threejs/viewport/editor-layers');
|
|
835
836
|
board.root.traverse((object) => {
|
|
@@ -881,7 +882,6 @@ export function installThreeBoardDocument(store: ThreeBoardStore): string {
|
|
|
881
882
|
readOnly: true,
|
|
882
883
|
preview: threeBoardPreview,
|
|
883
884
|
presentation: () => ({ kind: 'workspace', id: THREE_COMPONENTS_DOCUMENT_ID }),
|
|
884
|
-
onActivate: () => store.setActiveViewportTab('edit'),
|
|
885
885
|
},
|
|
886
886
|
{ category: 'canvas' },
|
|
887
887
|
);
|
|
@@ -73,30 +73,30 @@
|
|
|
73
73
|
* only way it comes back.
|
|
74
74
|
*/
|
|
75
75
|
|
|
76
|
-
import { getProjectStoryRegions } from '@volter/editor-
|
|
76
|
+
import { getProjectStoryRegions } from '@volter/editor-sdk/kit/stories/project-story-regions';
|
|
77
77
|
import {
|
|
78
78
|
declaredStoryMedium,
|
|
79
79
|
reportUndeclaredStoryMedium,
|
|
80
|
-
} from '@volter/editor-
|
|
80
|
+
} from '@volter/editor-sdk/kit/stories/story-declared-medium';
|
|
81
81
|
import {
|
|
82
82
|
deriveStoryGroupPath,
|
|
83
83
|
formatStoryGroupPath,
|
|
84
84
|
storyGroupKey,
|
|
85
|
-
} from '@volter/editor-
|
|
86
|
-
import { type ProjectStoryModule, pickComponentPreviewStory } from '@volter/editor-
|
|
85
|
+
} from '@volter/editor-sdk/kit/stories/story-grouping';
|
|
86
|
+
import { type ProjectStoryModule, pickComponentPreviewStory } from '@volter/editor-sdk/kit/stories/story-registry';
|
|
87
87
|
import {
|
|
88
88
|
lastStoryMountPhaseTiming,
|
|
89
89
|
type MountedStoryObject3D,
|
|
90
90
|
type StoryMountInTurn,
|
|
91
91
|
type StoryPreviewComponent,
|
|
92
92
|
withStoryMountTurn,
|
|
93
|
-
} from '
|
|
94
|
-
import { mountedStoryHasThreeContent } from '@volter/editor-
|
|
93
|
+
} from '../../host/stories/story-three-preview';
|
|
94
|
+
import { mountedStoryHasThreeContent } from '@volter/editor-threejs/kit/stories/three-story-model';
|
|
95
95
|
import {
|
|
96
96
|
markViewportSegment,
|
|
97
97
|
noteViewportBreakdownCounts,
|
|
98
98
|
recordViewportStoryMount,
|
|
99
|
-
} from '@volter/editor-
|
|
99
|
+
} from '@volter/editor-sdk/kit/viewport-activation-timings';
|
|
100
100
|
import { collectContentNodeRecords } from '@volter/editor-threejs/viewport/content-bounds';
|
|
101
101
|
import { EDITOR_LAYER } from '@volter/editor-threejs/viewport/editor-layers';
|
|
102
102
|
import { setUserData } from '@volter/threejs-runtime/ecs/user-data';
|
|
@@ -9,15 +9,15 @@
|
|
|
9
9
|
* when it does not.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import { commandLine } from '@volter/editor-
|
|
13
|
-
import type { ComponentBoard, ComponentBoardContext } from '@volter/editor-
|
|
14
|
-
import { editorConsole } from '@volter/editor-
|
|
12
|
+
import { commandLine } from '@volter/editor-sdk/kit/product-command';
|
|
13
|
+
import type { ComponentBoard, ComponentBoardContext } from '@volter/editor-sdk/kit/component-board-registry';
|
|
14
|
+
import { editorConsole } from '@volter/editor-sdk/kit/editor-console';
|
|
15
15
|
import {
|
|
16
16
|
getStoryMediaPresence,
|
|
17
17
|
subscribeStoryMediaPresence,
|
|
18
18
|
} from '../../host/stories/story-media-presence';
|
|
19
|
-
import { projectStoriesReady, subscribeProjectStoryModules } from '@volter/editor-
|
|
20
|
-
import { THREE_COMPONENTS_DOCUMENT_ID } from '@volter/editor-
|
|
19
|
+
import { projectStoriesReady, subscribeProjectStoryModules } from '@volter/editor-sdk/kit/stories/story-registry';
|
|
20
|
+
import { THREE_COMPONENTS_DOCUMENT_ID } from '@volter/editor-sdk/kit/workspace-document-ids';
|
|
21
21
|
|
|
22
22
|
/** The tab reads `3D`, the peer of `Scene` and `UI` in the center strip. */
|
|
23
23
|
const THREE_COMPONENTS_TITLE = '3D';
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* "MATERIALIZE PASTEBOARD FROM UI BOARD" in the command palette
|
|
3
|
-
* (`@volter/editor-sdk/chrome`, a `workspace.action` contribution) — the ONE
|
|
4
|
-
* action that turns the UI board's derived auto-grid into an authored
|
|
5
|
-
* pasteboard `.tsx`.
|
|
6
|
-
*
|
|
7
|
-
* It was a row in the host's own `action-registry.ts:404-423`, lazily
|
|
8
|
-
* importing `pasteboard-materialize.ts` — a host action about THIS package's
|
|
9
|
-
* design-time surface, which is the only thing that kept both files in the
|
|
10
|
-
* host (WORK.md §The open-source launch item 17). Shape transcribed from
|
|
11
|
-
* `@volter/editor-game/contributions/profiler.action.ts`: a static `actions` array, no
|
|
12
|
-
* subscribe, because this action's availability never changes — it either
|
|
13
|
-
* materializes or it refuses by name.
|
|
14
|
-
*
|
|
15
|
-
* THE OUTCOME LANDS IN THE EDITOR CONSOLE EITHER WAY, unchanged from the row
|
|
16
|
-
* it left: the success sentence names the file (which also opens), a refusal
|
|
17
|
-
* names its remedy.
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
import { editorConsole } from '@volter/editor-core/editor-console';
|
|
21
|
-
import type { ActionContribution } from '@volter/editor-sdk/chrome';
|
|
22
|
-
|
|
23
|
-
export const point = 'workspace.action';
|
|
24
|
-
|
|
25
|
-
export const actions: ActionContribution['actions'] = [
|
|
26
|
-
{
|
|
27
|
-
id: 'pasteboard.materialize',
|
|
28
|
-
label: 'Materialize Pasteboard from UI Board',
|
|
29
|
-
execute: async () => {
|
|
30
|
-
const { materializePasteboard } = await import('../../src/react/pasteboard-materialize');
|
|
31
|
-
try {
|
|
32
|
-
editorConsole.log(`[pasteboard] ${await materializePasteboard()}`, 'authoring');
|
|
33
|
-
} catch (error) {
|
|
34
|
-
editorConsole.error(
|
|
35
|
-
`[pasteboard] materialize refused: ${error instanceof Error ? error.message : String(error)}`,
|
|
36
|
-
'authoring',
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
];
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The Behavior debugger's palette actions (`@volter/editor-sdk/chrome`, a
|
|
3
|
-
* `workspace.action` contribution) — a LIVE set: `Inspect Behavior` (the
|
|
4
|
-
* first truthful live actor, the same reveal as Debug ▸ Inspect Behavior)
|
|
5
|
-
* plus one `Inspect Behavior: <machine>` per running XState actor. The host
|
|
6
|
-
* asks `actions` when the palette opens and re-lists on `subscribe`: an
|
|
7
|
-
* actor registering or a hierarchy change (any shell-store notification, so
|
|
8
|
-
* the listing walks the object map only while a palette is open).
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import type { ActionContribution } from '@volter/editor-sdk/chrome';
|
|
12
|
-
import { editorHost } from '@volter/editor-sdk/host';
|
|
13
|
-
import { subscribeXStateBehaviorInspections } from '@volter/threejs-runtime/behavior/xstate-inspection';
|
|
14
|
-
import {
|
|
15
|
-
listLiveBehaviors,
|
|
16
|
-
openBehaviorDocument,
|
|
17
|
-
openFirstBehaviorDocument,
|
|
18
|
-
} from '../src/xstate/live-behaviors';
|
|
19
|
-
|
|
20
|
-
export const point = 'workspace.action';
|
|
21
|
-
|
|
22
|
-
export const actions: ActionContribution['actions'] = () => [
|
|
23
|
-
{
|
|
24
|
-
id: 'inspect-behavior',
|
|
25
|
-
label: 'Inspect Behavior',
|
|
26
|
-
execute: () => void openFirstBehaviorDocument(),
|
|
27
|
-
},
|
|
28
|
-
...listLiveBehaviors().map((entry) => ({
|
|
29
|
-
id: `xstate-machine:${entry.machineId}:${entry.nodeId}`,
|
|
30
|
-
label: `Inspect Behavior: ${entry.machineId}`,
|
|
31
|
-
execute: () => void openBehaviorDocument(entry.nodeId),
|
|
32
|
-
})),
|
|
33
|
-
];
|
|
34
|
-
|
|
35
|
-
export const subscribe: ActionContribution['subscribe'] = (listener) => {
|
|
36
|
-
const stopInspections = subscribeXStateBehaviorInspections(listener);
|
|
37
|
-
const stopHierarchy = editorHost().hierarchy.subscribe(listener);
|
|
38
|
-
return () => {
|
|
39
|
-
stopInspections();
|
|
40
|
-
stopHierarchy();
|
|
41
|
-
};
|
|
42
|
-
};
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* THE BEHAVIOR DOCUMENT (`workspace.document`): the REAL live actor of the
|
|
3
|
-
* machine you asked to inspect, drawn as its graph — the same asset-document
|
|
4
|
-
* pattern the animation and model editors use, inspect-only.
|
|
5
|
-
*
|
|
6
|
-
* Its subject is `live-behaviors.ts`'s (`openBehaviorDocument(nodeId)` sets it
|
|
7
|
-
* and opens this tab, from the section's button, the Debug menu and each
|
|
8
|
-
* `Inspect Behavior: <id>` palette action). With no live actor for that node —
|
|
9
|
-
* the game stopped, the actor detached — the document says so rather than
|
|
10
|
-
* drawing a machine nothing is running.
|
|
11
|
-
*
|
|
12
|
-
* No `tool`: it drives no registered callable.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import type { ToolContributionProps, ToolDocumentToolbar } from '@volter/editor-sdk/contributions';
|
|
16
|
-
import {
|
|
17
|
-
subscribeXStateBehaviorInspections,
|
|
18
|
-
xstateBehaviorInspectionsVersion,
|
|
19
|
-
} from '@volter/threejs-runtime/behavior/xstate-inspection';
|
|
20
|
-
import { useSyncExternalStore } from 'react';
|
|
21
|
-
import {
|
|
22
|
-
behaviorSubject,
|
|
23
|
-
behaviorSubjectVersion,
|
|
24
|
-
liveBehaviorFor,
|
|
25
|
-
subscribeBehaviorSubject,
|
|
26
|
-
} from '../src/xstate/live-behaviors';
|
|
27
|
-
import { XStateMachineInspector } from '../src/xstate/XStateMachineInspector';
|
|
28
|
-
|
|
29
|
-
export const point = 'workspace.document';
|
|
30
|
-
export const title = 'Behavior';
|
|
31
|
-
|
|
32
|
-
/** Re-render on both live facts this document draws: which node it is on, and
|
|
33
|
-
* whether that node still carries an inspection. */
|
|
34
|
-
function useSubjectBehavior() {
|
|
35
|
-
useSyncExternalStore(subscribeBehaviorSubject, behaviorSubjectVersion, behaviorSubjectVersion);
|
|
36
|
-
useSyncExternalStore(
|
|
37
|
-
subscribeXStateBehaviorInspections,
|
|
38
|
-
xstateBehaviorInspectionsVersion,
|
|
39
|
-
xstateBehaviorInspectionsVersion,
|
|
40
|
-
);
|
|
41
|
-
const nodeId = behaviorSubject();
|
|
42
|
-
return nodeId ? liveBehaviorFor(nodeId) : undefined;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/** The document's header, in the host's own strip: which machine, and that it
|
|
46
|
-
* is a live actor you may read but not edit. */
|
|
47
|
-
export const Toolbar: ToolDocumentToolbar = () => {
|
|
48
|
-
const behavior = useSubjectBehavior();
|
|
49
|
-
return (
|
|
50
|
-
<span data-testid="xstate-behavior-toolbar" style={{ fontSize: 11 }}>
|
|
51
|
-
{behavior ? `${behavior.machine.id} · Live actor · inspect-only` : 'Behavior unavailable'}
|
|
52
|
-
</span>
|
|
53
|
-
);
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
export default function XStateBehaviorDocument(_props: ToolContributionProps) {
|
|
57
|
-
const behavior = useSubjectBehavior();
|
|
58
|
-
return (
|
|
59
|
-
<div className="vgai-behavior-document" data-testid="xstate-behavior-document">
|
|
60
|
-
{behavior ? (
|
|
61
|
-
<XStateMachineInspector
|
|
62
|
-
machine={behavior.machine}
|
|
63
|
-
actor={behavior.actor}
|
|
64
|
-
title={behavior.machine.id}
|
|
65
|
-
/>
|
|
66
|
-
) : (
|
|
67
|
-
<div className="vgai-behavior-document__empty">
|
|
68
|
-
This live behavior is no longer registered.
|
|
69
|
-
</div>
|
|
70
|
-
)}
|
|
71
|
-
</div>
|
|
72
|
-
);
|
|
73
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The Behavior Inspector section (`selection.inspector`, §4.3): the machine a
|
|
3
|
-
* selected entity is actually running.
|
|
4
|
-
*
|
|
5
|
-
* `match` reads the hierarchy door for the node's own live inspection mark, so
|
|
6
|
-
* it matches ONLY a real live actor — a template entity (no machine) never
|
|
7
|
-
* matches, and the section cannot render for it.
|
|
8
|
-
*/
|
|
9
|
-
import type {
|
|
10
|
-
ToolContributionNode,
|
|
11
|
-
ToolInspectorContributionProps,
|
|
12
|
-
} from '@volter/editor-sdk/contributions';
|
|
13
|
-
import { liveBehaviorFor } from '../src/xstate/live-behaviors';
|
|
14
|
-
import { XStateMachineSection } from '../src/xstate/XStateBehaviorSection';
|
|
15
|
-
|
|
16
|
-
export const point = 'selection.inspector';
|
|
17
|
-
export const title = 'Behavior';
|
|
18
|
-
/** Where the host registered it before the move: the contributed band's own
|
|
19
|
-
* base, ahead of modules that claim no place. */
|
|
20
|
-
export const order = 0;
|
|
21
|
-
|
|
22
|
-
export function match(node: ToolContributionNode | null): boolean {
|
|
23
|
-
return node !== null && liveBehaviorFor(node.id) !== undefined;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export default function XStateBehaviorInspector({ nodeId }: ToolInspectorContributionProps) {
|
|
27
|
-
return <XStateMachineSection nodeId={nodeId} />;
|
|
28
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Debug ▸ Inspect Behavior — opens the first truthful live actor as the
|
|
3
|
-
* Behavior document. Disabled while no live actor is registered, which is the
|
|
4
|
-
* same predicate the open path itself refuses on; `disabled` is asked at
|
|
5
|
-
* render, so it follows the session.
|
|
6
|
-
*/
|
|
7
|
-
import type { MenuContribution } from '@volter/editor-sdk/chrome';
|
|
8
|
-
import { listLiveBehaviors, openFirstBehaviorDocument } from '../src/xstate/live-behaviors';
|
|
9
|
-
|
|
10
|
-
export const point = 'workspace.menu';
|
|
11
|
-
|
|
12
|
-
export const menu: MenuContribution = {
|
|
13
|
-
menu: 'debug',
|
|
14
|
-
items: [
|
|
15
|
-
{
|
|
16
|
-
id: 'inspect-behavior',
|
|
17
|
-
label: 'Inspect Behavior',
|
|
18
|
-
testId: 'menu-inspect-behavior',
|
|
19
|
-
disabled: () => listLiveBehaviors().length === 0,
|
|
20
|
-
execute: () => void openFirstBehaviorDocument(),
|
|
21
|
-
},
|
|
22
|
-
],
|
|
23
|
-
};
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* "MATERIALIZE PASTEBOARD" (queue item 4): turn the UI board's DERIVED,
|
|
3
|
-
* ephemeral auto-grid into an AUTHORED pasteboard `.tsx` — the one action the
|
|
4
|
-
* ratified design names ("ephemeral auto-grid when no file; one action
|
|
5
|
-
* materializes it"). The generated file is ordinary project source: it
|
|
6
|
-
* imports each board story's OWNER COMPONENT and places it under `<At x y>`
|
|
7
|
-
* at the position the auto-grid gave its frame, so the derived layout becomes
|
|
8
|
-
* literals a drag can then rewrite. Nothing regenerates the file afterwards —
|
|
9
|
-
* it is the project's, exactly like every `vgai add` copy.
|
|
10
|
-
*
|
|
11
|
-
* Refusals are loud and name their remedy: no open project, no storage, no
|
|
12
|
-
* pasteboard helpers (`vgai add pasteboard`), a file already at the target
|
|
13
|
-
* path, or a board with nothing on it. A story whose owner component cannot
|
|
14
|
-
* be resolved to an importable export is SKIPPED BY NAME in the returned
|
|
15
|
-
* sentence rather than emitting an import that does not compile.
|
|
16
|
-
*
|
|
17
|
-
* ## Why it is this package's
|
|
18
|
-
*
|
|
19
|
-
* Its subject is THE UI BOARD — the design-time surface `@volter/editor-game` registers
|
|
20
|
-
* a mount for (`design-time-react-mount.ts`, unit 12) — and it reads that
|
|
21
|
-
* board's own frame placements. It stayed a host file only because its one
|
|
22
|
-
* caller was a host `action-registry.ts` row; the action POINT
|
|
23
|
-
* (`@volter/editor-sdk/chrome`, `workspace.action`) is what that row becomes,
|
|
24
|
-
* and `contributions/pasteboard.action.ts` is the row now. Unit 12's header
|
|
25
|
-
* called this file "NOT the dom lane's" on the strength of that caller; the
|
|
26
|
-
* caller is what moved (WORK.md §The open-source launch item 17, the edge map
|
|
27
|
-
* in `scripts/validate-editor-closure.mjs`).
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
import { commandLine } from '@volter/editor-core/product-command';
|
|
31
|
-
import { listProjectComponents } from '@volter/editor-core/api/assets';
|
|
32
|
-
import type { ProjectComponentEntry } from '@volter/editor-core/asset-workflow/project-content';
|
|
33
|
-
import { reactStoryBoardFramePlacements } from '@volter/editor-core/authoring/react-story-board';
|
|
34
|
-
import { getProjectPreviewStories } from '@volter/editor-core/stories/story-registry';
|
|
35
|
-
import { domStoryBoardMembers } from '@volter/editor-core/stories/three-story-model';
|
|
36
|
-
import { createProjectSourceFile } from '@volter/editor-core/ui-source/source-write-backend';
|
|
37
|
-
|
|
38
|
-
export const PASTEBOARD_HELPERS_PATH = 'src/lib/pasteboard/pasteboard.tsx';
|
|
39
|
-
export const MATERIALIZED_PASTEBOARD_PATH = 'src/design/pasteboard.tsx';
|
|
40
|
-
|
|
41
|
-
/** The story's owner-module convention: `Hud.stories.tsx` → `Hud.tsx`. */
|
|
42
|
-
function storyOwnerModulePath(storyModulePath: string): string {
|
|
43
|
-
return storyModulePath.replace(/\.stories(?=\.[^.]+$)/, '');
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/** Relative import specifier from `src/design/` to a project-relative path. */
|
|
47
|
-
function importSpecifierFromDesign(componentPath: string): string {
|
|
48
|
-
const withoutExtension = componentPath.replace(/\.[cm]?[jt]sx?$/, '');
|
|
49
|
-
return `../${withoutExtension.replace(/^src\//, '')}`;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function componentForOwnerModule(
|
|
53
|
-
components: readonly ProjectComponentEntry[],
|
|
54
|
-
ownerModulePath: string,
|
|
55
|
-
): ProjectComponentEntry | null {
|
|
56
|
-
const inModule = components.filter(
|
|
57
|
-
(entry) => entry.path === ownerModulePath && (entry.exported || entry.defaultExport),
|
|
58
|
-
);
|
|
59
|
-
return (
|
|
60
|
-
inModule.find((entry) => entry.defaultExport) ?? (inModule.length === 1 ? inModule[0]! : null)
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export async function materializePasteboard(): Promise<string> {
|
|
65
|
-
const helpers = await fetch('/__ui-source/read', {
|
|
66
|
-
method: 'POST',
|
|
67
|
-
headers: { 'Content-Type': 'application/json' },
|
|
68
|
-
body: JSON.stringify({ file: PASTEBOARD_HELPERS_PATH }),
|
|
69
|
-
});
|
|
70
|
-
if (!helpers.ok) {
|
|
71
|
-
throw new Error(
|
|
72
|
-
`Materialize pasteboard needs the pasteboard helpers at ${PASTEBOARD_HELPERS_PATH} — ` +
|
|
73
|
-
`run ${commandLine('add pasteboard')} first.`,
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
const layer = document.querySelector<HTMLElement>('[data-vgai-react-story-board="true"]');
|
|
77
|
-
const placements = reactStoryBoardFramePlacements(layer);
|
|
78
|
-
if (!placements || placements.length === 0) {
|
|
79
|
-
throw new Error(
|
|
80
|
-
'Materialize pasteboard reads the live UI board and it has no frames — open the UI ' +
|
|
81
|
-
'document (a project with dom stories) first.',
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
const stories = domStoryBoardMembers(getProjectPreviewStories());
|
|
85
|
-
const listing = await listProjectComponents();
|
|
86
|
-
const components = listing.ok ? listing.entries : [];
|
|
87
|
-
const placed: Array<{ importLine: string; name: string; x: number; y: number }> = [];
|
|
88
|
-
const skipped: string[] = [];
|
|
89
|
-
const importsBySpecifier = new Map<string, string>();
|
|
90
|
-
for (const placement of placements) {
|
|
91
|
-
const story = stories.find((candidate) => candidate.id === placement.storyId);
|
|
92
|
-
if (!story) continue;
|
|
93
|
-
const owner = storyOwnerModulePath(story.modulePath);
|
|
94
|
-
const component = componentForOwnerModule(components, owner);
|
|
95
|
-
if (!component) {
|
|
96
|
-
skipped.push(story.label ?? story.id);
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
|
-
const specifier = importSpecifierFromDesign(component.path);
|
|
100
|
-
const importLine = component.defaultExport
|
|
101
|
-
? `import ${component.name} from '${specifier}';`
|
|
102
|
-
: `import { ${component.name} } from '${specifier}';`;
|
|
103
|
-
importsBySpecifier.set(specifier, importLine);
|
|
104
|
-
placed.push({ importLine, name: component.name, x: placement.x, y: placement.y });
|
|
105
|
-
}
|
|
106
|
-
if (placed.length === 0) {
|
|
107
|
-
throw new Error(
|
|
108
|
-
'Materialize pasteboard resolved no importable owner component for any board frame ' +
|
|
109
|
-
`(skipped: ${skipped.join(', ') || 'none'}). A story's owner module must export the ` +
|
|
110
|
-
'component its frames render.',
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
const width = Math.max(...placed.map((entry) => entry.x)) + 960;
|
|
114
|
-
const height = Math.max(...placed.map((entry) => entry.y)) + 720;
|
|
115
|
-
const body = placed
|
|
116
|
-
.map(
|
|
117
|
-
(entry) => ` <At x={${entry.x}} y={${entry.y}}>\n <${entry.name} />\n </At>`,
|
|
118
|
-
)
|
|
119
|
-
.join('\n');
|
|
120
|
-
const code = `${[...importsBySpecifier.values()].sort().join('\n')}
|
|
121
|
-
import { At, Pasteboard } from '../lib/pasteboard/pasteboard';
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Materialized from the UI board's derived auto-grid — this file is now the
|
|
125
|
-
* AUTHORED canvas: edit freely, and a drag in the editor writes each At's
|
|
126
|
-
* x/y literals right here.
|
|
127
|
-
*/
|
|
128
|
-
export default function DesignPasteboard() {
|
|
129
|
-
return (
|
|
130
|
-
<Pasteboard width={${width}} height={${height}}>
|
|
131
|
-
${body}
|
|
132
|
-
</Pasteboard>
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
`;
|
|
136
|
-
const created = await createProjectSourceFile(MATERIALIZED_PASTEBOARD_PATH, code);
|
|
137
|
-
if (!created.created) {
|
|
138
|
-
throw new Error(
|
|
139
|
-
created.error ??
|
|
140
|
-
`${MATERIALIZED_PASTEBOARD_PATH} already exists — the pasteboard is already authored; ` +
|
|
141
|
-
'edit it directly (there is deliberately no regeneration).',
|
|
142
|
-
);
|
|
143
|
-
}
|
|
144
|
-
// The AssetBrowser owns asset-open routing; the event is its documented door.
|
|
145
|
-
window.dispatchEvent(
|
|
146
|
-
new CustomEvent('editor:open-project-asset', {
|
|
147
|
-
detail: { path: MATERIALIZED_PASTEBOARD_PATH, kind: 'source' },
|
|
148
|
-
}),
|
|
149
|
-
);
|
|
150
|
-
return (
|
|
151
|
-
`Materialized ${placed.length} frame(s) into ${MATERIALIZED_PASTEBOARD_PATH}` +
|
|
152
|
-
(skipped.length > 0 ? ` (skipped, no importable owner component: ${skipped.join(', ')})` : '')
|
|
153
|
-
);
|
|
154
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HOST-LEVEL audio unlock for game-created AudioContexts.
|
|
3
|
-
*
|
|
4
|
-
* A game running in the editor's page can create its AudioContext before the
|
|
5
|
-
* visitor's first gesture (survivor's auto-attack lands kills while they are
|
|
6
|
-
* still reading), and browsers with a strict autoplay policy then hold it
|
|
7
|
-
* suspended until `resume()` runs INSIDE a trusted input handler. The game's
|
|
8
|
-
* own unlock listeners go through the realm's gated re-dispatch, which is no
|
|
9
|
-
* longer that trusted stack — two human passes heard both flagship canvas
|
|
10
|
-
* games silent on first load and cured them only by restarting under a
|
|
11
|
-
* gesture (runhuman 23/33).
|
|
12
|
-
*
|
|
13
|
-
* The EDITOR owns the page, so it does what a game cannot: wrap the page's
|
|
14
|
-
* AudioContext constructor once at boot to track instances, and resume any
|
|
15
|
-
* suspended one from capture-phase pointerdown/keydown handlers — the real,
|
|
16
|
-
* trusted stack. Contexts already running are untouched; the listeners stay
|
|
17
|
-
* (cheap) so a context created later unlocks on the next gesture.
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
const tracked = new Set<WeakRef<AudioContext>>();
|
|
21
|
-
|
|
22
|
-
function resumeSuspended(): void {
|
|
23
|
-
for (const ref of tracked) {
|
|
24
|
-
const ctx = ref.deref();
|
|
25
|
-
if (!ctx || ctx.state === 'closed') {
|
|
26
|
-
tracked.delete(ref);
|
|
27
|
-
continue;
|
|
28
|
-
}
|
|
29
|
-
if (ctx.state === 'suspended') void ctx.resume();
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/** Install once at editor boot (main.tsx). Idempotent. */
|
|
34
|
-
export function installGameAudioUnlock(): void {
|
|
35
|
-
const host = window as unknown as { __vgaiAudioUnlock?: boolean } & typeof window;
|
|
36
|
-
if (host.__vgaiAudioUnlock) return;
|
|
37
|
-
host.__vgaiAudioUnlock = true;
|
|
38
|
-
const Orig = window.AudioContext;
|
|
39
|
-
if (typeof Orig !== 'function') return;
|
|
40
|
-
window.AudioContext = class extends Orig {
|
|
41
|
-
constructor(...args: ConstructorParameters<typeof AudioContext>) {
|
|
42
|
-
super(...args);
|
|
43
|
-
tracked.add(new WeakRef(this));
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
window.addEventListener('pointerdown', resumeSuspended, { capture: true });
|
|
47
|
-
window.addEventListener('keydown', resumeSuspended, { capture: true });
|
|
48
|
-
}
|