@volter/editor-game 0.5.65
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 +661 -0
- package/NOTICE +23 -0
- package/contributions/asset-budget-asset.menu.ts +26 -0
- package/contributions/asset-budget.action.ts +18 -0
- package/contributions/asset-budget.document.tsx +21 -0
- package/contributions/asset-budget.menu.ts +22 -0
- package/contributions/audio-unlock.service.ts +17 -0
- package/contributions/audio.utility.tsx +15 -0
- package/contributions/autoplay.service.ts +48 -0
- package/contributions/bridge.command.ts +172 -0
- package/contributions/build-profiles.document.tsx +21 -0
- package/contributions/build-progress.status.tsx +45 -0
- package/contributions/build.action.ts +26 -0
- package/contributions/build.command.ts +27 -0
- package/contributions/build.header.tsx +37 -0
- package/contributions/build.menu.ts +31 -0
- package/contributions/build.service.ts +31 -0
- package/contributions/connection.status.tsx +43 -0
- package/contributions/coverage.service.ts +118 -0
- package/contributions/edit-mode-audio.service.ts +23 -0
- package/contributions/edit-mode-networking.service.ts +30 -0
- package/contributions/game-document.service.ts +25 -0
- package/contributions/game-eval.command.ts +210 -0
- package/contributions/game.layout.ts +19 -0
- package/contributions/gameplay.command.ts +255 -0
- package/contributions/generation.service.ts +96 -0
- package/contributions/generations.status.tsx +53 -0
- package/contributions/ingest.service.ts +80 -0
- package/contributions/instances.command.ts +75 -0
- package/contributions/navmesh.menu.ts +39 -0
- package/contributions/navmesh.service.ts +19 -0
- package/contributions/network.utility.tsx +17 -0
- package/contributions/play.command.ts +355 -0
- package/contributions/profiler.action.ts +16 -0
- package/contributions/profiler.menu.ts +22 -0
- package/contributions/profiler.utility.tsx +17 -0
- package/contributions/react/component-board.service.ts +21 -0
- package/contributions/react/design-time-mount.service.ts +60 -0
- package/contributions/react/pasteboard.action.ts +41 -0
- package/contributions/react/react-inspector.service.ts +85 -0
- package/contributions/react/story-documents.service.ts +44 -0
- package/contributions/scene-document.service.ts +32 -0
- package/contributions/state-watch.action.ts +17 -0
- package/contributions/state-watch.menu.ts +23 -0
- package/contributions/state-watch.utility.tsx +20 -0
- package/contributions/team-playtest.service.ts +124 -0
- package/contributions/three/camera-runtime.inspector.tsx +34 -0
- package/contributions/three/component-board.service.ts +24 -0
- package/contributions/three/component-verbs.command.ts +110 -0
- package/contributions/three/component-verbs.service.ts +92 -0
- package/contributions/three/constraints.inspector.tsx +34 -0
- package/contributions/three/model-asset-sections.service.ts +26 -0
- package/contributions/three/reflection-probe-capture.inspector.tsx +32 -0
- package/contributions/three/story-documents.service.ts +31 -0
- package/contributions/three/three-authoring.service.ts +66 -0
- package/contributions/transport.header.tsx +19 -0
- package/contributions/xstate-behavior.action.ts +42 -0
- package/contributions/xstate-behavior.document.tsx +73 -0
- package/contributions/xstate-behavior.inspector.tsx +28 -0
- package/contributions/xstate-behavior.menu.ts +23 -0
- package/package.json +144 -0
- package/src/asset-budget/AssetBudgetPanel.tsx +1172 -0
- package/src/asset-budget/asset-budget-model.ts +799 -0
- package/src/asset-budget/basis-encoder.ts +165 -0
- package/src/asset-budget/gltf-io.ts +154 -0
- package/src/asset-budget/gltf-optimize.ts +384 -0
- package/src/asset-budget/image-dims.ts +78 -0
- package/src/asset-budget/optimize-apply.ts +221 -0
- package/src/audio/AudioDebuggerPanel.tsx +457 -0
- package/src/audio/audio-debugger-model.ts +87 -0
- package/src/bridge/call.ts +60 -0
- package/src/bridge/dispatch.ts +459 -0
- package/src/bridge/live-frames.ts +25 -0
- package/src/bridge/screenshot.ts +316 -0
- package/src/build/BuildProfilesPanel.tsx +476 -0
- package/src/build/build-session.ts +247 -0
- package/src/build/format-bytes.ts +14 -0
- package/src/command-results.ts +36 -0
- package/src/coverage/live-authoring-surface.ts +30 -0
- package/src/coverage/live-project-verbs.ts +162 -0
- package/src/coverage/native-system-coverage.ts +143 -0
- package/src/coverage/root-coverage.ts +79 -0
- package/src/coverage/session-coverage.ts +193 -0
- package/src/design-system-stories/ApplicationChrome.stories.tsx +100 -0
- package/src/design-system-stories/InspectorNarrowBodies.stories.tsx +406 -0
- package/src/edit-mode/edit-mode-audio.ts +56 -0
- package/src/edit-mode/edit-mode-networking.ts +112 -0
- package/src/game-document/DevicePresetPicker.tsx +84 -0
- package/src/game-document/GameCaptureFrameButton.tsx +45 -0
- package/src/game-document/GameDocument.tsx +215 -0
- package/src/game-document/GamePanel.tsx +662 -0
- package/src/game-document/InstanceInspectorPicker.tsx +183 -0
- package/src/game-document/crowd-debug.ts +183 -0
- package/src/game-document/device-preview.ts +336 -0
- package/src/game-document/game-view-store.ts +107 -0
- package/src/game-document/physics-debug.ts +187 -0
- package/src/generation/GenerationActivity.tsx +421 -0
- package/src/generation/GenerationGallery.css +231 -0
- package/src/generation/generation-documents.tsx +338 -0
- package/src/generation/generation-jobs.ts +128 -0
- package/src/generation/generation-presentation.ts +257 -0
- package/src/host/adapter-reach.ts +445 -0
- package/src/host/adapter-runtime-bindings.ts +303 -0
- package/src/host/after-paint.ts +112 -0
- package/src/host/api/configurations.ts +66 -0
- package/src/host/authoring/babylon-authoring-adapter.ts +703 -0
- package/src/host/authoring/canvas-runtime-recognition.ts +50 -0
- package/src/host/authoring/contract-hierarchy-authoring.ts +144 -0
- package/src/host/authoring/contract-scenes-stories.ts +204 -0
- package/src/host/authoring/creation-site-related.ts +55 -0
- package/src/host/authoring/ephemeral-persistence.ts +29 -0
- package/src/host/authoring/gesture-persist.ts +84 -0
- package/src/host/authoring/ingest-data-writer.ts +232 -0
- package/src/host/authoring/ingest-source-persistence.ts +826 -0
- package/src/host/authoring/mount-isolated-pixi-screen.ts +250 -0
- package/src/host/authoring/mounted-authoring.ts +41 -0
- package/src/host/authoring/owned-pixi-ticker-listeners.ts +96 -0
- package/src/host/authoring/phaser-live-authoring-adapter.ts +265 -0
- package/src/host/authoring/pixi-authoring-adapter.ts +1554 -0
- package/src/host/authoring/pixi-creation-site-write-target.ts +60 -0
- package/src/host/authoring/pixi-isolation-assets.ts +25 -0
- package/src/host/authoring/pixi-live-write-target.ts +979 -0
- package/src/host/authoring/pixi-source-identity.ts +141 -0
- package/src/host/authoring/pixi-still-presentation.ts +71 -0
- package/src/host/authoring/pixi-structure-history.ts +237 -0
- package/src/host/authoring/pixi-transform-channels.ts +205 -0
- package/src/host/authoring/selection-remount-handoff.ts +23 -0
- package/src/host/authoring/source-persistence-backend.ts +373 -0
- package/src/host/authoring/source-refresh-revisions.ts +81 -0
- package/src/host/authoring/struct-write-pipe.ts +143 -0
- package/src/host/auto-frame-window.ts +89 -0
- package/src/host/binding-resolver.ts +393 -0
- package/src/host/browser-transpile.ts +631 -0
- package/src/host/canvas-entry-runtime.ts +95 -0
- package/src/host/components/CameraAuthoringOverlay.tsx +216 -0
- package/src/host/components/HeaderTelemetry.tsx +341 -0
- package/src/host/components/PixiIsolationSceneContent.tsx +280 -0
- package/src/host/components/ResolutionPicker.tsx +89 -0
- package/src/host/components/ThreeIsolationSceneContent.tsx +180 -0
- package/src/host/components/frame-debugger-model.ts +579 -0
- package/src/host/components/header-telemetry-model.ts +74 -0
- package/src/host/components/scene-document.tsx +447 -0
- package/src/host/components/utility-view-state.ts +87 -0
- package/src/host/components/world-root-stage-binding.tsx +133 -0
- package/src/host/components/world-root-stage.ts +1046 -0
- package/src/host/coverage/authoring-read-probe.ts +583 -0
- package/src/host/coverage/capability-coverage.ts +1587 -0
- package/src/host/coverage/coverage-accounting.ts +261 -0
- package/src/host/coverage/game-contract-seam-evidence.ts +82 -0
- package/src/host/coverage/project-verb-coverage.ts +148 -0
- package/src/host/coverage/system-adapter-coverage.ts +373 -0
- package/src/host/design-system-stories/StoryLayout.tsx +104 -0
- package/src/host/design-system-stories/fixtures/authoring.ts +247 -0
- package/src/host/design-system-stories/fixtures/editor-runtime.tsx +115 -0
- package/src/host/document-preview-three.ts +110 -0
- package/src/host/entry-adjudication.ts +89 -0
- package/src/host/game-location-guard.ts +150 -0
- package/src/host/game-module-access.ts +196 -0
- package/src/host/game-realm-page.ts +358 -0
- package/src/host/game-realm-reclaim.ts +55 -0
- package/src/host/game-realm-storage.ts +104 -0
- package/src/host/gameplay-export.ts +288 -0
- package/src/host/gameplay-recording.ts +717 -0
- package/src/host/gated-globals.ts +1511 -0
- package/src/host/history/json-history-resource.ts +254 -0
- package/src/host/ingest/registry.ts +261 -0
- package/src/host/instance-extract-actions.ts +120 -0
- package/src/host/instance-fork-actions.ts +120 -0
- package/src/host/play-control-hook.ts +26 -0
- package/src/host/playwright-shim.ts +479 -0
- package/src/host/projection/dom.ts +295 -0
- package/src/host/projection/pixi.ts +288 -0
- package/src/host/r3f-entry-runtime.ts +77 -0
- package/src/host/react-mount-runtime.ts +162 -0
- package/src/host/realm-services.ts +148 -0
- package/src/host/recording-preview.ts +106 -0
- package/src/host/roots/module-root.ts +203 -0
- package/src/host/roots/react-root.ts +181 -0
- package/src/host/same-realm-loop-gate.ts +544 -0
- package/src/host/scene-view-drawability.ts +69 -0
- package/src/host/sdk/tools.ts +31 -0
- package/src/host/served-bundle-runtime-modules.ts +331 -0
- package/src/host/server-log-bridge.ts +60 -0
- package/src/host/staged-projects.ts +24 -0
- package/src/host/stories/mounted-story-viewport-source.ts +64 -0
- package/src/host/stories/story-arg-descriptors.ts +50 -0
- package/src/host/stories/story-media-presence.ts +152 -0
- package/src/host/surface-content.ts +87 -0
- package/src/host/take-named-export.ts +23 -0
- package/src/host/three-ingest-runtime.ts +76 -0
- package/src/host/types-fastnoise-lite.d.ts +7 -0
- package/src/host/types-mikktspace.d.ts +20 -0
- package/src/host/types-troika-three-text.d.ts +7 -0
- package/src/host/use-active-performance-source.ts +53 -0
- package/src/host/viewport-pose-memory.ts +48 -0
- package/src/host/viewport-root-presentation.ts +40 -0
- package/src/ingest/active-ingest.ts +251 -0
- package/src/ingest/active-scene-navigation.ts +43 -0
- package/src/ingest/authoring/ingest-dom-surface-authoring.ts +191 -0
- package/src/ingest/authoring/ingest-root-adapter.ts +897 -0
- package/src/ingest/capture-wait-report.ts +122 -0
- package/src/ingest/deferred-ingest-play.ts +216 -0
- package/src/ingest/deferred-ingest-session.ts +23 -0
- package/src/ingest/discovery-public-ingest.ts +242 -0
- package/src/ingest/dom-stub-mark.ts +7 -0
- package/src/ingest/entry-load.ts +56 -0
- package/src/ingest/game-contract-realm.ts +34 -0
- package/src/ingest/game-pointer-lock.ts +89 -0
- package/src/ingest/held-scene-repaint.ts +73 -0
- package/src/ingest/host-surface-box.ts +174 -0
- package/src/ingest/ingest-boot-viewport.ts +54 -0
- package/src/ingest/ingest-canvas-scene-document.tsx +177 -0
- package/src/ingest/ingest-canvas-scene.ts +50 -0
- package/src/ingest/ingest-evidence-hook.ts +131 -0
- package/src/ingest/ingest-frame-snapshot.ts +183 -0
- package/src/ingest/ingest-play-commands.ts +134 -0
- package/src/ingest/ingest-play-control.ts +299 -0
- package/src/ingest/ingest-render-debug.ts +320 -0
- package/src/ingest/ingest-siblings.ts +487 -0
- package/src/ingest/ingest-status.ts +62 -0
- package/src/ingest/live-ingest-facet.ts +46 -0
- package/src/ingest/module-mode.ts +229 -0
- package/src/ingest/mount-canvas-ingest-root.ts +899 -0
- package/src/ingest/mount-coverage.ts +296 -0
- package/src/ingest/mount-dom-ingest-root.ts +282 -0
- package/src/ingest/mount-ingest-root.ts +744 -0
- package/src/ingest/mount-three-ingest-root.ts +366 -0
- package/src/ingest/resolve-canvas.ts +47 -0
- package/src/ingest/resolve-three.ts +123 -0
- package/src/ingest/served-bundle.ts +109 -0
- package/src/ingest/served-html-boot.ts +292 -0
- package/src/ingest/surface-canvas.ts +84 -0
- package/src/ingest/surface-dom.ts +84 -0
- package/src/ingest/surface-three.ts +128 -0
- package/src/ingest/types.ts +76 -0
- package/src/ingest/unmount-ingest-root.ts +224 -0
- package/src/navmesh/navmesh-actions.ts +27 -0
- package/src/navmesh/navmesh-handler.ts +237 -0
- package/src/navmesh/navmesh-workflow-store.ts +78 -0
- package/src/network/NetworkInspectorPanel.tsx +644 -0
- package/src/network/network-inspector-model.ts +225 -0
- package/src/play/play-boot-stall.ts +118 -0
- package/src/play/play-log-events.ts +26 -0
- package/src/play/play-mode.ts +2553 -0
- package/src/play/play-recording.ts +335 -0
- package/src/play/react-play-live-authoring.ts +165 -0
- package/src/play-bar/PlayBar.tsx +488 -0
- package/src/play-bar/PlayerCountPicker.tsx +100 -0
- package/src/profiler/FrameDebuggerPanel.tsx +458 -0
- package/src/profiler/PerformancePanel.tsx +1068 -0
- package/src/profiler/ProfilerPanel.tsx +53 -0
- package/src/profiler/frame-debugger-store.ts +97 -0
- package/src/profiler/main-thread-busy.ts +90 -0
- package/src/react/design-time-react-mount.ts +782 -0
- package/src/react/dom-authoring-adapter.ts +764 -0
- package/src/react/pasteboard-materialize.ts +154 -0
- package/src/react/react-inspector-section.tsx +2496 -0
- package/src/react/react-world-authoring-adapter.ts +3795 -0
- package/src/react/story-documents/story-args-section.ts +19 -0
- package/src/react/story-documents/story-documents.tsx +1380 -0
- package/src/react/story-paint-bounds.ts +94 -0
- package/src/react/ui-board-document.tsx +101 -0
- package/src/react/ui-board-title.ts +9 -0
- package/src/react/ui-component-board.ts +72 -0
- package/src/services/audio-pose-guard.ts +81 -0
- package/src/services/game-audio-unlock.ts +48 -0
- package/src/state-watch/StateWatchPanel.tsx +535 -0
- package/src/three/authoring/camera-runtime-inspector-section.tsx +135 -0
- package/src/three/authoring/constraint-inspector-section.tsx +189 -0
- package/src/three/authoring/design-time-renderer.ts +189 -0
- package/src/three/authoring/model-asset-inspector-section.css +41 -0
- package/src/three/authoring/model-asset-inspector-section.tsx +869 -0
- package/src/three/authoring/oid-source-persistence.ts +557 -0
- package/src/three/authoring/r3f-design-session.ts +1174 -0
- package/src/three/authoring/r3f-source-authoring-adapter.ts +5949 -0
- package/src/three/authoring/reflection-probe-inspector-section.tsx +76 -0
- package/src/three/authoring/spatial-audio-handles.ts +215 -0
- package/src/three/authoring/spatial-collider-handles.ts +229 -0
- package/src/three/authoring/spatial-joint-handles.ts +114 -0
- package/src/three/authoring/spatial-light-handles.ts +178 -0
- package/src/three/authoring/spatial-lod-handles.ts +93 -0
- package/src/three/authoring/spatial-particle-handles.ts +368 -0
- package/src/three/authoring/three-authoring-adapter.ts +1953 -0
- package/src/three/authoring/three-scene-identity.ts +19 -0
- package/src/three/authoring/three-spatial-handles.ts +161 -0
- package/src/three/authoring/typed-three-inspector.ts +528 -0
- package/src/three/component-verbs/extract-menu.ts +71 -0
- package/src/three/component-verbs/fork-menu.ts +78 -0
- package/src/three/component-verbs/internals-menu.ts +91 -0
- package/src/three/story-documents/three-story-documents.tsx +607 -0
- package/src/three/three-board/ThreeBoardDocument.tsx +888 -0
- package/src/three/three-board/board-framing.ts +412 -0
- package/src/three/three-board/board-layout.ts +401 -0
- package/src/three/three-board/board-scene.ts +901 -0
- package/src/three/three-board/three-component-board.ts +62 -0
- package/src/xstate/XStateBehaviorSection.tsx +130 -0
- package/src/xstate/XStateMachineInspector.tsx +566 -0
- package/src/xstate/character-animation-machine.fixture.ts +74 -0
- package/src/xstate/live-behaviors.ts +106 -0
- package/src/xstate/use-live-actor-state.ts +44 -0
- package/src/xstate/xstate-graph.ts +235 -0
- package/src/xstate/xstate-layout.ts +76 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PER-ROOT COVERAGE — the generated capability report for EVERY root the editor
|
|
3
|
+
* currently has mounted, native and ingested alike.
|
|
4
|
+
*
|
|
5
|
+
* ## The defect this closes
|
|
6
|
+
*
|
|
7
|
+
* Coverage used to be an ingest-only instrument: `ingest/mount-coverage.ts`
|
|
8
|
+
* assembled facts for the one ingested world and nothing said anything about a
|
|
9
|
+
* native root at all. So a per-root gap on a first-party root — the measured
|
|
10
|
+
* case was a project's HUD (`dom`) root whose inspector was dead — surfaced
|
|
11
|
+
* only as a one-off session error, never as a standing row, and closing it
|
|
12
|
+
* depended on somebody remembering it existed.
|
|
13
|
+
*
|
|
14
|
+
* The generator does not care which lane produced a root. It asks each mounted
|
|
15
|
+
* root's own `AuthoringAdapter` which providers it exposes
|
|
16
|
+
* (`measureAuthoringProviders`, whose vocabulary the compiler pins to the
|
|
17
|
+
* contract), diffs that against the full contract minus what the root's SURFACE
|
|
18
|
+
* kind cannot have, and every delta is a standing row. Nothing here consults a
|
|
19
|
+
* game's id, its route, or its manifest.
|
|
20
|
+
*
|
|
21
|
+
* ## Where the rows go
|
|
22
|
+
*
|
|
23
|
+
* Two doors, one derivation — the same shape `ingest/mount-coverage.ts` already
|
|
24
|
+
* uses:
|
|
25
|
+
*
|
|
26
|
+
* - `vgai status`, through {@link rootCoverageFacet}, so an agent reads the
|
|
27
|
+
* same answer without opening the editor;
|
|
28
|
+
* - the editor console, through `coverage/session-coverage.ts`, which unions
|
|
29
|
+
* this family with the game- and project-scoped ones so the warning's
|
|
30
|
+
* headline counts every seam rather than this family's 21. The console
|
|
31
|
+
* ledger turns that into a standing unresolved condition, loud on every
|
|
32
|
+
* `vgai` command until it is closed.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
import { measureAdapter } from '../host/adapter-reach';
|
|
36
|
+
import {
|
|
37
|
+
type MountedRootSubject,
|
|
38
|
+
mountedRootSubjects,
|
|
39
|
+
} from '@volter/editor-core/authoring/mounted-root-subjects';
|
|
40
|
+
import {
|
|
41
|
+
type CapabilityCoverageReport,
|
|
42
|
+
deriveCapabilityCoverage,
|
|
43
|
+
} from '../host/coverage/capability-coverage';
|
|
44
|
+
import type { AdapterSurface } from '@volter/editor-project/adapter/adapter-surface';
|
|
45
|
+
|
|
46
|
+
/** One root's report. `surface` rides along because it is what decides which
|
|
47
|
+
* absences were excused, and a reader must be able to check that. */
|
|
48
|
+
export interface RootCoverageReport {
|
|
49
|
+
readonly worldId: string;
|
|
50
|
+
readonly surface: AdapterSurface | null;
|
|
51
|
+
readonly report: CapabilityCoverageReport;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The generated report for one root.
|
|
56
|
+
*
|
|
57
|
+
* A root owns only authoring reach. Runtime, system-registry, and project facts
|
|
58
|
+
* are omitted, so the universal derivation produces no rows for those families.
|
|
59
|
+
*/
|
|
60
|
+
export function deriveRootCoverage(subject: MountedRootSubject): RootCoverageReport {
|
|
61
|
+
const report = deriveCapabilityCoverage({
|
|
62
|
+
worldId: subject.worldId,
|
|
63
|
+
reach: measureAdapter(subject.adapter, subject.worldId),
|
|
64
|
+
surface: subject.surface,
|
|
65
|
+
reachMechanism: null,
|
|
66
|
+
});
|
|
67
|
+
return {
|
|
68
|
+
worldId: subject.worldId,
|
|
69
|
+
surface: subject.surface,
|
|
70
|
+
report,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Every mounted root's report, re-derived on read — a root's adapter gains and
|
|
75
|
+
* loses providers during a session (a design session swaps itself in), so a
|
|
76
|
+
* cached answer would start lying. */
|
|
77
|
+
export function rootCoverageFacet(): readonly RootCoverageReport[] {
|
|
78
|
+
return mountedRootSubjects().map(deriveRootCoverage);
|
|
79
|
+
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ONE COVERAGE HEADLINE PER SESSION — the union of every derived family.
|
|
3
|
+
*
|
|
4
|
+
* ## The defect this closes
|
|
5
|
+
*
|
|
6
|
+
* Coverage grew a family at a time, and each family kept its own console door:
|
|
7
|
+
* `coverage/root-coverage.ts` printed the `editor.*` rows per mounted root,
|
|
8
|
+
* `coverage/native-system-coverage.ts` printed the `system.*` rows, and each
|
|
9
|
+
* one's headline counted only its own rows. So the loudest sentence the product
|
|
10
|
+
* says about its own completeness read "N of 21 seams are MISSING" — 21 being
|
|
11
|
+
* the `AuthoringAdapter` provider vocabulary plus `editor.capture`, and nothing
|
|
12
|
+
* else. A session could print "0 of 21" while an entire family of native verbs
|
|
13
|
+
* (`coverage/project-verb-coverage.ts`) was absent, because no surface anywhere
|
|
14
|
+
* summed the families.
|
|
15
|
+
*
|
|
16
|
+
* A count that names one family's total "seams" is the clean-answer failure the
|
|
17
|
+
* whole derivation exists to end: it is crisp, always available, correlated
|
|
18
|
+
* with the truth, and wrong in exactly the cases worth investigating. So the
|
|
19
|
+
* families are UNIONED before anything is said, the headline counts the union,
|
|
20
|
+
* and the per-family split rides in the same sentence — a reader sees both the
|
|
21
|
+
* total and which family it is short in, and cannot mistake one for the other.
|
|
22
|
+
*
|
|
23
|
+
* ## What this owns, and what it does not
|
|
24
|
+
*
|
|
25
|
+
* It owns assembly and the console door. Every family still derives itself, in
|
|
26
|
+
* its own file, from its own facts; nothing here decides a verdict. The
|
|
27
|
+
* per-family facets on `vgai status` (`command-listener.ts`) stay separate for
|
|
28
|
+
* the same reason they always were — a machine reader wants the rows keyed by
|
|
29
|
+
* subject, and it is the HUMAN-facing sentence that has to be a union.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import { mountedRootSubjects } from '@volter/editor-core/authoring/mounted-root-subjects';
|
|
33
|
+
import {
|
|
34
|
+
type CoveragePart,
|
|
35
|
+
formatCapabilityCoverageBlocks,
|
|
36
|
+
unionCoverageReport,
|
|
37
|
+
} from '../host/coverage/capability-coverage';
|
|
38
|
+
import { editorConsole } from '@volter/editor-core/editor-console';
|
|
39
|
+
import { editorIsPlaying } from '@volter/editor-core/editor-session-mode';
|
|
40
|
+
import { projectAdapterFacet } from '@volter/editor-core/project-adapter';
|
|
41
|
+
import { getCurrentProject } from '@volter/editor-core/project-manager';
|
|
42
|
+
import { authoringSurfaceCoverage } from './live-authoring-surface';
|
|
43
|
+
import { projectVerbCoverage } from './live-project-verbs';
|
|
44
|
+
import { nativeSystemCoverage } from './native-system-coverage';
|
|
45
|
+
import { type RootCoverageReport, rootCoverageFacet } from './root-coverage';
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Every family that has something to say about this session, in report order:
|
|
49
|
+
* the per-root `editor.*` families first (cheapest to reason about), then the
|
|
50
|
+
* game-scoped `system.*`, then the project-scoped `project.*`.
|
|
51
|
+
*
|
|
52
|
+
* A root's part carries its worldId as the label because the same seam
|
|
53
|
+
* legitimately appears once per mounted root; the game- and project-scoped
|
|
54
|
+
* families appear once and carry none.
|
|
55
|
+
*/
|
|
56
|
+
export function sessionCoverageParts(
|
|
57
|
+
/** The per-root family, already derived. Grading a root is the expensive
|
|
58
|
+
* half of this whole file (it re-walks the root's tree through the
|
|
59
|
+
* conformance probe), and `reportSessionCoverage` needs the same rows for
|
|
60
|
+
* its mount-in-progress guard — deriving them twice per five-second sample
|
|
61
|
+
* was pure duplication, measured at ~175ms a copy on a 1822-node canvas
|
|
62
|
+
* world. */
|
|
63
|
+
roots: readonly RootCoverageReport[] = rootCoverageFacet(),
|
|
64
|
+
): readonly CoveragePart[] {
|
|
65
|
+
const parts: CoveragePart[] = roots.map((entry) => ({
|
|
66
|
+
label: entry.worldId,
|
|
67
|
+
report: entry.report,
|
|
68
|
+
}));
|
|
69
|
+
const systems = nativeSystemCoverage();
|
|
70
|
+
if (systems) parts.push({ label: null, report: systems });
|
|
71
|
+
const project = projectVerbCoverage();
|
|
72
|
+
if (project) parts.push({ label: null, report: project });
|
|
73
|
+
const authoring = authoringSurfaceCoverage();
|
|
74
|
+
if (authoring) parts.push({ label: null, report: authoring });
|
|
75
|
+
return parts;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** The session's whole coverage answer as ONE report, or `null` when no family
|
|
79
|
+
* had anything to measure (nothing mounted, no project open). */
|
|
80
|
+
export function sessionCoverageReport(
|
|
81
|
+
roots?: readonly RootCoverageReport[],
|
|
82
|
+
): ReturnType<typeof unionCoverageReport> | null {
|
|
83
|
+
const parts = sessionCoverageParts(roots ?? rootCoverageFacet());
|
|
84
|
+
if (parts.length === 0) return null;
|
|
85
|
+
return unionCoverageReport(getCurrentProject()?.config.name ?? 'session', parts);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Say it out loud, once per distinct gap set.
|
|
90
|
+
*
|
|
91
|
+
* Keyed on the rendered TEXT rather than a mount or project token, because the
|
|
92
|
+
* union's inputs come and go inside one session (a root mounts, a design
|
|
93
|
+
* session attaches, `vgai add` lands a script) and the honest rule is "say it
|
|
94
|
+
* when the answer changes". A recurrence after a real change is a new condition
|
|
95
|
+
* and gets said again; the server ledger sums repeats of an unchanged one.
|
|
96
|
+
*/
|
|
97
|
+
const _said = new Set<string>();
|
|
98
|
+
let _pendingSignature: string | null = null;
|
|
99
|
+
let _pendingSamples = 0;
|
|
100
|
+
|
|
101
|
+
function clearPendingCoverage(): void {
|
|
102
|
+
_pendingSignature = null;
|
|
103
|
+
_pendingSamples = 0;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function reportSessionCoverage(): void {
|
|
107
|
+
// Edit-time source authoring is the subject of the per-root provider rows.
|
|
108
|
+
// Play temporarily swaps those adapters for runtime/live projections with a
|
|
109
|
+
// deliberately smaller vocabulary. Recording that temporary projection in
|
|
110
|
+
// the unresolved ledger makes a successful Play look like a standing Edit
|
|
111
|
+
// defect after Play has ended, so the report waits for Edit's adapters.
|
|
112
|
+
if (editorIsPlaying()) {
|
|
113
|
+
clearPendingCoverage();
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
// ONE grading pass per sample. Every guard below and the report itself read
|
|
117
|
+
// these same rows.
|
|
118
|
+
const roots = rootCoverageFacet();
|
|
119
|
+
const report = sessionCoverageReport(roots);
|
|
120
|
+
if (!report || report.summary.gaps === 0) {
|
|
121
|
+
clearPendingCoverage();
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
// Say nothing while nothing is MOUNTED. The families each stand down for
|
|
125
|
+
// states they cannot measure, but the project family legitimately has
|
|
126
|
+
// manifest-fact rows pre-mount — and a pre-mount headline is still a
|
|
127
|
+
// transient the ledger would hold forever (measured: a boot-time "N of N
|
|
128
|
+
// seams MISSING" snapshot stood beside the real post-mount report as a
|
|
129
|
+
// second unresolved warning). The mount is the moment the session becomes
|
|
130
|
+
// the thing coverage describes; until then, silence is the honest report.
|
|
131
|
+
//
|
|
132
|
+
// "Mounted" is what `mountedRootSubjects()` means by it, and a root the
|
|
133
|
+
// editor has merely DISCLOSED does not count — see that function's
|
|
134
|
+
// `isBoundaryDisclosure`. A declared world wears the boundary disclosure
|
|
135
|
+
// adapter for the whole of its mount's assembly, so a session mid-assembly
|
|
136
|
+
// has subjects that are not yet the thing coverage describes. The guard lives
|
|
137
|
+
// HERE, in the one report path, precisely so no caller's timing can plant a
|
|
138
|
+
// transient: the vitals sampler is periodic and lands wherever it lands.
|
|
139
|
+
const mounted = mountedRootSubjects();
|
|
140
|
+
if (mounted.length === 0) {
|
|
141
|
+
clearPendingCoverage();
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
// A multi-root project assembles its composite incrementally. The first live
|
|
145
|
+
// child is not yet the declared authoring surface, and the ledger cannot
|
|
146
|
+
// retract the partial-root warning after the remaining children attach.
|
|
147
|
+
// Wait for every shipped region by source-owned id; a single-root/bare
|
|
148
|
+
// adapter keeps its historical `root` identity and is already atomic.
|
|
149
|
+
const declared = projectAdapterFacet()?.regions ?? [];
|
|
150
|
+
if (declared.length > 1) {
|
|
151
|
+
const mountedIds = new Set(mounted.map((subject) => subject.worldId));
|
|
152
|
+
if (declared.some((region) => !mountedIds.has(region.id))) {
|
|
153
|
+
clearPendingCoverage();
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// A root whose hierarchy has not completed one valid operation is not yet a
|
|
158
|
+
// stable authoring subject. Provider gaps observed before that point are an
|
|
159
|
+
// assembly snapshot: the adapter object exists, but the tree every provider
|
|
160
|
+
// addresses does not. Do not make that snapshot permanent in the server
|
|
161
|
+
// ledger. The live status facet and Doctor's final coverage phase still
|
|
162
|
+
// report a hierarchy that genuinely never becomes valid; this guard only
|
|
163
|
+
// keeps the periodic console reporter from treating "mount in progress" as
|
|
164
|
+
// a completed session.
|
|
165
|
+
if (
|
|
166
|
+
roots.some(
|
|
167
|
+
(root) => root.report.rows.find((row) => row.seam === 'editor.capture')?.status !== 'ok',
|
|
168
|
+
)
|
|
169
|
+
) {
|
|
170
|
+
clearPendingCoverage();
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const head = `session coverage "${report.summary.worldId}"`;
|
|
174
|
+
const warnings = formatCapabilityCoverageBlocks(report, head).filter(
|
|
175
|
+
(block) => block.level === 'warn',
|
|
176
|
+
);
|
|
177
|
+
const signature = warnings.map((block) => block.message).join('\n---\n');
|
|
178
|
+
if (_pendingSignature === signature) _pendingSamples++;
|
|
179
|
+
else {
|
|
180
|
+
_pendingSignature = signature;
|
|
181
|
+
_pendingSamples = 1;
|
|
182
|
+
}
|
|
183
|
+
// HMR and cold-remount replace an adapter between two snapshots. A single
|
|
184
|
+
// conformance failure during that handoff is not a standing condition; the
|
|
185
|
+
// next five-second sample must reproduce the exact gap set before it enters
|
|
186
|
+
// the unresolved ledger. Genuine gaps remain loud one sample later.
|
|
187
|
+
if (_pendingSamples < 2) return;
|
|
188
|
+
for (const block of warnings) {
|
|
189
|
+
if (_said.has(block.message)) continue;
|
|
190
|
+
_said.add(block.message);
|
|
191
|
+
editorConsole.warn(block.message, 'coverage');
|
|
192
|
+
}
|
|
193
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { ensureCoreUtilitiesRegistered } from '@volter/editor-core/components/core-utilities';
|
|
2
|
+
import { ProjectHeader } from '@volter/editor-core/components/ProjectHeader';
|
|
3
|
+
import { ensureCoreStatusContributionsRegistered } from '@volter/editor-core/components/status-contributions';
|
|
4
|
+
import {
|
|
5
|
+
installStoryWorkspaceUtilityController,
|
|
6
|
+
StoryEditorRuntime,
|
|
7
|
+
} from '../host/design-system-stories/fixtures/editor-runtime';
|
|
8
|
+
import { DesignSystemPage, StorySection } from '../host/design-system-stories/StoryLayout';
|
|
9
|
+
import { useEditorStore } from '@volter/editor-core/editor-runtime';
|
|
10
|
+
import { getCurrentProject, setActiveProject } from '@volter/editor-core/project-manager';
|
|
11
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
12
|
+
import { useLayoutEffect, useState } from 'react';
|
|
13
|
+
// The transport is `@volter/editor-game`'s; this gallery story shows its view over
|
|
14
|
+
// the design system (a story, not the shell, so no host closure pin counts it).
|
|
15
|
+
import { PlayBarView } from '../play-bar/PlayBar';
|
|
16
|
+
|
|
17
|
+
const meta = {
|
|
18
|
+
title: 'Design System/Application Chrome/Production Shell',
|
|
19
|
+
parameters: { controls: { disable: true } },
|
|
20
|
+
} satisfies Meta;
|
|
21
|
+
|
|
22
|
+
export default meta;
|
|
23
|
+
type Story = StoryObj<typeof meta>;
|
|
24
|
+
|
|
25
|
+
function ProductionApplicationChrome() {
|
|
26
|
+
const store = useEditorStore();
|
|
27
|
+
const [, ready] = useState(0);
|
|
28
|
+
const [playState, setPlayState] = useState<'stopped' | 'playing' | 'paused'>('stopped');
|
|
29
|
+
const updatePlayState = (next: 'stopped' | 'playing' | 'paused') => {
|
|
30
|
+
store.setPlayState(next);
|
|
31
|
+
setPlayState(next);
|
|
32
|
+
};
|
|
33
|
+
useLayoutEffect(() => {
|
|
34
|
+
const previousProject = getCurrentProject();
|
|
35
|
+
setActiveProject({
|
|
36
|
+
rootPath: '/projects/orbit-workshop',
|
|
37
|
+
config: {
|
|
38
|
+
manifestVersion: 2,
|
|
39
|
+
name: 'Orbit Workshop',
|
|
40
|
+
version: '0.8.0',
|
|
41
|
+
engine: { version: '0.24.0' },
|
|
42
|
+
hasThreeRoot: true,
|
|
43
|
+
// A three root has no scene-file document — its TSX/R3F source IS the
|
|
44
|
+
// document — so `openProject` derives `null` here for every
|
|
45
|
+
// three-root project. Mirror that instead of inventing a scene path.
|
|
46
|
+
defaultScene: null,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
ensureCoreUtilitiesRegistered();
|
|
50
|
+
ensureCoreStatusContributionsRegistered();
|
|
51
|
+
const uninstallWorkspaceController = installStoryWorkspaceUtilityController();
|
|
52
|
+
ready((value) => value + 1);
|
|
53
|
+
return () => {
|
|
54
|
+
uninstallWorkspaceController();
|
|
55
|
+
setActiveProject(previousProject);
|
|
56
|
+
};
|
|
57
|
+
}, []);
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<DesignSystemPage
|
|
61
|
+
eyebrow="Production application shell"
|
|
62
|
+
title="Global commands and passive status stay global"
|
|
63
|
+
summary="This story renders the same connected project header, runtime telemetry, application menus, transport, status registry, and coding-conversation tray as the editor. Document, panel, and viewport-local chrome remain with their owning production surfaces."
|
|
64
|
+
testId="application-chrome-production"
|
|
65
|
+
>
|
|
66
|
+
<StorySection title="Global command header">
|
|
67
|
+
<div className="ds-production-chrome-stage">
|
|
68
|
+
<ProjectHeader
|
|
69
|
+
transport={
|
|
70
|
+
<PlayBarView
|
|
71
|
+
state={playState}
|
|
72
|
+
playEditRegime={playState === 'stopped' ? null : 'ephemeral'}
|
|
73
|
+
onPlay={() => updatePlayState(playState === 'stopped' ? 'playing' : 'stopped')}
|
|
74
|
+
onPause={() => updatePlayState(playState === 'paused' ? 'playing' : 'paused')}
|
|
75
|
+
onStep={() => undefined}
|
|
76
|
+
onRestart={() => updatePlayState('playing')}
|
|
77
|
+
onStop={() => updatePlayState('stopped')}
|
|
78
|
+
/>
|
|
79
|
+
}
|
|
80
|
+
/>
|
|
81
|
+
</div>
|
|
82
|
+
</StorySection>
|
|
83
|
+
</DesignSystemPage>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function chromeStory(style: 'classic' | 'glass', backdrop: 'dark' | 'light'): Story {
|
|
88
|
+
return {
|
|
89
|
+
globals: { material: style, backdrop },
|
|
90
|
+
render: () => (
|
|
91
|
+
<StoryEditorRuntime>
|
|
92
|
+
<ProductionApplicationChrome />
|
|
93
|
+
</StoryEditorRuntime>
|
|
94
|
+
),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export const Classic: Story = chromeStory('classic', 'dark');
|
|
99
|
+
export const GlassDark: Story = chromeStory('glass', 'dark');
|
|
100
|
+
export const GlassLight: Story = chromeStory('glass', 'light');
|