@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
@@ -1,416 +1,49 @@
1
- // feat-20260612-rhi-destroy-renderer-dispose-gpu-lifecycle / M5 / w17-w20
2
- //
3
- // Renderer.dispose() 6-step cascade unit tests.
4
- //
5
- // Scope: validate the dispose chain at the Renderer-facade level using the
6
- // canonical mock GPU + mock canvas + real createRenderer pattern (mirrors
7
- // lights.unit.test.ts setupWebGPU). The 6-step cascade (plan-strategy D-2)
8
- // walks `gpuStore.destroyAll() -> graph.drain() -> disposeInstanceBuffers ->
9
- // IBL cache clear -> context.unconfigure() -> listenerRegistry.clear()`,
10
- // each step independently try/catch'd with `errorRegistry.fire(e)` on
11
- // failure (D-3 method A: void signature + sub-error fire + disposed=true
12
- // regardless).
13
- //
14
- // Coverage matrix (requirements AC-06 / AC-07 + plan-strategy §5.3):
15
- // w17. Happy-path 6-step cascade -- each downstream structure observably
16
- // cleared after dispose() (gpuStore maps empty, instanceBuffers
17
- // cleared, graph drained, ibl cache cleared, context unconfigured).
18
- // w18. Sub-step failure -> dispose still walks all 6 steps; errorRegistry
19
- // fires on the failing sub-error; second dispose is idempotent.
20
- // w19. dispose() -> draw(world) -> Result.err with code 'rhi-not-available'
21
- // (D-1: reuse existing closed-union member, no new ErrorCode).
22
- // w20. Second dispose() is no-op (idempotency -- D-5: GpuResource boolean
23
- // isDestroyed gates re-destroy).
1
+ import { World } from '@forgeax/engine-ecs';
2
+ import { rhi } from '@forgeax/engine-rhi-null';
3
+ import { describe, expect, it } from 'vitest';
4
+ import { constructRendererHost } from '../../../render/src/construct-renderer';
5
+ import { requireRenderer } from './renderer-test-utils';
24
6
 
25
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
26
-
27
- // ── Test harness: mock GPU device + canvas (lifted from lights.unit.test.ts) ──
28
-
29
- interface MockGL2Context {
30
- __mockTag: 'webgl2';
31
- getExtension: () => null;
32
- getParameter: () => number;
33
- isContextLost: () => boolean;
34
- }
35
-
36
- function makeMockGL2(): MockGL2Context {
37
- return {
38
- __mockTag: 'webgl2',
39
- getExtension: () => null,
40
- getParameter: () => 1,
41
- isContextLost: () => false,
42
- };
43
- }
44
-
45
- interface CanvasOptions {
46
- webgl2: 'context' | 'null';
47
- webgpu?: 'context' | 'null';
48
- }
49
-
50
- interface CanvasHooks {
51
- unconfigureCount: number;
52
- /**
53
- * When true, the mocked context's `unconfigure()` throws synchronously.
54
- * Used by w18 to prove that a sub-step failure does not halt the rest of
55
- * the dispose cascade and that the error fan-outs through errorRegistry.
56
- */
57
- unconfigureShouldThrow: boolean;
58
- }
59
-
60
- function makeMockCanvas(opts: CanvasOptions, hooks: CanvasHooks): HTMLCanvasElement {
61
- const canvas = {
62
- width: 800,
63
- height: 600,
64
- getContext(kind: string): unknown {
65
- if (kind === 'webgl2') {
66
- return opts.webgl2 === 'context' ? makeMockGL2() : null;
67
- }
68
- if (kind === 'webgpu') {
69
- if (opts.webgpu === 'context') {
70
- return {
71
- __mockTag: 'webgpu-canvas-context',
72
- configure: () => undefined,
73
- unconfigure: () => {
74
- hooks.unconfigureCount++;
75
- if (hooks.unconfigureShouldThrow) {
76
- throw new Error('mock unconfigure failure');
77
- }
78
- },
79
- getCurrentTexture: () => ({ createView: () => ({}) }),
80
- };
81
- }
82
- return null;
83
- }
84
- return null;
85
- },
86
- addEventListener: () => undefined,
87
- removeEventListener: () => undefined,
88
- };
89
- return canvas as Partial<HTMLCanvasElement> as HTMLCanvasElement;
90
- }
91
-
92
- interface DeviceCallLog {
93
- encoderFinishCount: number;
94
- drawIndexedCount: number;
95
- setBindGroupCount: number;
96
- beginRenderPassCount: number;
97
- setPipelineCount: number;
98
- queueSubmitCount: number;
99
- writeBufferCount: number;
100
- destroyTextureCount: number;
101
- destroyBufferCount: number;
102
- }
103
-
104
- function makeLog(): DeviceCallLog {
105
- return {
106
- encoderFinishCount: 0,
107
- drawIndexedCount: 0,
108
- setBindGroupCount: 0,
109
- beginRenderPassCount: 0,
110
- setPipelineCount: 0,
111
- queueSubmitCount: 0,
112
- writeBufferCount: 0,
113
- destroyTextureCount: 0,
114
- destroyBufferCount: 0,
115
- };
116
- }
117
-
118
- function makeMockGPUDevice(log: DeviceCallLog): { device: unknown } {
119
- const lost = new Promise<unknown>(() => undefined);
120
- const device = {
121
- __mockTag: 'gpu-device',
122
- lost,
123
- features: new Set(),
124
- limits: {},
125
- queue: {
126
- submit: () => {
127
- log.queueSubmitCount++;
128
- },
129
- writeBuffer: () => {
130
- log.writeBufferCount++;
131
- },
132
- writeTexture: () => undefined,
133
- },
134
- createShaderModule: () => ({ getCompilationInfo: async () => ({ messages: [] }) }),
135
- createBindGroupLayout: () => ({}),
136
- createPipelineLayout: () => ({}),
137
- createRenderPipeline: () => ({}),
138
- createBindGroup: () => ({}),
139
- createBuffer: () => ({
140
- getMappedRange: () => new ArrayBuffer(64),
141
- unmap: () => undefined,
142
- destroy: () => {
143
- log.destroyBufferCount++;
144
- },
145
- }),
146
- createCommandEncoder: () => ({
147
- beginRenderPass: () => {
148
- log.beginRenderPassCount++;
149
- return {
150
- setPipeline: () => {
151
- log.setPipelineCount++;
152
- },
153
- setVertexBuffer: () => undefined,
154
- setIndexBuffer: () => undefined,
155
- setBindGroup: () => {
156
- log.setBindGroupCount++;
157
- },
158
- draw: () => undefined,
159
- drawIndexed: () => {
160
- log.drawIndexedCount++;
161
- },
162
- end: () => undefined,
163
- };
164
- },
165
- finish: () => {
166
- log.encoderFinishCount++;
167
- return {};
168
- },
169
- }),
170
- createTexture: () => ({
171
- createView: () => ({}),
172
- destroy: () => {
173
- log.destroyTextureCount++;
174
- },
175
- }),
176
- createSampler: () => ({}),
177
- destroy: () => undefined,
178
- };
179
- return { device };
180
- }
181
-
182
- function makeMockGPU(deviceObj: unknown): unknown {
183
- return {
184
- requestAdapter: async () => ({
185
- requestDevice: async () => deviceObj,
186
- }),
187
- getPreferredCanvasFormat: () => 'bgra8unorm',
188
- };
7
+ function canvas(): HTMLCanvasElement {
8
+ return { width: 64, height: 64, getContext: () => null } as unknown as HTMLCanvasElement;
189
9
  }
190
10
 
191
- const baseNavigator: Navigator = {
192
- userAgent: 'mock-engine-test',
193
- } as Partial<Navigator> as Navigator;
11
+ const manifest = `data:application/json,${encodeURIComponent(JSON.stringify({ schemaVersion: '1.0.0', entries: [] }))}`;
194
12
 
195
- function buildManifestDataUrl(): string {
196
- const manifest = {
197
- schemaVersion: '1.0.0',
198
- entries: [
199
- { hash: 'pbr00000', wgsl: '/* pbr stub - calls f_schlick( */', glsl: '', bindings: '' },
200
- { hash: 'unlit000', wgsl: '/* unlit stub */', glsl: '', bindings: '' },
201
- {
202
- hash: 'tonemap0',
203
- wgsl: '/* tonemap stub - struct TonemapParams { exposure: f32 }; */',
204
- glsl: '',
205
- bindings: '',
206
- },
207
- ],
208
- };
209
- return `data:application/json,${encodeURIComponent(JSON.stringify(manifest))}`;
210
- }
211
-
212
- interface RendererShape {
213
- backend: string;
214
- ready: Promise<void>;
215
- draw: (
216
- worlds: unknown,
217
- opts: { cameraOwner: number; resourceOwner: number },
218
- ) => { ok: boolean; error?: { code: string } };
219
- dispose: () => void;
220
- onError: (cb: (err: { code: string }) => void) => () => void;
221
- store: {
222
- readonly textureGpuHandles: ReadonlyMap<unknown, unknown>;
223
- readonly cubemapGpuHandles: ReadonlyMap<unknown, unknown>;
224
- readonly meshGpuHandles: ReadonlyMap<unknown, unknown>;
225
- };
226
- }
227
-
228
- interface TestSetup {
229
- createRenderer: (canvas: unknown, opts?: unknown, bundler?: unknown) => Promise<RendererShape>;
230
- log: DeviceCallLog;
231
- hooks: CanvasHooks;
232
- }
233
-
234
- const ENGINE = '../createRenderer';
235
-
236
- async function setupWebGPU(): Promise<TestSetup> {
237
- const log = makeLog();
238
- const hooks: CanvasHooks = { unconfigureCount: 0, unconfigureShouldThrow: false };
239
- const { device } = makeMockGPUDevice(log);
240
- vi.stubGlobal('navigator', { ...baseNavigator, gpu: makeMockGPU(device) });
241
- const engine = (await import(ENGINE)) as {
242
- createRenderer: TestSetup['createRenderer'];
243
- };
244
- return { createRenderer: engine.createRenderer, log, hooks };
245
- }
246
-
247
- async function makeRenderer(setup: TestSetup): Promise<RendererShape> {
248
- const canvas = makeMockCanvas({ webgl2: 'context', webgpu: 'context' }, setup.hooks);
249
- const renderer = await setup.createRenderer(
250
- canvas,
251
- {},
252
- { shaderManifestUrl: buildManifestDataUrl() },
253
- );
254
- await renderer.ready;
255
- return renderer;
256
- }
257
-
258
- beforeEach(() => {
259
- vi.stubGlobal('navigator', { ...baseNavigator });
260
- });
261
-
262
- afterEach(() => {
263
- vi.unstubAllGlobals();
264
- vi.restoreAllMocks();
265
- });
266
-
267
- // ── w17: happy-path 6-step cascade ──────────────────────────────────────────
268
-
269
- describe('Renderer.dispose() 6-step cascade (w17)', () => {
270
- it('clears gpuStore handle maps after dispose (step 1: gpuStore.destroyAll)', async () => {
271
- const setup = await setupWebGPU();
272
- const renderer = await makeRenderer(setup);
273
- expect(renderer.store.textureGpuHandles.size).toBe(0);
274
- expect(renderer.store.cubemapGpuHandles.size).toBe(0);
275
- expect(renderer.store.meshGpuHandles.size).toBe(0);
276
- renderer.dispose();
277
- expect(renderer.store.textureGpuHandles.size).toBe(0);
278
- expect(renderer.store.cubemapGpuHandles.size).toBe(0);
279
- expect(renderer.store.meshGpuHandles.size).toBe(0);
13
+ describe('createRenderer disposal contract', () => {
14
+ it('keeps assets on the host and not on Renderer', async () => {
15
+ const host = await constructRendererHost(canvas(), { rhi }, { shaderManifestUrl: manifest });
16
+ expect(host.ok).toBe(true);
17
+ if (!host.ok) return;
18
+ expect(host.value.assets.inspect()).toBeDefined();
19
+ expect(host.value.renderer).not.toHaveProperty('assets');
20
+ expect(host.value.renderer).not.toHaveProperty('store');
21
+ host.value.renderer.dispose();
280
22
  });
281
23
 
282
- it('walks dispose without throw on a fresh (un-drawn) renderer', async () => {
283
- const setup = await setupWebGPU();
284
- const renderer = await makeRenderer(setup);
285
- expect(() => renderer.dispose()).not.toThrow();
286
- });
287
-
288
- it('calls context.unconfigure() at least once during dispose (step 5)', async () => {
289
- const setup = await setupWebGPU();
290
- const renderer = await makeRenderer(setup);
291
- expect(setup.hooks.unconfigureCount).toBe(0);
292
- renderer.dispose();
293
- expect(setup.hooks.unconfigureCount).toBeGreaterThanOrEqual(1);
294
- });
295
-
296
- it('detaches onError listeners after dispose (step 6: errorRegistry.clear)', async () => {
297
- const setup = await setupWebGPU();
298
- const renderer = await makeRenderer(setup);
299
- let postDisposeFireCount = 0;
300
- renderer.onError(() => {
301
- postDisposeFireCount++;
302
- });
24
+ it('disposes an attached lease path idempotently', async () => {
25
+ const renderer = await requireRenderer(canvas(), { rhi }, { shaderManifestUrl: manifest });
26
+ const world = new World();
27
+ const attached = renderer.attach(world);
28
+ expect(attached.ok).toBe(true);
303
29
  renderer.dispose();
304
- // Post-dispose draw fires errorRegistry; cleared listeners should NOT
305
- // observe the fire (charter P3: post-dispose renderer is dead, no
306
- // observable side-effects on user-supplied listeners).
307
- renderer.draw({} as unknown, { cameraOwner: 0, resourceOwner: 0 });
308
- expect(postDisposeFireCount).toBe(0);
309
- });
310
- });
311
-
312
- // ── w18: sub-step failure aggregation ───────────────────────────────────────
313
-
314
- describe('Renderer.dispose() sub-step failure aggregation (w18)', () => {
315
- it('sub-error in one step (context.unconfigure) does not halt subsequent steps', async () => {
316
- const setup = await setupWebGPU();
317
- const renderer = await makeRenderer(setup);
318
- // Inject a throw into step 5 (context.unconfigure). Since the cascade
319
- // is independent try/catch per step (D-3), step 6 (listenerRegistry
320
- // .clear) must still execute and second-dispose must remain idempotent.
321
- setup.hooks.unconfigureShouldThrow = true;
322
-
323
- let firedErrors = 0;
324
- let lastFiredCode: string | undefined;
325
- renderer.onError((err) => {
326
- firedErrors++;
327
- lastFiredCode = err.code;
328
- });
329
-
330
- expect(() => renderer.dispose()).not.toThrow();
331
- // The throw inside unconfigure was caught + fan-out through
332
- // errorRegistry.fire. Listener observes the fire BEFORE step 6
333
- // (listenerRegistry.clear) drains the listener list.
334
- expect(firedErrors).toBeGreaterThanOrEqual(1);
335
- // Sub-error is wrapped as an RhiError with structured code.
336
- expect(lastFiredCode).toBeDefined();
337
- // Step 6 still executed: subsequent dispose is idempotent.
338
- expect(() => renderer.dispose()).not.toThrow();
339
- });
340
-
341
- it('errorRegistry.fire is invoked for the sub-error before listeners detach', async () => {
342
- const setup = await setupWebGPU();
343
- const renderer = await makeRenderer(setup);
344
- setup.hooks.unconfigureShouldThrow = true;
345
-
346
- const observedErrors: Array<{ code: string }> = [];
347
- renderer.onError((err) => {
348
- observedErrors.push({ code: err.code });
349
- });
350
-
351
30
  renderer.dispose();
352
- // At least one error was fan-out from the sub-step failure (D-3 +
353
- // charter P3 explicit failure: every internal failure surfaces through
354
- // the errorRegistry channel).
355
- expect(observedErrors.length).toBeGreaterThanOrEqual(1);
31
+ expect(renderer.inspect().state).toBe('disposed');
32
+ expect(renderer.attach(world).ok).toBe(false);
356
33
  });
357
34
 
358
- it('second dispose() after a failing first dispose is a no-op (idempotency)', async () => {
359
- const setup = await setupWebGPU();
360
- const renderer = await makeRenderer(setup);
361
- setup.hooks.unconfigureShouldThrow = true;
35
+ it('returns a Result error instead of reopening a frame after disposal', async () => {
36
+ const renderer = await requireRenderer(canvas(), { rhi }, { shaderManifestUrl: manifest });
37
+ const world = new World();
38
+ const attached = renderer.attach(world);
39
+ expect(attached.ok).toBe(true);
40
+ if (!attached.ok) return;
362
41
  renderer.dispose();
363
- // Second call must be a no-op even after the first one experienced an
364
- // internal sub-error. The disposed flag was flipped on first call.
365
- expect(() => renderer.dispose()).not.toThrow();
366
- });
367
- });
368
-
369
- // ── w19: dispose -> draw fail-fast ──────────────────────────────────────────
370
-
371
- describe('Renderer.draw() after dispose() fail-fast (w19, D-1)', () => {
372
- it("returns Result.err with code 'rhi-not-available'", async () => {
373
- const setup = await setupWebGPU();
374
- const renderer = await makeRenderer(setup);
375
- renderer.dispose();
376
- const result = renderer.draw({} as unknown, { cameraOwner: 0, resourceOwner: 0 });
377
- expect(result.ok).toBe(false);
378
- expect(result.error?.code).toBe('rhi-not-available');
379
- });
380
-
381
- it('draw() pre-dispose still routes through the normal happy path', async () => {
382
- const setup = await setupWebGPU();
383
- const renderer = await makeRenderer(setup);
384
- // Pre-dispose draw should NOT return rhi-not-available (the disposed
385
- // gate must trigger only post-dispose; without a real World the inner
386
- // record stage may surface a different runtime error, but never the
387
- // disposed gate).
388
- const result = renderer.draw({} as unknown, { cameraOwner: 0, resourceOwner: 0 });
389
- if (!result.ok) {
390
- expect(result.error?.code).not.toBe('rhi-not-available');
391
- }
392
- });
393
- });
394
-
395
- // ── w20: second dispose idempotent ──────────────────────────────────────────
396
-
397
- describe('Renderer.dispose() idempotency (w20, D-5)', () => {
398
- it('second dispose() is silent (no throw, no double-destroy)', async () => {
399
- const setup = await setupWebGPU();
400
- const renderer = await makeRenderer(setup);
401
- renderer.dispose();
402
- expect(() => renderer.dispose()).not.toThrow();
403
- // Third for paranoia.
404
- expect(() => renderer.dispose()).not.toThrow();
405
- });
406
-
407
- it('dispose -> dispose -> draw still returns rhi-not-available', async () => {
408
- const setup = await setupWebGPU();
409
- const renderer = await makeRenderer(setup);
410
- renderer.dispose();
411
- renderer.dispose();
412
- const result = renderer.draw({} as unknown, { cameraOwner: 0, resourceOwner: 0 });
42
+ const result = renderer.draw({
43
+ leases: [attached.value],
44
+ camera: { lease: attached.value },
45
+ environment: { lease: attached.value },
46
+ });
413
47
  expect(result.ok).toBe(false);
414
- expect(result.error?.code).toBe('rhi-not-available');
415
48
  });
416
49
  });
@@ -8,9 +8,8 @@
8
8
  // B. createRenderer throws EngineEnvironmentError (channel 3 wasm load/init
9
9
  // failed in headless CI — loud failure, not silent)
10
10
  //
11
- // The test's primary assertion: "no silent no-op renderer" — if createRenderer
12
- // resolves, the returned renderer must have backend === 'webgpu' and
13
- // rhiAvailable must not be false (the old channel 4 shape).
11
+ // The test's primary assertion: "no silent no-op renderer" — if the public
12
+ // factory resolves, the returned renderer must be in the ready state.
14
13
 
15
14
  import { createRenderer, EngineEnvironmentError } from '@forgeax/engine-runtime';
16
15
  import { describe, expect, it } from 'vitest';
@@ -23,37 +22,33 @@ describe('createRenderer without navigator.gpu (browser-no-webgpu)', () => {
23
22
  expect(adapter).toBeNull();
24
23
  });
25
24
 
26
- it('createRenderer either succeeds (channel 3) or throws EngineEnvironmentError — never returns a no-op renderer', async () => {
25
+ it('createRenderer either succeeds (channel 3) or returns EngineEnvironmentError — never returns a no-op renderer', async () => {
27
26
  const canvas = document.createElement('canvas');
28
27
  canvas.width = 64;
29
28
  canvas.height = 64;
30
29
 
31
- try {
32
- const renderer = await createRenderer(canvas);
33
- // Channel 3 succeeded (rhi-wgpu wasm with internal webgl backend).
34
- // Verify it is a real renderer, not the deleted channel 4 no-op stub.
35
- expect(renderer.backend).toBe('webgpu');
36
- // The old channel 4 stub would have set rhiAvailable=false on the
37
- // renderer — verify that property does not exist or is not false.
38
- const rendererAny = renderer as unknown as Record<string, unknown>;
39
- expect(rendererAny.rhiAvailable).not.toBe(false);
40
- renderer.dispose();
41
- } catch (error: unknown) {
42
- // Channel 3 failed — acceptable in headless CI without a real GPU
43
- // context. The critical assertion: the error MUST be an
44
- // EngineEnvironmentError (loud, structured failure), not a silent
45
- // swallow that returns a no-op renderer.
46
- expect(error).toBeInstanceOf(EngineEnvironmentError);
47
- if (error instanceof EngineEnvironmentError) {
48
- // Verify the structured detail is populated so AI consumers can
49
- // diagnose the failure (charter P4 explicit failure).
50
- expect(error.reason).toBeTruthy();
51
- // w22 / M4: detail must never be empty — at least one of webgpuError
52
- // or wgpuError must be present.
53
- const hasWebgpu = error.detail.webgpuError !== undefined;
54
- const hasWgpu = error.detail.wgpuError !== undefined;
55
- expect(hasWebgpu || hasWgpu).toBe(true);
56
- }
30
+ const result = await createRenderer(canvas);
31
+ if (result.ok) {
32
+ // Channel 3 succeeded (rhi-wgpu wasm with its host backend).
33
+ // Verify it is a real renderer, not the deleted no-op stub.
34
+ expect(result.value.inspect().state).toBe('alive');
35
+ result.value.dispose();
36
+ return;
37
+ }
38
+ // Channel 3 failed — acceptable in headless CI without a real GPU
39
+ // context. The critical assertion: the error MUST be an
40
+ // EngineEnvironmentError (loud, structured failure), not a silent
41
+ // swallow that returns a no-op renderer.
42
+ expect(result.error).toBeInstanceOf(EngineEnvironmentError);
43
+ if (result.error instanceof EngineEnvironmentError) {
44
+ // Verify the structured detail is populated so AI consumers can
45
+ // diagnose the failure (charter P4 explicit failure).
46
+ expect(result.error.reason).toBeTruthy();
47
+ // w22 / M4: detail must never be empty at least one of webgpuError
48
+ // or wgpuError must be present.
49
+ const hasWebgpu = result.error.detail.webgpuError !== undefined;
50
+ const hasWgpu = result.error.detail.wgpuError !== undefined;
51
+ expect(hasWebgpu || hasWgpu).toBe(true);
57
52
  }
58
53
  });
59
54
  });
@@ -9,13 +9,13 @@
9
9
  // Byte-equiv guarantee is at the PSO descriptor level (M2-T4-TEST, plan D-5),
10
10
  // not the cache-key string level.
11
11
 
12
- import { cacheKeyOf, type PipelineSpec } from '@forgeax/engine-render/internal';
13
12
  import type {
14
13
  MaterialRenderState,
15
14
  PrimitiveTopology,
16
15
  VertexAttributeMap,
17
16
  } from '@forgeax/engine-types';
18
17
  import { describe, expect, it } from 'vitest';
18
+ import { cacheKeyOf, type PipelineSpec } from '../../../render/src/pipeline-spec';
19
19
 
20
20
  const PROCEDURAL_ATTR_LAYOUT: VertexAttributeMap = {
21
21
  position: new Float32Array(0),