@volter/sdk 0.0.0-stage → 0.5.204

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (523) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +20 -0
  3. package/README.md +38 -3
  4. package/package.json +510 -4
  5. package/src/account.ts +210 -0
  6. package/src/chrome.ts +88 -0
  7. package/src/client.ts +1646 -0
  8. package/src/commands.ts +66 -0
  9. package/src/contributions.ts +619 -0
  10. package/src/css-numeric-style.ts +97 -0
  11. package/src/document-probe.ts +282 -0
  12. package/src/editor-view.ts +225 -0
  13. package/src/extension.ts +40 -0
  14. package/src/generations.ts +178 -0
  15. package/src/host.ts +1157 -0
  16. package/src/http-transport.browser.ts +14 -0
  17. package/src/http-transport.node.ts +19 -0
  18. package/src/index.ts +131 -0
  19. package/src/kit/CapabilityCoverageSection.tsx +185 -0
  20. package/src/kit/account-client.ts +333 -0
  21. package/src/kit/action-registry.ts +317 -0
  22. package/src/kit/active-product.ts +76 -0
  23. package/src/kit/active-project.ts +155 -0
  24. package/src/kit/adapter-editor-config.ts +25 -0
  25. package/src/kit/adapter-module.ts +7 -0
  26. package/src/kit/adapter-observation.ts +49 -0
  27. package/src/kit/animation/animation-clock.ts +479 -0
  28. package/src/kit/animation/stage-transport.ts +385 -0
  29. package/src/kit/api/assets.ts +365 -0
  30. package/src/kit/api/project-open.ts +355 -0
  31. package/src/kit/api/project-source.ts +180 -0
  32. package/src/kit/api/project-state.ts +110 -0
  33. package/src/kit/api/relay.ts +270 -0
  34. package/src/kit/api/themes.ts +45 -0
  35. package/src/kit/api-asset-library-wire.ts +45 -0
  36. package/src/kit/api-base.ts +10 -0
  37. package/src/kit/api-build.ts +99 -0
  38. package/src/kit/api-git-wire.ts +56 -0
  39. package/src/kit/api-logs.ts +92 -0
  40. package/src/kit/api-project-identity.ts +74 -0
  41. package/src/kit/api-settings.ts +36 -0
  42. package/src/kit/api-worktrees.ts +205 -0
  43. package/src/kit/asset-capabilities.ts +344 -0
  44. package/src/kit/asset-compare-core.ts +171 -0
  45. package/src/kit/asset-editor-context.tsx +101 -0
  46. package/src/kit/asset-events.ts +96 -0
  47. package/src/kit/asset-inspector-actions.ts +87 -0
  48. package/src/kit/asset-selection-viewer-registry.ts +113 -0
  49. package/src/kit/asset-selection.ts +146 -0
  50. package/src/kit/asset-thumbnails.ts +25 -0
  51. package/src/kit/asset-viewers.ts +115 -0
  52. package/src/kit/asset-workflow/asset-import-jobs.ts +106 -0
  53. package/src/kit/asset-workflow/asset-ledger-backend.ts +126 -0
  54. package/src/kit/asset-workflow/asset-ledger.ts +156 -0
  55. package/src/kit/asset-workflow/asset-materialization-report.ts +140 -0
  56. package/src/kit/asset-workflow/asset-pack-manifest.ts +320 -0
  57. package/src/kit/asset-workflow/asset-types.ts +142 -0
  58. package/src/kit/asset-workflow/audio-preview-player.ts +193 -0
  59. package/src/kit/asset-workflow/audio-waveform.ts +22 -0
  60. package/src/kit/asset-workflow/cloud-asset-client.ts +263 -0
  61. package/src/kit/asset-workflow/hosted-asset-materialization.ts +236 -0
  62. package/src/kit/asset-workflow/image-view-scale.ts +31 -0
  63. package/src/kit/asset-workflow/import-contract.ts +124 -0
  64. package/src/kit/asset-workflow/ledger-write-lock.ts +244 -0
  65. package/src/kit/asset-workflow/pixi-spritesheet.ts +197 -0
  66. package/src/kit/asset-workflow/preview-resource-lifetime.ts +44 -0
  67. package/src/kit/asset-workflow/project-asset-commands.ts +20 -0
  68. package/src/kit/asset-workflow/project-content.ts +288 -0
  69. package/src/kit/asset-workflow/project-source-index.ts +545 -0
  70. package/src/kit/asset-workflow/thumbnail-system.ts +256 -0
  71. package/src/kit/authoring/active-adapter.ts +200 -0
  72. package/src/kit/authoring/active-systems.ts +422 -0
  73. package/src/kit/authoring/adapter-key.ts +18 -0
  74. package/src/kit/authoring/authoring-asset-url.ts +27 -0
  75. package/src/kit/authoring/bootstrap-state.ts +49 -0
  76. package/src/kit/authoring/boundary-authoring-adapter.ts +189 -0
  77. package/src/kit/authoring/canvas-scene-guides.ts +84 -0
  78. package/src/kit/authoring/composite-authoring-adapter.ts +2109 -0
  79. package/src/kit/authoring/consumer-actions.ts +531 -0
  80. package/src/kit/authoring/design-time-layers.ts +852 -0
  81. package/src/kit/authoring/design-time-mount-registry.ts +244 -0
  82. package/src/kit/authoring/edit-mode-authoring.ts +637 -0
  83. package/src/kit/authoring/empty-project-authoring.ts +22 -0
  84. package/src/kit/authoring/instance-source-menu.ts +135 -0
  85. package/src/kit/authoring/layered-pick.ts +185 -0
  86. package/src/kit/authoring/mounted-root-subjects.ts +146 -0
  87. package/src/kit/authoring/no-authoring-adapter.ts +59 -0
  88. package/src/kit/authoring/object3d-document-persistence.ts +122 -0
  89. package/src/kit/authoring/panel-authoring.ts +121 -0
  90. package/src/kit/authoring/project-authoring-session.ts +105 -0
  91. package/src/kit/authoring/provenance.ts +99 -0
  92. package/src/kit/authoring/react-canvas-navigation.ts +259 -0
  93. package/src/kit/authoring/react-design-canvas-style.ts +20 -0
  94. package/src/kit/authoring/react-story-board.ts +917 -0
  95. package/src/kit/authoring/selection-scope.ts +195 -0
  96. package/src/kit/authoring/shell-document-ops.ts +169 -0
  97. package/src/kit/authoring/story-board-chrome-fit.ts +107 -0
  98. package/src/kit/authoring/story-board-presentation.ts +111 -0
  99. package/src/kit/authoring/three-root.ts +67 -0
  100. package/src/kit/authoring/viewport-tool-context.ts +73 -0
  101. package/src/kit/authoring/viewport-tool-owner.ts +38 -0
  102. package/src/kit/authoring/world-session-state.ts +101 -0
  103. package/src/kit/authoring-seam-evidence.ts +300 -0
  104. package/src/kit/availability-tick.ts +66 -0
  105. package/src/kit/bitmap-label.ts +120 -0
  106. package/src/kit/boot-routing.ts +392 -0
  107. package/src/kit/breakpoint-state.ts +43 -0
  108. package/src/kit/build-identity.ts +16 -0
  109. package/src/kit/bytes-codec.ts +62 -0
  110. package/src/kit/cancellation-reason.ts +58 -0
  111. package/src/kit/canvas-frames.ts +88 -0
  112. package/src/kit/capture-camera-pose.ts +77 -0
  113. package/src/kit/capture-size.ts +88 -0
  114. package/src/kit/chrome-registry.ts +159 -0
  115. package/src/kit/chrome-slot-registry.ts +91 -0
  116. package/src/kit/collaboration-client.ts +264 -0
  117. package/src/kit/collaboration-presence.ts +41 -0
  118. package/src/kit/command-dispatch.ts +19 -0
  119. package/src/kit/command-listener.ts +2182 -0
  120. package/src/kit/command-registry.ts +71 -0
  121. package/src/kit/component-board-registry.ts +205 -0
  122. package/src/kit/component-states-registry.ts +199 -0
  123. package/src/kit/components/AlignToolbar.tsx +204 -0
  124. package/src/kit/components/ApplicationMenus.tsx +372 -0
  125. package/src/kit/components/AssetEditorShell.tsx +216 -0
  126. package/src/kit/components/AssetInspectorToolSection.tsx +124 -0
  127. package/src/kit/components/BoardRulers.tsx +354 -0
  128. package/src/kit/components/CanvasAddNodeDialogs.tsx +529 -0
  129. package/src/kit/components/CanvasSceneViewport.tsx +1195 -0
  130. package/src/kit/components/ChromeSlot.tsx +20 -0
  131. package/src/kit/components/CodeView.tsx +470 -0
  132. package/src/kit/components/CompactInspectorShell.tsx +39 -0
  133. package/src/kit/components/ConsolePanel.tsx +273 -0
  134. package/src/kit/components/GameplaySessionTimeline.tsx +295 -0
  135. package/src/kit/components/InspectionProjection.tsx +932 -0
  136. package/src/kit/components/Inspector.tsx +270 -0
  137. package/src/kit/components/InspectorCanvasPreview.tsx +35 -0
  138. package/src/kit/components/InspectorFieldsSection.tsx +290 -0
  139. package/src/kit/components/InspectorStoriesSection.tsx +92 -0
  140. package/src/kit/components/InspectorToolSection.tsx +96 -0
  141. package/src/kit/components/InspectorTransformSection.tsx +245 -0
  142. package/src/kit/components/LightExplorerPanel.tsx +433 -0
  143. package/src/kit/components/MediaProperties.tsx +145 -0
  144. package/src/kit/components/ProjectHeader.tsx +328 -0
  145. package/src/kit/components/ReactCanvasControls.tsx +358 -0
  146. package/src/kit/components/RootSelectionOverlay.tsx +3688 -0
  147. package/src/kit/components/RootTextEditor.tsx +79 -0
  148. package/src/kit/components/SaveStatus.tsx +70 -0
  149. package/src/kit/components/SurfaceCrashBoundary.tsx +105 -0
  150. package/src/kit/components/SurfaceStateOverlay.tsx +24 -0
  151. package/src/kit/components/ToolContributionSurfaces.tsx +49 -0
  152. package/src/kit/components/ToolHost.tsx +380 -0
  153. package/src/kit/components/Toolbar.tsx +811 -0
  154. package/src/kit/components/TransientHint.tsx +44 -0
  155. package/src/kit/components/VersionControlSection.tsx +470 -0
  156. package/src/kit/components/ViewportOverlaysMenu.tsx +177 -0
  157. package/src/kit/components/VolterLogo.tsx +18 -0
  158. package/src/kit/components/WorktreeSwitcher.tsx +712 -0
  159. package/src/kit/components/account-documents.tsx +1162 -0
  160. package/src/kit/components/asset-documents.tsx +794 -0
  161. package/src/kit/components/asset-editor-persistence.ts +216 -0
  162. package/src/kit/components/asset-selection-section.tsx +545 -0
  163. package/src/kit/components/asset-thumbnails.tsx +307 -0
  164. package/src/kit/components/asset-viewers/AudioViewer.tsx +201 -0
  165. package/src/kit/components/asset-viewers/GenericJsonViewer.tsx +102 -0
  166. package/src/kit/components/asset-viewers/ImageViewer.tsx +300 -0
  167. package/src/kit/components/asset-viewers/JsonAssetDocument.tsx +98 -0
  168. package/src/kit/components/asset-viewers/OnlineAssetDetail.tsx +426 -0
  169. package/src/kit/components/asset-viewers/SourceAssetViewer.tsx +356 -0
  170. package/src/kit/components/asset-viewers/SpritesheetSpriteView.tsx +102 -0
  171. package/src/kit/components/asset-viewers/VideoViewer.tsx +101 -0
  172. package/src/kit/components/asset-viewers/shader-source.ts +144 -0
  173. package/src/kit/components/board-guides.ts +150 -0
  174. package/src/kit/components/canvas-scene-hotkeys.ts +37 -0
  175. package/src/kit/components/canvas-temporary-pivot.ts +34 -0
  176. package/src/kit/components/core-utilities.tsx +94 -0
  177. package/src/kit/components/inspector-preview-section.tsx +223 -0
  178. package/src/kit/components/inspector-revert-label.ts +20 -0
  179. package/src/kit/components/inspector-selection.ts +42 -0
  180. package/src/kit/components/inspector-stories-gating.ts +171 -0
  181. package/src/kit/components/inspector-transform-subject.ts +11 -0
  182. package/src/kit/components/inspector-transform.ts +88 -0
  183. package/src/kit/components/kind-documents.tsx +544 -0
  184. package/src/kit/components/primitives/DraftColorInput.tsx +74 -0
  185. package/src/kit/components/project-tool-documents.tsx +402 -0
  186. package/src/kit/components/scene-documents.tsx +221 -0
  187. package/src/kit/components/status-contributions.tsx +407 -0
  188. package/src/kit/components/tool-documents.tsx +302 -0
  189. package/src/kit/components/tool-schema-form.tsx +262 -0
  190. package/src/kit/components/use-after-paint.ts +41 -0
  191. package/src/kit/components/use-project-image-assets.ts +86 -0
  192. package/src/kit/components/workspace-history.ts +32 -0
  193. package/src/kit/components/world-documents.tsx +570 -0
  194. package/src/kit/components/world-overlay-gestures.ts +1939 -0
  195. package/src/kit/composite-screenshot.ts +2238 -0
  196. package/src/kit/content-entry-source-registry.ts +184 -0
  197. package/src/kit/contribution-surfaces.ts +48 -0
  198. package/src/kit/coverage/canvas-reveal.ts +192 -0
  199. package/src/kit/coverage/design-time-surfaces.ts +101 -0
  200. package/src/kit/coverage/ontology-invariants.ts +466 -0
  201. package/src/kit/coverage/session-vitals.ts +503 -0
  202. package/src/kit/crash-null-boundary.ts +36 -0
  203. package/src/kit/creation-site-edit.ts +1491 -0
  204. package/src/kit/creation-site-registry.ts +160 -0
  205. package/src/kit/delegate-harness-registry.ts +134 -0
  206. package/src/kit/document-areas.ts +70 -0
  207. package/src/kit/document-context-registry.ts +193 -0
  208. package/src/kit/document-open-registry.ts +200 -0
  209. package/src/kit/document-play-extension.ts +221 -0
  210. package/src/kit/document-preview-source.ts +20 -0
  211. package/src/kit/document-renderer-session.ts +138 -0
  212. package/src/kit/document-stage-sessions.ts +26 -0
  213. package/src/kit/document-viewports.ts +120 -0
  214. package/src/kit/editor-api.ts +46 -0
  215. package/src/kit/editor-chrome-capture.ts +136 -0
  216. package/src/kit/editor-commands.ts +176 -0
  217. package/src/kit/editor-console.ts +580 -0
  218. package/src/kit/editor-current-view.ts +56 -0
  219. package/src/kit/editor-document-probe.ts +1168 -0
  220. package/src/kit/editor-git-client.ts +115 -0
  221. package/src/kit/editor-hotkeys.ts +728 -0
  222. package/src/kit/editor-lease-view.ts +39 -0
  223. package/src/kit/editor-lease.ts +415 -0
  224. package/src/kit/editor-mode.ts +19 -0
  225. package/src/kit/editor-notifications.ts +140 -0
  226. package/src/kit/editor-presence.ts +563 -0
  227. package/src/kit/editor-presentation-activity.ts +58 -0
  228. package/src/kit/editor-presentation-notice.ts +42 -0
  229. package/src/kit/editor-runtime.tsx +147 -0
  230. package/src/kit/editor-server-response.ts +86 -0
  231. package/src/kit/editor-session-attribution.ts +85 -0
  232. package/src/kit/editor-session-mode.ts +54 -0
  233. package/src/kit/editor-state-facets.ts +74 -0
  234. package/src/kit/editor-view-presentation.ts +777 -0
  235. package/src/kit/environment-images.ts +58 -0
  236. package/src/kit/eyedropper-session.ts +60 -0
  237. package/src/kit/files/file-provider.ts +62 -0
  238. package/src/kit/files/project-files.ts +270 -0
  239. package/src/kit/finders/index.ts +137 -0
  240. package/src/kit/finders/scenes-from-entrypoint-selection.ts +387 -0
  241. package/src/kit/frame/frame-parts.ts +30 -0
  242. package/src/kit/framed-document-capture.ts +34 -0
  243. package/src/kit/game-globals-prelude.ts +143 -0
  244. package/src/kit/game-surface-defaults.ts +33 -0
  245. package/src/kit/gameplay-dom-recording.ts +318 -0
  246. package/src/kit/gameplay-export-state.ts +14 -0
  247. package/src/kit/gameplay-replay.ts +417 -0
  248. package/src/kit/gameplay-session-time.ts +9 -0
  249. package/src/kit/gameplay-sessions.ts +204 -0
  250. package/src/kit/hierarchy-component-marks.ts +298 -0
  251. package/src/kit/hierarchy-internals.ts +197 -0
  252. package/src/kit/hierarchy-kind-icon.ts +217 -0
  253. package/src/kit/hierarchy-menu-registry.ts +67 -0
  254. package/src/kit/hierarchy-node-rows.ts +307 -0
  255. package/src/kit/hierarchy-panel-view.ts +280 -0
  256. package/src/kit/hierarchy-projection.ts +76 -0
  257. package/src/kit/hierarchy-row-media.ts +45 -0
  258. package/src/kit/hierarchy-row-model.ts +308 -0
  259. package/src/kit/hierarchy-rows.ts +11 -0
  260. package/src/kit/hierarchy-walk.ts +86 -0
  261. package/src/kit/history/editor-session.ts +25 -0
  262. package/src/kit/history/history-commands.ts +147 -0
  263. package/src/kit/history/history-delegate.ts +187 -0
  264. package/src/kit/history/history-limit-notices.ts +43 -0
  265. package/src/kit/history/history-service.ts +1189 -0
  266. package/src/kit/history/persistence-coordinator.ts +35 -0
  267. package/src/kit/history/project-file-history.ts +386 -0
  268. package/src/kit/history/project-root-history-backends.ts +139 -0
  269. package/src/kit/history/resource-registry.ts +209 -0
  270. package/src/kit/history/snapshot-store.ts +103 -0
  271. package/src/kit/history/source-history-backend.ts +546 -0
  272. package/src/kit/history-types.ts +124 -0
  273. package/src/kit/hmr-registration-group.ts +67 -0
  274. package/src/kit/hmr-stable-react-context.ts +23 -0
  275. package/src/kit/hotkeys.ts +190 -0
  276. package/src/kit/inference-diagnostics.ts +69 -0
  277. package/src/kit/initial-project.ts +80 -0
  278. package/src/kit/inspection/active-subject.ts +571 -0
  279. package/src/kit/inspection/active-surface.ts +142 -0
  280. package/src/kit/inspection/compose-subject.ts +1055 -0
  281. package/src/kit/inspection/compose.ts +7 -0
  282. package/src/kit/inspection/display.ts +171 -0
  283. package/src/kit/inspection/document-subject.ts +109 -0
  284. package/src/kit/inspection/game-subject.ts +85 -0
  285. package/src/kit/inspection/null-subject.ts +119 -0
  286. package/src/kit/inspection/serialize.ts +357 -0
  287. package/src/kit/inspection/use-active-inspection.ts +180 -0
  288. package/src/kit/inspection-model.ts +542 -0
  289. package/src/kit/inspection-node-media.ts +58 -0
  290. package/src/kit/inspector-presentation.ts +203 -0
  291. package/src/kit/inspector-property-grouping.ts +64 -0
  292. package/src/kit/inspector-section-registry.ts +221 -0
  293. package/src/kit/instance-source-actions.ts +163 -0
  294. package/src/kit/js-heap.ts +71 -0
  295. package/src/kit/key-actions.ts +91 -0
  296. package/src/kit/keymap-presets.ts +428 -0
  297. package/src/kit/layout-policy.ts +31 -0
  298. package/src/kit/light-explorer-model.ts +134 -0
  299. package/src/kit/live-canvas-frame.ts +55 -0
  300. package/src/kit/live-document.ts +296 -0
  301. package/src/kit/live-gesture-lock.ts +50 -0
  302. package/src/kit/live-seam-evidence.ts +11 -0
  303. package/src/kit/live-session-registry.ts +220 -0
  304. package/src/kit/live-transition.ts +391 -0
  305. package/src/kit/manifest-project.ts +107 -0
  306. package/src/kit/module-fetch-diagnosis.ts +192 -0
  307. package/src/kit/mount-failure-report.ts +154 -0
  308. package/src/kit/native-selection-style.ts +497 -0
  309. package/src/kit/object3d-document-write-policy.ts +137 -0
  310. package/src/kit/packaged-runtime.ts +108 -0
  311. package/src/kit/palettes/maya.palette.json +57 -0
  312. package/src/kit/palettes/substance.palette.json +57 -0
  313. package/src/kit/performance-profiler.ts +367 -0
  314. package/src/kit/performance-sources.ts +69 -0
  315. package/src/kit/photograph-notice.ts +141 -0
  316. package/src/kit/play-boot-phase.ts +166 -0
  317. package/src/kit/play-camera-flight.ts +35 -0
  318. package/src/kit/png-encode.worker.ts +26 -0
  319. package/src/kit/presentation-surface.ts +248 -0
  320. package/src/kit/product-command.ts +90 -0
  321. package/src/kit/project-adapter.ts +1140 -0
  322. package/src/kit/project-asset-refresh.ts +23 -0
  323. package/src/kit/project-asset-roots.ts +68 -0
  324. package/src/kit/project-local-state.ts +151 -0
  325. package/src/kit/project-manager.ts +243 -0
  326. package/src/kit/project-module-changes.ts +201 -0
  327. package/src/kit/project-module-split.ts +270 -0
  328. package/src/kit/project-play-layers.ts +25 -0
  329. package/src/kit/project-provenance.ts +115 -0
  330. package/src/kit/project-ready.ts +42 -0
  331. package/src/kit/project-shape.ts +68 -0
  332. package/src/kit/project-tools.ts +107 -0
  333. package/src/kit/projection-types.ts +44 -0
  334. package/src/kit/readiness.ts +113 -0
  335. package/src/kit/renderer-resource-counts.ts +27 -0
  336. package/src/kit/reported-play-state.ts +90 -0
  337. package/src/kit/resolve-contributed-command.ts +14 -0
  338. package/src/kit/resolve-relative-specifier.ts +33 -0
  339. package/src/kit/retained-document-states.ts +91 -0
  340. package/src/kit/scene-document-plan.ts +320 -0
  341. package/src/kit/scene-live-open.ts +210 -0
  342. package/src/kit/scoped-game-css.ts +152 -0
  343. package/src/kit/served-url.ts +5 -0
  344. package/src/kit/session-close.ts +17 -0
  345. package/src/kit/session-tombstone.ts +127 -0
  346. package/src/kit/settings/settings-provider.ts +82 -0
  347. package/src/kit/settings-store.ts +348 -0
  348. package/src/kit/shell-document-state.ts +27 -0
  349. package/src/kit/shell-store-door.ts +45 -0
  350. package/src/kit/shell-store.ts +722 -0
  351. package/src/kit/source-conflict.ts +122 -0
  352. package/src/kit/stage-context.ts +377 -0
  353. package/src/kit/stage-invalidation.ts +25 -0
  354. package/src/kit/stage-store-registry.ts +69 -0
  355. package/src/kit/startup-failure.ts +80 -0
  356. package/src/kit/state-report-deferral.ts +73 -0
  357. package/src/kit/storage/host-files-storage.ts +97 -0
  358. package/src/kit/storage/http-storage.ts +174 -0
  359. package/src/kit/storage/index.ts +75 -0
  360. package/src/kit/storage/mem-storage.ts +158 -0
  361. package/src/kit/storage/path-lock.ts +44 -0
  362. package/src/kit/storage/paths.ts +26 -0
  363. package/src/kit/storage-types.ts +127 -0
  364. package/src/kit/stories/StoryPreviewMount.tsx +306 -0
  365. package/src/kit/stories/compose-project-stories.ts +255 -0
  366. package/src/kit/stories/prefabs-finder.ts +54 -0
  367. package/src/kit/stories/prefabs-from-stories.ts +182 -0
  368. package/src/kit/stories/project-story-regions.ts +24 -0
  369. package/src/kit/stories/story-capture.ts +579 -0
  370. package/src/kit/stories/story-declared-medium.ts +126 -0
  371. package/src/kit/stories/story-discovery.ts +176 -0
  372. package/src/kit/stories/story-dom-runtime.ts +78 -0
  373. package/src/kit/stories/story-grouping.ts +111 -0
  374. package/src/kit/stories/story-mount-turn.ts +27 -0
  375. package/src/kit/stories/story-presentation.ts +215 -0
  376. package/src/kit/stories/story-preview-component.ts +7 -0
  377. package/src/kit/stories/story-registry.ts +530 -0
  378. package/src/kit/stories-scope.ts +35 -0
  379. package/src/kit/story-document-openers.ts +36 -0
  380. package/src/kit/story-thumbnails.ts +47 -0
  381. package/src/kit/surface-keyboard.ts +101 -0
  382. package/src/kit/surface-state.ts +135 -0
  383. package/src/kit/system-seam-evidence.ts +72 -0
  384. package/src/kit/tab-census.ts +202 -0
  385. package/src/kit/tab-lifecycle-client.ts +227 -0
  386. package/src/kit/theme-library.ts +897 -0
  387. package/src/kit/theme-preference.ts +429 -0
  388. package/src/kit/three-viewport-presentation.ts +23 -0
  389. package/src/kit/tool-contribution-play.ts +74 -0
  390. package/src/kit/tool-loader.ts +1918 -0
  391. package/src/kit/transform-mode-request.ts +66 -0
  392. package/src/kit/transient-hint.ts +78 -0
  393. package/src/kit/transport-strip.tsx +174 -0
  394. package/src/kit/ui-source/adapter-region-includes.ts +238 -0
  395. package/src/kit/ui-source/file-region-resolver.ts +302 -0
  396. package/src/kit/ui-source/inspect.ts +775 -0
  397. package/src/kit/ui-source/source-write-backend.ts +605 -0
  398. package/src/kit/ui-source/tier-source-write-backend.ts +279 -0
  399. package/src/kit/user-local-state.ts +105 -0
  400. package/src/kit/viewport-activation-timings.ts +840 -0
  401. package/src/kit/viewport-editor-controls.ts +22 -0
  402. package/src/kit/viewport-presentation.ts +668 -0
  403. package/src/kit/viewport-surface-status.tsx +55 -0
  404. package/src/kit/wait-until.ts +37 -0
  405. package/src/kit/worker-call-metrics.ts +166 -0
  406. package/src/kit/workspace-areas.ts +191 -0
  407. package/src/kit/workspace-aux-commands.ts +11 -0
  408. package/src/kit/workspace-available-documents.ts +142 -0
  409. package/src/kit/workspace-core-utilities.ts +31 -0
  410. package/src/kit/workspace-document-ids.ts +59 -0
  411. package/src/kit/workspace-document-registry.ts +624 -0
  412. package/src/kit/workspace-document-restore.ts +146 -0
  413. package/src/kit/workspace-host-commands.ts +141 -0
  414. package/src/kit/workspace-persistence-gate.ts +40 -0
  415. package/src/kit/workspace-play-utilities.ts +44 -0
  416. package/src/kit/workspace-presets.ts +446 -0
  417. package/src/kit/workspace-regions.ts +276 -0
  418. package/src/kit/workspace-static-panels.ts +73 -0
  419. package/src/kit/workspace-status-registry.ts +121 -0
  420. package/src/kit/workspace-storage.ts +35 -0
  421. package/src/kit/workspace-style.ts +226 -0
  422. package/src/kit/workspace-utility-commands.ts +74 -0
  423. package/src/kit/workspace-utility-registry.ts +263 -0
  424. package/src/kit/world-adoption-event.ts +23 -0
  425. package/src/kit/world-adoption.ts +115 -0
  426. package/src/kit/world-canvas-viewport-state.ts +35 -0
  427. package/src/kit/world-document-routing.ts +104 -0
  428. package/src/kit/world-pan-state.ts +198 -0
  429. package/src/kit/write-pipe.ts +173 -0
  430. package/src/layout-arrangements.ts +5 -0
  431. package/src/layouts.tsx +108 -0
  432. package/src/looks.ts +16 -0
  433. package/src/project/output-roots.ts +73 -0
  434. package/src/project/tab-census.ts +155 -0
  435. package/src/project-tool-catalog.ts +104 -0
  436. package/src/selection.tsx +107 -0
  437. package/src/services.ts +18 -0
  438. package/src/session/build-report.ts +22 -0
  439. package/src/session/collaboration-types.ts +262 -0
  440. package/src/session/command-table.ts +327 -0
  441. package/src/session/discovery.ts +100 -0
  442. package/src/session/editor-brand.ts +48 -0
  443. package/src/session/editor-compatibility.ts +329 -0
  444. package/src/session/editor-control-lifecycle.ts +68 -0
  445. package/src/session/editor-control-protocol.ts +5 -0
  446. package/src/session/entrypoint-selection-readers.ts +66 -0
  447. package/src/session/entrypoint-selection-source.ts +120 -0
  448. package/src/session/game-css-scope.ts +30 -0
  449. package/src/session/hosted-attachment.ts +225 -0
  450. package/src/session/limited-view.ts +82 -0
  451. package/src/session/product-create.ts +24 -0
  452. package/src/session/product-locator.ts +478 -0
  453. package/src/session/project-module-url.ts +242 -0
  454. package/src/session/project-serving.ts +164 -0
  455. package/src/session/project-upgrade.ts +669 -0
  456. package/src/session/registry-format.ts +210 -0
  457. package/src/session/relative-path-guard.ts +56 -0
  458. package/src/session/scoped-game-css.ts +461 -0
  459. package/src/session/source-glob.ts +15 -0
  460. package/src/session/tool-contribution-convention.ts +123 -0
  461. package/src/session/workbench-locator.ts +712 -0
  462. package/src/session.ts +41 -0
  463. package/src/share.ts +160 -0
  464. package/src/source-analysis.ts +28 -0
  465. package/src/source-authoring.ts +439 -0
  466. package/src/tools/errors.ts +91 -0
  467. package/src/tools/provider-execution.ts +70 -0
  468. package/src/tools/registry.ts +341 -0
  469. package/src/tools/types.ts +159 -0
  470. package/src/transport.ts +100 -0
  471. package/src/types.ts +1693 -0
  472. package/src/views.ts +164 -0
  473. package/src/widgets/design-system.ts +93 -0
  474. package/src/widgets/editor-appearance.ts +151 -0
  475. package/src/widgets/editor-material.ts +83 -0
  476. package/src/widgets/icon-set-registry.ts +105 -0
  477. package/src/widgets/index.ts +71 -0
  478. package/src/widgets/inspector-widgets/AlignmentGrid.tsx +182 -0
  479. package/src/widgets/inspector-widgets/AssetSlotPicker.tsx +123 -0
  480. package/src/widgets/inspector-widgets/BorderEditor.tsx +309 -0
  481. package/src/widgets/inspector-widgets/ColorPicker.tsx +549 -0
  482. package/src/widgets/inspector-widgets/CurveEditor.tsx +359 -0
  483. package/src/widgets/inspector-widgets/FilterEditor.tsx +108 -0
  484. package/src/widgets/inspector-widgets/FontPicker.tsx +191 -0
  485. package/src/widgets/inspector-widgets/GradientEditor.tsx +623 -0
  486. package/src/widgets/inspector-widgets/ScrubbableInput.tsx +180 -0
  487. package/src/widgets/inspector-widgets/ShadowEditor.tsx +319 -0
  488. package/src/widgets/inspector-widgets/color-utils.ts +201 -0
  489. package/src/widgets/inspector-widgets/curve-utils.ts +212 -0
  490. package/src/widgets/inspector-widgets/index.ts +25 -0
  491. package/src/widgets/inspector-widgets/shared.tsx +140 -0
  492. package/src/widgets/interactive-edit-scope.ts +33 -0
  493. package/src/widgets/patterns/Dialog.tsx +140 -0
  494. package/src/widgets/patterns/Fields.tsx +44 -0
  495. package/src/widgets/patterns/List.tsx +25 -0
  496. package/src/widgets/patterns/StateSurface.tsx +40 -0
  497. package/src/widgets/patterns/Surfaces.tsx +122 -0
  498. package/src/widgets/patterns/Tabs.tsx +80 -0
  499. package/src/widgets/patterns/Toolbar.tsx +72 -0
  500. package/src/widgets/patterns/Tree.tsx +72 -0
  501. package/src/widgets/primitives/AnchoredMenu.tsx +260 -0
  502. package/src/widgets/primitives/Button.tsx +62 -0
  503. package/src/widgets/primitives/ColorInput.tsx +78 -0
  504. package/src/widgets/primitives/DraftTextInput.tsx +63 -0
  505. package/src/widgets/primitives/EditorIcon.tsx +157 -0
  506. package/src/widgets/primitives/FormControls.tsx +88 -0
  507. package/src/widgets/primitives/HoverPreview.tsx +96 -0
  508. package/src/widgets/primitives/JsonInput.tsx +113 -0
  509. package/src/widgets/primitives/Layout.tsx +100 -0
  510. package/src/widgets/primitives/Menu.tsx +161 -0
  511. package/src/widgets/primitives/NumberInput.tsx +169 -0
  512. package/src/widgets/primitives/Panel.tsx +80 -0
  513. package/src/widgets/primitives/SectionHeader.tsx +77 -0
  514. package/src/widgets/primitives/Text.tsx +54 -0
  515. package/src/widgets/primitives/ThemeRootPortal.tsx +52 -0
  516. package/src/widgets/primitives/Tooltip.tsx +204 -0
  517. package/src/widgets/primitives/Vec3Input.tsx +70 -0
  518. package/src/widgets/primitives/banner-tones.ts +32 -0
  519. package/src/widgets/primitives/clamp-to-viewport.ts +44 -0
  520. package/src/widgets/primitives/editor-icons.ts +254 -0
  521. package/src/widgets/primitives/panel-header-styles.ts +42 -0
  522. package/src/widgets/theme.ts +2841 -0
  523. package/src/widgets/z-index.ts +25 -0
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Runtime detection of the PACKAGED editor server (`packages/editor/server/
3
+ * packaged.ts` — a `@volter/editor-core` npm package with NO monorepo checkout on
4
+ * disk) from editor CLIENT code. Needed because a react world's mount
5
+ * (`react-mount-runtime.ts`'s `resolveReactRootMountRuntime`) must resolve its
6
+ * `react`/`react-dom/client` from the
7
+ * PROJECT's own module graph ONLY under this runtime — see that function's
8
+ * doc comment, and `packaged.ts`'s header doc comment ("React-world OID
9
+ * authoring parity"), for the dual-React-instance bug this closes. Under
10
+ * dev, this must resolve `false` so the existing static-import path
11
+ * stays byte-unchanged (one shared Vite instance already collapses both
12
+ * react copies via `resolve.dedupe`).
13
+ *
14
+ * Reads the server's own `packaged` flag off `/__editor/project`'s response
15
+ * (computed server-side via `isMonorepoScaffoldRoot`, `server-utils.ts`)
16
+ * rather than probing a URL that only resolves in packaged mode: an
17
+ * unconditional dynamic `import()` probe would 404 (and log an
18
+ * unsuppressible browser console error) on EVERY react-world mount under
19
+ * dev — the exact reasoning `binding-resolver.ts`'s
20
+ * `loadProjectUIRegistry` doc comment already recorded for `hasUiRegistry`
21
+ * ("the client must not probe /@fs for it").
22
+ *
23
+ * A plain inline `fetch()`, not `editor-api.ts`'s `getCurrentServerProject`
24
+ * — same reasoning `loadProjectUIRegistry` documents: this module (via
25
+ * `binding-resolver.ts`) must stay importable by headless Node/vitest
26
+ * suites, and `editor-api.ts`'s module top level pulls in `./storage`.
27
+ *
28
+ * A HOST THAT SERVES NO `/__editor/project` is answered locally rather than by
29
+ * a doomed fetch: it is never the packaged runtime, because "packaged" names a
30
+ * Node host serving a project's own module graph, and a 404's console error is
31
+ * unsuppressible on every doorway of every mount. Same guard, same reason, as
32
+ * `ui-source/tier-source-write-backend.ts`'s `serverSourceWriteRoutes`.
33
+ *
34
+ * ## What is memoized, and what a FAILED probe does
35
+ *
36
+ * An ANSWER is memoized for the page — the runtime a server process runs
37
+ * under cannot change without a restart, so a settled answer is settled. A
38
+ * probe that never got an answer is NOT memoized, and does NOT resolve: it
39
+ * drops the memo and REJECTS, so the next caller asks again.
40
+ *
41
+ * Both halves were bought by one measured failure. A `.catch(() => false)`
42
+ * latch turned a single unreachable fetch — a mount landing in the window
43
+ * while the editor's `edit` command restarts its dev server, which it does on any
44
+ * server-file change — into a page where EVERY doorway
45
+ * (`three-ingest-runtime`, `canvas-entry-runtime`, `r3f-entry-runtime`,
46
+ * the two story runtimes, `binding-resolver`'s react
47
+ * mount) silently resolved the SHELL's namespace for the rest of the
48
+ * session. Under the packaged runtime that is the wrong graph, and the cost
49
+ * lands 10–15 seconds later as a mount failure whose message blames the
50
+ * GAME ("bundles its own (un-shared) copy of three") for a defect in this
51
+ * host — the exact mis-attribution `three-ingest-runtime.ts`'s own
52
+ * loud-throw comment already refuses to make for the sibling case.
53
+ *
54
+ * So "I don't know" is never spent as "dev". Every doorway reads this with
55
+ * `await isPackagedRuntime()` and does nothing else with the answer, so the
56
+ * rejection propagates to the mount site unchanged: nothing mounts on a
57
+ * guessed graph, the message names this host, and because the memo is
58
+ * dropped the remedy it states — retry the mount — is a real one rather
59
+ * than advice.
60
+ */
61
+
62
+ import { editorServerJson } from '@volter/sdk/kit/editor-server-response';
63
+
64
+ let cachedIsPackaged: Promise<boolean> | null = null;
65
+
66
+ export function isPackagedRuntime(): Promise<boolean> {
67
+ if (!cachedIsPackaged) {
68
+ // The `fetch` call is INSIDE the chain so that a synchronous throw from it
69
+ // is a rejected probe like any other, rather than an exception thrown at
70
+ // whoever happened to ask first.
71
+ const probe: Promise<boolean> = Promise.resolve()
72
+ .then(() => fetch('/__editor/project'))
73
+ .then((res) =>
74
+ editorServerJson<{ project?: { packaged?: boolean } | null }>(
75
+ res,
76
+ '`/__editor/project` did not answer',
77
+ ),
78
+ )
79
+ .then((data) => Boolean(data.project?.packaged))
80
+ .catch((err: unknown) => {
81
+ if (cachedIsPackaged === probe) cachedIsPackaged = null;
82
+ throw new Error(
83
+ "This editor session's runtime is unknown — `/__editor/project` did not answer, so " +
84
+ 'which module graph a world mounts in (this shell’s, or the project’s) cannot be ' +
85
+ 'decided and nothing was mounted on a guess. This is a fault in the editor host, ' +
86
+ 'not in the game. The answer is not latched: retry the mount (reopen the project) ' +
87
+ `and the question is asked again. (${err instanceof Error ? err.message : String(err)})`,
88
+ { cause: err },
89
+ );
90
+ });
91
+ cachedIsPackaged = probe;
92
+ }
93
+ return cachedIsPackaged;
94
+ }
95
+
96
+ /** Test-only: reset the memoized result between tests (mirrors
97
+ * `setCachedProjectUIRegistry`'s test-seam shape). */
98
+ export function resetPackagedRuntimeCacheForTest(): void {
99
+ cachedIsPackaged = null;
100
+ }
101
+
102
+ /** Test-only: pre-seed the probe's answer. jsdom has no `/__editor/project` to
103
+ * ask (vitest's MODE is not `web`, so the browser short-circuit does not
104
+ * apply), and the loud unknown-runtime refusal — correct in a live session —
105
+ * is pure noise in a suite that mounts portable stories. */
106
+ export function setPackagedRuntimeForTest(packaged: boolean): void {
107
+ cachedIsPackaged = Promise.resolve(packaged);
108
+ }
@@ -0,0 +1,57 @@
1
+ {
2
+ "schemaVersion": 3,
3
+ "name": "Maya",
4
+ "theme": {
5
+ "id": "maya",
6
+ "color": {
7
+ "surface": {
8
+ "shell": "#2b2b2b",
9
+ "panel": "#444444",
10
+ "chrome": "#373737",
11
+ "raised": "#4b4b4b",
12
+ "inset": "#333333",
13
+ "overlay": "rgba(55,55,55,0.94)"
14
+ },
15
+ "boundary": {
16
+ "default": "#2b2b2b",
17
+ "strong": "#5a5a5a"
18
+ },
19
+ "content": {
20
+ "primary": "#cccccc",
21
+ "muted": "#a8a8a8",
22
+ "dim": "#858585",
23
+ "onAccent": "#ffffff",
24
+ "onBright": {
25
+ "primary": "#1c1c1c",
26
+ "muted": "rgba(28,28,28,0.82)",
27
+ "dim": "rgba(28,28,28,0.7)"
28
+ }
29
+ },
30
+ "accent": {
31
+ "default": "#5285a6",
32
+ "muted": "rgba(82,133,166,0.34)"
33
+ },
34
+ "semantic": {
35
+ "danger": "#d9534f",
36
+ "dangerMuted": "rgba(217,83,79,0.28)",
37
+ "dangerFaint": "rgba(217,83,79,0.12)",
38
+ "warning": "#e0a030",
39
+ "warningMuted": "rgba(224,160,48,0.28)",
40
+ "success": "#4fd85b",
41
+ "successMuted": "rgba(79,216,91,0.28)",
42
+ "dynamic": "#e6a6ff",
43
+ "dynamicMuted": "rgba(230,166,255,0.18)",
44
+ "instance": "#4fd85b"
45
+ },
46
+ "neutralOverlay": {
47
+ "hover": "rgba(255,255,255,0.07)",
48
+ "active": "rgba(255,255,255,0.12)"
49
+ },
50
+ "scrim": "rgba(0,0,0,0.55)"
51
+ },
52
+ "typography": {
53
+ "sans": "'Helvetica Neue', Arial, system-ui, sans-serif",
54
+ "mono": "Menlo, Consolas, monospace"
55
+ }
56
+ }
57
+ }
@@ -0,0 +1,57 @@
1
+ {
2
+ "schemaVersion": 3,
3
+ "name": "Substance",
4
+ "theme": {
5
+ "id": "substance",
6
+ "color": {
7
+ "surface": {
8
+ "shell": "#1e1e1e",
9
+ "panel": "#252525",
10
+ "chrome": "#2a2a2a",
11
+ "raised": "#2d2d2d",
12
+ "inset": "#1a1a1a",
13
+ "overlay": "rgba(37,37,37,0.94)"
14
+ },
15
+ "boundary": {
16
+ "default": "#3a3a3a",
17
+ "strong": "#4a4a4a"
18
+ },
19
+ "content": {
20
+ "primary": "#d9d9d9",
21
+ "muted": "#a6a6a6",
22
+ "dim": "#7f7f7f",
23
+ "onAccent": "#ffffff",
24
+ "onBright": {
25
+ "primary": "#1e1e1e",
26
+ "muted": "rgba(30,30,30,0.82)",
27
+ "dim": "rgba(30,30,30,0.7)"
28
+ }
29
+ },
30
+ "accent": {
31
+ "default": "#4aa3df",
32
+ "muted": "rgba(74,163,223,0.3)"
33
+ },
34
+ "semantic": {
35
+ "danger": "#e5534b",
36
+ "dangerMuted": "rgba(229,83,75,0.28)",
37
+ "dangerFaint": "rgba(229,83,75,0.12)",
38
+ "warning": "#e3a52f",
39
+ "warningMuted": "rgba(227,165,47,0.28)",
40
+ "success": "#5cc27a",
41
+ "successMuted": "rgba(92,194,122,0.28)",
42
+ "dynamic": "#4aa3df",
43
+ "dynamicMuted": "rgba(74,163,223,0.18)",
44
+ "instance": "#e98b3a"
45
+ },
46
+ "neutralOverlay": {
47
+ "hover": "rgba(255,255,255,0.06)",
48
+ "active": "rgba(255,255,255,0.11)"
49
+ },
50
+ "scrim": "rgba(0,0,0,0.62)"
51
+ },
52
+ "typography": {
53
+ "sans": "'Source Sans 3', 'Segoe UI', system-ui, sans-serif",
54
+ "mono": "'Source Code Pro', Menlo, monospace"
55
+ }
56
+ }
57
+ }
@@ -0,0 +1,367 @@
1
+ export interface PerformanceTiming {
2
+ readonly name: string;
3
+ readonly ms: number;
4
+ /**
5
+ * Offset (ms) from THIS frame's start (`frameStart`) at which the timing
6
+ * began — a MEASURED value (e.g. a phase's `phaseStart - frameStart`), never
7
+ * synthesized. Present on per-frame phase timings (W4b, so a Chrome trace
8
+ * can place each phase span under its frame at the real offset). OMITTED on
9
+ * cross-frame aggregate rollups (`PerformanceSnapshot.phases`/`systems`/
10
+ * `components`), where no single start point exists — absent, never a
11
+ * fabricated 0.
12
+ */
13
+ readonly startMs?: number;
14
+ }
15
+
16
+ /**
17
+ * One MEASURED span within a frame (W4b) — a system or component invocation,
18
+ * with the phase it ran in and its measured start offset from `frameStart`.
19
+ * Distinct from {@link PerformanceTiming}: a span is a single timed
20
+ * invocation carrying `phase` + always-present `startMs` (the trace/flame
21
+ * unit), whereas a `PerformanceTiming` may be a cross-frame rollup.
22
+ */
23
+ export interface PerformanceSpan {
24
+ readonly name: string;
25
+ readonly phase: string;
26
+ /** Measured offset (ms) from `frameStart` at which this span began. */
27
+ readonly startMs: number;
28
+ readonly ms: number;
29
+ }
30
+
31
+ /** Renderer counters accumulated over a frame (from `renderer.info`). */
32
+ export interface PerformanceRenderStats {
33
+ readonly gpuMs: number | null;
34
+ readonly drawCalls: number;
35
+ readonly triangles: number;
36
+ readonly geometries: number;
37
+ readonly textures: number;
38
+ /**
39
+ * How many top-level `renderer.render()` submissions the last presentation
40
+ * took (`renderer.info.render.frame`'s delta across one draw) — a composer
41
+ * chain, a shadow pass and a post stack each cost one. `null` (never a
42
+ * fabricated 0, same rule as `gpuMs`) when no reporter counted them: a
43
+ * reporter that omits `renderPasses` is saying it does not know, which is
44
+ * different from saying nothing was drawn.
45
+ */
46
+ readonly renderPasses: number | null;
47
+ }
48
+
49
+ export interface PerformanceFrame {
50
+ readonly id: number;
51
+ readonly timestamp: number;
52
+ readonly intervalMs: number;
53
+ readonly cpuMs: number;
54
+ readonly phases: readonly PerformanceTiming[];
55
+ /**
56
+ * Per-invocation system spans measured this frame (W4b). Ordered by
57
+ * `startMs` (execution order), NOT accumulated — a system that ran twice
58
+ * (two substeps) appears twice. Empty when the profiler saw no named
59
+ * systems this frame.
60
+ */
61
+ readonly systems: readonly PerformanceSpan[];
62
+ /**
63
+ * Per-invocation component spans measured this frame (W4b) — populated ONLY
64
+ * while `recording` (component timing is gated on recording, matching
65
+ * `beginComponent`/`endComponent`). Empty otherwise.
66
+ */
67
+ readonly components: readonly PerformanceSpan[];
68
+ /**
69
+ * Renderer counters reported during this frame (W4b) — a snapshot of the
70
+ * accumulated `reportRender` totals taken at `endFrame`. `gpuMs` is `null`
71
+ * when no GPU timer reported (headless/SwiftShader), never a fabricated 0.
72
+ */
73
+ readonly render: PerformanceRenderStats;
74
+ }
75
+
76
+ export interface PerformanceSnapshot {
77
+ readonly enabled: boolean;
78
+ readonly recording: boolean;
79
+ readonly fps: number;
80
+ readonly cpuMs: number;
81
+ readonly p95Ms: number;
82
+ readonly p99Ms: number;
83
+ readonly frames: readonly PerformanceFrame[];
84
+ readonly phases: readonly PerformanceTiming[];
85
+ readonly systems: readonly PerformanceTiming[];
86
+ readonly components: readonly PerformanceTiming[];
87
+ readonly render: PerformanceRenderStats;
88
+ }
89
+
90
+ const now = () => globalThis.performance?.now() ?? Date.now();
91
+
92
+ function percentile(sorted: readonly number[], fraction: number): number {
93
+ if (sorted.length === 0) return 0;
94
+ return sorted[Math.min(sorted.length - 1, Math.floor((sorted.length - 1) * fraction))] ?? 0;
95
+ }
96
+
97
+ /** Game-owned, bounded external store for browser-native performance diagnostics. */
98
+ export function createPerformanceProfiler(initiallyEnabled = false) {
99
+ const listeners = new Set<() => void>();
100
+ const frames: PerformanceFrame[] = [];
101
+ const currentPhases = new Map<string, { ms: number; startMs: number }>();
102
+ const currentSystems = new Map<string, number>();
103
+ const currentComponents = new Map<string, number>();
104
+ // Per-frame span logs (W4b) — cleared each beginFrame, snapshotted into the
105
+ // frame at endFrame. Distinct from the accumulate-by-name aggregate maps
106
+ // above (which back the cross-frame snapshot rollups): these preserve every
107
+ // individual invocation and its measured start offset, for the trace.
108
+ let frameSystems: PerformanceSpan[] = [];
109
+ let frameComponents: PerformanceSpan[] = [];
110
+ let enabled = initiallyEnabled;
111
+ // The header's always-visible FPS sparkline needs frame INTERVALS without
112
+ // turning on the full profiler. Full profiling measures phases/systems,
113
+ // issues GPU timer queries at render sites, and intentionally warns about
114
+ // overhead; a glanceable heartbeat must not silently opt the user into all
115
+ // of that work. `telemetryEnabled` records only the frame envelope.
116
+ let telemetryEnabled = false;
117
+ let recording = false;
118
+ let frameId = 0;
119
+ let frameStart = 0;
120
+ let lastFrameStart = 0;
121
+ /**
122
+ * Phase start times, innermost last. A STACK rather than the single slot
123
+ * this used to be, because phases NEST: the three adapter brackets its CPU
124
+ * render submission as its own phase (`render.submit`,
125
+ * `dev/render-vitals.ts`) from inside the frame's enclosing `render` phase.
126
+ * With one slot the inner `beginPhase()` overwrote the outer's start, so the
127
+ * outer `endPhase('render')` measured only the tail after the inner phase —
128
+ * silently under-reporting the very phase the inner one was decomposing.
129
+ * Balanced callers are unaffected; `endPhase` with an empty stack falls back
130
+ * to `frameStart` rather than a stale start from a previous frame.
131
+ */
132
+ const phaseStack: number[] = [];
133
+ let systemStart = 0;
134
+ let componentStart = 0;
135
+ let render: PerformanceRenderStats = {
136
+ gpuMs: null,
137
+ drawCalls: 0,
138
+ triangles: 0,
139
+ geometries: 0,
140
+ textures: 0,
141
+ renderPasses: null,
142
+ };
143
+ let snapshot: PerformanceSnapshot = {
144
+ enabled,
145
+ recording,
146
+ fps: 0,
147
+ cpuMs: 0,
148
+ p95Ms: 0,
149
+ p99Ms: 0,
150
+ frames: [],
151
+ phases: [],
152
+ systems: [],
153
+ components: [],
154
+ render,
155
+ };
156
+
157
+ function publish(): void {
158
+ const latest = frames.at(-1);
159
+ // Frame-only subscribers need no percentile work. Keep this window stable
160
+ // so a retained snapshot's first percentile read still describes its frames.
161
+ const snapshotFrames = frames.slice();
162
+ let sortedIntervals: number[] | undefined;
163
+ const readPercentile = (fraction: number): number => {
164
+ sortedIntervals ??= snapshotFrames
165
+ .map((frame) => frame.intervalMs)
166
+ .filter((value) => value > 0)
167
+ .sort((a, b) => a - b);
168
+ return percentile(sortedIntervals, fraction);
169
+ };
170
+ snapshot = {
171
+ enabled,
172
+ recording,
173
+ fps: latest?.intervalMs ? 1000 / latest.intervalMs : 0,
174
+ cpuMs: latest?.cpuMs ?? 0,
175
+ get p95Ms() {
176
+ return readPercentile(0.95);
177
+ },
178
+ get p99Ms() {
179
+ return readPercentile(0.99);
180
+ },
181
+ frames: snapshotFrames,
182
+ phases: latest?.phases ?? [],
183
+ systems: [...currentSystems].map(([name, ms]) => ({ name, ms })).sort((a, b) => b.ms - a.ms),
184
+ components: [...currentComponents]
185
+ .map(([name, ms]) => ({ name, ms }))
186
+ .sort((a, b) => b.ms - a.ms),
187
+ render,
188
+ };
189
+ for (const listener of listeners) listener();
190
+ }
191
+
192
+ return {
193
+ get enabled() {
194
+ return enabled;
195
+ },
196
+ set enabled(value: boolean) {
197
+ if (enabled === value) return;
198
+ enabled = value;
199
+ if (value && !telemetryEnabled) lastFrameStart = 0;
200
+ publish();
201
+ },
202
+ get telemetryEnabled() {
203
+ return telemetryEnabled;
204
+ },
205
+ set telemetryEnabled(value: boolean) {
206
+ if (telemetryEnabled === value) return;
207
+ const wasInactive = !enabled && !telemetryEnabled;
208
+ telemetryEnabled = value;
209
+ if (value && wasInactive) lastFrameStart = 0;
210
+ publish();
211
+ },
212
+ get recording() {
213
+ return recording;
214
+ },
215
+ startRecording() {
216
+ const wasInactive = !enabled && !telemetryEnabled;
217
+ enabled = true;
218
+ if (wasInactive) lastFrameStart = 0;
219
+ recording = true;
220
+ frames.length = 0;
221
+ publish();
222
+ },
223
+ stopRecording() {
224
+ recording = false;
225
+ publish();
226
+ },
227
+ clear() {
228
+ frames.length = 0;
229
+ publish();
230
+ },
231
+ beginFrame() {
232
+ if (!enabled && !telemetryEnabled) return;
233
+ currentPhases.clear();
234
+ currentSystems.clear();
235
+ currentComponents.clear();
236
+ frameSystems = [];
237
+ frameComponents = [];
238
+ // A frame that threw mid-phase leaves entries on the stack; a fresh
239
+ // frame starts from nothing rather than inheriting them.
240
+ phaseStack.length = 0;
241
+ render = {
242
+ gpuMs: null,
243
+ drawCalls: 0,
244
+ triangles: 0,
245
+ geometries: 0,
246
+ textures: 0,
247
+ renderPasses: null,
248
+ };
249
+ frameStart = now();
250
+ },
251
+ beginPhase() {
252
+ if (!enabled) return;
253
+ phaseStack.push(now());
254
+ },
255
+ endPhase(name: string) {
256
+ if (!enabled) return;
257
+ // See `phaseStack`: pop restores the ENCLOSING phase's own start, so a
258
+ // nested bracket measures itself without truncating its parent.
259
+ const phaseStart = phaseStack.pop() ?? frameStart;
260
+ const elapsed = now() - phaseStart;
261
+ const existing = currentPhases.get(name);
262
+ // Accumulate ms across re-entries of the same phase, but keep the FIRST
263
+ // measured start offset (earliest entry) as the span's startMs.
264
+ currentPhases.set(name, {
265
+ ms: (existing?.ms ?? 0) + elapsed,
266
+ startMs: existing?.startMs ?? phaseStart - frameStart,
267
+ });
268
+ if (recording)
269
+ performance.measure(`volter.phase.${name}`, { start: phaseStart, duration: elapsed });
270
+ },
271
+ systemObserver: {
272
+ beginSystem() {
273
+ if (!enabled) return;
274
+ systemStart = now();
275
+ },
276
+ endSystem(scope: string, phase: string, name: string) {
277
+ if (!enabled) return;
278
+ const end = now();
279
+ const key = `${scope} / ${phase} / ${name}`;
280
+ currentSystems.set(key, (currentSystems.get(key) ?? 0) + end - systemStart);
281
+ frameSystems.push({
282
+ name: key,
283
+ phase,
284
+ startMs: systemStart - frameStart,
285
+ ms: end - systemStart,
286
+ });
287
+ },
288
+ },
289
+ beginComponent() {
290
+ if (!recording) return;
291
+ componentStart = now();
292
+ },
293
+ endComponent(name: string, phase = '') {
294
+ if (!recording) return;
295
+ const end = now();
296
+ currentComponents.set(name, (currentComponents.get(name) ?? 0) + end - componentStart);
297
+ frameComponents.push({
298
+ name,
299
+ phase,
300
+ startMs: componentStart - frameStart,
301
+ ms: end - componentStart,
302
+ });
303
+ },
304
+ reportRender(stats: {
305
+ gpuMs: number | null;
306
+ drawCalls: number;
307
+ triangles: number;
308
+ geometries: number;
309
+ textures: number;
310
+ /** Omit when this reporter does not count passes — see
311
+ * {@link PerformanceRenderStats.renderPasses}. */
312
+ renderPasses?: number;
313
+ }) {
314
+ if (!enabled) return;
315
+ render = {
316
+ gpuMs: stats.gpuMs ?? render.gpuMs,
317
+ drawCalls: render.drawCalls + stats.drawCalls,
318
+ triangles: render.triangles + stats.triangles,
319
+ geometries: render.geometries + stats.geometries,
320
+ textures: render.textures + stats.textures,
321
+ renderPasses:
322
+ stats.renderPasses === undefined
323
+ ? render.renderPasses
324
+ : (render.renderPasses ?? 0) + stats.renderPasses,
325
+ };
326
+ },
327
+ endFrame() {
328
+ if (!enabled && !telemetryEnabled) return;
329
+ const timestamp = now();
330
+ const intervalMs = lastFrameStart === 0 ? 0 : frameStart - lastFrameStart;
331
+ lastFrameStart = frameStart;
332
+ const frame: PerformanceFrame = {
333
+ id: ++frameId,
334
+ timestamp,
335
+ intervalMs,
336
+ cpuMs: timestamp - frameStart,
337
+ phases: [...currentPhases]
338
+ .map(([name, { ms, startMs }]) => ({ name, ms, startMs }))
339
+ .sort((a, b) => b.ms - a.ms),
340
+ systems: frameSystems.slice(),
341
+ components: frameComponents.slice(),
342
+ render: { ...render },
343
+ };
344
+ frames.push(frame);
345
+ if (frames.length > 600) frames.splice(0, frames.length - 600);
346
+ if (recording)
347
+ performance.measure('volter.frame', { start: frameStart, duration: frame.cpuMs });
348
+ publish();
349
+ },
350
+ subscribe(listener: () => void) {
351
+ listeners.add(listener);
352
+ return () => {
353
+ listeners.delete(listener);
354
+ };
355
+ },
356
+ getSnapshot() {
357
+ return snapshot;
358
+ },
359
+ exportJSON() {
360
+ // version 2 (W4b): frames now carry per-frame `systems`/`components`
361
+ // spans, per-frame `render` counters, and `startMs` on phase timings.
362
+ return JSON.stringify({ version: 2, capturedAt: new Date().toISOString(), frames }, null, 2);
363
+ },
364
+ };
365
+ }
366
+
367
+ export type PerformanceProfiler = ReturnType<typeof createPerformanceProfiler>;
@@ -0,0 +1,69 @@
1
+ import type { PerformanceProfiler } from './performance-profiler';
2
+
3
+ export interface EditorPerformanceSource {
4
+ readonly id: string;
5
+ readonly label: string;
6
+ readonly kind: 'scene' | 'source' | 'asset' | 'game';
7
+ readonly profiler: PerformanceProfiler;
8
+ /** Mount identity for a Game runtime source. Document identity stays
9
+ * `workspace:game`; this disambiguates the runtime inspected inside it. */
10
+ readonly instanceId?: string;
11
+ }
12
+
13
+ const sources = new Map<string, EditorPerformanceSource>();
14
+ const listeners = new Set<() => void>();
15
+ let version = 0;
16
+
17
+ function notify(): void {
18
+ version++;
19
+ for (const listener of listeners) listener();
20
+ }
21
+
22
+ /** Register one real render loop as a profiler source. */
23
+ export function registerPerformanceSource(source: EditorPerformanceSource): () => void {
24
+ sources.set(source.id, source);
25
+ notify();
26
+ return () => {
27
+ if (sources.get(source.id) !== source) return;
28
+ sources.delete(source.id);
29
+ notify();
30
+ };
31
+ }
32
+
33
+ export function performanceSourceForDocument(
34
+ documentId: string | null,
35
+ ): EditorPerformanceSource | null {
36
+ return documentId ? (sources.get(documentId) ?? null) : null;
37
+ }
38
+
39
+ /** Every registered render loop. The self-vitals checks
40
+ * (`coverage/session-vitals.ts`) ask "did the thing that is running draw a
41
+ * frame", which is a question about whichever loop exists, not about the
42
+ * document the user happens to be looking at. */
43
+ export function allPerformanceSources(): readonly EditorPerformanceSource[] {
44
+ return [...sources.values()];
45
+ }
46
+
47
+ export function performanceSourceForGameInstance(
48
+ instanceId: string | null,
49
+ ): EditorPerformanceSource | null {
50
+ if (instanceId === null) return null;
51
+ for (const source of sources.values()) {
52
+ if (source.kind === 'game' && source.instanceId === instanceId) return source;
53
+ }
54
+ return null;
55
+ }
56
+
57
+ export function subscribePerformanceSources(listener: () => void): () => void {
58
+ listeners.add(listener);
59
+ return () => listeners.delete(listener);
60
+ }
61
+
62
+ export function performanceSourcesVersion(): number {
63
+ return version;
64
+ }
65
+
66
+ export function __resetPerformanceSourcesForTest(): void {
67
+ sources.clear();
68
+ notify();
69
+ }