@forgeax/engine-runtime 0.1.4 → 0.1.7

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 (606) hide show
  1. package/README.md +65 -83
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/__tests__/animation-graph-collect-roundtrip.test.d.ts +2 -0
  4. package/dist/__tests__/animation-graph-collect-roundtrip.test.d.ts.map +1 -0
  5. package/dist/__tests__/animation-graph-serialize.unit.test.d.ts +2 -0
  6. package/dist/__tests__/animation-graph-serialize.unit.test.d.ts.map +1 -0
  7. package/dist/__tests__/asset-brand-and-name-retirement.test.d.ts +2 -0
  8. package/dist/__tests__/asset-brand-and-name-retirement.test.d.ts.map +1 -0
  9. package/dist/__tests__/asset-error-exhaustive.test-d.d.ts +11 -0
  10. package/dist/__tests__/asset-error-exhaustive.test-d.d.ts.map +1 -0
  11. package/dist/__tests__/asset-registry-guid-reverse.test.d.ts +2 -0
  12. package/dist/__tests__/asset-registry-guid-reverse.test.d.ts.map +1 -0
  13. package/dist/__tests__/asset-registry-hdr-equirect.test.d.ts +2 -0
  14. package/dist/__tests__/asset-registry-hdr-equirect.test.d.ts.map +1 -0
  15. package/dist/__tests__/asset-registry-mesh-pack-payload.dawn.test.d.ts +2 -0
  16. package/dist/__tests__/asset-registry-mesh-pack-payload.dawn.test.d.ts.map +1 -0
  17. package/dist/__tests__/asset-registry-mounts.test.d.ts +2 -0
  18. package/dist/__tests__/asset-registry-mounts.test.d.ts.map +1 -0
  19. package/dist/__tests__/asset-registry.browser.test.d.ts +2 -0
  20. package/dist/__tests__/asset-registry.browser.test.d.ts.map +1 -0
  21. package/dist/__tests__/asset-registry.dawn.test.d.ts +2 -0
  22. package/dist/__tests__/asset-registry.dawn.test.d.ts.map +1 -0
  23. package/dist/__tests__/asset-registry.listCatalog.test.d.ts +2 -0
  24. package/dist/__tests__/asset-registry.listCatalog.test.d.ts.map +1 -0
  25. package/dist/__tests__/asset-registry.mesh-bin.test.d.ts +2 -0
  26. package/dist/__tests__/asset-registry.mesh-bin.test.d.ts.map +1 -0
  27. package/dist/__tests__/asset-registry.pack-cache.test.d.ts +2 -0
  28. package/dist/__tests__/asset-registry.pack-cache.test.d.ts.map +1 -0
  29. package/dist/__tests__/asset-registry.raw-container-failfast.test.d.ts +2 -0
  30. package/dist/__tests__/asset-registry.raw-container-failfast.test.d.ts.map +1 -0
  31. package/dist/__tests__/asset-registry.recursive.spec.d.ts +2 -0
  32. package/dist/__tests__/asset-registry.recursive.spec.d.ts.map +1 -0
  33. package/dist/__tests__/asset-registry.unit.test.d.ts +2 -0
  34. package/dist/__tests__/asset-registry.unit.test.d.ts.map +1 -0
  35. package/dist/__tests__/asset.unit.test.d.ts +2 -0
  36. package/dist/__tests__/asset.unit.test.d.ts.map +1 -0
  37. package/dist/__tests__/audio-load-by-guid.unit.test.d.ts +2 -0
  38. package/dist/__tests__/audio-load-by-guid.unit.test.d.ts.map +1 -0
  39. package/dist/__tests__/backend-selection.integration.test.d.ts +2 -0
  40. package/dist/__tests__/backend-selection.integration.test.d.ts.map +1 -0
  41. package/dist/__tests__/basis-catalog-dispatch.integration.test.d.ts +2 -0
  42. package/dist/__tests__/basis-catalog-dispatch.integration.test.d.ts.map +1 -0
  43. package/dist/__tests__/builtin-asset-registry.unit.test.d.ts +2 -0
  44. package/dist/__tests__/builtin-asset-registry.unit.test.d.ts.map +1 -0
  45. package/dist/__tests__/collect-scene-asset.test.d.ts +1 -2
  46. package/dist/__tests__/collect-scene-asset.test.d.ts.map +1 -1
  47. package/dist/__tests__/collect-scene-mount-collapse.test.d.ts +2 -0
  48. package/dist/__tests__/collect-scene-mount-collapse.test.d.ts.map +1 -0
  49. package/dist/__tests__/collect-transient-roundtrip.test.d.ts +1 -1
  50. package/dist/__tests__/collect-transient-roundtrip.test.d.ts.map +1 -1
  51. package/dist/__tests__/collect-transient-skip.test.d.ts +1 -2
  52. package/dist/__tests__/collect-transient-skip.test.d.ts.map +1 -1
  53. package/dist/__tests__/compressed-texture-physical-extent.integration.test.d.ts +2 -0
  54. package/dist/__tests__/compressed-texture-physical-extent.integration.test.d.ts.map +1 -0
  55. package/dist/__tests__/dawn/mesh-update-dawn.test.d.ts +2 -0
  56. package/dist/__tests__/dawn/mesh-update-dawn.test.d.ts.map +1 -0
  57. package/dist/__tests__/dawn/upload-texture.dawn.test.d.ts +2 -0
  58. package/dist/__tests__/dawn/upload-texture.dawn.test.d.ts.map +1 -0
  59. package/dist/__tests__/draw-published.d.ts +2 -2
  60. package/dist/__tests__/draw-published.d.ts.map +1 -1
  61. package/dist/__tests__/dynamic-texture-store.unit.test.d.ts +2 -0
  62. package/dist/__tests__/dynamic-texture-store.unit.test.d.ts.map +1 -0
  63. package/dist/__tests__/errors.unit.test.d.ts +2 -0
  64. package/dist/__tests__/errors.unit.test.d.ts.map +1 -0
  65. package/dist/__tests__/extract-skin-mismatch.unit.test.d.ts +2 -0
  66. package/dist/__tests__/extract-skin-mismatch.unit.test.d.ts.map +1 -0
  67. package/dist/__tests__/fetch-binary-decompress.test.d.ts +2 -0
  68. package/dist/__tests__/fetch-binary-decompress.test.d.ts.map +1 -0
  69. package/dist/__tests__/four-path-compression.integration.test.d.ts +2 -0
  70. package/dist/__tests__/four-path-compression.integration.test.d.ts.map +1 -0
  71. package/dist/__tests__/fullscreen-feature-host.dawn.test.d.ts +2 -0
  72. package/dist/__tests__/fullscreen-feature-host.dawn.test.d.ts.map +1 -0
  73. package/dist/__tests__/guid-for-asset.unit.test.d.ts +2 -0
  74. package/dist/__tests__/guid-for-asset.unit.test.d.ts.map +1 -0
  75. package/dist/__tests__/handle-migration.test.d.ts +2 -0
  76. package/dist/__tests__/handle-migration.test.d.ts.map +1 -0
  77. package/dist/__tests__/helpers/register-runtime-components.d.ts.map +1 -1
  78. package/dist/__tests__/host-custom-kind-contract.test-d.d.ts +2 -0
  79. package/dist/__tests__/host-custom-kind-contract.test-d.d.ts.map +1 -0
  80. package/dist/__tests__/host-custom-kind-contract.test.d.ts +2 -0
  81. package/dist/__tests__/host-custom-kind-contract.test.d.ts.map +1 -0
  82. package/dist/__tests__/inspect-name.test.d.ts +2 -0
  83. package/dist/__tests__/inspect-name.test.d.ts.map +1 -0
  84. package/dist/__tests__/instantiate-mount-deferred-wiring.test.d.ts +2 -0
  85. package/dist/__tests__/instantiate-mount-deferred-wiring.test.d.ts.map +1 -0
  86. package/dist/__tests__/loadbyguid-payload.unit.test.d.ts +2 -0
  87. package/dist/__tests__/loadbyguid-payload.unit.test.d.ts.map +1 -0
  88. package/dist/__tests__/loadbyguid-texture-intern.unit.test.d.ts +2 -0
  89. package/dist/__tests__/loadbyguid-texture-intern.unit.test.d.ts.map +1 -0
  90. package/dist/__tests__/loader-extract-graceful.test.d.ts +2 -0
  91. package/dist/__tests__/loader-extract-graceful.test.d.ts.map +1 -0
  92. package/dist/__tests__/loader-name-survival.test.d.ts +2 -0
  93. package/dist/__tests__/loader-name-survival.test.d.ts.map +1 -0
  94. package/dist/__tests__/mesh-bin-contract.test.d.ts +2 -0
  95. package/dist/__tests__/mesh-bin-contract.test.d.ts.map +1 -0
  96. package/dist/__tests__/mesh-bin-skin-roundtrip.unit.test.d.ts +2 -0
  97. package/dist/__tests__/mesh-bin-skin-roundtrip.unit.test.d.ts.map +1 -0
  98. package/dist/__tests__/mesh-bin.test.d.ts +2 -0
  99. package/dist/__tests__/mesh-bin.test.d.ts.map +1 -0
  100. package/dist/__tests__/mesh-loader-skin-contract.unit.test.d.ts +2 -0
  101. package/dist/__tests__/mesh-loader-skin-contract.unit.test.d.ts.map +1 -0
  102. package/dist/__tests__/new-kind-refs-contract.test.d.ts +2 -0
  103. package/dist/__tests__/new-kind-refs-contract.test.d.ts.map +1 -0
  104. package/dist/__tests__/package-promotion.test.d.ts +2 -0
  105. package/dist/__tests__/package-promotion.test.d.ts.map +1 -0
  106. package/dist/__tests__/package-rename.test.d.ts +2 -0
  107. package/dist/__tests__/package-rename.test.d.ts.map +1 -0
  108. package/dist/__tests__/recover-error-exhaustive.test-d.d.ts +1 -1
  109. package/dist/__tests__/recover-error-exhaustive.test-d.d.ts.map +1 -1
  110. package/dist/__tests__/render-error-exhaustive.test-d.d.ts +1 -1
  111. package/dist/__tests__/render-error-exhaustive.test-d.d.ts.map +1 -1
  112. package/dist/__tests__/render-feature-prepared-graphics.fixture.d.ts +10 -0
  113. package/dist/__tests__/render-feature-prepared-graphics.fixture.d.ts.map +1 -0
  114. package/dist/__tests__/render-system-extract.unit.test.d.ts +2 -0
  115. package/dist/__tests__/render-system-extract.unit.test.d.ts.map +1 -0
  116. package/dist/__tests__/renderer-test-utils.d.ts +10 -0
  117. package/dist/__tests__/renderer-test-utils.d.ts.map +1 -0
  118. package/dist/__tests__/renderer.test-d.d.ts +2 -0
  119. package/dist/__tests__/renderer.test-d.d.ts.map +1 -0
  120. package/dist/__tests__/resolve-asset-handle-err.test.d.ts +2 -0
  121. package/dist/__tests__/resolve-asset-handle-err.test.d.ts.map +1 -0
  122. package/dist/__tests__/resolve-asset-handle.unit.test.d.ts +2 -0
  123. package/dist/__tests__/resolve-asset-handle.unit.test.d.ts.map +1 -0
  124. package/dist/__tests__/resolveName-fallback.test.d.ts +2 -0
  125. package/dist/__tests__/resolveName-fallback.test.d.ts.map +1 -0
  126. package/dist/__tests__/resolveName-null-package.test.d.ts +2 -0
  127. package/dist/__tests__/resolveName-null-package.test.d.ts.map +1 -0
  128. package/dist/__tests__/resolveName-unified-entry.test.d.ts +2 -0
  129. package/dist/__tests__/resolveName-unified-entry.test.d.ts.map +1 -0
  130. package/dist/__tests__/resolveName.test.d.ts +2 -0
  131. package/dist/__tests__/resolveName.test.d.ts.map +1 -0
  132. package/dist/__tests__/roots-to-scene-asset.test.d.ts +1 -1
  133. package/dist/__tests__/roots-to-scene-asset.test.d.ts.map +1 -1
  134. package/dist/__tests__/roundtrip-primitive.test.d.ts +2 -0
  135. package/dist/__tests__/roundtrip-primitive.test.d.ts.map +1 -0
  136. package/dist/__tests__/scene-bare-guid-refs-instantiate.test.d.ts +2 -0
  137. package/dist/__tests__/scene-bare-guid-refs-instantiate.test.d.ts.map +1 -0
  138. package/dist/__tests__/scene-instance-authoring.integration.test.d.ts +2 -0
  139. package/dist/__tests__/scene-instance-authoring.integration.test.d.ts.map +1 -0
  140. package/dist/__tests__/scene-mount-fixed-point.test.d.ts +2 -0
  141. package/dist/__tests__/scene-mount-fixed-point.test.d.ts.map +1 -0
  142. package/dist/__tests__/scene-mount-roundtrip.test.d.ts +2 -0
  143. package/dist/__tests__/scene-mount-roundtrip.test.d.ts.map +1 -0
  144. package/dist/__tests__/scene-mount-wrapper-roundtrip.test.d.ts +2 -0
  145. package/dist/__tests__/scene-mount-wrapper-roundtrip.test.d.ts.map +1 -0
  146. package/dist/__tests__/scene-sugar-instantiate.test.d.ts +2 -0
  147. package/dist/__tests__/scene-sugar-instantiate.test.d.ts.map +1 -0
  148. package/dist/__tests__/serialize-mounts-roundtrip.test.d.ts +2 -0
  149. package/dist/__tests__/serialize-mounts-roundtrip.test.d.ts.map +1 -0
  150. package/dist/__tests__/serialize-scene-asset.test.d.ts +1 -1
  151. package/dist/__tests__/serialize-scene-asset.test.d.ts.map +1 -1
  152. package/dist/__tests__/template-game-default-api-contract.test.d.ts +2 -0
  153. package/dist/__tests__/template-game-default-api-contract.test.d.ts.map +1 -0
  154. package/dist/__tests__/tileset-asset-validate.test.d.ts +2 -0
  155. package/dist/__tests__/tileset-asset-validate.test.d.ts.map +1 -0
  156. package/dist/__tests__/transcode-fallback.unit.test.d.ts +2 -0
  157. package/dist/__tests__/transcode-fallback.unit.test.d.ts.map +1 -0
  158. package/dist/__tests__/transient-runtime-behavior.test.d.ts +2 -0
  159. package/dist/__tests__/transient-runtime-behavior.test.d.ts.map +1 -0
  160. package/dist/__tests__/video-loader-consumption.test.d.ts +2 -0
  161. package/dist/__tests__/video-loader-consumption.test.d.ts.map +1 -0
  162. package/dist/__tests__/video-loader-smoke.dawn.test.d.ts +2 -0
  163. package/dist/__tests__/video-loader-smoke.dawn.test.d.ts.map +1 -0
  164. package/dist/backend-selection.d.ts +13 -0
  165. package/dist/backend-selection.d.ts.map +1 -0
  166. package/dist/collect-scene-asset.d.ts +7 -4
  167. package/dist/collect-scene-asset.d.ts.map +1 -1
  168. package/dist/createRenderer.d.ts +14 -2
  169. package/dist/createRenderer.d.ts.map +1 -1
  170. package/dist/errors/environment.d.ts +1 -1
  171. package/dist/errors/environment.d.ts.map +1 -1
  172. package/dist/index.d.ts +20 -82
  173. package/dist/index.d.ts.map +1 -1
  174. package/dist/index.mjs +107 -108
  175. package/dist/index.mjs.map +1 -1
  176. package/dist/renderer-host.d.ts +9 -0
  177. package/dist/renderer-host.d.ts.map +1 -0
  178. package/dist/renderer-host.mjs +62 -0
  179. package/dist/renderer-host.mjs.map +1 -0
  180. package/dist/scene-instances/index.d.ts +2 -0
  181. package/dist/scene-instances/index.d.ts.map +1 -0
  182. package/dist/scene-utils/mount-override-fold.d.ts +1 -2
  183. package/dist/scene-utils/mount-override-fold.d.ts.map +1 -1
  184. package/dist/systems/sprite-animation-tick.d.ts +1 -1
  185. package/dist/systems/sprite-animation-tick.d.ts.map +1 -1
  186. package/dist/systems/transparent-sort.d.ts +1 -2
  187. package/dist/systems/transparent-sort.d.ts.map +1 -1
  188. package/dist/tilemap-register-validate.d.ts.map +1 -1
  189. package/package.json +34 -33
  190. package/src/__tests__/active-camera.unit.test.ts +19 -9
  191. package/src/__tests__/animation-graph-collect-roundtrip.test.ts +213 -0
  192. package/src/__tests__/animation-graph-serialize.unit.test.ts +171 -0
  193. package/src/__tests__/append-injection.test.ts +1 -1
  194. package/src/__tests__/asset-brand-and-name-retirement.test.ts +102 -0
  195. package/src/__tests__/asset-error-exhaustive.test-d.ts +62 -0
  196. package/src/__tests__/asset-registry-guid-reverse.test.ts +608 -0
  197. package/src/__tests__/asset-registry-hdr-equirect.test.ts +78 -0
  198. package/src/__tests__/asset-registry-mesh-pack-payload.dawn.test.ts +232 -0
  199. package/src/__tests__/asset-registry-mounts.test.ts +806 -0
  200. package/src/__tests__/asset-registry.browser.test.ts +81 -0
  201. package/src/__tests__/asset-registry.dawn.test.ts +94 -0
  202. package/src/__tests__/asset-registry.listCatalog.test.ts +170 -0
  203. package/src/__tests__/asset-registry.mesh-bin.test.ts +316 -0
  204. package/src/__tests__/asset-registry.pack-cache.test.ts +969 -0
  205. package/src/__tests__/asset-registry.raw-container-failfast.test.ts +225 -0
  206. package/src/__tests__/asset-registry.recursive.spec.ts +1397 -0
  207. package/src/__tests__/asset-registry.unit.test.ts +1030 -0
  208. package/src/__tests__/asset.unit.test.ts +7107 -0
  209. package/src/__tests__/audio-load-by-guid.unit.test.ts +126 -0
  210. package/src/__tests__/backend-selection.integration.test.ts +11 -0
  211. package/src/__tests__/basis-catalog-dispatch.integration.test.ts +320 -0
  212. package/src/__tests__/bind-group-cache-keying.test.ts +4 -4
  213. package/src/__tests__/block-upload-math.unit.test.ts +2 -2
  214. package/src/__tests__/builtin-asset-registry.unit.test.ts +112 -0
  215. package/src/__tests__/builtin-shader-register-e2e.test.ts +1 -1
  216. package/src/__tests__/cache-false-eviction.test.ts +2 -1
  217. package/src/__tests__/cache-isolation-matrix.test.ts +2 -1
  218. package/src/__tests__/camera-clear-snapshot-equivalence.unit.test.ts +5 -6
  219. package/src/__tests__/clamp-to-last.e2e.browser.test.ts +29 -19
  220. package/src/__tests__/collect-scene-asset.test.ts +49 -52
  221. package/src/__tests__/collect-scene-mount-collapse.test.ts +391 -0
  222. package/src/__tests__/collect-subtree.unit.test.ts +1 -2
  223. package/src/__tests__/collect-transient-children-absent.test.ts +24 -10
  224. package/src/__tests__/collect-transient-roundtrip.test.ts +44 -20
  225. package/src/__tests__/collect-transient-skip.test.ts +24 -13
  226. package/src/__tests__/components.test-d.ts +1 -6
  227. package/src/__tests__/components.unit.test.ts +20 -19
  228. package/src/__tests__/composite-skybox-cross-world.browser.test.ts +59 -27
  229. package/src/__tests__/compressed-texture-physical-extent.integration.test.ts +139 -0
  230. package/src/__tests__/create-renderer-assembly.integration.test.ts +42 -29
  231. package/src/__tests__/createRenderer-dispose.test.ts +35 -402
  232. package/src/__tests__/createRenderer.browser-no-webgpu.test.ts +25 -30
  233. package/src/__tests__/createRenderer.unit.test.ts +1 -1
  234. package/src/__tests__/dawn/hello-sprite-nineslice-section.dawn.test.ts +27 -63
  235. package/src/__tests__/dawn/ibl-precompute-readback.dawn.test.ts +56 -47
  236. package/src/__tests__/dawn/instances-per-instance-pbr.dawn.test.ts +49 -29
  237. package/src/__tests__/dawn/instances-shadow.dawn.test.ts +26 -15
  238. package/src/__tests__/dawn/instances-uniform-fallback.dawn.test.ts +13 -14
  239. package/src/__tests__/dawn/material-alpha.dawn.test.ts +23 -31
  240. package/src/__tests__/dawn/material-cooked-fixture.dawn.test.ts +24 -9
  241. package/src/__tests__/dawn/{mesh-update.dawn.test.ts → mesh-update-dawn.test.ts} +42 -134
  242. package/src/__tests__/dawn/mipmap-srgb-linear.dawn.test.ts +14 -7
  243. package/src/__tests__/dawn/per-entity-material-texture-isolation.dawn.test.ts +16 -28
  244. package/src/__tests__/dawn/sprite-nineslice-mesh-bind.dawn.test.ts +23 -39
  245. package/src/__tests__/dawn/upload-texture.dawn.test.ts +198 -0
  246. package/src/__tests__/dawn/user-handle-mesh-render.dawn.test.ts +12 -14
  247. package/src/__tests__/dawn/user-mesh-upload.dawn.test.ts +27 -22
  248. package/src/__tests__/dawn/zero-manifest-mesh-fail.dawn.test.ts +25 -28
  249. package/src/__tests__/dawn/zero-manifest-ready.dawn.test.ts +10 -11
  250. package/src/__tests__/demo-sortscope-migration.unit.test.ts +5 -5
  251. package/src/__tests__/derive-bgl-integration.test.ts +34 -44
  252. package/src/__tests__/derive-render-data-skin.unit.test.ts +1 -1
  253. package/src/__tests__/draw-published.ts +11 -4
  254. package/src/__tests__/dynamic-texture-store.unit.test.ts +190 -0
  255. package/src/__tests__/equirect-bc6h.integration.test.ts +144 -21
  256. package/src/__tests__/errors.unit.test.ts +1227 -0
  257. package/src/__tests__/extract-frames-graceful-degradation.test.ts +3 -7
  258. package/src/__tests__/extract-frames-merge.test.ts +35 -22
  259. package/src/__tests__/extract-record-no-hardcoded-texture-fields.test.ts +5 -16
  260. package/src/__tests__/extract-skin-mismatch.unit.test.ts +322 -0
  261. package/src/__tests__/fetch-binary-decompress.test.ts +356 -0
  262. package/src/__tests__/four-path-compression.integration.test.ts +395 -0
  263. package/src/__tests__/frame-targets-shadow-regression.unit.test.ts +1 -1
  264. package/src/__tests__/fullscreen-feature-host.dawn.test.ts +80 -0
  265. package/src/__tests__/fullscreen-post-bgl-depth.test.ts +4 -2
  266. package/src/__tests__/fullscreen-post-depth-params-arity.test.ts +3 -3
  267. package/src/__tests__/fullscreen-post-process-pass.dawn.test.ts +39 -23
  268. package/src/__tests__/fullscreen-post-process-pass.unit.test.ts +4 -2
  269. package/src/__tests__/fxaa-pixel-diff.dawn.test.ts +28 -17
  270. package/src/__tests__/fxaa-validation-and-resize.dawn.test.ts +29 -18
  271. package/src/__tests__/fxaa-zero-overhead.dawn.test.ts +16 -12
  272. package/src/__tests__/geometry.unit.test.ts +525 -159
  273. package/src/__tests__/glyph-tilemap-worldid.test.ts +1 -1
  274. package/src/__tests__/gpu-resource-cow-survivor.test.ts +6 -4
  275. package/src/__tests__/guid-for-asset.unit.test.ts +102 -0
  276. package/src/__tests__/handle-migration.test.ts +136 -0
  277. package/src/__tests__/helpers/register-runtime-components.ts +4 -2
  278. package/src/__tests__/helpers/register-scene-components.ts +1 -1
  279. package/src/__tests__/host-custom-kind-contract.test-d.ts +47 -0
  280. package/src/__tests__/host-custom-kind-contract.test.ts +578 -0
  281. package/src/__tests__/inspect-name.test.ts +139 -0
  282. package/src/__tests__/instances.test-d.ts +1 -1
  283. package/src/__tests__/instantiate-mount-deferred-wiring.test.ts +112 -0
  284. package/src/__tests__/light-casters-9-light.browser.test.ts +73 -76
  285. package/src/__tests__/light-gpu-byte-neutral.unit.test.ts +7 -10
  286. package/src/__tests__/light-snapshot.test-d.ts +2 -2
  287. package/src/__tests__/lights-vec-negative.unit.test.ts +1 -1
  288. package/src/__tests__/lights.unit.test.ts +31 -511
  289. package/src/__tests__/loadbyguid-payload.unit.test.ts +117 -0
  290. package/src/__tests__/loadbyguid-texture-intern.unit.test.ts +213 -0
  291. package/src/__tests__/loader-extract-graceful.test.ts +146 -0
  292. package/src/__tests__/loader-name-survival.test.ts +213 -0
  293. package/src/__tests__/m3-vec-negative.unit.test.ts +3 -2
  294. package/src/__tests__/material-texture-uv-scale.unit.test.ts +101 -31
  295. package/src/__tests__/materials.unit.test.ts +10 -27
  296. package/src/__tests__/mesh-bin-contract.test.ts +28 -0
  297. package/src/__tests__/mesh-bin-skin-roundtrip.unit.test.ts +149 -0
  298. package/src/__tests__/mesh-bin.test.ts +38 -0
  299. package/src/__tests__/mesh-loader-skin-contract.unit.test.ts +120 -0
  300. package/src/__tests__/mesh-ssbo-grow.unit.test.ts +3 -3
  301. package/src/__tests__/mip-gate.unit.test.ts +1 -1
  302. package/src/__tests__/msaa-sprite-pixel-diff.dawn.test.ts +29 -68
  303. package/src/__tests__/new-kind-refs-contract.test.ts +132 -0
  304. package/src/__tests__/node-shims.d.ts +4 -6
  305. package/src/__tests__/package-promotion.test.ts +88 -0
  306. package/src/__tests__/package-rename.test.ts +103 -0
  307. package/src/__tests__/pass-selector.unit.test.ts +2 -2
  308. package/src/__tests__/pbr-pipeline.unit.test.ts +21 -25
  309. package/src/__tests__/pipeline-builder-msaa.unit.test.ts +6 -9
  310. package/src/__tests__/pipeline-cache-keying.unit.test.ts +6 -9
  311. package/src/__tests__/pipeline-spec.test.ts +16 -177
  312. package/src/__tests__/pipeline.unit.test.ts +154 -1693
  313. package/src/__tests__/point-light-shadow.dawn.test.ts +33 -42
  314. package/src/__tests__/point-light-shadow.unit.test.ts +19 -60
  315. package/src/__tests__/post-process-error-codes.unit.test.ts +4 -1
  316. package/src/__tests__/post-process-params-component.unit.test.ts +1 -1
  317. package/src/__tests__/post-process-params-extract.unit.test.ts +2 -5
  318. package/src/__tests__/postprocess-camera-consistency.test.ts +4 -7
  319. package/src/__tests__/profiler-assembly.integration.test.ts +1 -1
  320. package/src/__tests__/propagate-transforms.dawn.test.ts +12 -11
  321. package/src/__tests__/record-worldid-isolation.test.ts +7 -29
  322. package/src/__tests__/recover-error-exhaustive.test-d.ts +1 -1
  323. package/src/__tests__/render-error-exhaustive.test-d.ts +117 -71
  324. package/src/__tests__/render-feature-assembly.test-d.ts +20 -9
  325. package/src/__tests__/render-feature-prepared-graphics-docs.unit.test.ts +8 -6
  326. package/src/__tests__/render-feature-prepared-graphics.browser.test.ts +65 -559
  327. package/src/__tests__/render-feature-prepared-graphics.dawn.test.ts +57 -544
  328. package/src/__tests__/render-feature-prepared-graphics.fixture.ts +104 -0
  329. package/src/__tests__/render-feature-prepared-graphics.integration.test.ts +40 -248
  330. package/src/__tests__/render-feature-prepared-graphics.regression.integration.test.ts +83 -340
  331. package/src/__tests__/render-feature-recover.integration.test.ts +9 -49
  332. package/src/__tests__/render-feature-runtime-surface.test-d.ts +17 -20
  333. package/src/__tests__/render-schema-consumer.integration.test.ts +20 -13
  334. package/src/__tests__/render-schema-owner-boundary.unit.test.ts +2 -6
  335. package/src/__tests__/render-system-cross-world-overlay-queue.test.ts +5 -5
  336. package/src/__tests__/render-system-extract-dispatch-ordering.test.ts +16 -31
  337. package/src/__tests__/render-system-extract.test.ts +36 -51
  338. package/src/__tests__/render-system-extract.unit.test.ts +360 -0
  339. package/src/__tests__/render-system-fold-bucket.unit.test.ts +3 -5
  340. package/src/__tests__/render-system-fold-fallback.unit.test.ts +6 -3
  341. package/src/__tests__/render-system-fold-material.unit.test.ts +3 -5
  342. package/src/__tests__/render-system-fold-metrics.unit.test.ts +5 -5
  343. package/src/__tests__/render-system-fold-modegate.unit.test.ts +6 -6
  344. package/src/__tests__/render-system-fold.dawn.test.ts +7 -5
  345. package/src/__tests__/render-system-mega.test.ts +292 -190
  346. package/src/__tests__/render-system-owner-split-contract.test.ts +10 -32
  347. package/src/__tests__/render-system-record-multi-material-textureview.test.ts +59 -45
  348. package/src/__tests__/render-system-record-per-submesh-transparency.test.ts +23 -29
  349. package/src/__tests__/render-system-record.test.ts +398 -235
  350. package/src/__tests__/render-system-record.unit.test.ts +25 -26
  351. package/src/__tests__/render-system-skin-bg.unit.test.ts +8 -12
  352. package/src/__tests__/renderer-consumer.test-d.ts +16 -3
  353. package/src/__tests__/renderer-health.unit.test.ts +26 -916
  354. package/src/__tests__/renderer-lifecycle.integration.test.ts +19 -6
  355. package/src/__tests__/renderer-recover.unit.test.ts +49 -1069
  356. package/src/__tests__/renderer-result.test-d.ts +19 -9
  357. package/src/__tests__/renderer-surface.unit.test.ts +3 -5
  358. package/src/__tests__/renderer-test-utils.ts +56 -0
  359. package/src/__tests__/renderer.test-d.ts +61 -0
  360. package/src/__tests__/resolve-asset-handle-err.test.ts +111 -0
  361. package/src/__tests__/resolve-asset-handle.unit.test.ts +64 -0
  362. package/src/__tests__/resolve-depth-only-view.test.ts +1 -1
  363. package/src/__tests__/resolveName-fallback.test.ts +64 -0
  364. package/src/__tests__/resolveName-null-package.test.ts +38 -0
  365. package/src/__tests__/resolveName-unified-entry.test.ts +65 -0
  366. package/src/__tests__/resolveName.test.ts +64 -0
  367. package/src/__tests__/rhi-null-command-flow.unit.test.ts +56 -260
  368. package/src/__tests__/rhi-null-renderer-lifecycle.unit.test.ts +41 -169
  369. package/src/__tests__/roots-to-scene-asset.test.ts +199 -93
  370. package/src/__tests__/roundtrip-primitive.test.ts +351 -0
  371. package/src/__tests__/scene-bare-guid-refs-instantiate.test.ts +123 -0
  372. package/src/__tests__/scene-equirect-roundtrip.test.ts +103 -16
  373. package/src/__tests__/scene-instance-authoring.integration.test.ts +8 -0
  374. package/src/__tests__/scene-instance-bridge.integration.test.ts +1 -1
  375. package/src/__tests__/scene-instance-component.test.ts +1 -1
  376. package/src/__tests__/scene-mount-fixed-point.test.ts +257 -0
  377. package/src/__tests__/scene-mount-roundtrip.test.ts +987 -0
  378. package/src/__tests__/scene-mount-wrapper-roundtrip.test.ts +202 -0
  379. package/src/__tests__/scene-sugar-instantiate.test.ts +324 -0
  380. package/src/__tests__/serialize-mounts-roundtrip.test.ts +533 -0
  381. package/src/__tests__/serialize-scene-asset.test.ts +219 -22
  382. package/src/__tests__/shadow-caster-empty-schema.test.ts +3 -3
  383. package/src/__tests__/shadow-csm-cascade-loadop.test.ts +37 -17
  384. package/src/__tests__/shadow-csm-component.test.ts +3 -5
  385. package/src/__tests__/shadow-csm-extract.test.ts +2 -100
  386. package/src/__tests__/shadow-csm-orthoz.test.ts +2 -16
  387. package/src/__tests__/shadow-csm-runtime-vary.dawn.test.ts +19 -14
  388. package/src/__tests__/shadow-csm-tile-consistency.test.ts +32 -26
  389. package/src/__tests__/shadow-csm-ubo.dawn.test.ts +8 -49
  390. package/src/__tests__/shadow-csm-ubo.test.ts +3 -25
  391. package/src/__tests__/shadow-csm-viewport.browser.test.ts +1 -1
  392. package/src/__tests__/shadow-fields-observable.dawn.test.ts +67 -56
  393. package/src/__tests__/shadow-m1.dawn.test.ts +8 -9
  394. package/src/__tests__/shadow-mesh-ssbo-order.test.ts +11 -27
  395. package/src/__tests__/skin-errors.unit.test.ts +1 -1
  396. package/src/__tests__/skin-extract-getarrayview-count.unit.test.ts +7 -5
  397. package/src/__tests__/skylight-lazy-projection.test.ts +36 -15
  398. package/src/__tests__/sparse-tag-scene-roundtrip.test.ts +5 -5
  399. package/src/__tests__/sprite-cullmode-flip.dawn.test.ts +47 -64
  400. package/src/__tests__/sprite-lit-bgl-byte-identical.test.ts +15 -14
  401. package/src/__tests__/sprite-lit-extract-branch.test.ts +1 -1
  402. package/src/__tests__/sprite-lit-pipeline-cache-key.test.ts +1 -1
  403. package/src/__tests__/ssao-bgl.test.ts +16 -9
  404. package/src/__tests__/ssao-buffers.test.ts +2 -2
  405. package/src/__tests__/ssao-data.test.ts +2 -2
  406. package/src/__tests__/ssao-errors.test.ts +1 -1
  407. package/src/__tests__/ssao-passes.test.ts +68 -392
  408. package/src/__tests__/ssao-pipelines.test.ts +1 -1
  409. package/src/__tests__/ssao-uniform-layout.test.ts +8 -6
  410. package/src/__tests__/stencil-outline-pixel.dawn.test.ts +25 -17
  411. package/src/__tests__/swap-chain-format.unit.test.ts +5 -7
  412. package/src/__tests__/systems.unit.test.ts +536 -1326
  413. package/src/__tests__/template-game-default-api-contract.test.ts +362 -0
  414. package/src/__tests__/text.unit.test.ts +56 -33
  415. package/src/__tests__/tilemap-childed-despawn.test.ts +8 -14
  416. package/src/__tests__/tilemap-chunk-extract.overhang-bounds.test.ts +8 -12
  417. package/src/__tests__/tilemap-chunk-extract.propagate-order.test.ts +2 -1
  418. package/src/__tests__/tilemap-chunk-extract.test.ts +13 -17
  419. package/src/__tests__/tilemap-dirty-rebuild.test.ts +7 -11
  420. package/src/__tests__/tilemap-material-cache.test.ts +8 -13
  421. package/src/__tests__/tilemap-multi-atlas.test.ts +12 -32
  422. package/src/__tests__/tilemap-owner-boundary.unit.test.ts +5 -2
  423. package/src/__tests__/tilemap-region-pack.test.ts +8 -12
  424. package/src/__tests__/tilemap-spawn-flip-pivot.test.ts +8 -12
  425. package/src/__tests__/tilemap-uv-inset.test.ts +11 -14
  426. package/src/__tests__/tilemap-validate.test.ts +1 -1
  427. package/src/__tests__/tileset-asset-validate.test.ts +638 -0
  428. package/src/__tests__/transcode-fallback.unit.test.ts +207 -0
  429. package/src/__tests__/transform-hierarchy-pixel-diff.dawn.test.ts +36 -28
  430. package/src/__tests__/transient-fields-collect.test.ts +28 -21
  431. package/src/__tests__/transient-runtime-behavior.test.ts +227 -0
  432. package/src/__tests__/transparent-sort-tilemap-sprite-interleave.test.ts +4 -4
  433. package/src/__tests__/variant-selection.unit.test.ts +1 -1
  434. package/src/__tests__/video-extract-bindgroup.dawn.test.ts +89 -136
  435. package/src/__tests__/video-loader-consumption.test.ts +86 -0
  436. package/src/__tests__/video-loader-smoke.dawn.test.ts +60 -0
  437. package/src/__tests__/view-ubo-layout.browser.test.ts +0 -22
  438. package/src/__tests__/world-entity-key.test.ts +1 -1
  439. package/src/__tests__/world-scene-despawn.test.ts +1 -1
  440. package/src/__tests__/world-scene-instantiate.test.ts +2 -36
  441. package/src/__tests__/world-scene-nested.test.ts +1 -1
  442. package/src/__tests__/world-scene-override.test.ts +1 -1
  443. package/src/backend-selection.ts +69 -0
  444. package/src/collect-scene-asset.ts +35 -23
  445. package/src/components/__tests__/camera.test-d.ts +1 -1
  446. package/src/components/__tests__/camera.test.ts +1 -1
  447. package/src/components/__tests__/sprite-animation.test-d.ts +2 -2
  448. package/src/components/__tests__/tile-layer.test-d.ts +1 -1
  449. package/src/components/__tests__/tile-layer.unit.test.ts +2 -2
  450. package/src/createRenderer.ts +24 -36
  451. package/src/errors/environment.ts +1 -1
  452. package/src/index.ts +51 -113
  453. package/src/renderer-host.ts +33 -0
  454. package/src/scene-instances/__tests__/post-spawn-resolve-joints.unit.test.ts +1 -1
  455. package/src/scene-instances/index.ts +4 -0
  456. package/src/scene-utils/mount-override-fold.ts +3 -7
  457. package/src/systems/__tests__/transparent-sort.bench.ts +3 -3
  458. package/src/systems/sprite-animation-tick.ts +1 -1
  459. package/src/systems/transparent-sort.ts +38 -38
  460. package/src/tilemap-register-validate.ts +4 -4
  461. package/dist/__tests__/bind-group-cache-binding.test.d.ts +0 -2
  462. package/dist/__tests__/bind-group-cache-binding.test.d.ts.map +0 -1
  463. package/dist/__tests__/bind-group-cache-frame.test.d.ts +0 -2
  464. package/dist/__tests__/bind-group-cache-frame.test.d.ts.map +0 -1
  465. package/dist/__tests__/dawn/mesh-update.dawn.test.d.ts +0 -2
  466. package/dist/__tests__/dawn/mesh-update.dawn.test.d.ts.map +0 -1
  467. package/dist/__tests__/dispatch-fullscreen-pass-composite-swapchain.dawn.test.d.ts +0 -2
  468. package/dist/__tests__/dispatch-fullscreen-pass-composite-swapchain.dawn.test.d.ts.map +0 -1
  469. package/dist/__tests__/dispatch-fullscreen-pass-custom-reads.dawn.test.d.ts +0 -2
  470. package/dist/__tests__/dispatch-fullscreen-pass-custom-reads.dawn.test.d.ts.map +0 -1
  471. package/dist/__tests__/dispatch-fullscreen-pass-depth-composite.dawn.test.d.ts +0 -2
  472. package/dist/__tests__/dispatch-fullscreen-pass-depth-composite.dawn.test.d.ts.map +0 -1
  473. package/dist/__tests__/dispatch-fullscreen-pass-params.unit.test.d.ts +0 -2
  474. package/dist/__tests__/dispatch-fullscreen-pass-params.unit.test.d.ts.map +0 -1
  475. package/dist/__tests__/fog-producer-manifest.d.ts +0 -131
  476. package/dist/__tests__/fog-producer-manifest.d.ts.map +0 -1
  477. package/dist/__tests__/fog-producer-pixel-probe.d.ts +0 -42
  478. package/dist/__tests__/fog-producer-pixel-probe.d.ts.map +0 -1
  479. package/dist/__tests__/fog-producer-pixel.browser.test.d.ts +0 -2
  480. package/dist/__tests__/fog-producer-pixel.browser.test.d.ts.map +0 -1
  481. package/dist/__tests__/fog-producer-pixel.dawn.test.d.ts +0 -2
  482. package/dist/__tests__/fog-producer-pixel.dawn.test.d.ts.map +0 -1
  483. package/dist/__tests__/fog-producer-real-fixture.d.ts +0 -5
  484. package/dist/__tests__/fog-producer-real-fixture.d.ts.map +0 -1
  485. package/dist/__tests__/fog-producer-vfx-effect.d.ts +0 -3
  486. package/dist/__tests__/fog-producer-vfx-effect.d.ts.map +0 -1
  487. package/dist/__tests__/fog-scene-asset.integration.test.d.ts +0 -2
  488. package/dist/__tests__/fog-scene-asset.integration.test.d.ts.map +0 -1
  489. package/dist/__tests__/gpu-resource-store-cubemap-status.test.d.ts +0 -2
  490. package/dist/__tests__/gpu-resource-store-cubemap-status.test.d.ts.map +0 -1
  491. package/dist/__tests__/gpu-resource.test.d.ts +0 -2
  492. package/dist/__tests__/gpu-resource.test.d.ts.map +0 -1
  493. package/dist/__tests__/hdrp-bgl-slots.browser.test.d.ts +0 -2
  494. package/dist/__tests__/hdrp-bgl-slots.browser.test.d.ts.map +0 -1
  495. package/dist/__tests__/hdrp-buffers.unit.test.d.ts +0 -2
  496. package/dist/__tests__/hdrp-buffers.unit.test.d.ts.map +0 -1
  497. package/dist/__tests__/hdrp-execute-filter.unit.test.d.ts +0 -2
  498. package/dist/__tests__/hdrp-execute-filter.unit.test.d.ts.map +0 -1
  499. package/dist/__tests__/hdrp-gbuffer-attachments.browser.test.d.ts +0 -2
  500. package/dist/__tests__/hdrp-gbuffer-attachments.browser.test.d.ts.map +0 -1
  501. package/dist/__tests__/hdrp-pipeline-asset-type.test-d.d.ts +0 -2
  502. package/dist/__tests__/hdrp-pipeline-asset-type.test-d.d.ts.map +0 -1
  503. package/dist/__tests__/hdrp-ssao-boundary.test.d.ts +0 -2
  504. package/dist/__tests__/hdrp-ssao-boundary.test.d.ts.map +0 -1
  505. package/dist/__tests__/hdrp-ssao-falsification.test.d.ts +0 -2
  506. package/dist/__tests__/hdrp-ssao-falsification.test.d.ts.map +0 -1
  507. package/dist/__tests__/helpers/primitive-world.d.ts +0 -8
  508. package/dist/__tests__/helpers/primitive-world.d.ts.map +0 -1
  509. package/dist/__tests__/helpers/render-asset-port.d.ts +0 -15
  510. package/dist/__tests__/helpers/render-asset-port.d.ts.map +0 -1
  511. package/dist/__tests__/helpers/scene-asset-port.d.ts +0 -9
  512. package/dist/__tests__/helpers/scene-asset-port.d.ts.map +0 -1
  513. package/dist/__tests__/material-derived-coordinates.integration.test.d.ts +0 -2
  514. package/dist/__tests__/material-derived-coordinates.integration.test.d.ts.map +0 -1
  515. package/dist/__tests__/pipeline-layout-selection.test.d.ts +0 -2
  516. package/dist/__tests__/pipeline-layout-selection.test.d.ts.map +0 -1
  517. package/dist/__tests__/post-process-reads-narrowing.test-d.d.ts +0 -2
  518. package/dist/__tests__/post-process-reads-narrowing.test-d.d.ts.map +0 -1
  519. package/dist/__tests__/post-process-register-roundtrip.dawn.test.d.ts +0 -2
  520. package/dist/__tests__/post-process-register-roundtrip.dawn.test.d.ts.map +0 -1
  521. package/dist/__tests__/render-feature-zero-feature.browser.test.d.ts +0 -2
  522. package/dist/__tests__/render-feature-zero-feature.browser.test.d.ts.map +0 -1
  523. package/dist/__tests__/render-pipeline-trivial.dawn.test.d.ts +0 -2
  524. package/dist/__tests__/render-pipeline-trivial.dawn.test.d.ts.map +0 -1
  525. package/dist/__tests__/shadow-csm-caster-membership.test.d.ts +0 -2
  526. package/dist/__tests__/shadow-csm-caster-membership.test.d.ts.map +0 -1
  527. package/dist/__tests__/shadow-csm-pssm.test.d.ts +0 -2
  528. package/dist/__tests__/shadow-csm-pssm.test.d.ts.map +0 -1
  529. package/dist/__tests__/shadow-csm-temporal.browser.test.d.ts +0 -2
  530. package/dist/__tests__/shadow-csm-temporal.browser.test.d.ts.map +0 -1
  531. package/dist/__tests__/shadow-csm-viewport.test.d.ts +0 -2
  532. package/dist/__tests__/shadow-csm-viewport.test.d.ts.map +0 -1
  533. package/dist/__tests__/shadow-m2.dawn.test.d.ts +0 -2
  534. package/dist/__tests__/shadow-m2.dawn.test.d.ts.map +0 -1
  535. package/dist/__tests__/shadow-m3-calibrate-run.dawn.test.d.ts +0 -2
  536. package/dist/__tests__/shadow-m3-calibrate-run.dawn.test.d.ts.map +0 -1
  537. package/dist/__tests__/shadow-m3-calibrate.d.ts +0 -83
  538. package/dist/__tests__/shadow-m3-calibrate.d.ts.map +0 -1
  539. package/dist/__tests__/shadow-m3.dawn.test.d.ts +0 -2
  540. package/dist/__tests__/shadow-m3.dawn.test.d.ts.map +0 -1
  541. package/dist/__tests__/shadow-probe-control-flow.dawn.test.d.ts +0 -2
  542. package/dist/__tests__/shadow-probe-control-flow.dawn.test.d.ts.map +0 -1
  543. package/dist/__tests__/shadow-quality-metrics.dawn.test.d.ts +0 -2
  544. package/dist/__tests__/shadow-quality-metrics.dawn.test.d.ts.map +0 -1
  545. package/dist/__tests__/temporal-off-path.unit.test.d.ts +0 -2
  546. package/dist/__tests__/temporal-off-path.unit.test.d.ts.map +0 -1
  547. package/dist/__tests__/video-cache-regression.unit.test.d.ts +0 -2
  548. package/dist/__tests__/video-cache-regression.unit.test.d.ts.map +0 -1
  549. package/dist/asset-kind.d.ts +0 -4
  550. package/dist/asset-kind.d.ts.map +0 -1
  551. package/dist/errors/sprite-animation.d.ts +0 -3
  552. package/dist/errors/sprite-animation.d.ts.map +0 -1
  553. package/dist/scene-asset-port.d.ts +0 -17
  554. package/dist/scene-asset-port.d.ts.map +0 -1
  555. package/dist/scene-collect-errors.d.ts +0 -22
  556. package/dist/scene-collect-errors.d.ts.map +0 -1
  557. package/dist/shadow-m3-calibrate.d.ts +0 -40
  558. package/dist/shadow-m3-calibrate.d.ts.map +0 -1
  559. package/src/__tests__/bind-group-cache-binding.test.ts +0 -2513
  560. package/src/__tests__/bind-group-cache-frame.test.ts +0 -1511
  561. package/src/__tests__/dispatch-fullscreen-pass-composite-swapchain.dawn.test.ts +0 -204
  562. package/src/__tests__/dispatch-fullscreen-pass-custom-reads.dawn.test.ts +0 -297
  563. package/src/__tests__/dispatch-fullscreen-pass-depth-composite.dawn.test.ts +0 -271
  564. package/src/__tests__/dispatch-fullscreen-pass-params.unit.test.ts +0 -321
  565. package/src/__tests__/fog-producer-manifest.ts +0 -162
  566. package/src/__tests__/fog-producer-pixel-probe.ts +0 -263
  567. package/src/__tests__/fog-producer-pixel.browser.test.ts +0 -26
  568. package/src/__tests__/fog-producer-pixel.dawn.test.ts +0 -55
  569. package/src/__tests__/fog-producer-real-fixture.ts +0 -805
  570. package/src/__tests__/fog-producer-vfx-effect.ts +0 -272
  571. package/src/__tests__/fog-scene-asset.integration.test.ts +0 -123
  572. package/src/__tests__/gpu-resource-store-cubemap-status.test.ts +0 -207
  573. package/src/__tests__/gpu-resource.test.ts +0 -1206
  574. package/src/__tests__/hdrp-bgl-slots.browser.test.ts +0 -50
  575. package/src/__tests__/hdrp-buffers.unit.test.ts +0 -70
  576. package/src/__tests__/hdrp-execute-filter.unit.test.ts +0 -200
  577. package/src/__tests__/hdrp-gbuffer-attachments.browser.test.ts +0 -64
  578. package/src/__tests__/hdrp-pipeline-asset-type.test-d.ts +0 -139
  579. package/src/__tests__/hdrp-ssao-boundary.test.ts +0 -237
  580. package/src/__tests__/hdrp-ssao-falsification.test.ts +0 -289
  581. package/src/__tests__/helpers/primitive-world.ts +0 -91
  582. package/src/__tests__/helpers/render-asset-port.ts +0 -65
  583. package/src/__tests__/helpers/scene-asset-port.ts +0 -23
  584. package/src/__tests__/material-derived-coordinates.integration.test.ts +0 -100
  585. package/src/__tests__/pipeline-layout-selection.test.ts +0 -298
  586. package/src/__tests__/post-process-reads-narrowing.test-d.ts +0 -52
  587. package/src/__tests__/post-process-register-roundtrip.dawn.test.ts +0 -230
  588. package/src/__tests__/render-feature-zero-feature.browser.test.ts +0 -152
  589. package/src/__tests__/render-pipeline-trivial.dawn.test.ts +0 -525
  590. package/src/__tests__/shadow-csm-caster-membership.test.ts +0 -232
  591. package/src/__tests__/shadow-csm-pssm.test.ts +0 -142
  592. package/src/__tests__/shadow-csm-temporal.browser.test.ts +0 -145
  593. package/src/__tests__/shadow-csm-viewport.test.ts +0 -74
  594. package/src/__tests__/shadow-m2.dawn.test.ts +0 -394
  595. package/src/__tests__/shadow-m3-calibrate-run.dawn.test.ts +0 -248
  596. package/src/__tests__/shadow-m3-calibrate.ts +0 -203
  597. package/src/__tests__/shadow-m3.dawn.test.ts +0 -288
  598. package/src/__tests__/shadow-probe-control-flow.dawn.test.ts +0 -264
  599. package/src/__tests__/shadow-quality-metrics.dawn.test.ts +0 -324
  600. package/src/__tests__/temporal-off-path.unit.test.ts +0 -69
  601. package/src/__tests__/video-cache-regression.unit.test.ts +0 -186
  602. package/src/asset-kind.ts +0 -7
  603. package/src/errors/sprite-animation.ts +0 -5
  604. package/src/scene-asset-port.ts +0 -32
  605. package/src/scene-collect-errors.ts +0 -30
  606. package/src/shadow-m3-calibrate.ts +0 -171
@@ -0,0 +1,81 @@
1
+ // w12 - AssetRegistry browser path (loadByGuid + GUID-keyed catalog API)
2
+ //
3
+ // Migration from load(url) to loadByGuid (feat-20260513-guid-asset-package-system w13).
4
+ // feat-20260614 M8 (D-17): the registry catalogues GUID -> payload and
5
+ // `loadByGuid` returns the PAYLOAD (no handle). Column minting moved to
6
+ // `world.allocSharedRef`. Covers catalog + loadByGuid ok path + payload
7
+ // idempotency + AC-11 inspect() shape for a GUID-catalogued asset.
8
+
9
+ import { AssetRegistry } from '@forgeax/engine-assets-runtime';
10
+ import { AssetGuid } from '@forgeax/engine-pack/guid';
11
+ import type { MeshAsset as TypesMeshAsset } from '@forgeax/engine-types';
12
+ import { describe, expect, it } from 'vitest';
13
+ import { makeMockShaderRegistry } from './helpers/mock-shader-registry';
14
+
15
+ const GUID_BROWSER_A = '00000000-0000-7000-8000-000000000021';
16
+
17
+ function makeMesh(): TypesMeshAsset {
18
+ return {
19
+ kind: 'mesh',
20
+ // 1 vertex * 12F canonical layout (position vec3 + normal vec3 + uv vec2 + tangent vec4)
21
+ vertices: new Float32Array([0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1]),
22
+ indices: new Uint16Array([0]),
23
+ attributes: {},
24
+ submeshes: [
25
+ {
26
+ indexOffset: 0,
27
+ indexCount: 1,
28
+ vertexCount: 12,
29
+ topology: 'triangle-list',
30
+ materialSlot: 0,
31
+ },
32
+ ],
33
+
34
+ materialSlots: [{ slotName: 'Default' }],
35
+ };
36
+ }
37
+
38
+ describe('w12 - AssetRegistry browser loadByGuid happy path', () => {
39
+ it('loadByGuid() returns Ok(payload) for a catalogued GUID', async () => {
40
+ const reg = new AssetRegistry(makeMockShaderRegistry());
41
+ const parseResult = AssetGuid.parse(GUID_BROWSER_A);
42
+ if (!parseResult.ok) throw new Error('expected ok');
43
+ const guid = parseResult.value;
44
+ const mesh = makeMesh();
45
+ reg.catalog<TypesMeshAsset>(guid, mesh);
46
+ const res = await reg.loadByGuid<TypesMeshAsset>(guid);
47
+ expect(res.ok).toBe(true);
48
+ if (!res.ok) return;
49
+ expect(res.value.kind).toBe('mesh');
50
+ });
51
+
52
+ it('two loadByGuid(sameGuid) calls return the same payload', async () => {
53
+ const reg = new AssetRegistry(makeMockShaderRegistry());
54
+ const parseResult = AssetGuid.parse(GUID_BROWSER_A);
55
+ if (!parseResult.ok) throw new Error('expected ok');
56
+ const guid = parseResult.value;
57
+ reg.catalog<TypesMeshAsset>(guid, makeMesh());
58
+ const a = await reg.loadByGuid<TypesMeshAsset>(guid);
59
+ const b = await reg.loadByGuid<TypesMeshAsset>(guid);
60
+ expect(a.ok).toBe(true);
61
+ expect(b.ok).toBe(true);
62
+ if (a.ok && b.ok) {
63
+ expect(a.value).toBe(b.value);
64
+ }
65
+ });
66
+
67
+ it('AC-11: inspect() reports MeshAsset brand after catalog()', async () => {
68
+ const reg = new AssetRegistry(makeMockShaderRegistry());
69
+ const before = reg.inspect().assets.length;
70
+ const parseResult = AssetGuid.parse(GUID_BROWSER_A);
71
+ if (!parseResult.ok) throw new Error('expected ok');
72
+ const guid = parseResult.value;
73
+ reg.catalog<TypesMeshAsset>(guid, makeMesh());
74
+ const snap = reg.inspect();
75
+ expect(snap.assets.length).toBe(before + 1);
76
+ const last = snap.assets[snap.assets.length - 1];
77
+ expect(last).toBeDefined();
78
+ if (last === undefined) return;
79
+ expect(last.kind).toBe('mesh');
80
+ });
81
+ });
@@ -0,0 +1,94 @@
1
+ // w13 - AssetRegistry Node path (loadByGuid + GUID-keyed catalog API).
2
+ //
3
+ // Migration from load(url) to loadByGuid (feat-20260513-guid-asset-package-system w13).
4
+ // feat-20260614 M8 (D-17): the registry catalogues GUID -> payload and
5
+ // `loadByGuid` returns the PAYLOAD (no handle); column minting moved to
6
+ // `world.allocSharedRef`, handle->payload resolution to `resolveAssetHandle`.
7
+ // Covers catalog + loadByGuid ok path + payload idempotency + asset-not-found
8
+ // error path on missing GUID + asset-not-found on an unresolvable handle.
9
+
10
+ import { AssetRegistry, resolveAssetHandle } from '@forgeax/engine-assets-runtime';
11
+ import { World } from '@forgeax/engine-ecs';
12
+ import { AssetGuid } from '@forgeax/engine-pack/guid';
13
+ import type { Handle, TextureAsset, MeshAsset as TypesMeshAsset } from '@forgeax/engine-types';
14
+ import { toShared } from '@forgeax/engine-types';
15
+ import { describe, expect, it } from 'vitest';
16
+ import { makeMockShaderRegistry } from './helpers/mock-shader-registry';
17
+
18
+ const GUID_DAWN_A = '00000000-0000-7000-8000-000000000031';
19
+ const GUID_DAWN_B = '00000000-0000-7000-8000-000000000032';
20
+
21
+ function makeMesh(): TypesMeshAsset {
22
+ return {
23
+ kind: 'mesh',
24
+ // 1 vertex * 12F canonical layout (position vec3 + normal vec3 + uv vec2 + tangent vec4)
25
+ vertices: new Float32Array([0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1]),
26
+ indices: new Uint16Array([0]),
27
+ attributes: {},
28
+ submeshes: [
29
+ {
30
+ indexOffset: 0,
31
+ indexCount: 1,
32
+ vertexCount: 12,
33
+ topology: 'triangle-list',
34
+ materialSlot: 0,
35
+ },
36
+ ],
37
+
38
+ materialSlots: [{ slotName: 'Default' }],
39
+ };
40
+ }
41
+
42
+ describe('w13 - AssetRegistry Node loadByGuid happy path', () => {
43
+ it('loadByGuid() returns Ok(payload) for a catalogued GUID', async () => {
44
+ const reg = new AssetRegistry(makeMockShaderRegistry());
45
+ const parseResult = AssetGuid.parse(GUID_DAWN_A);
46
+ if (!parseResult.ok) throw new Error('expected ok');
47
+ const guid = parseResult.value;
48
+ const mesh = makeMesh();
49
+ reg.catalog<TypesMeshAsset>(guid, mesh);
50
+ const res = await reg.loadByGuid<TypesMeshAsset>(guid);
51
+ expect(res.ok).toBe(true);
52
+ if (!res.ok) return;
53
+ expect(res.value.kind).toBe('mesh');
54
+ });
55
+
56
+ it('two loadByGuid(sameGuid) calls return same payload (idempotent)', async () => {
57
+ const reg = new AssetRegistry(makeMockShaderRegistry());
58
+ const parseResult = AssetGuid.parse(GUID_DAWN_A);
59
+ if (!parseResult.ok) throw new Error('expected ok');
60
+ const guid = parseResult.value;
61
+ reg.catalog<TypesMeshAsset>(guid, makeMesh());
62
+ const a = await reg.loadByGuid<TypesMeshAsset>(guid);
63
+ const b = await reg.loadByGuid<TypesMeshAsset>(guid);
64
+ expect(a.ok).toBe(true);
65
+ expect(b.ok).toBe(true);
66
+ if (a.ok && b.ok) {
67
+ expect(a.value).toBe(b.value);
68
+ }
69
+ });
70
+ });
71
+
72
+ describe('w13 - AssetRegistry Node error paths (AC-03 migration)', () => {
73
+ it('asset-not-found: loadByGuid(unregistered guid)', async () => {
74
+ const reg = new AssetRegistry(makeMockShaderRegistry());
75
+ const parseResult = AssetGuid.parse(GUID_DAWN_B);
76
+ if (!parseResult.ok) throw new Error('expected ok');
77
+ const guid = parseResult.value;
78
+ const res = await reg.loadByGuid<TypesMeshAsset>(guid);
79
+ expect(res.ok).toBe(false);
80
+ if (!res.ok) expect(res.error.code).toBe('asset-not-found');
81
+ });
82
+
83
+ it('asset-not-found: resolveAssetHandle(unallocated gen-0 handle)', () => {
84
+ const world = new World();
85
+ // gen-0 user-tier handle for a never-allocated slot: passes the generation
86
+ // gate (storeGen defaults to 0) then misses the payload -> asset-not-found.
87
+ // (A gen>0 handle would instead surface 'shared-ref-stale' per D-3/AC-10 —
88
+ // see asset.unit.test.ts "unresolvable handle: stale error forwarded".)
89
+ const fake = toShared<'TextureAsset'>(99999);
90
+ const res = resolveAssetHandle<TextureAsset>(world, fake as Handle<string, 'shared'>);
91
+ expect(res.ok).toBe(false);
92
+ if (!res.ok) expect(res.error.code).toBe('asset-not-found');
93
+ });
94
+ });
@@ -0,0 +1,170 @@
1
+ // w1 TDD: listCatalog unit test (plan-strategy section 2 D1)
2
+ //
3
+ // Test-first approach — call listCatalog() before it exists on AssetRegistry,
4
+ // confirming the TDD "red" phase via TypeScript compile error (TS2339).
5
+ // w2 will add the implementation and turn these tests green.
6
+ //
7
+ // plan-strategy section 2 D1 (engine export for AC-03 asset panel enumeration);
8
+ // requirements AC-03 (asset panel = engine truth, no parallel discovery);
9
+ // research Finding 5 (AssetRegistry public API is all guid point-lookup;
10
+ // assetCatalog/packIndexCache are private — no enumeration primitive exists yet).
11
+
12
+ import { AssetRegistry } from '@forgeax/engine-assets-runtime';
13
+ import { AssetGuid } from '@forgeax/engine-pack/guid';
14
+ import type { MeshAsset } from '@forgeax/engine-types';
15
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
16
+ import { makeMockShaderRegistry } from './helpers/mock-shader-registry';
17
+
18
+ function makeReg(): AssetRegistry {
19
+ return new AssetRegistry(makeMockShaderRegistry());
20
+ }
21
+
22
+ function makeMeshFixture(): MeshAsset {
23
+ return {
24
+ kind: 'mesh',
25
+ vertices: new Float32Array(36),
26
+ indices: new Uint16Array([0, 1, 2]),
27
+ attributes: {},
28
+ materialSlots: [{ slotName: 'Default' }],
29
+ submeshes: [
30
+ {
31
+ indexOffset: 0,
32
+ indexCount: 3,
33
+ vertexCount: 3,
34
+ materialSlot: 0,
35
+ topology: 'triangle-list' as const,
36
+ },
37
+ ],
38
+ } as unknown as MeshAsset;
39
+ }
40
+
41
+ describe('D-1 listCatalog() (TDD: red before w2 impl)', () => {
42
+ it('returns non-empty array for catalogued assets matching inspect() truth', () => {
43
+ const reg = makeReg();
44
+ const guid = AssetGuid.format(AssetGuid.random());
45
+ const mesh = makeMeshFixture();
46
+ reg.catalog(guid, mesh);
47
+
48
+ const list = reg.listCatalog();
49
+ expect(Array.isArray(list)).toBe(true);
50
+ expect(list.length).toBeGreaterThan(0);
51
+
52
+ const found = list.find(
53
+ (e: { guid: string; kind: string; name?: string; packageUrl: string }) =>
54
+ e.guid === guid.toLowerCase(),
55
+ );
56
+ expect(found).toBeDefined();
57
+ expect(found?.guid).toBe(guid.toLowerCase());
58
+ expect(found?.kind).toBe('mesh');
59
+ // name derived via resolveName (empty for no-package catalogued asset)
60
+ expect(found).toHaveProperty('name');
61
+ expect(found).toHaveProperty('packageUrl');
62
+ });
63
+
64
+ it('returns empty array for a registry with zero catalogued assets (boundary E3)', () => {
65
+ const reg = makeReg();
66
+ // Fresh registry still has builtins. Clear them via invalidateAll.
67
+ reg.invalidateAll();
68
+ const list = reg.listCatalog();
69
+ expect(Array.isArray(list)).toBe(true);
70
+ expect(list.length).toBe(0);
71
+ });
72
+
73
+ it('surfaces dev-path refs as flattened GUID edges (Content Browser dependency graph)', () => {
74
+ const reg = makeReg();
75
+ const guid = AssetGuid.format(AssetGuid.random());
76
+ const dep1 = AssetGuid.format(AssetGuid.random());
77
+ const dep2 = AssetGuid.format(AssetGuid.random());
78
+ const mesh = makeMeshFixture();
79
+ // catalog(guid, asset, refs) stores the rich AssetRef[] on the envelope;
80
+ // listCatalog must flatten it to plain GUID strings.
81
+ reg.catalog(guid, mesh, [{ guid: dep1, sourceField: { fieldName: 'a' } }, { guid: dep2 }]);
82
+
83
+ const found = reg.listCatalog().find((e) => e.guid === guid.toLowerCase());
84
+ expect(found?.refs).toEqual([dep1, dep2]);
85
+ });
86
+
87
+ it('omits refs when an asset has no outgoing edges (add-only, undefined not [])', () => {
88
+ const reg = makeReg();
89
+ const guid = AssetGuid.format(AssetGuid.random());
90
+ reg.catalog(guid, makeMeshFixture());
91
+
92
+ const found = reg.listCatalog().find((e) => e.guid === guid.toLowerCase());
93
+ expect(found).toBeDefined();
94
+ expect(found?.refs).toBeUndefined();
95
+ });
96
+
97
+ it('returns a snapshot — two calls return distinct array objects (no internal Map leak, charter P4)', () => {
98
+ const reg = makeReg();
99
+ const guid = AssetGuid.format(AssetGuid.random());
100
+ const mesh = makeMeshFixture();
101
+ reg.catalog(guid, mesh);
102
+
103
+ const first = reg.listCatalog();
104
+ const firstLen = first.length;
105
+
106
+ const second = reg.listCatalog();
107
+ expect(second.length).toBe(firstLen);
108
+ // Snapshot identity: two calls return distinct array objects
109
+ // (no internal Map reference leak — charter P4).
110
+ expect(first).not.toBe(second);
111
+ });
112
+ });
113
+
114
+ // Prod path: sourcePath is only present on the pack-index (fetchPackIndex ->
115
+ // packIndexCache), never on dev-path catalog() envelopes. Editors need it to
116
+ // locate the `.meta.json` sidecar for external-asset CRUD; `packageUrl`
117
+ // points at the Pack v2 package and cannot
118
+ // be reversed to the source path.
119
+ describe('listCatalog() prod-path sourcePath (editor CRUD sidecar lookup)', () => {
120
+ const PACK_INDEX_URL = '/pack-index.json';
121
+ const MESH_GUID = 'a0000000-0000-4000-a000-000000000001';
122
+ const MESH_URL = '/assets/arrow_bow.fbx.a0000000.pack.json';
123
+ const MESH_SOURCE = 'games/marscraft/assets/arrow_bow.fbx';
124
+ // A row that omits sourcePath (legacy / malformed pack-index) must surface as
125
+ // undefined, not '', so consumers can distinguish "no source" from "empty".
126
+ const INLINE_GUID = 'a0000000-0000-4000-a000-000000000002';
127
+
128
+ let originalFetch: typeof globalThis.fetch | undefined;
129
+
130
+ beforeEach(() => {
131
+ originalFetch = globalThis.fetch;
132
+ });
133
+
134
+ afterEach(() => {
135
+ if (originalFetch !== undefined) {
136
+ globalThis.fetch = originalFetch;
137
+ } else {
138
+ // biome-ignore lint/suspicious/noExplicitAny: test teardown
139
+ delete (globalThis as any).fetch;
140
+ }
141
+ });
142
+
143
+ it('surfaces sourcePath from the pack-index; omits it for rows that lack one', async () => {
144
+ const reg = makeReg();
145
+ reg.configurePackIndex(PACK_INDEX_URL);
146
+
147
+ const packIndex = [
148
+ { guid: MESH_GUID, packageUrl: MESH_URL, kind: 'mesh', sourcePath: MESH_SOURCE },
149
+ { guid: INLINE_GUID, packageUrl: '/assets/other.pack.json', kind: 'mesh' },
150
+ ];
151
+ globalThis.fetch = vi.fn().mockImplementation((url: string) => {
152
+ if (url === PACK_INDEX_URL) {
153
+ return Promise.resolve({ ok: true, json: () => Promise.resolve(packIndex) });
154
+ }
155
+ return Promise.resolve({ ok: false, status: 404 });
156
+ }) as typeof globalThis.fetch;
157
+
158
+ // Populate packIndexCache without needing the (missing) pack bodies:
159
+ // refreshCatalog fetches + parses the pack-index into packIndexCache, which
160
+ // is the source listCatalog reads for prod rows.
161
+ await reg.refreshCatalog();
162
+
163
+ const withSource = reg.listCatalog().find((e) => e.guid === MESH_GUID.toLowerCase());
164
+ expect(withSource?.sourcePath).toBe(MESH_SOURCE);
165
+
166
+ const withoutSource = reg.listCatalog().find((e) => e.guid === INLINE_GUID.toLowerCase());
167
+ expect(withoutSource).toBeDefined();
168
+ expect(withoutSource?.sourcePath).toBeUndefined();
169
+ });
170
+ });
@@ -0,0 +1,316 @@
1
+ // asset-registry.mesh-bin.test.ts -- bug-20260610-pack-mesh-binarize-fetchpackfile-cache
2
+ // M2 / m2-1: regression test for mesh binarize round-trip via .pack.json + .bin
3
+ // sidecar (Fix A). RED at this commit (loader cannot read .bin yet); GREEN
4
+ // after the implementation commit.
5
+ //
6
+ // Cases (plan-decisions D-6):
7
+ // (A) binarized new path -- mesh entry payload is the empty sentinel (vertices=[],
8
+ // indices=[], data=Uint8Array(0)); the runtime resolves vertices/indices from
9
+ // a sibling <guid>.bin URL referenced by the catalog row. Asserts
10
+ // round-tripped vertices and indices are byte-equal to the originals.
11
+ // (B) inline fallback (CON-7) -- mesh entry payload carries inline number arrays
12
+ // (legacy pack shape). meshLoader's existing Array.isArray branch must still
13
+ // work. Asserts handle resolves and registered MeshAsset has the inline
14
+ // vertices/indices.
15
+ // (C) empty mesh -- vertices=[], indices=[] sentinel + 16-byte deterministic
16
+ // header (vlen=0, ilen=0, iwidth=0, jsonlen=0). loader returns a mesh with
17
+ // 0 vertices and 0 indices, no panic.
18
+ //
19
+ // Anchors: requirements AC-04 / AC-05 / CON-1 / CON-7;
20
+ // plan-strategy decisions D-1 / D-2 / D-3 / D-6;
21
+ // plan-decisions D-6 (3-case coverage).
22
+ //
23
+ // The test producer delegates the v4 header and canonical projection to the
24
+ // import owner; the runtime only consumes the resulting bytes.
25
+
26
+ import { AssetRegistry } from '@forgeax/engine-assets-runtime';
27
+ import { packMeshBinV4 } from '@forgeax/engine-import';
28
+ import { AssetGuid } from '@forgeax/engine-pack/guid';
29
+ import type { MeshAsset } from '@forgeax/engine-types';
30
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
31
+ import { makeMockShaderRegistry } from './helpers/mock-shader-registry';
32
+
33
+ // 12 floats per vertex (position vec3 + normal vec3 + uv vec2 + tangent vec4) --
34
+ // matches PROCEDURAL_FLOATS_PER_VERTEX and the meshLoader stride invariant.
35
+ const FLOATS_PER_VERTEX = 12;
36
+
37
+ const MESH_BIN_GUID = '00000000-0000-7000-8000-00006d657368'; // mesh sentinel
38
+ const MESH_INLINE_GUID = '00000000-0000-7000-8000-696e6c696e65'; // inline
39
+ const MESH_EMPTY_GUID = '00000000-0000-7000-8000-656d70747974'; // empty
40
+
41
+ function packMeshBinForTest(
42
+ vertices: Float32Array,
43
+ indices: Uint16Array | Uint32Array,
44
+ metaJson: string,
45
+ ): Uint8Array {
46
+ const parsed = JSON.parse(metaJson) as Record<string, unknown>;
47
+ const vertexCount = vertices.length / FLOATS_PER_VERTEX;
48
+ const position = new Float32Array(vertexCount * 3);
49
+ const normal = new Float32Array(vertexCount * 3);
50
+ const uv = new Float32Array(vertexCount * 2);
51
+ const tangent = new Float32Array(vertexCount * 4);
52
+ for (let vertex = 0; vertex < vertexCount; vertex++) {
53
+ const source = vertex * FLOATS_PER_VERTEX;
54
+ position.set(vertices.subarray(source, source + 3), vertex * 3);
55
+ normal.set(vertices.subarray(source + 3, source + 6), vertex * 3);
56
+ uv.set(vertices.subarray(source + 6, source + 8), vertex * 2);
57
+ tangent.set(vertices.subarray(source + 8, source + 12), vertex * 4);
58
+ }
59
+ const packed = packMeshBinV4(
60
+ {
61
+ vertices,
62
+ indices,
63
+ attributes: {
64
+ position,
65
+ normal,
66
+ uv,
67
+ tangent,
68
+ },
69
+ submeshes: parsed.submeshes as MeshAsset['submeshes'],
70
+ aabb: parsed.aabb as MeshAsset['aabb'],
71
+ },
72
+ 'runtime://asset-registry',
73
+ );
74
+ if (!packed.ok) throw new Error(packed.error.actual);
75
+ return packed.value;
76
+ }
77
+
78
+ function makePackIndex(rows: Array<{ guid: string; packageUrl: string }>) {
79
+ return rows.map((r) => ({
80
+ guid: r.guid,
81
+ packageUrl: r.packageUrl,
82
+ kind: 'mesh' as const,
83
+ }));
84
+ }
85
+
86
+ interface FetchRoute {
87
+ json?: unknown;
88
+ bytes?: Uint8Array;
89
+ status?: number;
90
+ }
91
+
92
+ function installFetchMock(routes: Map<string, FetchRoute>): void {
93
+ globalThis.fetch = (async (input: string | URL | Request) => {
94
+ const url =
95
+ typeof input === 'string'
96
+ ? input
97
+ : input instanceof URL
98
+ ? input.href
99
+ : (input as Request).url;
100
+ const route = routes.get(url);
101
+ if (route === undefined) {
102
+ return {
103
+ ok: false,
104
+ status: 404,
105
+ json: async () => null,
106
+ arrayBuffer: async () => new ArrayBuffer(0),
107
+ } as unknown as Response;
108
+ }
109
+ if (route.status !== undefined && route.status >= 400) {
110
+ return { ok: false, status: route.status } as unknown as Response;
111
+ }
112
+ return {
113
+ ok: true,
114
+ status: 200,
115
+ json: async () => route.json,
116
+ arrayBuffer: async () =>
117
+ route.bytes !== undefined
118
+ ? route.bytes.buffer.slice(
119
+ route.bytes.byteOffset,
120
+ route.bytes.byteOffset + route.bytes.byteLength,
121
+ )
122
+ : new ArrayBuffer(0),
123
+ } as unknown as Response;
124
+ }) as unknown as typeof globalThis.fetch;
125
+ }
126
+
127
+ describe('mesh-bin loader (M2 / m2-1)', () => {
128
+ const originalFetch = globalThis.fetch;
129
+
130
+ beforeEach(() => {
131
+ vi.restoreAllMocks();
132
+ });
133
+
134
+ afterEach(() => {
135
+ globalThis.fetch = originalFetch;
136
+ });
137
+
138
+ it('(A) binarized path: vertices/indices reconstructed byte-equal from sibling .bin', async () => {
139
+ // Two-vertex triangle stub (24 floats total = 2 verts * 12F). Vertex count <=
140
+ // 0xffff -> Uint16Array indices.
141
+ const vertices = new Float32Array(FLOATS_PER_VERTEX * 2);
142
+ for (let i = 0; i < vertices.length; i++) vertices[i] = i + 0.5;
143
+ const indices = new Uint16Array([0, 1, 0]);
144
+ const metaJson = JSON.stringify({
145
+ submeshes: [{ indexOffset: 0, indexCount: 3, vertexCount: 2, topology: 'triangle-list' }],
146
+ attributes: {},
147
+ aabb: [0, 0, 0, 1, 1, 1],
148
+ });
149
+ const binBytes = packMeshBinForTest(vertices, indices, metaJson);
150
+
151
+ const packIndexUrl = '/pack-index.json';
152
+ const packUrl = `/assets/${MESH_BIN_GUID.toLowerCase()}.pack.json`;
153
+ const binUrl = `/assets/${MESH_BIN_GUID.toLowerCase()}/body.bin`;
154
+ const routes = new Map<string, FetchRoute>([
155
+ [packIndexUrl, { json: makePackIndex([{ guid: MESH_BIN_GUID, packageUrl: packUrl }]) }],
156
+ [
157
+ packUrl,
158
+ {
159
+ json: {
160
+ schemaVersion: '2.0.0',
161
+ kind: 'internal-text-package',
162
+ assets: [
163
+ {
164
+ guid: MESH_BIN_GUID,
165
+ kind: 'mesh',
166
+ payload: {},
167
+ refs: [],
168
+ artifacts: {
169
+ body: {
170
+ path: `${MESH_BIN_GUID.toLowerCase()}/body.bin`,
171
+ mediaType: 'application/x-forgeax-mesh',
172
+ },
173
+ },
174
+ },
175
+ ],
176
+ },
177
+ },
178
+ ],
179
+ [binUrl, { bytes: binBytes }],
180
+ ]);
181
+ installFetchMock(routes);
182
+
183
+ const reg = new AssetRegistry(makeMockShaderRegistry());
184
+ reg.configurePackIndex(packIndexUrl);
185
+
186
+ const parsed = AssetGuid.parse(MESH_BIN_GUID);
187
+ expect(parsed.ok).toBe(true);
188
+ if (!parsed.ok) return;
189
+
190
+ const result = await reg.loadByGuid<MeshAsset>(parsed.value);
191
+ expect(result.ok).toBe(true);
192
+ if (!result.ok) return;
193
+
194
+ // D-17: loadByGuid returns the payload directly (registry holds no handles).
195
+ const mesh = result.value;
196
+ expect(mesh.kind).toBe('mesh');
197
+ expect(mesh.vertices.length).toBe(vertices.length);
198
+ for (let i = 0; i < vertices.length; i++) {
199
+ expect(mesh.vertices[i]).toBe(vertices[i]);
200
+ }
201
+ expect(mesh.indices).toBeInstanceOf(Uint16Array);
202
+ expect(mesh.indices?.length).toBe(indices.length);
203
+ if (mesh.indices !== undefined) {
204
+ for (let i = 0; i < indices.length; i++) {
205
+ expect(mesh.indices[i]).toBe(indices[i]);
206
+ }
207
+ }
208
+ });
209
+
210
+ it('(B) inline fallback (CON-7): legacy pack with Array.isArray vertices still loads', async () => {
211
+ // Single triangle, 12 floats per vertex, 3 vertices -> 36 floats, 3 indices.
212
+ const verticesArr: number[] = [];
213
+ for (let i = 0; i < FLOATS_PER_VERTEX * 3; i++) verticesArr.push(i + 0.25);
214
+ const indicesArr: number[] = [0, 1, 2];
215
+
216
+ const packIndexUrl = '/pack-index.json';
217
+ const packUrl = '/assets/inline.pack.json';
218
+ const routes = new Map<string, FetchRoute>([
219
+ [packIndexUrl, { json: makePackIndex([{ guid: MESH_INLINE_GUID, packageUrl: packUrl }]) }],
220
+ [
221
+ packUrl,
222
+ {
223
+ json: {
224
+ schemaVersion: '2.0.0',
225
+ kind: 'internal-text-package',
226
+ assets: [
227
+ {
228
+ guid: MESH_INLINE_GUID,
229
+ kind: 'mesh',
230
+ payload: {
231
+ vertices: verticesArr,
232
+ indices: indicesArr,
233
+ attributes: {},
234
+ },
235
+ refs: [],
236
+ artifacts: {},
237
+ },
238
+ ],
239
+ },
240
+ },
241
+ ],
242
+ ]);
243
+ installFetchMock(routes);
244
+
245
+ const reg = new AssetRegistry(makeMockShaderRegistry());
246
+ reg.configurePackIndex(packIndexUrl);
247
+
248
+ const parsed = AssetGuid.parse(MESH_INLINE_GUID);
249
+ expect(parsed.ok).toBe(true);
250
+ if (!parsed.ok) return;
251
+
252
+ const result = await reg.loadByGuid<MeshAsset>(parsed.value);
253
+ expect(result.ok).toBe(true);
254
+ if (!result.ok) return;
255
+
256
+ // D-17: loadByGuid returns the payload directly (registry holds no handles).
257
+ const mesh = result.value;
258
+ expect(mesh.kind).toBe('mesh');
259
+ expect(mesh.vertices.length).toBe(verticesArr.length);
260
+ expect(mesh.vertices[0]).toBe(0.25);
261
+ expect(mesh.indices?.length).toBe(indicesArr.length);
262
+ });
263
+
264
+ it('(C) empty mesh: v4 projection decodes to 0 verts / 0 indices', async () => {
265
+ const binBytes = packMeshBinForTest(
266
+ new Float32Array(0),
267
+ new Uint16Array(0),
268
+ JSON.stringify({
269
+ submeshes: [{ indexOffset: 0, indexCount: 0, vertexCount: 0, materialSlot: 0 }],
270
+ aabb: [0, 0, 0, 0, 0, 0],
271
+ }),
272
+ );
273
+
274
+ const packIndexUrl = '/pack-index.json';
275
+ const packUrl = `/assets/${MESH_EMPTY_GUID.toLowerCase()}.pack.json`;
276
+ const binUrl = `/assets/${MESH_EMPTY_GUID.toLowerCase()}/body.bin`;
277
+ const routes = new Map<string, FetchRoute>([
278
+ [packIndexUrl, { json: makePackIndex([{ guid: MESH_EMPTY_GUID, packageUrl: packUrl }]) }],
279
+ [
280
+ packUrl,
281
+ {
282
+ json: {
283
+ schemaVersion: '2.0.0',
284
+ kind: 'internal-text-package',
285
+ assets: [
286
+ {
287
+ guid: MESH_EMPTY_GUID,
288
+ kind: 'mesh',
289
+ payload: {},
290
+ refs: [],
291
+ artifacts: {
292
+ body: {
293
+ path: `${MESH_EMPTY_GUID.toLowerCase()}/body.bin`,
294
+ mediaType: 'application/x-forgeax-mesh',
295
+ },
296
+ },
297
+ },
298
+ ],
299
+ },
300
+ },
301
+ ],
302
+ [binUrl, { bytes: binBytes }],
303
+ ]);
304
+ installFetchMock(routes);
305
+
306
+ const reg = new AssetRegistry(makeMockShaderRegistry());
307
+ reg.configurePackIndex(packIndexUrl);
308
+
309
+ const parsed = AssetGuid.parse(MESH_EMPTY_GUID);
310
+ expect(parsed.ok).toBe(true);
311
+ if (!parsed.ok) return;
312
+
313
+ const result = await reg.loadByGuid<MeshAsset>(parsed.value);
314
+ expect(result.ok).toBe(false);
315
+ });
316
+ });