@forgeax/engine-runtime 0.1.23 → 0.1.24

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 (368) hide show
  1. package/README.md +15 -6
  2. package/dist/__tests__/advance-animation-player.cases.unit.test.d.ts +2 -0
  3. package/dist/__tests__/advance-animation-player.cases.unit.test.d.ts.map +1 -0
  4. package/dist/__tests__/asset-registry-aabb.cases.unit.test.d.ts +2 -0
  5. package/dist/__tests__/asset-registry-aabb.cases.unit.test.d.ts.map +1 -0
  6. package/dist/__tests__/asset-registry-bootstrap.cases.unit.test.d.ts +2 -0
  7. package/dist/__tests__/asset-registry-bootstrap.cases.unit.test.d.ts.map +1 -0
  8. package/dist/__tests__/asset-registry-builtin-nineslice.cases.unit.test.d.ts +2 -0
  9. package/dist/__tests__/asset-registry-builtin-nineslice.cases.unit.test.d.ts.map +1 -0
  10. package/dist/__tests__/asset-registry-d9-tile-sampler-soft-warn.cases.unit.test.d.ts +2 -0
  11. package/dist/__tests__/asset-registry-d9-tile-sampler-soft-warn.cases.unit.test.d.ts.map +1 -0
  12. package/dist/__tests__/asset-registry-guid.cases.unit.test.d.ts +2 -0
  13. package/dist/__tests__/asset-registry-guid.cases.unit.test.d.ts.map +1 -0
  14. package/dist/__tests__/asset-registry-material-validate.cases.unit.test.d.ts +2 -0
  15. package/dist/__tests__/asset-registry-material-validate.cases.unit.test.d.ts.map +1 -0
  16. package/dist/__tests__/asset-registry-mesh-fail-fast.cases.unit.test.d.ts +2 -0
  17. package/dist/__tests__/asset-registry-mesh-fail-fast.cases.unit.test.d.ts.map +1 -0
  18. package/dist/__tests__/asset-registry-scene.cases.unit.test.d.ts +2 -0
  19. package/dist/__tests__/asset-registry-scene.cases.unit.test.d.ts.map +1 -0
  20. package/dist/__tests__/asset-registry-sprite-slices-validate.cases.unit.test.d.ts +2 -0
  21. package/dist/__tests__/asset-registry-sprite-slices-validate.cases.unit.test.d.ts.map +1 -0
  22. package/dist/__tests__/asset-renderer-assembly.cases.unit.test.d.ts +2 -0
  23. package/dist/__tests__/asset-renderer-assembly.cases.unit.test.d.ts.map +1 -0
  24. package/dist/__tests__/asset.cases.unit.test.d.ts +2 -0
  25. package/dist/__tests__/asset.cases.unit.test.d.ts.map +1 -0
  26. package/dist/__tests__/bloom-gating.cases.unit.test.d.ts +2 -0
  27. package/dist/__tests__/bloom-gating.cases.unit.test.d.ts.map +1 -0
  28. package/dist/__tests__/builtin-guid-ssot.cases.unit.test.d.ts +2 -0
  29. package/dist/__tests__/builtin-guid-ssot.cases.unit.test.d.ts.map +1 -0
  30. package/dist/__tests__/builtin-pack.cases.unit.test.d.ts +2 -0
  31. package/dist/__tests__/builtin-pack.cases.unit.test.d.ts.map +1 -0
  32. package/dist/__tests__/camera-antialias.cases.unit.test.d.ts +2 -0
  33. package/dist/__tests__/camera-antialias.cases.unit.test.d.ts.map +1 -0
  34. package/dist/__tests__/camera-bloom.cases.unit.test.d.ts +2 -0
  35. package/dist/__tests__/camera-bloom.cases.unit.test.d.ts.map +1 -0
  36. package/dist/__tests__/camera-clear-schema.cases.unit.test.d.ts +2 -0
  37. package/dist/__tests__/camera-clear-schema.cases.unit.test.d.ts.map +1 -0
  38. package/dist/__tests__/camera-ortho.cases.unit.test.d.ts +2 -0
  39. package/dist/__tests__/camera-ortho.cases.unit.test.d.ts.map +1 -0
  40. package/dist/__tests__/cluster-binner.cases.unit.test.d.ts +2 -0
  41. package/dist/__tests__/cluster-binner.cases.unit.test.d.ts.map +1 -0
  42. package/dist/__tests__/create-renderer-fallback-shader-manifest.cases.unit.test.d.ts +2 -0
  43. package/dist/__tests__/create-renderer-fallback-shader-manifest.cases.unit.test.d.ts.map +1 -0
  44. package/dist/__tests__/create-renderer-uniform-fallback.cases.unit.test.d.ts +2 -0
  45. package/dist/__tests__/create-renderer-uniform-fallback.cases.unit.test.d.ts.map +1 -0
  46. package/dist/__tests__/cubemap-upload.cases.unit.test.d.ts +2 -0
  47. package/dist/__tests__/cubemap-upload.cases.unit.test.d.ts.map +1 -0
  48. package/dist/__tests__/dev-import-transport.cases.unit.test.d.ts +2 -0
  49. package/dist/__tests__/dev-import-transport.cases.unit.test.d.ts.map +1 -0
  50. package/dist/__tests__/engine-metrics.cases.unit.test.d.ts +2 -0
  51. package/dist/__tests__/engine-metrics.cases.unit.test.d.ts.map +1 -0
  52. package/dist/__tests__/equirect-projection-error.cases.unit.test.d.ts +2 -0
  53. package/dist/__tests__/equirect-projection-error.cases.unit.test.d.ts.map +1 -0
  54. package/dist/__tests__/font-asset-load.cases.unit.test.d.ts +2 -0
  55. package/dist/__tests__/font-asset-load.cases.unit.test.d.ts.map +1 -0
  56. package/dist/__tests__/fxaa-intermediate-texture.cases.unit.test.d.ts +2 -0
  57. package/dist/__tests__/fxaa-intermediate-texture.cases.unit.test.d.ts.map +1 -0
  58. package/dist/__tests__/fxaa-pipeline.cases.unit.test.d.ts +2 -0
  59. package/dist/__tests__/fxaa-pipeline.cases.unit.test.d.ts.map +1 -0
  60. package/dist/__tests__/gpu-residency.cases.unit.test.d.ts +2 -0
  61. package/dist/__tests__/gpu-residency.cases.unit.test.d.ts.map +1 -0
  62. package/dist/__tests__/gpu-resource-release.cases.unit.test.d.ts +2 -0
  63. package/dist/__tests__/gpu-resource-release.cases.unit.test.d.ts.map +1 -0
  64. package/dist/__tests__/handle-quad.cases.unit.test.d.ts +2 -0
  65. package/dist/__tests__/handle-quad.cases.unit.test.d.ts.map +1 -0
  66. package/dist/__tests__/hdrp-bgl-slots.cases.unit.test.d.ts +2 -0
  67. package/dist/__tests__/hdrp-bgl-slots.cases.unit.test.d.ts.map +1 -0
  68. package/dist/__tests__/hdrp-grid-invalid.cases.unit.test.d.ts +2 -0
  69. package/dist/__tests__/hdrp-grid-invalid.cases.unit.test.d.ts.map +1 -0
  70. package/dist/__tests__/hdrp-index-list-overflow-once.cases.unit.test.d.ts +2 -0
  71. package/dist/__tests__/hdrp-index-list-overflow-once.cases.unit.test.d.ts.map +1 -0
  72. package/dist/__tests__/hdrp-light-budget.cases.unit.test.d.ts +2 -0
  73. package/dist/__tests__/hdrp-light-budget.cases.unit.test.d.ts.map +1 -0
  74. package/dist/__tests__/hdrp-pipeline-asset-config.cases.unit.test.d.ts +2 -0
  75. package/dist/__tests__/hdrp-pipeline-asset-config.cases.unit.test.d.ts.map +1 -0
  76. package/dist/__tests__/helpers/renderer-device-loss-dawn.d.ts +25 -0
  77. package/dist/__tests__/helpers/renderer-device-loss-dawn.d.ts.map +1 -0
  78. package/dist/__tests__/helpers/standard-material-manifest.d.ts +0 -1
  79. package/dist/__tests__/helpers/standard-material-manifest.d.ts.map +1 -1
  80. package/dist/__tests__/ibl-pipeline-cache.cases.unit.test.d.ts +2 -0
  81. package/dist/__tests__/ibl-pipeline-cache.cases.unit.test.d.ts.map +1 -0
  82. package/dist/__tests__/lazy-catalog.cases.unit.test.d.ts +2 -0
  83. package/dist/__tests__/lazy-catalog.cases.unit.test.d.ts.map +1 -0
  84. package/dist/__tests__/load-by-guid-hdr.cases.unit.test.d.ts +2 -0
  85. package/dist/__tests__/load-by-guid-hdr.cases.unit.test.d.ts.map +1 -0
  86. package/dist/__tests__/load-by-guid-prod-material-parent.cases.unit.test.d.ts +2 -0
  87. package/dist/__tests__/load-by-guid-prod-material-parent.cases.unit.test.d.ts.map +1 -0
  88. package/dist/__tests__/load-by-guid-prod.cases.unit.test.d.ts +2 -0
  89. package/dist/__tests__/load-by-guid-prod.cases.unit.test.d.ts.map +1 -0
  90. package/dist/__tests__/loader-registry.cases.unit.test.d.ts +2 -0
  91. package/dist/__tests__/loader-registry.cases.unit.test.d.ts.map +1 -0
  92. package/dist/__tests__/m7-hdrp-demo-shape.cases.unit.test.d.ts +2 -0
  93. package/dist/__tests__/m7-hdrp-demo-shape.cases.unit.test.d.ts.map +1 -0
  94. package/dist/__tests__/mipmap-formula.cases.unit.test.d.ts +2 -0
  95. package/dist/__tests__/mipmap-formula.cases.unit.test.d.ts.map +1 -0
  96. package/dist/__tests__/mipmap-pipeline-cache.cases.unit.test.d.ts +2 -0
  97. package/dist/__tests__/mipmap-pipeline-cache.cases.unit.test.d.ts.map +1 -0
  98. package/dist/__tests__/parse-asset-payload-material.cases.unit.test.d.ts +2 -0
  99. package/dist/__tests__/parse-asset-payload-material.cases.unit.test.d.ts.map +1 -0
  100. package/dist/__tests__/parse-asset-payload-texture.cases.unit.test.d.ts +2 -0
  101. package/dist/__tests__/parse-asset-payload-texture.cases.unit.test.d.ts.map +1 -0
  102. package/dist/__tests__/parse-scene-payload-refs.cases.unit.test.d.ts +2 -0
  103. package/dist/__tests__/parse-scene-payload-refs.cases.unit.test.d.ts.map +1 -0
  104. package/dist/__tests__/pass-selector.cases.unit.test.d.ts +2 -0
  105. package/dist/__tests__/pass-selector.cases.unit.test.d.ts.map +1 -0
  106. package/dist/__tests__/pipeline-builder.cases.unit.test.d.ts +2 -0
  107. package/dist/__tests__/pipeline-builder.cases.unit.test.d.ts.map +1 -0
  108. package/dist/__tests__/pipeline-cache-key-topology.cases.unit.test.d.ts +2 -0
  109. package/dist/__tests__/pipeline-cache-key-topology.cases.unit.test.d.ts.map +1 -0
  110. package/dist/__tests__/pipeline-vertex-stride-branch.cases.unit.test.d.ts +2 -0
  111. package/dist/__tests__/pipeline-vertex-stride-branch.cases.unit.test.d.ts.map +1 -0
  112. package/dist/__tests__/pipeline.cases.unit.test.d.ts +2 -0
  113. package/dist/__tests__/pipeline.cases.unit.test.d.ts.map +1 -0
  114. package/dist/__tests__/post-process-register.cases.unit.test.d.ts +2 -0
  115. package/dist/__tests__/post-process-register.cases.unit.test.d.ts.map +1 -0
  116. package/dist/__tests__/propagate-transforms.cases.unit.test.d.ts +2 -0
  117. package/dist/__tests__/propagate-transforms.cases.unit.test.d.ts.map +1 -0
  118. package/dist/__tests__/record-all-topology.cases.unit.test.d.ts +2 -0
  119. package/dist/__tests__/record-all-topology.cases.unit.test.d.ts.map +1 -0
  120. package/dist/__tests__/record-draw-branch.cases.unit.test.d.ts +2 -0
  121. package/dist/__tests__/record-draw-branch.cases.unit.test.d.ts.map +1 -0
  122. package/dist/__tests__/record-strip-index-format.cases.unit.test.d.ts +2 -0
  123. package/dist/__tests__/record-strip-index-format.cases.unit.test.d.ts.map +1 -0
  124. package/dist/__tests__/register-with-guid-rgba16float.cases.unit.test.d.ts +2 -0
  125. package/dist/__tests__/register-with-guid-rgba16float.cases.unit.test.d.ts.map +1 -0
  126. package/dist/__tests__/render-data.cases.unit.test.d.ts +2 -0
  127. package/dist/__tests__/render-data.cases.unit.test.d.ts.map +1 -0
  128. package/dist/__tests__/render-error-exhaustive.test-d.d.ts.map +1 -1
  129. package/dist/__tests__/render-query-regression.cases.unit.test.d.ts +2 -0
  130. package/dist/__tests__/render-query-regression.cases.unit.test.d.ts.map +1 -0
  131. package/dist/__tests__/render-system-record-submesh.cases.unit.test.d.ts +2 -0
  132. package/dist/__tests__/render-system-record-submesh.cases.unit.test.d.ts.map +1 -0
  133. package/dist/__tests__/render-system-record-warn-once.cases.unit.test.d.ts +2 -0
  134. package/dist/__tests__/render-system-record-warn-once.cases.unit.test.d.ts.map +1 -0
  135. package/dist/__tests__/renderer-device-loss-multi-world.integration.test.d.ts +2 -0
  136. package/dist/__tests__/renderer-device-loss-multi-world.integration.test.d.ts.map +1 -0
  137. package/dist/__tests__/renderer-device-loss-provider-feasibility.dawn.test.d.ts +2 -0
  138. package/dist/__tests__/renderer-device-loss-provider-feasibility.dawn.test.d.ts.map +1 -0
  139. package/dist/__tests__/renderer-device-loss-recovery.dawn.test.d.ts +2 -0
  140. package/dist/__tests__/renderer-device-loss-recovery.dawn.test.d.ts.map +1 -0
  141. package/dist/__tests__/renderer-draw-world.cases.unit.test.d.ts +2 -0
  142. package/dist/__tests__/renderer-draw-world.cases.unit.test.d.ts.map +1 -0
  143. package/dist/__tests__/renderer-recovery-consumer.integration.test.d.ts +2 -0
  144. package/dist/__tests__/renderer-recovery-consumer.integration.test.d.ts.map +1 -0
  145. package/dist/__tests__/renderstate-pipeline-cache.cases.unit.test.d.ts +2 -0
  146. package/dist/__tests__/renderstate-pipeline-cache.cases.unit.test.d.ts.map +1 -0
  147. package/dist/__tests__/resolve-scene-guids.cases.unit.test.d.ts +2 -0
  148. package/dist/__tests__/resolve-scene-guids.cases.unit.test.d.ts.map +1 -0
  149. package/dist/__tests__/shadow-skip-non-triangle.cases.unit.test.d.ts +2 -0
  150. package/dist/__tests__/shadow-skip-non-triangle.cases.unit.test.d.ts.map +1 -0
  151. package/dist/__tests__/skin-errors-kebab-case.cases.unit.test.d.ts +2 -0
  152. package/dist/__tests__/skin-errors-kebab-case.cases.unit.test.d.ts.map +1 -0
  153. package/dist/__tests__/skin-instances-coexist.cases.unit.test.d.ts +2 -0
  154. package/dist/__tests__/skin-instances-coexist.cases.unit.test.d.ts.map +1 -0
  155. package/dist/__tests__/skin-m2-extract-happy.cases.unit.test.d.ts +2 -0
  156. package/dist/__tests__/skin-m2-extract-happy.cases.unit.test.d.ts.map +1 -0
  157. package/dist/__tests__/skin-m2-extract-joint-error.cases.unit.test.d.ts +2 -0
  158. package/dist/__tests__/skin-m2-extract-joint-error.cases.unit.test.d.ts.map +1 -0
  159. package/dist/__tests__/skin-m2-extract-null-assets.cases.unit.test.d.ts +2 -0
  160. package/dist/__tests__/skin-m2-extract-null-assets.cases.unit.test.d.ts.map +1 -0
  161. package/dist/__tests__/skin-m2-extract-skeleton-error.cases.unit.test.d.ts +2 -0
  162. package/dist/__tests__/skin-m2-extract-skeleton-error.cases.unit.test.d.ts.map +1 -0
  163. package/dist/__tests__/skin-m3-record-cache.cases.unit.test.d.ts +2 -0
  164. package/dist/__tests__/skin-m3-record-cache.cases.unit.test.d.ts.map +1 -0
  165. package/dist/__tests__/skin-palette-extract.cases.unit.test.d.ts +2 -0
  166. package/dist/__tests__/skin-palette-extract.cases.unit.test.d.ts.map +1 -0
  167. package/dist/__tests__/skin-pipeline-routing.cases.unit.test.d.ts +2 -0
  168. package/dist/__tests__/skin-pipeline-routing.cases.unit.test.d.ts.map +1 -0
  169. package/dist/__tests__/skin.cases.unit.test.d.ts +2 -0
  170. package/dist/__tests__/skin.cases.unit.test.d.ts.map +1 -0
  171. package/dist/__tests__/skybox-extract.cases.unit.test.d.ts +2 -0
  172. package/dist/__tests__/skybox-extract.cases.unit.test.d.ts.map +1 -0
  173. package/dist/__tests__/skybox-shader-compile.cases.unit.test.d.ts +2 -0
  174. package/dist/__tests__/skybox-shader-compile.cases.unit.test.d.ts.map +1 -0
  175. package/dist/__tests__/skylight-bind-group.cases.unit.test.d.ts +2 -0
  176. package/dist/__tests__/skylight-bind-group.cases.unit.test.d.ts.map +1 -0
  177. package/dist/__tests__/skylight-component.cases.unit.test.d.ts +2 -0
  178. package/dist/__tests__/skylight-component.cases.unit.test.d.ts.map +1 -0
  179. package/dist/__tests__/skylight-fallback-path.cases.unit.test.d.ts +2 -0
  180. package/dist/__tests__/skylight-fallback-path.cases.unit.test.d.ts.map +1 -0
  181. package/dist/__tests__/skylight-pipeline-layout.cases.unit.test.d.ts +2 -0
  182. package/dist/__tests__/skylight-pipeline-layout.cases.unit.test.d.ts.map +1 -0
  183. package/dist/__tests__/skylight-solid-color-extract.cases.unit.test.d.ts +2 -0
  184. package/dist/__tests__/skylight-solid-color-extract.cases.unit.test.d.ts.map +1 -0
  185. package/dist/__tests__/sprite-animation-tick-boundary.cases.unit.test.d.ts +2 -0
  186. package/dist/__tests__/sprite-animation-tick-boundary.cases.unit.test.d.ts.map +1 -0
  187. package/dist/__tests__/sprite-animation-tick-clamp.cases.unit.test.d.ts +2 -0
  188. package/dist/__tests__/sprite-animation-tick-clamp.cases.unit.test.d.ts.map +1 -0
  189. package/dist/__tests__/sprite-animation-tick-frame-duration-negative.cases.unit.test.d.ts +2 -0
  190. package/dist/__tests__/sprite-animation-tick-frame-duration-negative.cases.unit.test.d.ts.map +1 -0
  191. package/dist/__tests__/sprite-animation-tick-frame-duration-zero.cases.unit.test.d.ts +2 -0
  192. package/dist/__tests__/sprite-animation-tick-frame-duration-zero.cases.unit.test.d.ts.map +1 -0
  193. package/dist/__tests__/sprite-animation-tick-loop.cases.unit.test.d.ts +2 -0
  194. package/dist/__tests__/sprite-animation-tick-loop.cases.unit.test.d.ts.map +1 -0
  195. package/dist/__tests__/sprite-animation-tick-override-probe.cases.unit.test.d.ts +2 -0
  196. package/dist/__tests__/sprite-animation-tick-override-probe.cases.unit.test.d.ts.map +1 -0
  197. package/dist/__tests__/sprite-animation-tick-regions-mismatch.cases.unit.test.d.ts +2 -0
  198. package/dist/__tests__/sprite-animation-tick-regions-mismatch.cases.unit.test.d.ts.map +1 -0
  199. package/dist/__tests__/storage-buffer-caps.cases.unit.test.d.ts +2 -0
  200. package/dist/__tests__/storage-buffer-caps.cases.unit.test.d.ts.map +1 -0
  201. package/dist/__tests__/systems.cases.unit.test.d.ts +2 -0
  202. package/dist/__tests__/systems.cases.unit.test.d.ts.map +1 -0
  203. package/dist/__tests__/tonemap-hdr-target.cases.unit.test.d.ts +2 -0
  204. package/dist/__tests__/tonemap-hdr-target.cases.unit.test.d.ts.map +1 -0
  205. package/dist/__tests__/tonemap-pipeline-split.cases.unit.test.d.ts +2 -0
  206. package/dist/__tests__/tonemap-pipeline-split.cases.unit.test.d.ts.map +1 -0
  207. package/dist/__tests__/tonemap.cases.unit.test.d.ts +2 -0
  208. package/dist/__tests__/tonemap.cases.unit.test.d.ts.map +1 -0
  209. package/dist/__tests__/transparent-sort-config-get.cases.unit.test.d.ts +2 -0
  210. package/dist/__tests__/transparent-sort-config-get.cases.unit.test.d.ts.map +1 -0
  211. package/dist/__tests__/transparent-sort-config-set.cases.unit.test.d.ts +2 -0
  212. package/dist/__tests__/transparent-sort-config-set.cases.unit.test.d.ts.map +1 -0
  213. package/dist/__tests__/transparent-sort.cases.unit.test.d.ts +2 -0
  214. package/dist/__tests__/transparent-sort.cases.unit.test.d.ts.map +1 -0
  215. package/dist/__tests__/upload-texture-consistency.cases.unit.test.d.ts +2 -0
  216. package/dist/__tests__/upload-texture-consistency.cases.unit.test.d.ts.map +1 -0
  217. package/dist/__tests__/verify-revisions.cases.unit.test.d.ts +2 -0
  218. package/dist/__tests__/verify-revisions.cases.unit.test.d.ts.map +1 -0
  219. package/dist/__tests__/wire-default-loaders.cases.unit.test.d.ts +2 -0
  220. package/dist/__tests__/wire-default-loaders.cases.unit.test.d.ts.map +1 -0
  221. package/dist/__tests__/zero-camera-clear-fallback.cases.unit.test.d.ts +2 -0
  222. package/dist/__tests__/zero-camera-clear-fallback.cases.unit.test.d.ts.map +1 -0
  223. package/dist/dev-import-transport.d.ts.map +1 -1
  224. package/dist/index.mjs +1 -1
  225. package/dist/index.mjs.map +1 -1
  226. package/package.json +30 -30
  227. package/src/__tests__/advance-animation-player.cases.unit.test.ts +1666 -0
  228. package/src/__tests__/asset-registry-aabb.cases.unit.test.ts +676 -0
  229. package/src/__tests__/asset-registry-bootstrap.cases.unit.test.ts +472 -0
  230. package/src/__tests__/asset-registry-builtin-nineslice.cases.unit.test.ts +481 -0
  231. package/src/__tests__/asset-registry-d9-tile-sampler-soft-warn.cases.unit.test.ts +568 -0
  232. package/src/__tests__/asset-registry-guid.cases.unit.test.ts +500 -0
  233. package/src/__tests__/asset-registry-material-validate.cases.unit.test.ts +756 -0
  234. package/src/__tests__/asset-registry-mesh-fail-fast.cases.unit.test.ts +591 -0
  235. package/src/__tests__/asset-registry-scene.cases.unit.test.ts +501 -0
  236. package/src/__tests__/asset-registry-sprite-slices-validate.cases.unit.test.ts +536 -0
  237. package/src/__tests__/asset-renderer-assembly.cases.unit.test.ts +496 -0
  238. package/src/__tests__/asset.cases.unit.test.ts +439 -0
  239. package/src/__tests__/bind-group-cache-keying.test.ts +6 -2
  240. package/src/__tests__/bloom-gating.cases.unit.test.ts +428 -0
  241. package/src/__tests__/builtin-guid-ssot.cases.unit.test.ts +472 -0
  242. package/src/__tests__/builtin-pack.cases.unit.test.ts +639 -0
  243. package/src/__tests__/builtin-shader-register-e2e.test.ts +1 -1
  244. package/src/__tests__/camera-antialias.cases.unit.test.ts +372 -0
  245. package/src/__tests__/camera-bloom.cases.unit.test.ts +396 -0
  246. package/src/__tests__/camera-clear-schema.cases.unit.test.ts +391 -0
  247. package/src/__tests__/camera-ortho.cases.unit.test.ts +484 -0
  248. package/src/__tests__/cluster-binner.cases.unit.test.ts +817 -0
  249. package/src/__tests__/collect-scene-mount-collapse.test.ts +5 -1
  250. package/src/__tests__/create-renderer-fallback-shader-manifest.cases.unit.test.ts +345 -0
  251. package/src/__tests__/create-renderer-uniform-fallback.cases.unit.test.ts +445 -0
  252. package/src/__tests__/cubemap-upload.cases.unit.test.ts +593 -0
  253. package/src/__tests__/dawn/ibl-precompute-readback.dawn.test.ts +184 -17
  254. package/src/__tests__/dawn/material-alpha.dawn.test.ts +17 -4
  255. package/src/__tests__/derive-bgl-integration.test.ts +8 -8
  256. package/src/__tests__/dev-import-transport.cases.unit.test.ts +503 -0
  257. package/src/__tests__/engine-metrics.cases.unit.test.ts +371 -0
  258. package/src/__tests__/equirect-projection-error.cases.unit.test.ts +416 -0
  259. package/src/__tests__/font-asset-load.cases.unit.test.ts +510 -0
  260. package/src/__tests__/fxaa-intermediate-texture.cases.unit.test.ts +690 -0
  261. package/src/__tests__/fxaa-pipeline.cases.unit.test.ts +546 -0
  262. package/src/__tests__/gpu-residency.cases.unit.test.ts +479 -0
  263. package/src/__tests__/gpu-resource-release.cases.unit.test.ts +929 -0
  264. package/src/__tests__/handle-quad.cases.unit.test.ts +491 -0
  265. package/src/__tests__/hdrp-bgl-slots.cases.unit.test.ts +451 -0
  266. package/src/__tests__/hdrp-grid-invalid.cases.unit.test.ts +408 -0
  267. package/src/__tests__/hdrp-index-list-overflow-once.cases.unit.test.ts +405 -0
  268. package/src/__tests__/hdrp-light-budget.cases.unit.test.ts +483 -0
  269. package/src/__tests__/hdrp-pipeline-asset-config.cases.unit.test.ts +441 -0
  270. package/src/__tests__/helpers/renderer-device-loss-dawn.ts +69 -0
  271. package/src/__tests__/helpers/standard-material-manifest.ts +11 -15
  272. package/src/__tests__/ibl-pipeline-cache.cases.unit.test.ts +415 -0
  273. package/src/__tests__/lazy-catalog.cases.unit.test.ts +848 -0
  274. package/src/__tests__/light-gpu-byte-neutral.unit.test.ts +6 -5
  275. package/src/__tests__/load-by-guid-hdr.cases.unit.test.ts +582 -0
  276. package/src/__tests__/load-by-guid-prod-material-parent.cases.unit.test.ts +1514 -0
  277. package/src/__tests__/load-by-guid-prod.cases.unit.test.ts +557 -0
  278. package/src/__tests__/loader-registry.cases.unit.test.ts +767 -0
  279. package/src/__tests__/m7-hdrp-demo-shape.cases.unit.test.ts +361 -0
  280. package/src/__tests__/material-texture-uv-scale.unit.test.ts +2 -2
  281. package/src/__tests__/materials.unit.test.ts +29 -10
  282. package/src/__tests__/mipmap-formula.cases.unit.test.ts +434 -0
  283. package/src/__tests__/mipmap-pipeline-cache.cases.unit.test.ts +490 -0
  284. package/src/__tests__/parse-asset-payload-material.cases.unit.test.ts +565 -0
  285. package/src/__tests__/parse-asset-payload-texture.cases.unit.test.ts +720 -0
  286. package/src/__tests__/parse-scene-payload-refs.cases.unit.test.ts +767 -0
  287. package/src/__tests__/pass-selector.cases.unit.test.ts +376 -0
  288. package/src/__tests__/pbr-pipeline.unit.test.ts +23 -5
  289. package/src/__tests__/pipeline-builder.cases.unit.test.ts +624 -0
  290. package/src/__tests__/pipeline-cache-key-topology.cases.unit.test.ts +807 -0
  291. package/src/__tests__/pipeline-vertex-stride-branch.cases.unit.test.ts +379 -0
  292. package/src/__tests__/pipeline.cases.unit.test.ts +370 -0
  293. package/src/__tests__/post-process-register.cases.unit.test.ts +405 -0
  294. package/src/__tests__/propagate-transforms.cases.unit.test.ts +502 -0
  295. package/src/__tests__/propagate-transforms.dawn.test.ts +19 -2
  296. package/src/__tests__/record-all-topology.cases.unit.test.ts +608 -0
  297. package/src/__tests__/record-draw-branch.cases.unit.test.ts +621 -0
  298. package/src/__tests__/record-strip-index-format.cases.unit.test.ts +419 -0
  299. package/src/__tests__/register-with-guid-rgba16float.cases.unit.test.ts +469 -0
  300. package/src/__tests__/render-data.cases.unit.test.ts +553 -0
  301. package/src/__tests__/render-error-exhaustive.test-d.ts +1 -0
  302. package/src/__tests__/render-query-regression.cases.unit.test.ts +531 -0
  303. package/src/__tests__/render-system-record-submesh.cases.unit.test.ts +740 -0
  304. package/src/__tests__/render-system-record-warn-once.cases.unit.test.ts +418 -0
  305. package/src/__tests__/render-system-record.test.ts +15 -33
  306. package/src/__tests__/renderer-device-loss-multi-world.integration.test.ts +103 -0
  307. package/src/__tests__/renderer-device-loss-provider-feasibility.dawn.test.ts +124 -0
  308. package/src/__tests__/renderer-device-loss-recovery.dawn.test.ts +50 -0
  309. package/src/__tests__/renderer-draw-world.cases.unit.test.ts +514 -0
  310. package/src/__tests__/renderer-recovery-consumer.integration.test.ts +96 -0
  311. package/src/__tests__/renderstate-pipeline-cache.cases.unit.test.ts +631 -0
  312. package/src/__tests__/resolve-scene-guids.cases.unit.test.ts +1123 -0
  313. package/src/__tests__/shadow-caster-empty-schema.test.ts +1 -1
  314. package/src/__tests__/shadow-fields-observable.dawn.test.ts +2 -2
  315. package/src/__tests__/shadow-m1.dawn.test.ts +1 -1
  316. package/src/__tests__/shadow-skip-non-triangle.cases.unit.test.ts +681 -0
  317. package/src/__tests__/skin-errors-kebab-case.cases.unit.test.ts +475 -0
  318. package/src/__tests__/skin-extract-getarrayview-count.unit.test.ts +5 -4
  319. package/src/__tests__/skin-instances-coexist.cases.unit.test.ts +375 -0
  320. package/src/__tests__/skin-m2-extract-happy.cases.unit.test.ts +592 -0
  321. package/src/__tests__/skin-m2-extract-joint-error.cases.unit.test.ts +619 -0
  322. package/src/__tests__/skin-m2-extract-null-assets.cases.unit.test.ts +569 -0
  323. package/src/__tests__/skin-m2-extract-skeleton-error.cases.unit.test.ts +585 -0
  324. package/src/__tests__/skin-m3-record-cache.cases.unit.test.ts +457 -0
  325. package/src/__tests__/skin-palette-extract.cases.unit.test.ts +635 -0
  326. package/src/__tests__/skin-pipeline-routing.cases.unit.test.ts +411 -0
  327. package/src/__tests__/skin.cases.unit.test.ts +421 -0
  328. package/src/__tests__/skybox-extract.cases.unit.test.ts +511 -0
  329. package/src/__tests__/skybox-shader-compile.cases.unit.test.ts +437 -0
  330. package/src/__tests__/skylight-bind-group.cases.unit.test.ts +642 -0
  331. package/src/__tests__/skylight-component.cases.unit.test.ts +386 -0
  332. package/src/__tests__/skylight-fallback-path.cases.unit.test.ts +566 -0
  333. package/src/__tests__/skylight-lazy-projection.test.ts +35 -20
  334. package/src/__tests__/skylight-pipeline-layout.cases.unit.test.ts +506 -0
  335. package/src/__tests__/skylight-solid-color-extract.cases.unit.test.ts +399 -0
  336. package/src/__tests__/sprite-animation-tick-boundary.cases.unit.test.ts +521 -0
  337. package/src/__tests__/sprite-animation-tick-clamp.cases.unit.test.ts +453 -0
  338. package/src/__tests__/sprite-animation-tick-frame-duration-negative.cases.unit.test.ts +447 -0
  339. package/src/__tests__/sprite-animation-tick-frame-duration-zero.cases.unit.test.ts +395 -0
  340. package/src/__tests__/sprite-animation-tick-loop.cases.unit.test.ts +494 -0
  341. package/src/__tests__/sprite-animation-tick-override-probe.cases.unit.test.ts +439 -0
  342. package/src/__tests__/sprite-animation-tick-regions-mismatch.cases.unit.test.ts +466 -0
  343. package/src/__tests__/sprite-lit-bgl-byte-identical.test.ts +5 -5
  344. package/src/__tests__/sprite-lit-pipeline-cache-key.test.ts +1 -1
  345. package/src/__tests__/ssao-pipelines.test.ts +1 -1
  346. package/src/__tests__/storage-buffer-caps.cases.unit.test.ts +373 -0
  347. package/src/__tests__/systems.cases.unit.test.ts +425 -0
  348. package/src/__tests__/tilemap-chunk-extract.overhang-bounds.test.ts +1 -1
  349. package/src/__tests__/tonemap-hdr-target.cases.unit.test.ts +670 -0
  350. package/src/__tests__/tonemap-pipeline-split.cases.unit.test.ts +867 -0
  351. package/src/__tests__/tonemap.cases.unit.test.ts +446 -0
  352. package/src/__tests__/transparent-sort-config-get.cases.unit.test.ts +395 -0
  353. package/src/__tests__/transparent-sort-config-set.cases.unit.test.ts +424 -0
  354. package/src/__tests__/transparent-sort.cases.unit.test.ts +684 -0
  355. package/src/__tests__/upload-texture-consistency.cases.unit.test.ts +478 -0
  356. package/src/__tests__/verify-revisions.cases.unit.test.ts +619 -0
  357. package/src/__tests__/wire-default-loaders.cases.unit.test.ts +461 -0
  358. package/src/__tests__/zero-camera-clear-fallback.cases.unit.test.ts +374 -0
  359. package/src/dev-import-transport.ts +2 -1
  360. package/dist/__tests__/asset.unit.test.d.ts +0 -2
  361. package/dist/__tests__/asset.unit.test.d.ts.map +0 -1
  362. package/dist/__tests__/pipeline.unit.test.d.ts +0 -2
  363. package/dist/__tests__/pipeline.unit.test.d.ts.map +0 -1
  364. package/dist/__tests__/systems.unit.test.d.ts +0 -2
  365. package/dist/__tests__/systems.unit.test.d.ts.map +0 -1
  366. package/src/__tests__/asset.unit.test.ts +0 -7113
  367. package/src/__tests__/pipeline.unit.test.ts +0 -5279
  368. package/src/__tests__/systems.unit.test.ts +0 -9061
@@ -0,0 +1,624 @@
1
+ // @ts-nocheck — merged file: cross-source node:fs/node:path imports outside @types/node coverage in runtime tsconfig
2
+ // Consolidated by feat-20260609-test-pool-startup-reduction-merge-tiny-test-files
3
+ // biome-ignore-all lint/complexity/noUselessLoneBlockStatements: block-scope isolation between merged source files (consolidation paradigm)
4
+ //
5
+ // Source files (N=33):
6
+ // - packages/runtime/__tests__/create-renderer-fallback.test.ts
7
+ // - packages/runtime/src/__tests__/cluster-binner.test.ts
8
+ // - packages/runtime/src/__tests__/create-renderer-fallback-shader-manifest.test.ts
9
+ // - packages/runtime/src/__tests__/create-renderer-uniform-fallback.test.ts
10
+ // - packages/runtime/src/__tests__/createRenderer.test.ts
11
+ // - packages/runtime/src/__tests__/dispatch-sort.test.ts
12
+ // - packages/runtime/src/__tests__/engine-metrics.test.ts
13
+ // - packages/runtime/src/__tests__/device/gpu-residency-caps-guard.test.ts
14
+ // - packages/runtime/src/__tests__/pass-selector.test.ts
15
+ // - packages/runtime/src/__tests__/pipeline-builder.test.ts
16
+ // - packages/runtime/src/__tests__/pipeline-cache-key-topology.test.ts
17
+ // - packages/runtime/src/__tests__/pipeline-rename-grep-gate.test.ts
18
+ // - packages/runtime/src/__tests__/pipeline-vertex-stride-branch.test.ts
19
+ // - packages/runtime/src/__tests__/post-process-register.test.ts
20
+ // - packages/runtime/src/__tests__/record-all-topology.test.ts
21
+ // - packages/runtime/src/__tests__/record-draw-branch.test.ts
22
+ // - packages/runtime/src/__tests__/record-strip-index-format.test.ts
23
+ // - packages/runtime/src/__tests__/render-query-regression.test.ts
24
+ // - packages/runtime/src/__tests__/renderer-draw-world.test.ts
25
+ // - packages/runtime/src/__tests__/renderer-input-snapshot.test.ts
26
+ // - packages/runtime/src/__tests__/renderer-read-pixels.test.ts
27
+ // - packages/runtime/src/__tests__/renderer-ready.test.ts
28
+ // - packages/runtime/src/__tests__/renderstate-pipeline-cache.test.ts
29
+ // - packages/runtime/src/__tests__/storage-buffer-caps.test.ts
30
+ // - packages/runtime/src/__tests__/device/gpu-residency.test.ts
31
+ // - packages/runtime/src/__tests__/render-data.test.ts
32
+ // - packages/runtime/src/__tests__/hdrp-bgl-slots.test.ts
33
+ // - packages/runtime/src/__tests__/hdrp-caps-gate.test.ts
34
+ // - packages/runtime/src/__tests__/hdrp-grid-invalid.test.ts
35
+ // - packages/runtime/src/__tests__/hdrp-index-list-overflow-once.test.ts
36
+ // - packages/runtime/src/__tests__/hdrp-light-budget.test.ts
37
+ // - packages/runtime/src/__tests__/hdrp-pipeline-asset-config.test.ts
38
+ // - packages/runtime/src/__tests__/m7-hdrp-demo-shape.test.ts
39
+ //
40
+ // Paradigm: each block-scope wraps a source file. ancestorTitles[0] is the
41
+ // source-preserved inner describe (NOT the source filename for these 3 files
42
+ // — recovery path: vitest report ancestorTitles -> grep this file -> upstream
43
+ // `// ─── from <name>.test.ts ───` block separator -> source filename).
44
+ // Top-level imports merged + deduped.
45
+
46
+ import { existsSync, readFileSync } from 'node:fs';
47
+ import { dirname, resolve } from 'node:path';
48
+ import { fileURLToPath } from 'node:url';
49
+ import { HANDLE_CUBE, HANDLE_TRIANGLE, resolveAssetHandle } from '@forgeax/engine-assets-runtime';
50
+ import type { World as WorldType } from '@forgeax/engine-ecs';
51
+ import { defineComponent, World } from '@forgeax/engine-ecs';
52
+ import {
53
+ buildMeshAttributeMapForUvSets,
54
+ createBoxGeometry,
55
+ createConeGeometry,
56
+ createCylinderGeometry,
57
+ createPlaneGeometry,
58
+ createSphereGeometry,
59
+ createTorusGeometry,
60
+ PROCEDURAL_FLOATS_PER_VERTEX,
61
+ } from '@forgeax/engine-geometry';
62
+ import { type Mat4, mat4, type Vec3, vec3 } from '@forgeax/engine-math';
63
+ import type { Renderer as RendererType } from '@forgeax/engine-render';
64
+ import { Camera, MeshFilter, MeshRenderer } from '@forgeax/engine-render';
65
+ import {
66
+ err,
67
+ ok,
68
+ type PipelineLayout,
69
+ type RenderPipeline,
70
+ type Result,
71
+ type RhiCaps,
72
+ type RhiDevice,
73
+ RhiError,
74
+ ok as rhiOk,
75
+ type ShaderModule,
76
+ } from '@forgeax/engine-rhi';
77
+ import {
78
+ acquireCanvasContext as acquireNullCanvasContext,
79
+ createShaderModule as createNullShaderModule,
80
+ RhiNullAdapter,
81
+ } from '@forgeax/engine-rhi-null';
82
+ import { ChildOf, Transform } from '@forgeax/engine-scene';
83
+ import {
84
+ findVariantByKey,
85
+ type MaterialShaderEntry,
86
+ type MaterialShaderManifestEntry,
87
+ type MaterialShaderManifestVariant,
88
+ } from '@forgeax/engine-shader';
89
+ import {
90
+ type AssetError,
91
+ type EquirectAsset,
92
+ type Handle,
93
+ type MaterialRenderState,
94
+ type MeshAsset,
95
+ type PassSelector,
96
+ type PrimitiveTopology,
97
+ type RenderPipelineAsset,
98
+ type TextureAsset,
99
+ toShared,
100
+ } from '@forgeax/engine-types';
101
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
102
+ import {
103
+ bin,
104
+ type ClusterBinError,
105
+ calculateSphereClusterBounds,
106
+ clusterSpaceObjectAabb,
107
+ deriveCullingRadius,
108
+ ndcPositionToCluster,
109
+ viewZToZSlice,
110
+ } from '../../../render/src/cluster-binner';
111
+ import { GpuResidencyCache } from '../../../render/src/device/gpu-residency';
112
+ import { createEngineMetrics } from '../../../render/src/engine-metrics';
113
+ import { assertStorageBufferCap } from '../../../render/src/light-buffer-layout';
114
+ import {
115
+ buildPbrPipelineLayouts,
116
+ buildPbrViewBglEntries,
117
+ type PbrCaps,
118
+ } from '../../../render/src/pbr-pipeline';
119
+ import {
120
+ HdrpInstallError,
121
+ validateClusterGrid,
122
+ } from '../../../render/src/pipeline/standard-pipeline';
123
+ import {
124
+ buildPipelineForMaterialShader,
125
+ type PipelineBuilderContext,
126
+ type PipelineBuilderShaderModuleFactory,
127
+ } from '../../../render/src/pipeline-builder';
128
+ import {
129
+ cacheKeyOf,
130
+ createHdrpBindGroupLayoutDescriptor,
131
+ type PipelineSpec,
132
+ } from '../../../render/src/pipeline-spec';
133
+ import {
134
+ deriveRenderDataCubemap,
135
+ deriveRenderDataMesh,
136
+ deriveRenderDataTexture,
137
+ } from '../../../render/src/render-data';
138
+ import { extractFrame, prepareExtractContext } from '../../../render/src/render-system-extract';
139
+ import { matchPass } from '../../../render/src/systems/pass-selector';
140
+ import { makeMockShaderRegistry } from './helpers/mock-shader-registry';
141
+ import { standardMaterialShaderVariants } from './helpers/standard-material-manifest';
142
+
143
+ function makeExplicitNullRhi(spies: {
144
+ setIndexBuffer: ReturnType<typeof vi.fn>;
145
+ setVertexBuffer: ReturnType<typeof vi.fn>;
146
+ draw: ReturnType<typeof vi.fn>;
147
+ drawIndexed: ReturnType<typeof vi.fn>;
148
+ }): unknown {
149
+ const adapter = new RhiNullAdapter();
150
+ const requestDevice = adapter.requestDevice.bind(adapter);
151
+ adapter.requestDevice = async () => {
152
+ const result = await requestDevice();
153
+ if (result.ok) {
154
+ const device = result.value;
155
+ const createCommandEncoder = device.createCommandEncoder.bind(device);
156
+ device.createCommandEncoder = (desc) => {
157
+ const encoderResult = createCommandEncoder(desc);
158
+ if (!encoderResult.ok) return encoderResult;
159
+ const encoder = encoderResult.value;
160
+ const beginRenderPass = encoder.beginRenderPass.bind(encoder);
161
+ encoder.beginRenderPass = (passDesc) => {
162
+ const pass = beginRenderPass(passDesc);
163
+ const draw = pass.draw.bind(pass);
164
+ const drawIndexed = pass.drawIndexed.bind(pass);
165
+ const setIndexBuffer = pass.setIndexBuffer.bind(pass);
166
+ const setVertexBuffer = pass.setVertexBuffer.bind(pass);
167
+ pass.draw = (...args) => {
168
+ spies.draw(...args);
169
+ draw(...args);
170
+ };
171
+ pass.drawIndexed = (...args) => {
172
+ spies.drawIndexed(...args);
173
+ drawIndexed(...args);
174
+ };
175
+ pass.setIndexBuffer = (...args) => {
176
+ spies.setIndexBuffer(...args);
177
+ setIndexBuffer(...args);
178
+ };
179
+ pass.setVertexBuffer = (...args) => {
180
+ spies.setVertexBuffer(...args);
181
+ setVertexBuffer(...args);
182
+ };
183
+ return pass;
184
+ };
185
+ return { ok: true, value: encoder };
186
+ };
187
+ }
188
+ return result;
189
+ };
190
+ return {
191
+ requestAdapter: async () => ({ ok: true, value: adapter }),
192
+ acquireCanvasContext: acquireNullCanvasContext,
193
+ createShaderModule: (device: unknown, desc: { code: string; label?: string }) =>
194
+ createNullShaderModule(device as never, desc),
195
+ };
196
+ }
197
+
198
+ vi.mock('@forgeax/engine-rhi-wgpu', () => {
199
+ return {
200
+ rhi: {
201
+ requestAdapter: async () => ({
202
+ ok: false,
203
+ error: {
204
+ code: 'adapter-unavailable',
205
+ expected: 'adapter available',
206
+ hint: 'default mock fail',
207
+ },
208
+ }),
209
+ getPreferredCanvasFormat: () => 'bgra8unorm',
210
+ acquireCanvasContext: () => ({
211
+ ok: false,
212
+ error: {
213
+ code: 'webgpu-runtime-error',
214
+ expected: 'context available',
215
+ hint: 'default mock fail',
216
+ },
217
+ }),
218
+ },
219
+ ensureReady: async () => undefined,
220
+ };
221
+ });
222
+
223
+ void [
224
+ Camera,
225
+ ChildOf,
226
+ GpuResidencyCache,
227
+ HANDLE_CUBE,
228
+ HANDLE_TRIANGLE,
229
+ HdrpInstallError,
230
+ MeshFilter,
231
+ MeshRenderer,
232
+ PROCEDURAL_FLOATS_PER_VERTEX,
233
+ RhiError,
234
+ RhiNullAdapter,
235
+ Transform,
236
+ World,
237
+ acquireNullCanvasContext,
238
+ afterEach,
239
+ assertStorageBufferCap,
240
+ beforeEach,
241
+ bin,
242
+ buildMeshAttributeMapForUvSets,
243
+ buildPbrPipelineLayouts,
244
+ buildPbrViewBglEntries,
245
+ buildPipelineForMaterialShader,
246
+ cacheKeyOf,
247
+ calculateSphereClusterBounds,
248
+ clusterSpaceObjectAabb,
249
+ createBoxGeometry,
250
+ createConeGeometry,
251
+ createCylinderGeometry,
252
+ createEngineMetrics,
253
+ createHdrpBindGroupLayoutDescriptor,
254
+ createNullShaderModule,
255
+ createPlaneGeometry,
256
+ createSphereGeometry,
257
+ createTorusGeometry,
258
+ defineComponent,
259
+ deriveCullingRadius,
260
+ deriveRenderDataCubemap,
261
+ deriveRenderDataMesh,
262
+ deriveRenderDataTexture,
263
+ describe,
264
+ dirname,
265
+ err,
266
+ existsSync,
267
+ expect,
268
+ extractFrame,
269
+ fileURLToPath,
270
+ findVariantByKey,
271
+ it,
272
+ makeExplicitNullRhi,
273
+ makeMockShaderRegistry,
274
+ mat4,
275
+ matchPass,
276
+ ndcPositionToCluster,
277
+ ok,
278
+ prepareExtractContext,
279
+ readFileSync,
280
+ resolve,
281
+ resolveAssetHandle,
282
+ rhiOk,
283
+ standardMaterialShaderVariants,
284
+ toShared,
285
+ validateClusterGrid,
286
+ vec3,
287
+ vi,
288
+ viewZToZSlice,
289
+ ];
290
+ type __MergedKeep =
291
+ | AssetError
292
+ | ClusterBinError
293
+ | EquirectAsset
294
+ | Handle
295
+ | Mat4
296
+ | MaterialRenderState
297
+ | MaterialShaderEntry
298
+ | MaterialShaderManifestEntry
299
+ | MaterialShaderManifestVariant
300
+ | MeshAsset
301
+ | PassSelector
302
+ | PbrCaps
303
+ | PipelineBuilderContext
304
+ | PipelineBuilderShaderModuleFactory
305
+ | PipelineLayout
306
+ | PipelineSpec
307
+ | PrimitiveTopology
308
+ | RenderPipeline
309
+ | RenderPipelineAsset
310
+ | RendererType
311
+ | Result
312
+ | RhiCaps
313
+ | RhiDevice
314
+ | ShaderModule
315
+ | TextureAsset
316
+ | Vec3
317
+ | WorldType;
318
+
319
+ {
320
+ // --- from pipeline-builder.test.ts ---
321
+ const SHADER_MODULE_SENTINEL = Symbol('mock-shader-module');
322
+ const RENDER_PIPELINE_SENTINEL = Symbol('mock-render-pipeline');
323
+ const PIPELINE_LAYOUT_SENTINEL = Symbol('mock-pipeline-layout');
324
+
325
+ function makeMockEntry(): MaterialShaderEntry {
326
+ return {
327
+ source: '@vertex fn vs_main() -> @builtin(position) vec4<f32> { return vec4<f32>(0.0); }',
328
+ paramSchema: [
329
+ { name: 'baseColor', type: 'color' },
330
+ { name: 'time', type: 'f32' },
331
+ ],
332
+ };
333
+ }
334
+
335
+ interface MockSet {
336
+ factory: PipelineBuilderShaderModuleFactory;
337
+ device: Pick<RhiDevice, 'createRenderPipeline'>;
338
+ createShaderModule: ReturnType<typeof vi.fn>;
339
+ createRenderPipeline: ReturnType<typeof vi.fn>;
340
+ }
341
+
342
+ function makeMocks(opts?: {
343
+ createShaderModuleResult?: Result<ShaderModule, RhiError>;
344
+ createRenderPipelineResult?: Result<RenderPipeline, RhiError>;
345
+ }): MockSet {
346
+ const shaderModule = { [SHADER_MODULE_SENTINEL]: 'mock' } as unknown as ShaderModule;
347
+ const renderPipeline = { [RENDER_PIPELINE_SENTINEL]: 'mock' } as unknown as RenderPipeline;
348
+ const createShaderModule = vi.fn(
349
+ (): Result<ShaderModule, RhiError> => opts?.createShaderModuleResult ?? ok(shaderModule),
350
+ );
351
+ const createRenderPipeline = vi.fn(
352
+ (): Result<RenderPipeline, RhiError> =>
353
+ opts?.createRenderPipelineResult ?? ok(renderPipeline),
354
+ );
355
+ return {
356
+ factory: { createShaderModule } as PipelineBuilderShaderModuleFactory,
357
+ device: { createRenderPipeline } as unknown as Pick<RhiDevice, 'createRenderPipeline'>,
358
+ createShaderModule,
359
+ createRenderPipeline,
360
+ };
361
+ }
362
+
363
+ function makeMockContext(mocks: MockSet): PipelineBuilderContext {
364
+ return {
365
+ device: mocks.device as unknown as RhiDevice,
366
+ shaderModuleFactory: mocks.factory,
367
+ pipelineLayout: { [PIPELINE_LAYOUT_SENTINEL]: 'mock' } as unknown as PipelineLayout,
368
+ colorFormat: 'bgra8unorm-srgb',
369
+ depthFormat: 'depth24plus-stencil8',
370
+ vertexBuffers: [
371
+ {
372
+ arrayStride: 12 * 4,
373
+ attributes: [
374
+ { shaderLocation: 0, offset: 0, format: 'float32x3' },
375
+ { shaderLocation: 1, offset: 3 * 4, format: 'float32x3' },
376
+ { shaderLocation: 2, offset: 6 * 4, format: 'float32x2' },
377
+ { shaderLocation: 3, offset: 8 * 4, format: 'float32x4' },
378
+ ],
379
+ },
380
+ ] as unknown as readonly GPUVertexBufferLayout[],
381
+ };
382
+ }
383
+
384
+ // ─── Tests ────────────────────────────────────────────────────────────────
385
+
386
+ describe('buildPipelineForMaterialShader (M9-T01)', () => {
387
+ it('(a) valid call returns Ok(RenderPipeline) and invokes createShaderModule + createRenderPipeline once', () => {
388
+ const mocks = makeMocks();
389
+ const ctx = makeMockContext(mocks);
390
+ const entry = makeMockEntry();
391
+
392
+ const result = buildPipelineForMaterialShader('my-game::pulse-material', entry, ctx);
393
+
394
+ expect(result.ok).toBe(true);
395
+ expect(mocks.createShaderModule).toHaveBeenCalledTimes(1);
396
+ expect(mocks.createRenderPipeline).toHaveBeenCalledTimes(1);
397
+ // The shader source flows through unchanged.
398
+ const shaderArg = mocks.createShaderModule.mock.calls[0]?.[0] as { code: string };
399
+ expect(shaderArg.code).toBe(entry.source);
400
+ });
401
+
402
+ it('(b) shaderModuleFactory.createShaderModule failure propagates as Result.err(RhiError)', () => {
403
+ const shaderErr = new RhiError({
404
+ code: 'shader-compile-failed',
405
+ expected: 'WGSL compiles',
406
+ hint: 'inspect WGSL source for syntax errors',
407
+ });
408
+ const mocks = makeMocks({
409
+ createShaderModuleResult: err(shaderErr),
410
+ });
411
+ const ctx = makeMockContext(mocks);
412
+ const entry = makeMockEntry();
413
+
414
+ const result = buildPipelineForMaterialShader('my-game::pulse-material', entry, ctx);
415
+
416
+ expect(result.ok).toBe(false);
417
+ if (!result.ok) {
418
+ expect(result.error.code).toBe('shader-compile-failed');
419
+ }
420
+ expect(mocks.createRenderPipeline).not.toHaveBeenCalled();
421
+ });
422
+
423
+ it('(c) device.createRenderPipeline failure propagates as Result.err(shader-compile-failed)', () => {
424
+ const pipelineErr = new RhiError({
425
+ code: 'shader-compile-failed',
426
+ expected: 'pipeline build succeeds',
427
+ hint: 'check binding layout matches shader bindings',
428
+ });
429
+ const mocks = makeMocks({
430
+ createRenderPipelineResult: err(pipelineErr),
431
+ });
432
+ const ctx = makeMockContext(mocks);
433
+ const entry = makeMockEntry();
434
+
435
+ const result = buildPipelineForMaterialShader('my-game::pulse-material', entry, ctx);
436
+
437
+ expect(result.ok).toBe(false);
438
+ if (!result.ok) {
439
+ expect(result.error.code).toBe('shader-compile-failed');
440
+ }
441
+ expect(mocks.createShaderModule).toHaveBeenCalledTimes(1);
442
+ expect(mocks.createRenderPipeline).toHaveBeenCalledTimes(1);
443
+ });
444
+
445
+ it('(d) repeated invocations build equivalent pipelines (caller owns cache; helper is pure)', () => {
446
+ const mocks = makeMocks();
447
+ const ctx = makeMockContext(mocks);
448
+ const entry = makeMockEntry();
449
+
450
+ const r1 = buildPipelineForMaterialShader('my-game::pulse-material', entry, ctx);
451
+ const r2 = buildPipelineForMaterialShader('my-game::pulse-material', entry, ctx);
452
+
453
+ expect(r1.ok).toBe(true);
454
+ expect(r2.ok).toBe(true);
455
+ // The helper itself does not cache -- each call re-invokes the device.
456
+ expect(mocks.createShaderModule).toHaveBeenCalledTimes(2);
457
+ expect(mocks.createRenderPipeline).toHaveBeenCalledTimes(2);
458
+ // The pipeline descriptor passed to createRenderPipeline carries the
459
+ // pipelineLayout from ctx (charter P4 consistent abstraction: same
460
+ // 4-BGL chain reused across MaterialShader entries).
461
+ const firstDesc = mocks.createRenderPipeline.mock.calls[0]?.[0] as { layout: unknown };
462
+ expect(firstDesc.layout).toBe(ctx.pipelineLayout);
463
+ });
464
+
465
+ // ─── w11: entry point parameterization tests (TDD red phase) ──────────
466
+
467
+ it('(e) pass with vertexEntry and fragmentEntry uses them as entry points', () => {
468
+ const mocks = makeMocks();
469
+ const ctx = makeMockContext(mocks);
470
+ const entry = makeMockEntry();
471
+
472
+ const result = buildPipelineForMaterialShader(
473
+ 'my-game::shadow',
474
+ entry,
475
+ ctx,
476
+ undefined, // renderState
477
+ undefined, // geometry
478
+ 'vs_shadow',
479
+ 'fs_shadow',
480
+ );
481
+
482
+ expect(result.ok).toBe(true);
483
+ const desc = mocks.createRenderPipeline.mock.calls[0]?.[0] as {
484
+ vertex: { entryPoint: string };
485
+ fragment: { entryPoint: string };
486
+ };
487
+ expect(desc.vertex.entryPoint).toBe('vs_shadow');
488
+ expect(desc.fragment.entryPoint).toBe('fs_shadow');
489
+ });
490
+
491
+ it('(f) pass without vertexEntry/fragmentEntry defaults to vs_main/fs_main', () => {
492
+ const mocks = makeMocks();
493
+ const ctx = makeMockContext(mocks);
494
+ const entry = makeMockEntry();
495
+
496
+ const result = buildPipelineForMaterialShader('my-game::default-entry', entry, ctx);
497
+
498
+ expect(result.ok).toBe(true);
499
+ const desc = mocks.createRenderPipeline.mock.calls[0]?.[0] as {
500
+ vertex: { entryPoint: string };
501
+ fragment: { entryPoint: string };
502
+ };
503
+ expect(desc.vertex.entryPoint).toBe('vs_main');
504
+ expect(desc.fragment.entryPoint).toBe('fs_main');
505
+ });
506
+
507
+ // ─── w13: per-pass defines injection tests (TDD red phase) ──────────────
508
+
509
+ it('(g) defines={USE_ALPHA_TEST:"1"} prepends #define to shader source', () => {
510
+ const mocks = makeMocks();
511
+ const ctx = makeMockContext(mocks);
512
+ const entry = makeMockEntry();
513
+
514
+ const result = buildPipelineForMaterialShader(
515
+ 'my-game::alpha-test',
516
+ entry,
517
+ ctx,
518
+ undefined, // renderState
519
+ undefined, // geometry
520
+ undefined, // vertexEntry
521
+ undefined, // fragmentEntry
522
+ { USE_ALPHA_TEST: '1' },
523
+ );
524
+
525
+ expect(result.ok).toBe(true);
526
+ const shaderArg = mocks.createShaderModule.mock.calls[0]?.[0] as { code: string };
527
+ expect(shaderArg.code).toBe(`#define USE_ALPHA_TEST 1\n${entry.source}`);
528
+ });
529
+
530
+ it('(h) empty defines records inject nothing', () => {
531
+ const mocks = makeMocks();
532
+ const ctx = makeMockContext(mocks);
533
+ const entry = makeMockEntry();
534
+
535
+ const result = buildPipelineForMaterialShader(
536
+ 'my-game::no-defines',
537
+ entry,
538
+ ctx,
539
+ undefined, // renderState
540
+ undefined, // geometry
541
+ undefined, // vertexEntry
542
+ undefined, // fragmentEntry
543
+ {},
544
+ );
545
+
546
+ expect(result.ok).toBe(true);
547
+ const shaderArg = mocks.createShaderModule.mock.calls[0]?.[0] as { code: string };
548
+ expect(shaderArg.code).toBe(entry.source);
549
+ });
550
+
551
+ it('(i) multiple defines keys produce multiple #define lines', () => {
552
+ const mocks = makeMocks();
553
+ const ctx = makeMockContext(mocks);
554
+ const entry = makeMockEntry();
555
+
556
+ const result = buildPipelineForMaterialShader(
557
+ 'my-game::multi-defines',
558
+ entry,
559
+ ctx,
560
+ undefined, // renderState
561
+ undefined, // geometry
562
+ undefined, // vertexEntry
563
+ undefined, // fragmentEntry
564
+ { USE_ALPHA_TEST: '1', LIGHT_COUNT: '4' },
565
+ );
566
+
567
+ expect(result.ok).toBe(true);
568
+ const shaderArg = mocks.createShaderModule.mock.calls[0]?.[0] as { code: string };
569
+ expect(shaderArg.code).toBe(
570
+ `#define USE_ALPHA_TEST 1\n#define LIGHT_COUNT 4\n${entry.source}`,
571
+ );
572
+ });
573
+
574
+ // ─── w1: mask + frontFace pipeline descriptor pass-through (TDD red phase) ─
575
+
576
+ it('(k) renderState with frontFace="cw" lands in GPUPrimitiveState.frontFace', () => {
577
+ const mocks = makeMocks();
578
+ const ctx = makeMockContext(mocks);
579
+ const entry = makeMockEntry();
580
+ const renderState = {
581
+ frontFace: 'cw' as const,
582
+ } as MaterialRenderState;
583
+
584
+ const result = buildPipelineForMaterialShader(
585
+ 'my-game::frontface-cw-red',
586
+ entry,
587
+ ctx,
588
+ renderState,
589
+ );
590
+
591
+ expect(result.ok).toBe(true);
592
+ const desc = mocks.createRenderPipeline.mock.calls[0]?.[0] as {
593
+ primitive: { frontFace?: string };
594
+ };
595
+ expect(desc.primitive.frontFace).toBe('cw');
596
+ });
597
+
598
+ it('(l) renderState without new fields defaults to mask=undefined + frontFace=ccw (equiv status quo)', () => {
599
+ const mocks = makeMocks();
600
+ const ctx = makeMockContext(mocks);
601
+ const entry = makeMockEntry();
602
+ // omit stencilReadMask / stencilWriteMask / frontFace entirely
603
+ const renderState: MaterialRenderState = { cullMode: 'none' };
604
+
605
+ const result = buildPipelineForMaterialShader(
606
+ 'my-game::default-fields-red',
607
+ entry,
608
+ ctx,
609
+ renderState,
610
+ );
611
+
612
+ expect(result.ok).toBe(true);
613
+ const desc = mocks.createRenderPipeline.mock.calls[0]?.[0] as {
614
+ depthStencil: { stencilReadMask?: number; stencilWriteMask?: number };
615
+ primitive: { frontFace?: string };
616
+ };
617
+ // Mask fields are undefined when not provided (WebGPU defaults to 0xFFFFFFFF internally).
618
+ expect(desc.depthStencil.stencilReadMask).toBeUndefined();
619
+ expect(desc.depthStencil.stencilWriteMask).toBeUndefined();
620
+ // frontFace defaults to 'ccw' (existing hardcoded behavior).
621
+ expect(desc.primitive.frontFace).toBe('ccw');
622
+ });
623
+ });
624
+ }