@volter/sdk 0.0.0-stage → 0.5.203

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 +1166 -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 +317 -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 +403 -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,356 @@
1
+ import { AssetViewerSlot } from '@volter/sdk/kit/asset-viewers';
2
+ import { themeVars } from '@volter/sdk/widgets';
3
+ import { useEffect, useState, useSyncExternalStore } from 'react';
4
+ import { declaredRoots } from '@volter/project/adapter/manifest-interpreter';
5
+ import { loadGameManifest, type ResolvedAdapterRoot } from '@volter/project/manifest/load';
6
+ import { assetCapabilities } from '@volter/sdk/kit/asset-capabilities';
7
+ import { getCurrentProject } from '@volter/sdk/kit/project-manager';
8
+ import { projectAdapterFacet, subscribeProjectAdapter } from '@volter/sdk/kit/project-adapter';
9
+ import { resolveFileRegion } from '@volter/sdk/kit/ui-source/file-region-resolver';
10
+ import { editorServerJson } from '@volter/sdk/kit/editor-server-response';
11
+ import {
12
+ projectModuleChangeMatches,
13
+ subscribeProjectModuleChange,
14
+ } from '@volter/sdk/kit/project-module-changes';
15
+ import { AssetEditorShell } from '@volter/sdk/kit/components/AssetEditorShell';
16
+ import { CodeView, codeViewLanguage } from '../CodeView';
17
+ import { AudioViewer } from './AudioViewer';
18
+ import { ImageViewer } from './ImageViewer';
19
+ import { JsonAssetDocument } from './JsonAssetDocument';
20
+
21
+ export type SourceAssetRoute =
22
+ | 'model'
23
+ | 'image'
24
+ | 'audio'
25
+ | 'json'
26
+ | 'environment'
27
+ | 'lut'
28
+ | 'shader'
29
+ | 'module'
30
+ | 'text'
31
+ | 'binary';
32
+
33
+ /**
34
+ * A project script the editor can EXECUTE, and therefore a candidate live
35
+ * model module (`LiveModuleDocument`). The bound is the dev server's own: only
36
+ * `src/**` scripts are classified, HMR-stamped and re-served on save
37
+ * (`server/project-hmr-files.ts`'s `classifyProjectHotUpdate` returns `ignore`
38
+ * for everything else), so a script outside `src/` could be imported once but
39
+ * never re-executed — a live document that silently stops being live. Whether
40
+ * such a module actually BUILDS an `Object3D` is decided by running it, never
41
+ * by its name.
42
+ */
43
+ function isProjectScriptPath(assetPath: string): boolean {
44
+ const clean = (assetPath.split(/[?#]/, 1)[0] ?? '').replace(/^\//, '');
45
+ return clean.startsWith('src/') && /\.(?:[cm]?[jt]sx?)$/.test(clean);
46
+ }
47
+
48
+ export function sourceAssetRoute(assetPath: string): SourceAssetRoute {
49
+ const capability = assetCapabilities(assetPath);
50
+ if (capability.editor === 'model') return 'model';
51
+ if (capability.editor === 'image') return 'image';
52
+ if (capability.editor === 'audio') return 'audio';
53
+ if (capability.editor === 'data') return 'json';
54
+ if (capability.editor === 'environment') return 'environment';
55
+ if (capability.format === 'cube') return 'lut';
56
+ if (capability.format === 'glsl' || capability.format === 'vert' || capability.format === 'frag')
57
+ return 'shader';
58
+ if (isProjectScriptPath(assetPath)) return 'module';
59
+ if (capability.editor === 'source' && capability.previewable) return 'text';
60
+ return 'binary';
61
+ }
62
+
63
+ /**
64
+ * THE FILE IS THE SUBJECT.
65
+ *
66
+ * A source/module document had no selection context of its own, and
67
+ * `waitForAssetDocumentInspector` waits for exactly that — so
68
+ * `editor.openAsset('/src/foo.ts', 'source')` opened the document, showed the
69
+ * code, and then sat until the relay's budget ran out and reported a
70
+ * `play-stall`: a timeout about the tab for a document that was already on
71
+ * screen. (The JSON route acked because `JsonAssetDocument` goes through
72
+ * `AssetEditorShell`.)
73
+ *
74
+ * There is no invented subject here and nothing new to publish: a source
75
+ * document's subject is the FILE, its identity row is the filename and the
76
+ * kind, and its note is the Info the shell already shows for every other
77
+ * asset — so it registers through the SAME holder every Asset Lab document
78
+ * uses (`AssetEditorShell` → `AssetEditorSubject`) rather than growing a
79
+ * second one.
80
+ */
81
+ function TextSourcePreview({
82
+ documentId,
83
+ assetPath,
84
+ active = true,
85
+ }: {
86
+ readonly documentId: string;
87
+ readonly assetPath: string;
88
+ readonly active?: boolean;
89
+ }) {
90
+ const [content, setContent] = useState<string | null>(null);
91
+ const [error, setError] = useState<string | null>(null);
92
+ const fileName = assetPath.split('/').pop() ?? assetPath;
93
+ useEffect(() => {
94
+ let cancelled = false;
95
+ setContent(null);
96
+ setError(null);
97
+ const path = assetPath.replace(/^\//, '');
98
+ let revision = 0;
99
+ async function read() {
100
+ const request = ++revision;
101
+ try {
102
+ // The author's file as written — the project's dev server would answer
103
+ // a module path with its TRANSFORMED output (the globals prelude, the
104
+ // compiled JSX), which is not the source this document shows.
105
+ const url = `/__editor/source-file?path=${encodeURIComponent(path)}`;
106
+ const value = await fetch(url, { cache: 'no-store' }).then((response) => {
107
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
108
+ return response.text();
109
+ });
110
+ if (!cancelled && request === revision) {
111
+ setContent(value);
112
+ setError(null);
113
+ }
114
+ } catch (reason) {
115
+ if (!cancelled && request === revision)
116
+ setError(reason instanceof Error ? reason.message : String(reason));
117
+ }
118
+ }
119
+ const refresh = (changed: string) => {
120
+ if (projectModuleChangeMatches(changed, path)) void read();
121
+ };
122
+ const stop = subscribeProjectModuleChange(refresh);
123
+ void read();
124
+ return () => {
125
+ cancelled = true;
126
+ stop();
127
+ };
128
+ }, [assetPath]);
129
+ return (
130
+ <AssetEditorShell
131
+ documentId={documentId}
132
+ active={active}
133
+ type="source"
134
+ title={fileName}
135
+ sections={[]}
136
+ status={`source · ${assetPath}`}
137
+ fill
138
+ >
139
+ <div
140
+ style={{
141
+ padding: 12,
142
+ height: '100%',
143
+ minHeight: 0,
144
+ display: 'flex',
145
+ flexDirection: 'column',
146
+ gap: 8,
147
+ }}
148
+ >
149
+ <div
150
+ style={{
151
+ padding: 8,
152
+ // The well GROWS to the panel instead of stopping at a fixed
153
+ // budget: this document is a whole tab, and CodeView virtualizes,
154
+ // so there is nothing to buy by capping it. (It inherited a
155
+ // 560px ceiling from the small in-panel preview it was cut from,
156
+ // which left most of a full-tab source document empty.)
157
+ flex: 1,
158
+ minHeight: 0,
159
+ display: 'flex',
160
+ overflow: 'hidden',
161
+ background: themeVars.surface.inset,
162
+ border: `1px solid ${themeVars.boundary.default}`,
163
+ borderRadius: themeVars.shape.small,
164
+ }}
165
+ >
166
+ {error !== null || content === null ? (
167
+ <div
168
+ style={{
169
+ fontFamily: themeVars.typography.mono,
170
+ fontSize: 11,
171
+ lineHeight: 1.5,
172
+ color: error ? themeVars.semantic.danger : themeVars.content.muted,
173
+ padding: 4,
174
+ }}
175
+ >
176
+ {error ?? 'Loading…'}
177
+ </div>
178
+ ) : (
179
+ <CodeView
180
+ value={content}
181
+ followChanges
182
+ language={codeViewLanguage(assetPath)}
183
+ fontSize={11}
184
+ maxHeight="100%"
185
+ ariaLabel={`Source of ${assetPath}`}
186
+ />
187
+ )}
188
+ </div>
189
+ </div>
190
+ </AssetEditorShell>
191
+ );
192
+ }
193
+
194
+ /** A format whose native view no integration in this composition provides: the
195
+ * file is still a document with its own identity, like the binary route below. */
196
+ function NoNativeViewer({
197
+ documentId,
198
+ assetPath,
199
+ active,
200
+ }: {
201
+ readonly documentId: string;
202
+ readonly assetPath: string;
203
+ readonly active: boolean;
204
+ }) {
205
+ const name = assetPath.split('/').pop() ?? assetPath;
206
+ return (
207
+ <AssetEditorShell
208
+ documentId={documentId}
209
+ active={active}
210
+ type="source"
211
+ title={name}
212
+ sections={[]}
213
+ status={`no viewer · ${assetPath}`}
214
+ >
215
+ <div style={{ padding: 16, color: themeVars.content.muted, fontSize: 12 }}>
216
+ No editor package in this project renders {name}; the file is available in the project
217
+ and stays selectable and referenceable.
218
+ </div>
219
+ </AssetEditorShell>
220
+ );
221
+ }
222
+
223
+ /** Read the file's declared surface before executing a possible model builder.
224
+ * A DOM or canvas component is source here; calling it outside its renderer
225
+ * can throw (React hooks), or perform work just to discover it is not a model.
226
+ * Unplaced modules retain the existing Object3D builder contract. */
227
+ function ProjectModuleSourceViewer({ documentId, assetPath, active }: {
228
+ documentId: string;
229
+ assetPath: string;
230
+ active: boolean;
231
+ }) {
232
+ const projectRoot = getCurrentProject()?.rootPath;
233
+ const facet = useSyncExternalStore(subscribeProjectAdapter, projectAdapterFacet);
234
+ const [roots, setRoots] = useState<readonly ResolvedAdapterRoot[] | null>(null);
235
+ const [declarationError, setDeclarationError] = useState<string | null>(null);
236
+ useEffect(() => {
237
+ let cancelled = false;
238
+ setRoots(null);
239
+ setDeclarationError(null);
240
+ if (!projectRoot || !facet) return;
241
+ void (async () => {
242
+ try {
243
+ const raw = await editorServerJson<unknown>(
244
+ await fetch('/volter.project.json', { cache: 'no-store' }),
245
+ 'Reading this source file’s declared surface failed',
246
+ );
247
+ const manifest = loadGameManifest(raw, { configurationKinds: 'defer' });
248
+ if (!cancelled) setRoots(declaredRoots(manifest));
249
+ } catch (error) {
250
+ if (!cancelled) setDeclarationError(error instanceof Error ? error.message : String(error));
251
+ }
252
+ })();
253
+ return () => { cancelled = true; };
254
+ }, [projectRoot, facet]);
255
+ const preview = <TextSourcePreview documentId={documentId} assetPath={assetPath} active={active} />;
256
+ // Unknown declarations are not permission to execute the source.
257
+ if (!projectRoot || !facet || !roots || declarationError) return <>
258
+ {declarationError && <div role="alert">{declarationError}</div>}
259
+ {preview}
260
+ </>;
261
+ const path = (assetPath.split(/[?#]/, 1)[0] ?? '').replaceAll('\\', '/').replace(/^\.\//, '').replace(/^\//, '');
262
+ const region = resolveFileRegion({
263
+ file: path,
264
+ projectRelative: path,
265
+ regions: facet.regions,
266
+ regionOfEntry: (file) => {
267
+ const root = roots.find((candidate) => candidate.entry?.replace(/^\.\//, '') === file);
268
+ return root ? facet.regions.find((candidate) => candidate.id === root.id) : undefined;
269
+ },
270
+ });
271
+ if (region.surface === 'dom' || region.surface === 'canvas') return preview;
272
+ return <AssetViewerSlot route="module" documentId={documentId} assetPath={assetPath}
273
+ projectRoot={projectRoot} displayName={assetPath.split('/').pop() ?? assetPath}
274
+ active={active} fallback={preview} whenUnregistered={preview} />;
275
+ }
276
+
277
+ /** Viewer for downloaded catalog source/animation files without a magic fallback. */
278
+ export function SourceAssetViewer({
279
+ documentId,
280
+ assetPath,
281
+ active = true,
282
+ }: {
283
+ documentId: string;
284
+ assetPath: string;
285
+ active?: boolean;
286
+ }) {
287
+ switch (sourceAssetRoute(assetPath)) {
288
+ case 'model':
289
+ case 'environment':
290
+ case 'lut':
291
+ case 'shader': {
292
+ // The format's native view is the media integration's
293
+ // (`@volter/sdk/kit/asset-viewers`); without one, the file is
294
+ // still opened as what it is.
295
+ const route = sourceAssetRoute(assetPath) as 'model' | 'environment' | 'lut' | 'shader';
296
+ return (
297
+ <AssetViewerSlot
298
+ route={route}
299
+ documentId={documentId}
300
+ assetPath={assetPath}
301
+ displayName={assetPath.split('/').pop() ?? assetPath}
302
+ active={active}
303
+ whenUnregistered={<NoNativeViewer documentId={documentId} assetPath={assetPath} active={active} />}
304
+ />
305
+ );
306
+ }
307
+ case 'image':
308
+ return <ImageViewer assetPath={assetPath} />;
309
+ case 'audio':
310
+ return <AudioViewer assetPath={assetPath} />;
311
+ case 'json':
312
+ // Content-routed: a native three.quarks document opens as the particle
313
+ // editor, any other JSON keeps the generic viewer.
314
+ return (
315
+ <JsonAssetDocument
316
+ documentId={documentId}
317
+ assetPath={assetPath}
318
+ displayName={assetPath.split('/').pop() ?? assetPath}
319
+ active={active}
320
+ sections={[]}
321
+ status={`json · ${assetPath}`}
322
+ />
323
+ );
324
+ case 'module': {
325
+ // Content-routed, like the quarks JSON above: a project script that
326
+ // BUILDS an Object3D opens as the live modeling document; anything else
327
+ // keeps this viewer's text preview.
328
+ return <ProjectModuleSourceViewer documentId={documentId} assetPath={assetPath} active={active} />;
329
+ }
330
+ case 'text':
331
+ return <TextSourcePreview documentId={documentId} assetPath={assetPath} active={active} />;
332
+ case 'binary':
333
+ // Same subject rule as the text route above — the FILE. A document that
334
+ // publishes nothing is a document `editor.openAsset` can only time out
335
+ // against, and "no renderer" is not "no identity".
336
+ return (
337
+ <AssetEditorShell
338
+ documentId={documentId}
339
+ active={active}
340
+ type="binary source"
341
+ title={assetPath.split('/').pop() ?? assetPath}
342
+ sections={[]}
343
+ status={`binary · ${assetPath}`}
344
+ >
345
+ <div style={{ padding: 16, color: themeVars.content.muted, fontSize: 12 }}>
346
+ <div style={{ color: themeVars.content.primary, fontWeight: 600, marginBottom: 6 }}>
347
+ {assetPath.split('/').pop()}
348
+ </div>
349
+ This binary source is available in the project, but it has no safe in-editor renderer.
350
+ Its file remains selectable and referenceable without being misidentified as another
351
+ format.
352
+ </div>
353
+ </AssetEditorShell>
354
+ );
355
+ }
356
+ }
@@ -0,0 +1,102 @@
1
+ /**
2
+ * One sprite from a packed atlas — Aseprite's cel / Unity's Sprite /
3
+ * Godot's AtlasTexture. The sheet is the source texture; this paints the
4
+ * named frame onto the untrimmed canvas at nearest-neighbor.
5
+ */
6
+ import { useEffect, useRef } from 'react';
7
+ import { integerFitScale } from '../../asset-workflow/image-view-scale';
8
+ import { type PixiSpritesheetFrame, packedFrameRect } from '@volter/sdk/kit/asset-workflow/pixi-spritesheet';
9
+
10
+ export function paintSpriteFrame(
11
+ canvas: HTMLCanvasElement,
12
+ image: CanvasImageSource,
13
+ frame: PixiSpritesheetFrame,
14
+ ): void {
15
+ const destWidth = Math.max(1, frame.sourceWidth ?? frame.width);
16
+ const destHeight = Math.max(1, frame.sourceHeight ?? frame.height);
17
+ canvas.width = destWidth;
18
+ canvas.height = destHeight;
19
+ const context = canvas.getContext('2d');
20
+ if (!context) return;
21
+ context.imageSmoothingEnabled = false;
22
+ context.clearRect(0, 0, destWidth, destHeight);
23
+ const packed = packedFrameRect(frame);
24
+ if (frame.rotated) {
25
+ context.save();
26
+ context.translate(frame.trimX, frame.trimY + packed.width);
27
+ context.rotate(-Math.PI / 2);
28
+ context.drawImage(
29
+ image,
30
+ packed.x,
31
+ packed.y,
32
+ packed.width,
33
+ packed.height,
34
+ 0,
35
+ 0,
36
+ packed.width,
37
+ packed.height,
38
+ );
39
+ context.restore();
40
+ return;
41
+ }
42
+ context.drawImage(
43
+ image,
44
+ packed.x,
45
+ packed.y,
46
+ packed.width,
47
+ packed.height,
48
+ frame.trimX,
49
+ frame.trimY,
50
+ packed.width,
51
+ packed.height,
52
+ );
53
+ }
54
+
55
+ export function SpritesheetSpriteView({
56
+ sheetUrl,
57
+ frame,
58
+ scale,
59
+ maxEdge,
60
+ }: {
61
+ sheetUrl: string;
62
+ frame: PixiSpritesheetFrame;
63
+ scale?: number;
64
+ maxEdge?: number;
65
+ }) {
66
+ const canvasRef = useRef<HTMLCanvasElement>(null);
67
+ const destWidth = Math.max(1, frame.sourceWidth ?? frame.width);
68
+ const destHeight = Math.max(1, frame.sourceHeight ?? frame.height);
69
+ const resolved =
70
+ maxEdge != null ? integerFitScale(destWidth, destHeight, maxEdge, maxEdge) : (scale ?? 1);
71
+ const displayWidth = Math.max(1, Math.round(destWidth * resolved));
72
+ const displayHeight = Math.max(1, Math.round(destHeight * resolved));
73
+
74
+ useEffect(() => {
75
+ const canvas = canvasRef.current;
76
+ if (!canvas) return;
77
+ const image = new Image();
78
+ let cancelled = false;
79
+ image.onload = () => {
80
+ if (!cancelled) paintSpriteFrame(canvas, image, frame);
81
+ };
82
+ image.src = sheetUrl;
83
+ return () => {
84
+ cancelled = true;
85
+ };
86
+ }, [frame, sheetUrl]);
87
+
88
+ return (
89
+ <canvas
90
+ ref={canvasRef}
91
+ width={destWidth}
92
+ height={destHeight}
93
+ aria-hidden
94
+ style={{
95
+ width: displayWidth,
96
+ height: displayHeight,
97
+ imageRendering: 'pixelated',
98
+ display: 'block',
99
+ }}
100
+ />
101
+ );
102
+ }
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Video Asset Lab document: the clip itself, with the browser's own controls.
3
+ *
4
+ * Deliberately no custom transport, no autoplay and no muting — a reference
5
+ * clip is watched, and `<video controls>` is already the control surface every
6
+ * person on this machine knows. The bytes come from the session, which serves
7
+ * the project's own files.
8
+ */
9
+
10
+ import { Text, text } from '@volter/sdk/widgets';
11
+ import { useCallback, useEffect, useState } from 'react';
12
+
13
+ export function VideoViewer({ assetPath }: { assetPath: string }) {
14
+ const [failed, setFailed] = useState(false);
15
+ const [size, setSize] = useState<{ w: number; h: number } | null>(null);
16
+ const source = assetPath;
17
+ useEffect(() => {
18
+ setFailed(false);
19
+ }, [source]);
20
+ const name = assetPath.split('/').pop() ?? assetPath;
21
+ const measure = useCallback((element: HTMLVideoElement | null) => {
22
+ if (!element) return;
23
+ if (element.error) {
24
+ setFailed(true);
25
+ return;
26
+ }
27
+ if (element.videoWidth <= 0) return;
28
+ setSize((current) =>
29
+ current && current.w === element.videoWidth && current.h === element.videoHeight
30
+ ? current
31
+ : { w: element.videoWidth, h: element.videoHeight },
32
+ );
33
+ }, []);
34
+
35
+ return (
36
+ <div
37
+ data-testid="video-asset-document"
38
+ style={{
39
+ height: '100%',
40
+ minHeight: 240,
41
+ display: 'flex',
42
+ flexDirection: 'column',
43
+ minWidth: 0,
44
+ }}
45
+ >
46
+ <div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '6px 8px' }}>
47
+ <Text tone="dim" variant="label">
48
+ {name}
49
+ </Text>
50
+ {size && (
51
+ <Text tone="muted" variant="code">
52
+ {size.w} × {size.h}
53
+ </Text>
54
+ )}
55
+ </div>
56
+ <div
57
+ className="volter-asset-transparency-well"
58
+ style={{
59
+ flex: 1,
60
+ minHeight: 0,
61
+ display: 'flex',
62
+ alignItems: 'center',
63
+ justifyContent: 'center',
64
+ padding: 12,
65
+ }}
66
+ >
67
+ {failed ? (
68
+ <div style={{ color: text[2], fontSize: 12, textAlign: 'center' }}>
69
+ {name} could not be played from {source}. The file may be missing, or its codec may not
70
+ be one this browser decodes.
71
+ </div>
72
+ ) : (
73
+ <video
74
+ key={source}
75
+ src={source}
76
+ controls
77
+ playsInline
78
+ preload="metadata"
79
+ // MEASURED, not just listened for: a clip whose metadata is already
80
+ // decoded when React attaches (a cached file, a reopened document)
81
+ // fires `loadedmetadata` BEFORE the listener exists, and the header
82
+ // then reported no dimensions over a video the layout had already
83
+ // sized from real ones. The ref reads the element's own state on
84
+ // attach; the event covers everything that arrives later.
85
+ //
86
+ // `measure` is STABLE and its write is a no-change guard, both for
87
+ // the same reason: an inline ref is a new function every render, so
88
+ // React detaches and re-runs it every render, and a `setSize` that
89
+ // writes a fresh object each time is then an infinite update loop.
90
+ // Measured here — it took the editor's chrome down with
91
+ // "Maximum update depth exceeded".
92
+ ref={measure}
93
+ onError={() => setFailed(true)}
94
+ onLoadedMetadata={(event) => measure(event.currentTarget)}
95
+ style={{ maxWidth: '100%', maxHeight: '100%', display: 'block' }}
96
+ />
97
+ )}
98
+ </div>
99
+ </div>
100
+ );
101
+ }