@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,331 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE SERVED BUNDLE'S DEPENDENCY LIST — what a vendored game's bare imports
|
|
3
|
+
* resolve to when its bytes are served as a static bundle rather than being
|
|
4
|
+
* part of the editor's own Vite graph.
|
|
5
|
+
*
|
|
6
|
+
* A game vendored as a SERVABLE BUNDLE (`public/ingest/<id>/`,
|
|
7
|
+
* `ingest/served-bundle.ts`) is fetched and bundled in the page
|
|
8
|
+
* (`browser-transpile.ts`, esbuild-wasm), with every bare import marked
|
|
9
|
+
* external. This module answers those externals: each one maps to a LAZY
|
|
10
|
+
* import of the editor's own live copy — `three`, `react`, fiber, Pixi, the
|
|
11
|
+
* engine — so the game shares the singletons the editor already runs (two
|
|
12
|
+
* copies of three break `instanceof`; two reconcilers cannot own one canvas).
|
|
13
|
+
*
|
|
14
|
+
* THE LIST IS DERIVED, NOT CURATED. Capabilities are the sanctioned way a
|
|
15
|
+
* game gains functionality, so the union of what the game template and the
|
|
16
|
+
* catalog's capabilities import IS the definition of the dependencies this
|
|
17
|
+
* resolver may have to answer — and it is computable.
|
|
18
|
+
* `scripts/check-served-bundle-modules.mjs` (pre-commit) holds this table to
|
|
19
|
+
* that union: a capability that starts importing a package this list does not
|
|
20
|
+
* ship, or a loader nothing imports any more, fails the commit by name. An import outside the list is a wall
|
|
21
|
+
* `browser-transpile.ts` states in product words; nothing degrades silently.
|
|
22
|
+
*
|
|
23
|
+
* THREE FAMILIES, one resolver ({@link servedBundleRuntimeModuleLoader}):
|
|
24
|
+
* - the explicit table below (packages and package subpaths);
|
|
25
|
+
* - every RUNTIME-PACKAGE module, by glob — `@volter/editor-project/<path>`,
|
|
26
|
+
* `@volter/threejs-runtime/<path>` and `@volter/game-runtime/<path>` resolve
|
|
27
|
+
* to the editor's own source, minus each package's Node-only modules;
|
|
28
|
+
* - three's two spellings of one file (`three/addons/*` ≡
|
|
29
|
+
* `three/examples/jsm/*`), so either registers both.
|
|
30
|
+
*
|
|
31
|
+
* Resolution is LAZY per specifier a game actually imports: a table this wide
|
|
32
|
+
* must never be awaited whole on first Play.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
import { registerRuntimeModuleResolver } from './browser-transpile';
|
|
36
|
+
|
|
37
|
+
let _resolverRegistered = false;
|
|
38
|
+
|
|
39
|
+
export const BUNDLE_RUNTIME_MODULE_LOADERS: Record<string, () => Promise<unknown>> = {
|
|
40
|
+
three: () => import('three'),
|
|
41
|
+
'three/addons/controls/OrbitControls.js': () => import('three/addons/controls/OrbitControls.js'),
|
|
42
|
+
'three/addons/controls/TrackballControls.js': () =>
|
|
43
|
+
import('three/addons/controls/TrackballControls.js'),
|
|
44
|
+
'three/addons/environments/RoomEnvironment.js': () =>
|
|
45
|
+
import('three/addons/environments/RoomEnvironment.js'),
|
|
46
|
+
'three/addons/math/ConvexHull.js': () => import('three/addons/math/ConvexHull.js'),
|
|
47
|
+
'three/addons/objects/MarchingCubes.js': () => import('three/addons/objects/MarchingCubes.js'),
|
|
48
|
+
'three/addons/interactive/SelectionBox.js': () =>
|
|
49
|
+
import('three/addons/interactive/SelectionBox.js'),
|
|
50
|
+
'three/addons/geometries/ConvexGeometry.js': () =>
|
|
51
|
+
import('three/addons/geometries/ConvexGeometry.js'),
|
|
52
|
+
'three/addons/geometries/TextGeometry.js': () =>
|
|
53
|
+
import('three/addons/geometries/TextGeometry.js'),
|
|
54
|
+
'three/addons/geometries/DecalGeometry.js': () =>
|
|
55
|
+
import('three/addons/geometries/DecalGeometry.js'),
|
|
56
|
+
'three/addons/geometries/RoundedBoxGeometry.js': () =>
|
|
57
|
+
import('three/addons/geometries/RoundedBoxGeometry.js'),
|
|
58
|
+
'three/addons/loaders/FontLoader.js': () => import('three/addons/loaders/FontLoader.js'),
|
|
59
|
+
'three/addons/loaders/HDRLoader.js': () => import('three/addons/loaders/HDRLoader.js'),
|
|
60
|
+
'three/addons/loaders/EXRLoader.js': () => import('three/addons/loaders/EXRLoader.js'),
|
|
61
|
+
'three/addons/loaders/GLTFLoader.js': () => import('three/addons/loaders/GLTFLoader.js'),
|
|
62
|
+
'three/addons/loaders/RGBELoader.js': () => import('three/addons/loaders/RGBELoader.js'),
|
|
63
|
+
'three/addons/objects/Sky.js': () => import('three/addons/objects/Sky.js'),
|
|
64
|
+
'three/addons/libs/lil-gui.module.min.js': () =>
|
|
65
|
+
import('three/addons/libs/lil-gui.module.min.js'),
|
|
66
|
+
'three/addons/libs/mikktspace.module.js': () => import('three/addons/libs/mikktspace.module.js'),
|
|
67
|
+
'three/addons/libs/stats.module.js': () => import('three/addons/libs/stats.module.js'),
|
|
68
|
+
'three/addons/libs/tween.module.js': () => import('three/addons/libs/tween.module.js'),
|
|
69
|
+
'three/addons/modifiers/SimplifyModifier.js': () =>
|
|
70
|
+
import('three/addons/modifiers/SimplifyModifier.js'),
|
|
71
|
+
'three/addons/postprocessing/EffectComposer.js': () =>
|
|
72
|
+
import('three/addons/postprocessing/EffectComposer.js'),
|
|
73
|
+
'three/addons/postprocessing/OutputPass.js': () =>
|
|
74
|
+
import('three/addons/postprocessing/OutputPass.js'),
|
|
75
|
+
'three/addons/postprocessing/RenderPass.js': () =>
|
|
76
|
+
import('three/addons/postprocessing/RenderPass.js'),
|
|
77
|
+
'three/addons/postprocessing/UnrealBloomPass.js': () =>
|
|
78
|
+
import('three/addons/postprocessing/UnrealBloomPass.js'),
|
|
79
|
+
'three/addons/renderers/CSS3DRenderer.js': () =>
|
|
80
|
+
import('three/addons/renderers/CSS3DRenderer.js'),
|
|
81
|
+
'three/addons/utils/BufferGeometryUtils.js': () =>
|
|
82
|
+
import('three/addons/utils/BufferGeometryUtils.js'),
|
|
83
|
+
'three/addons/utils/SkeletonUtils.js': () => import('three/addons/utils/SkeletonUtils.js'),
|
|
84
|
+
// Same module, second spelling: `three/addons/*` and `three/examples/jsm/*`
|
|
85
|
+
// are one file behind two export paths, and a shim is keyed by SPECIFIER, so
|
|
86
|
+
// both have to be registered — the examples' character code uses this one.
|
|
87
|
+
'three/examples/jsm/utils/SkeletonUtils.js': () =>
|
|
88
|
+
import('three/examples/jsm/utils/SkeletonUtils.js'),
|
|
89
|
+
'three/examples/jsm/animation/CCDIKSolver.js': () =>
|
|
90
|
+
import('three/examples/jsm/animation/CCDIKSolver.js'),
|
|
91
|
+
zod: () => import('zod'),
|
|
92
|
+
react: () => import('react'),
|
|
93
|
+
'react/jsx-runtime': () => import('react/jsx-runtime'),
|
|
94
|
+
'react-dom/client': () => import('react-dom/client'),
|
|
95
|
+
// R3F — what a game's world roots are made of. Without these,
|
|
96
|
+
// `browser-transpile.ts` throws "not a registered runtime module" and a TSX
|
|
97
|
+
// world in a served bundle cannot mount at all. Measured against what the
|
|
98
|
+
// template and every example import: fiber (23 sites), drei (15), rapier (11).
|
|
99
|
+
'@react-three/fiber': () => import('@react-three/fiber'),
|
|
100
|
+
'@react-three/drei': () => import('@react-three/drei'),
|
|
101
|
+
// Project source spells a runtime import by its published package name, and
|
|
102
|
+
// the loader resolves it through the editor's own source, so the project and
|
|
103
|
+
// the editor share one live module namespace.
|
|
104
|
+
'@volter/threejs-runtime/adapter/constraint': () =>
|
|
105
|
+
import('@volter/threejs-runtime/adapter/constraint'),
|
|
106
|
+
'@volter/game-runtime/adapter/first-party-audio-system': () =>
|
|
107
|
+
import('@volter/game-runtime/adapter/first-party-audio-system'),
|
|
108
|
+
'@volter/threejs-runtime/adapter/first-party-navigation-system': () =>
|
|
109
|
+
import('@volter/threejs-runtime/adapter/first-party-navigation-system'),
|
|
110
|
+
'@volter/threejs-runtime/adapter/hierarchy-marks': () =>
|
|
111
|
+
import('@volter/threejs-runtime/adapter/hierarchy-marks'),
|
|
112
|
+
'@volter/editor-project/adapter/system-adapter': () => import('@volter/editor-project/adapter/system-adapter'),
|
|
113
|
+
'@volter/threejs-runtime/ai/navigation': () => import('@volter/threejs-runtime/ai/navigation'),
|
|
114
|
+
'@volter/threejs-runtime/animation/animation-clock': () =>
|
|
115
|
+
import('@volter/threejs-runtime/animation/animation-clock'),
|
|
116
|
+
'@volter/threejs-runtime/animation/xstate-animation-binding': () =>
|
|
117
|
+
import('@volter/threejs-runtime/animation/xstate-animation-binding'),
|
|
118
|
+
'@volter/game-runtime/canvas-react': () => import('@volter/game-runtime/canvas-react'),
|
|
119
|
+
// `@volter/game-runtime/config` also exports the Node-only Vite data-check plugin.
|
|
120
|
+
// Hosted project code only consumes its browser-safe schema primitives, so
|
|
121
|
+
// assemble that namespace from their source modules without pulling node:fs
|
|
122
|
+
// into the editor build.
|
|
123
|
+
'@volter/game-runtime/config': async () => ({
|
|
124
|
+
...(await import('@volter/game-runtime/data/curve')),
|
|
125
|
+
...(await import('@volter/game-runtime/data/data-ref')),
|
|
126
|
+
}),
|
|
127
|
+
'@volter/game-runtime/data/curve': () => import('@volter/game-runtime/data/curve'),
|
|
128
|
+
'@volter/game-runtime/data/data-asset': () => import('@volter/game-runtime/data/data-asset'),
|
|
129
|
+
'@volter/game-runtime/dev/instruments': () => import('@volter/game-runtime/dev/instruments'),
|
|
130
|
+
'@volter/threejs-runtime/loader': () => import('@volter/threejs-runtime/loader'),
|
|
131
|
+
'@volter/game-runtime/react/world-state': () => import('@volter/game-runtime/react/world-state'),
|
|
132
|
+
'@volter/game-runtime/runtime/debug-registry': () =>
|
|
133
|
+
import('@volter/game-runtime/runtime/debug-registry'),
|
|
134
|
+
'@volter/game-runtime/runtime/game': () => import('@volter/game-runtime/runtime/game'),
|
|
135
|
+
'@volter/game-runtime/world3d-react': () => import('@volter/game-runtime/world3d-react'),
|
|
136
|
+
'@volter/game-runtime/world3d-react/rapier-physics-bridge': () =>
|
|
137
|
+
import('@volter/game-runtime/world3d-react/rapier-physics-bridge'),
|
|
138
|
+
// …and the factory that mounts an example's default-exported world. A
|
|
139
|
+
// three root cannot mount hosted without it.
|
|
140
|
+
// The mesh-kit's two library-backed modifiers. `src/lib/mesh/modifiers.ts` —
|
|
141
|
+
// scaffolded into EVERY default project by the humanoid capability, and
|
|
142
|
+
// present verbatim in the template and four examples — imports both at
|
|
143
|
+
// module scope (`Brush`/`Evaluator` from three-bvh-csg, `MeshBVH` from
|
|
144
|
+
// three-mesh-bvh). The moment that source is browser-transpiled instead of
|
|
145
|
+
// pre-bundled, an unregistered specifier makes `shimUrlFor` throw "not a
|
|
146
|
+
// registered runtime module" — in the DEPLOYED build only, where typecheck
|
|
147
|
+
// cannot see it. Registered here so the transpile path resolves them to the
|
|
148
|
+
// editor's live singletons, same as `three` itself — both build on THREE
|
|
149
|
+
// (`Brush extends THREE.Mesh`; `MeshBVH` is handed real BufferGeometry), so
|
|
150
|
+
// a second copy carrying its own THREE would break `instanceof`.
|
|
151
|
+
'three-bvh-csg': () => import('three-bvh-csg'),
|
|
152
|
+
'three-mesh-bvh': () => import('three-mesh-bvh'),
|
|
153
|
+
// `@volter/editor-project/adapter` is TYPE-ONLY since P-6, so a project importing it emits
|
|
154
|
+
// nothing and never reaches this table; the entry stays as a harmless
|
|
155
|
+
// backstop. The seam's IMPLEMENTERS now live at their own paths, and a
|
|
156
|
+
// project that calls one needs that path registered — top-down-strategy's
|
|
157
|
+
// `use-squad.ts` calls `createNavigationAdapter`. Caught by
|
|
158
|
+
// `browser-bundle-runtime-modules.test.ts`, which regenerates the real
|
|
159
|
+
// bundle; without this, hosted Play throws "not a registered runtime module".
|
|
160
|
+
'@volter/editor-project/adapter': () => import('@volter/editor-project/adapter'),
|
|
161
|
+
// feature-scenes' WaterSurface loads its detail normal map via the shared cache:
|
|
162
|
+
'@volter/threejs-runtime/asset-loaders': () => import('@volter/threejs-runtime/asset-loaders'),
|
|
163
|
+
'@volter/threejs-runtime/ecs/scene-query': () => import('@volter/threejs-runtime/ecs/scene-query'),
|
|
164
|
+
'@volter/threejs-runtime/ecs/user-data': () => import('@volter/threejs-runtime/ecs/user-data'),
|
|
165
|
+
'@volter/threejs-runtime/setup/setup-renderer': () =>
|
|
166
|
+
import('@volter/threejs-runtime/setup/setup-renderer'),
|
|
167
|
+
// littlest-tokyo (GLTF quick-start) extras:
|
|
168
|
+
'@volter/game-runtime/input/rebind-controller': () =>
|
|
169
|
+
import('@volter/game-runtime/input/rebind-controller'),
|
|
170
|
+
// The generic fetched-asset parse error — the template's and
|
|
171
|
+
// top-down-strategy's `runtime/pixi-adapter.ts` raise it, so a canvas root
|
|
172
|
+
// cannot mount hosted without it registered.
|
|
173
|
+
'@volter/threejs-runtime/asset-parse-error': () =>
|
|
174
|
+
import('@volter/threejs-runtime/asset-parse-error'),
|
|
175
|
+
// rendering-scale's render lab drives the engine's batch renderer + scoped
|
|
176
|
+
// render settings directly:
|
|
177
|
+
'@volter/threejs-runtime/render/render-batch-system': () =>
|
|
178
|
+
import('@volter/threejs-runtime/render/render-batch-system'),
|
|
179
|
+
'@volter/threejs-runtime/render/render-settings': () =>
|
|
180
|
+
import('@volter/threejs-runtime/render/render-settings'),
|
|
181
|
+
// The bundle inlines @colyseus/schema (modular-action's rooms), and the
|
|
182
|
+
// library's own BUFFER_SIZE warning string contains a verbatim
|
|
183
|
+
// `import ... from "@colyseus/schema"` snippet the drift-guard's lexical
|
|
184
|
+
// scan cannot tell from a real external. Registering the loader is the
|
|
185
|
+
// safe answer either way: if the specifier ever becomes a true external,
|
|
186
|
+
// hosted Play resolves it instead of throwing.
|
|
187
|
+
'@colyseus/schema': () => import('@colyseus/schema'),
|
|
188
|
+
// The rest of the runtime closure of the template and the catalog's
|
|
189
|
+
// capabilities. Each entry names its importer, so a removal is checked
|
|
190
|
+
// against the same sweep.
|
|
191
|
+
'@colyseus/sdk': () => import('@colyseus/sdk'), // template main.ts
|
|
192
|
+
'react-dom': () => import('react-dom'), // react-root capability's flushSync
|
|
193
|
+
// ---- Editor-citizen modules PROJECT TOOL CONTRIBUTIONS import. A
|
|
194
|
+
// contribution is project source rendered inside the editor's own panels,
|
|
195
|
+
// so these must resolve to the editor's LIVE modules — a second copy of the
|
|
196
|
+
// contributions SDK would register into a registry nothing reads, exactly
|
|
197
|
+
// the two-reconcilers failure `@pixi/react` documents above.
|
|
198
|
+
'@volter/editor-sdk': () => import('@volter/editor-sdk'),
|
|
199
|
+
'@volter/editor-sdk/layouts': () => import('@volter/editor-sdk/layouts'),
|
|
200
|
+
'@volter/editor-sdk/layout-arrangements': () => import('@volter/editor-sdk/layout-arrangements'),
|
|
201
|
+
'@volter/editor-sdk/contributions': () => import('@volter/editor-sdk/contributions'),
|
|
202
|
+
'@volter/editor-sdk/widgets': () => import('@volter/editor-sdk/widgets'),
|
|
203
|
+
'@editor/game-module-access': () => import('./game-module-access'),
|
|
204
|
+
'@volter/editor-sdk/tools': () => import('./sdk/tools'),
|
|
205
|
+
'@volter/editor-sdk/generations': () => import('@volter/editor-sdk/generations'),
|
|
206
|
+
// Project stories usually import `@storybook/react` types only (erased),
|
|
207
|
+
// but a value import must be the SAME csf-tools instance the editor's
|
|
208
|
+
// story registry composes with.
|
|
209
|
+
'@storybook/react': () => import('@storybook/react'),
|
|
210
|
+
// three subpaths the estate spells out (both spellings resolve — see the
|
|
211
|
+
// resolver below); GLTFExporter is the bake tools' writer, FBX/OBJ the
|
|
212
|
+
// model-import readers, ShaderPass/Pass the post-processing customizers.
|
|
213
|
+
'three/addons/exporters/GLTFExporter.js': () => import('three/addons/exporters/GLTFExporter.js'),
|
|
214
|
+
'three/addons/loaders/FBXLoader.js': () => import('three/addons/loaders/FBXLoader.js'),
|
|
215
|
+
'three/addons/loaders/OBJLoader.js': () => import('three/addons/loaders/OBJLoader.js'),
|
|
216
|
+
'three/addons/postprocessing/ShaderPass.js': () =>
|
|
217
|
+
import('three/addons/postprocessing/ShaderPass.js'),
|
|
218
|
+
'three/addons/postprocessing/Pass.js': () => import('three/addons/postprocessing/Pass.js'),
|
|
219
|
+
'three/addons/animation/CCDIKSolver.js': () => import('three/addons/animation/CCDIKSolver.js'),
|
|
220
|
+
// drei's per-component entries — the same module graph as the package root
|
|
221
|
+
// (drei has no `exports` map; these are its real files), so identities match.
|
|
222
|
+
'@react-three/drei/core/RoundedBox': () => import('@react-three/drei/core/RoundedBox'),
|
|
223
|
+
'@react-three/drei/core/OrbitControls': () => import('@react-three/drei/core/OrbitControls'),
|
|
224
|
+
'@react-three/drei/core/PerspectiveCamera': () =>
|
|
225
|
+
import('@react-three/drei/core/PerspectiveCamera'),
|
|
226
|
+
'@react-three/drei/core/OrthographicCamera': () =>
|
|
227
|
+
import('@react-three/drei/core/OrthographicCamera'),
|
|
228
|
+
'@react-three/drei/core/Gltf': () => import('@react-three/drei/core/Gltf'),
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
/** The bundle-external specifiers this resolver can shim at Play time. */
|
|
232
|
+
export const REGISTERED_BUNDLE_SPECIFIERS: readonly string[] = Object.keys(
|
|
233
|
+
BUNDLE_RUNTIME_MODULE_LOADERS,
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Every RUNTIME-PACKAGE source module, lazily, keyed by its path under that
|
|
238
|
+
* package's `src/`. A game's source spells a runtime package by its published
|
|
239
|
+
* name (`@volter/threejs-runtime/adapter/constraint`), and it resolves HERE, to
|
|
240
|
+
* the editor's own copy, which is what keeps the runtime's singletons single.
|
|
241
|
+
* The exclusions name each package's Node-only modules (`node:fs` at module
|
|
242
|
+
* scope); a project importing one gets the wall, correctly — they do not
|
|
243
|
+
* exist in a browser.
|
|
244
|
+
*
|
|
245
|
+
* One `import.meta.glob` per package because the call must be statically
|
|
246
|
+
* analyzable: Vite reads the literal array, so a loop over package names
|
|
247
|
+
* cannot express it.
|
|
248
|
+
*
|
|
249
|
+
* `@volter/game-runtime/config` stays in the explicit table above: its published
|
|
250
|
+
* entry also exports the Node-only Vite data plugin, so the browser namespace
|
|
251
|
+
* is assembled from its browser-safe halves there, and the explicit table wins.
|
|
252
|
+
*/
|
|
253
|
+
const PROJECT_SOURCE_MODULES = import.meta.glob([
|
|
254
|
+
'../../../editor-project/src/**/*.ts',
|
|
255
|
+
'../../../editor-project/src/**/*.tsx',
|
|
256
|
+
'!**/*.d.ts',
|
|
257
|
+
'!**/manifest/load-file.ts',
|
|
258
|
+
'!**/manifest/locate.ts',
|
|
259
|
+
'!**/manifest/kind-modules.ts',
|
|
260
|
+
'!**/manifest/runtime-environment.ts',
|
|
261
|
+
]) as Record<string, () => Promise<unknown>>;
|
|
262
|
+
|
|
263
|
+
const THREEJS_RUNTIME_SOURCE_MODULES = import.meta.glob([
|
|
264
|
+
'../../../threejs-runtime/src/**/*.ts',
|
|
265
|
+
'../../../threejs-runtime/src/**/*.tsx',
|
|
266
|
+
'!**/*.d.ts',
|
|
267
|
+
]) as Record<string, () => Promise<unknown>>;
|
|
268
|
+
|
|
269
|
+
const GAME_RUNTIME_SOURCE_MODULES = import.meta.glob([
|
|
270
|
+
'../../../game-runtime/src/**/*.ts',
|
|
271
|
+
'../../../game-runtime/src/**/*.tsx',
|
|
272
|
+
'!**/*.d.ts',
|
|
273
|
+
'!**/data/vite-plugin-data.ts',
|
|
274
|
+
// `config.ts` statically re-exports the data-check Vite plugin (node:fs), so
|
|
275
|
+
// the published entry is Node-tainted as a whole — the explicit table above
|
|
276
|
+
// assembles `@volter/game-runtime/config`'s browser-safe namespace instead.
|
|
277
|
+
'!**/src/config.ts',
|
|
278
|
+
]) as Record<string, () => Promise<unknown>>;
|
|
279
|
+
|
|
280
|
+
/** package name -> [its glob root, its lazy module table]. */
|
|
281
|
+
const RUNTIME_PACKAGE_SOURCES: readonly (readonly [
|
|
282
|
+
string,
|
|
283
|
+
string,
|
|
284
|
+
Record<string, () => Promise<unknown>>,
|
|
285
|
+
])[] = [
|
|
286
|
+
['@volter/editor-project', '../../../editor-project/src/', PROJECT_SOURCE_MODULES],
|
|
287
|
+
['@volter/threejs-runtime', '../../../threejs-runtime/src/', THREEJS_RUNTIME_SOURCE_MODULES],
|
|
288
|
+
['@volter/game-runtime', '../../../game-runtime/src/', GAME_RUNTIME_SOURCE_MODULES],
|
|
289
|
+
];
|
|
290
|
+
|
|
291
|
+
function runtimePackageLoader(specifier: string): (() => Promise<unknown>) | undefined {
|
|
292
|
+
for (const [name, root, modules] of RUNTIME_PACKAGE_SOURCES) {
|
|
293
|
+
if (specifier !== name && !specifier.startsWith(`${name}/`)) continue;
|
|
294
|
+
const subpath = specifier === name ? 'index' : specifier.slice(name.length + 1);
|
|
295
|
+
const base = `${root}${subpath.replace(/\.(?:[cm]?js|tsx?)$/, '')}`;
|
|
296
|
+
return modules[`${base}.ts`] ?? modules[`${base}.tsx`] ?? modules[`${base}/index.ts`];
|
|
297
|
+
}
|
|
298
|
+
return undefined;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* The one resolver `browser-transpile.ts` asks: a bare specifier → a lazy
|
|
303
|
+
* loader of the editor's live copy, or `undefined` when the editor does not
|
|
304
|
+
* ship it. `scripts/validate-browser-runtime-modules.mjs` mirrors
|
|
305
|
+
* these three rules over the estate's source (it cannot import this module,
|
|
306
|
+
* which is Vite-only through `import.meta.glob`); the two are kept to the same
|
|
307
|
+
* shape on purpose, and the gate's header names this function as its twin.
|
|
308
|
+
*/
|
|
309
|
+
export function servedBundleRuntimeModuleLoader(
|
|
310
|
+
specifier: string,
|
|
311
|
+
): (() => Promise<unknown>) | undefined {
|
|
312
|
+
const explicit = BUNDLE_RUNTIME_MODULE_LOADERS[specifier];
|
|
313
|
+
if (explicit) return explicit;
|
|
314
|
+
const runtimePackage = runtimePackageLoader(specifier);
|
|
315
|
+
if (runtimePackage) return runtimePackage;
|
|
316
|
+
if (specifier.startsWith('three/examples/jsm/')) {
|
|
317
|
+
return BUNDLE_RUNTIME_MODULE_LOADERS[specifier.replace('three/examples/jsm/', 'three/addons/')];
|
|
318
|
+
}
|
|
319
|
+
if (specifier.startsWith('three/addons/')) {
|
|
320
|
+
return BUNDLE_RUNTIME_MODULE_LOADERS[specifier.replace('three/addons/', 'three/examples/jsm/')];
|
|
321
|
+
}
|
|
322
|
+
return undefined;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/** Install the resolver once. Nothing loads here — a specifier loads the first
|
|
326
|
+
* time a project imports it (`ensureBareImportsLoaded`). */
|
|
327
|
+
export async function ensureServedBundleRuntimeModules(): Promise<void> {
|
|
328
|
+
if (_resolverRegistered) return;
|
|
329
|
+
registerRuntimeModuleResolver(servedBundleRuntimeModuleLoader);
|
|
330
|
+
_resolverRegistered = true;
|
|
331
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The dev server's `server-log` stream → the editor console. This lives
|
|
3
|
+
* BESIDE the console rather than in it: the console is a sink the shell feeds
|
|
4
|
+
* and never a transport client (ARCHITECTURE-CORE §Editor chrome, "the
|
|
5
|
+
* viewport stack is separable"), so the one place that knows both the SSE
|
|
6
|
+
* endpoint and the console is this shell-side bridge, mounted once by the
|
|
7
|
+
* session's viewport panel.
|
|
8
|
+
*/
|
|
9
|
+
import { getServerValidationLog } from '@volter/editor-core/api/project-state';
|
|
10
|
+
import { emitServerLogEntry } from '@volter/editor-core/editor-console';
|
|
11
|
+
import { connectEvents } from '@volter/editor-core/editor-presence';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Connect to the editor SSE endpoint and pipe `server-log` events
|
|
15
|
+
* into the editor console tagged with source 'server'.
|
|
16
|
+
*
|
|
17
|
+
* PD-13: `server-log` is a LIVE broadcast with no replay, and the dev server
|
|
18
|
+
* validates the whole project at boot — before any tab exists. Every R3F00x
|
|
19
|
+
* authoring warning found then was announced to zero clients, and
|
|
20
|
+
* `runFileValidation` re-broadcasts a file's warnings only when the SET
|
|
21
|
+
* CHANGES, so it was never announced again: the terminal had them and this
|
|
22
|
+
* console did not. After attaching the live listener we therefore PULL the
|
|
23
|
+
* current set from `/__editor/validation-log` and render it through the same
|
|
24
|
+
* `emitServerLogEntry`. Attach-then-pull, in that order, because the failure
|
|
25
|
+
* we can tolerate is showing one line twice, not losing a live one.
|
|
26
|
+
*/
|
|
27
|
+
export function connectServerLogs(): () => void {
|
|
28
|
+
// Browser mode has no Node dev server, so `/__editor/events`
|
|
29
|
+
// does not exist — an unconditional `EventSource` here would auto-retry
|
|
30
|
+
// against a dead endpoint forever (the same anti-pattern A2 already fixed
|
|
31
|
+
// for the CLI/asset/scene SSE consumers via `getEditorMode() === 'browser'`
|
|
32
|
+
// guards; this one was missed). There is no browser-mode server-log source
|
|
33
|
+
// to bridge from, so this is a clean skip, not a routed replacement.
|
|
34
|
+
const source = connectEvents();
|
|
35
|
+
|
|
36
|
+
source.addEventListener('server-log', (e: MessageEvent) => {
|
|
37
|
+
try {
|
|
38
|
+
emitServerLogEntry(JSON.parse(e.data) as { level: string; message: string });
|
|
39
|
+
} catch {
|
|
40
|
+
/* ignore malformed events */
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
let released = false;
|
|
45
|
+
void (async () => {
|
|
46
|
+
try {
|
|
47
|
+
const entries = await getServerValidationLog();
|
|
48
|
+
if (released) return;
|
|
49
|
+
for (const entry of entries) emitServerLogEntry(entry);
|
|
50
|
+
} catch {
|
|
51
|
+
// A server that predates this endpoint (or a torn-down one) simply has
|
|
52
|
+
// nothing to replay — never a reason to break the live listener above.
|
|
53
|
+
}
|
|
54
|
+
})();
|
|
55
|
+
|
|
56
|
+
return () => {
|
|
57
|
+
released = true;
|
|
58
|
+
source.close();
|
|
59
|
+
};
|
|
60
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE STAGED PROJECTS' ADDRESSES — where this editor build serves the games
|
|
3
|
+
* it vendors as servable bundles (`public/ingest/<id>/`, the repo's
|
|
4
|
+
* `vendor/games` locks), the way `/examples/<id>/` serves its examples.
|
|
5
|
+
* Staged content is the HOST's catalog: the New Project screen's IMPORTED
|
|
6
|
+
* group (`imported-gallery.ts`, the generated gallery) and the in-tree fixture
|
|
7
|
+
* registry (`ingest/registry.ts`) read these; the LANE that mounts an
|
|
8
|
+
* unmodified game (`@volter/editor-game`'s `src/ingest/`) resolves a
|
|
9
|
+
* staged manifest to a mountable game from the same addresses.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** Root-relative base every vendored ingest is served under. */
|
|
13
|
+
export const PUBLIC_INGEST_BASE = '/ingest/';
|
|
14
|
+
|
|
15
|
+
/** A single path segment: no separators, no traversal, no query/hash. */
|
|
16
|
+
const SAFE_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
17
|
+
|
|
18
|
+
export function isSafeIngestId(id: string): boolean {
|
|
19
|
+
return SAFE_ID_RE.test(id) && id !== '.' && id !== '..';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function publicIngestManifestUrl(id: string): string {
|
|
23
|
+
return `${PUBLIC_INGEST_BASE}${id}/vgai.project.json`;
|
|
24
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A mounted portable story, retained until its owner AND every viewport
|
|
3
|
+
* borrower has finished with it.
|
|
4
|
+
*
|
|
5
|
+
* It lives beside `story-three-preview.ts` — the module that mounts and
|
|
6
|
+
* disposes the `MountedStoryObject3D` it wraps — rather than inside any one
|
|
7
|
+
* document, because TWO documents own a mount on these terms: the isolation
|
|
8
|
+
* SCENE document (`components/scene-documents.tsx`) and the per-story 3D
|
|
9
|
+
* document. A document that opens a mounted story is a contribution; the
|
|
10
|
+
* retain/release physics of the mount underneath it is the host's, the same
|
|
11
|
+
* way `story-three-preview.ts` and the story registry are.
|
|
12
|
+
*
|
|
13
|
+
* See `story-three-preview.ts`'s header for the measured black-panel defect a
|
|
14
|
+
* SECOND owner of one mount produces: `build()` hands out a borrow whose
|
|
15
|
+
* `dispose()` returns it, and the underlying Object3D is disposed only once
|
|
16
|
+
* the owner has retired AND no borrow is outstanding.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { disposeStoryObject3D, type MountedStoryObject3D } from '@volter/editor-core/stories/story-three-preview';
|
|
20
|
+
|
|
21
|
+
export interface MountedStoryViewportSource {
|
|
22
|
+
readonly build: () => {
|
|
23
|
+
root: MountedStoryObject3D['root'];
|
|
24
|
+
hierarchyRoots: readonly MountedStoryObject3D['root'][];
|
|
25
|
+
update: (deltaSeconds: number) => void;
|
|
26
|
+
dispose: () => void;
|
|
27
|
+
};
|
|
28
|
+
readonly dispose: () => void;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function mountedStoryViewportSource(
|
|
32
|
+
mounted: MountedStoryObject3D,
|
|
33
|
+
): MountedStoryViewportSource {
|
|
34
|
+
let retired = false;
|
|
35
|
+
let released = false;
|
|
36
|
+
let borrowers = 0;
|
|
37
|
+
const release = () => {
|
|
38
|
+
if (!retired || borrowers !== 0 || released) return;
|
|
39
|
+
released = true;
|
|
40
|
+
void disposeStoryObject3D(mounted);
|
|
41
|
+
};
|
|
42
|
+
return {
|
|
43
|
+
build: () => {
|
|
44
|
+
if (released) throw new Error('This story source has already been released.');
|
|
45
|
+
borrowers++;
|
|
46
|
+
let returned = false;
|
|
47
|
+
return {
|
|
48
|
+
root: mounted.root,
|
|
49
|
+
hierarchyRoots: [...mounted.root.children],
|
|
50
|
+
update: (deltaSeconds) => mounted.advance(deltaSeconds),
|
|
51
|
+
dispose: () => {
|
|
52
|
+
if (returned) return;
|
|
53
|
+
returned = true;
|
|
54
|
+
borrowers--;
|
|
55
|
+
release();
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
},
|
|
59
|
+
dispose: () => {
|
|
60
|
+
retired = true;
|
|
61
|
+
release();
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ONE rule for "which portable-story args are editable, and as what" —
|
|
3
|
+
* extracted verbatim from `authoring/react-world-authoring-adapter.ts`'s
|
|
4
|
+
* private `portableStoryArgDescriptors` (the Storybook-Controls semantic it has
|
|
5
|
+
* always applied to a story node in the React hierarchy), so the three-story
|
|
6
|
+
* board's per-story document describes its args the SAME way instead of
|
|
7
|
+
* inventing a second answer.
|
|
8
|
+
*
|
|
9
|
+
* Storybook's own Controls semantic: a story's arg is editable when it carries
|
|
10
|
+
* a primitive value the author can meaningfully type; anything else (a
|
|
11
|
+
* callback, a symbol, an unset arg) stays out of the visual form while
|
|
12
|
+
* remaining present in the complete args object the composed story is rendered
|
|
13
|
+
* with. Non-primitive OBJECT/array values are surfaced as `json`, which is what
|
|
14
|
+
* the generic inspector's JSON widget is for.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { PropertyDescriptor } from '@volter/editor-project/adapter';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Descriptors for one composed story's args, under `pathPrefix`.
|
|
21
|
+
*
|
|
22
|
+
* `pathPrefix` is the caller's, because the path namespace belongs to whoever
|
|
23
|
+
* owns the inspector node the descriptors are read back through — the React
|
|
24
|
+
* world adapter keys its story nodes under `story.arg.`, and the three-story
|
|
25
|
+
* document uses its own.
|
|
26
|
+
*/
|
|
27
|
+
export function storyArgPropertyDescriptors(
|
|
28
|
+
args: Record<string, unknown>,
|
|
29
|
+
pathPrefix: string,
|
|
30
|
+
): PropertyDescriptor[] {
|
|
31
|
+
return Object.entries(args).flatMap(([name, value]) => {
|
|
32
|
+
if (typeof value === 'function' || typeof value === 'symbol' || value === undefined) return [];
|
|
33
|
+
const type: PropertyDescriptor['type'] =
|
|
34
|
+
typeof value === 'boolean'
|
|
35
|
+
? 'boolean'
|
|
36
|
+
: typeof value === 'number'
|
|
37
|
+
? 'number'
|
|
38
|
+
: typeof value === 'string'
|
|
39
|
+
? 'string'
|
|
40
|
+
: 'json';
|
|
41
|
+
return [
|
|
42
|
+
{
|
|
43
|
+
path: `${pathPrefix}${name}`,
|
|
44
|
+
label: name,
|
|
45
|
+
type,
|
|
46
|
+
group: 'Args',
|
|
47
|
+
},
|
|
48
|
+
];
|
|
49
|
+
});
|
|
50
|
+
}
|