@forgeax/engine-render 0.1.7 → 0.1.19

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 (683) hide show
  1. package/README.md +140 -2
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/assembly/backend-contract.d.ts +12 -0
  4. package/dist/assembly/backend-contract.d.ts.map +1 -1
  5. package/dist/assembly/factory.d.ts +12 -2
  6. package/dist/assembly/factory.d.ts.map +1 -1
  7. package/dist/assembly/host-contract.d.ts +4 -0
  8. package/dist/assembly/host-contract.d.ts.map +1 -1
  9. package/dist/assembly/renderer-frame-transaction.d.ts +39 -0
  10. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -0
  11. package/dist/assembly/renderer-inspection.d.ts +22 -0
  12. package/dist/assembly/renderer-inspection.d.ts.map +1 -0
  13. package/dist/assembly/renderer-lifecycle.d.ts +4 -0
  14. package/dist/assembly/renderer-lifecycle.d.ts.map +1 -0
  15. package/dist/authoring.mjs +4 -2
  16. package/dist/authoring.mjs.map +1 -1
  17. package/dist/chunk-FJ6P52EE.mjs +46 -0
  18. package/dist/chunk-FJ6P52EE.mjs.map +1 -0
  19. package/dist/chunk-IPXCABEP.mjs +73 -0
  20. package/dist/chunk-IPXCABEP.mjs.map +1 -0
  21. package/dist/chunk-JDWARUOI.mjs +44 -0
  22. package/dist/chunk-JDWARUOI.mjs.map +1 -0
  23. package/dist/{chunk-YEJIUW7D.mjs → chunk-LOSO4CTV.mjs} +296 -547
  24. package/dist/chunk-LOSO4CTV.mjs.map +1 -0
  25. package/dist/chunk-PCHBPYML.mjs +385 -0
  26. package/dist/chunk-PCHBPYML.mjs.map +1 -0
  27. package/dist/chunk-RJRUS55L.mjs +9323 -0
  28. package/dist/chunk-RJRUS55L.mjs.map +1 -0
  29. package/dist/chunk-RXZ3RGOU.mjs +53 -0
  30. package/dist/chunk-RXZ3RGOU.mjs.map +1 -0
  31. package/dist/{chunk-CQXZC5XI.mjs → chunk-VFPLTKCU.mjs} +79 -69
  32. package/dist/chunk-VFPLTKCU.mjs.map +1 -0
  33. package/dist/chunk-YTQ5C7YQ.mjs +584 -0
  34. package/dist/chunk-YTQ5C7YQ.mjs.map +1 -0
  35. package/dist/components/atmosphere.d.ts +9 -0
  36. package/dist/components/atmosphere.d.ts.map +1 -0
  37. package/dist/components/camera.d.ts +2 -1
  38. package/dist/components/camera.d.ts.map +1 -1
  39. package/dist/components/fog.d.ts +8 -0
  40. package/dist/components/fog.d.ts.map +1 -0
  41. package/dist/components/index.d.ts +3 -0
  42. package/dist/components/index.d.ts.map +1 -1
  43. package/dist/components/motion-blur.d.ts +7 -0
  44. package/dist/components/motion-blur.d.ts.map +1 -0
  45. package/dist/construct-renderer.d.ts +2 -2
  46. package/dist/construct-renderer.d.ts.map +1 -1
  47. package/dist/construct-renderer.mjs +10914 -16392
  48. package/dist/construct-renderer.mjs.map +1 -1
  49. package/dist/device/device-scope.d.ts +4 -0
  50. package/dist/device/device-scope.d.ts.map +1 -1
  51. package/dist/environment/frame.d.ts +60 -0
  52. package/dist/environment/frame.d.ts.map +1 -0
  53. package/dist/environment/generation.d.ts +21 -0
  54. package/dist/environment/generation.d.ts.map +1 -0
  55. package/dist/environment/graph.d.ts +4 -0
  56. package/dist/environment/graph.d.ts.map +1 -0
  57. package/dist/environment/inspection.d.ts +48 -0
  58. package/dist/environment/inspection.d.ts.map +1 -0
  59. package/dist/environment/lifecycle.d.ts +39 -0
  60. package/dist/environment/lifecycle.d.ts.map +1 -0
  61. package/dist/environment/signature.d.ts +25 -0
  62. package/dist/environment/signature.d.ts.map +1 -0
  63. package/dist/errors/render.d.ts +136 -1
  64. package/dist/errors/render.d.ts.map +1 -1
  65. package/dist/extract/camera.d.ts +5 -0
  66. package/dist/extract/camera.d.ts.map +1 -0
  67. package/dist/extract/environment.d.ts +74 -0
  68. package/dist/extract/environment.d.ts.map +1 -0
  69. package/dist/extract/visibility.d.ts +1 -1
  70. package/dist/extract/visibility.d.ts.map +1 -1
  71. package/dist/features/host.d.ts +9 -2
  72. package/dist/features/host.d.ts.map +1 -1
  73. package/dist/features/motion-blur/motion-blur-feature.d.ts +16 -0
  74. package/dist/features/motion-blur/motion-blur-feature.d.ts.map +1 -0
  75. package/dist/features/motion-blur/motion-blur-params.d.ts +25 -0
  76. package/dist/features/motion-blur/motion-blur-params.d.ts.map +1 -0
  77. package/dist/features/plan.d.ts +17 -2
  78. package/dist/features/plan.d.ts.map +1 -1
  79. package/dist/features/prepared-gpu-work.d.ts +3 -1
  80. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  81. package/dist/features/prepared-graphics.d.ts +2 -1
  82. package/dist/features/prepared-graphics.d.ts.map +1 -1
  83. package/dist/features/render-graph-raster.d.ts +2 -1
  84. package/dist/features/render-graph-raster.d.ts.map +1 -1
  85. package/dist/features/targets.d.ts +3 -0
  86. package/dist/features/targets.d.ts.map +1 -1
  87. package/dist/features/types.d.ts +12 -0
  88. package/dist/features/types.d.ts.map +1 -1
  89. package/dist/fullscreen-post-process-pass.d.ts +7 -1
  90. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  91. package/dist/gpu-scene.d.ts +2 -0
  92. package/dist/gpu-scene.d.ts.map +1 -1
  93. package/dist/ibl/skylight-bind-group.d.ts +5 -6
  94. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  95. package/dist/index.d.ts +17 -6
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.mjs +6 -4
  98. package/dist/index.mjs.map +1 -1
  99. package/dist/inspection-types.d.ts +43 -1
  100. package/dist/inspection-types.d.ts.map +1 -1
  101. package/dist/internal.d.ts +2 -0
  102. package/dist/internal.d.ts.map +1 -1
  103. package/dist/internal.mjs +2 -0
  104. package/dist/materials.d.ts +22 -0
  105. package/dist/materials.d.ts.map +1 -1
  106. package/dist/pbr-pipeline.d.ts +10 -6
  107. package/dist/pbr-pipeline.d.ts.map +1 -1
  108. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  109. package/dist/pipeline/standard-pipeline.d.ts +3 -0
  110. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  111. package/dist/pipeline/standard-post.d.ts +48 -0
  112. package/dist/pipeline/standard-post.d.ts.map +1 -0
  113. package/dist/pipeline/standard-profile.d.ts +3 -6
  114. package/dist/pipeline/standard-profile.d.ts.map +1 -1
  115. package/dist/pipeline-builder.d.ts +18 -0
  116. package/dist/pipeline-builder.d.ts.map +1 -1
  117. package/dist/pipeline-spec.d.ts.map +1 -1
  118. package/dist/plugin.d.ts.map +1 -1
  119. package/dist/record/frame-snapshot.d.ts +100 -5
  120. package/dist/record/frame-snapshot.d.ts.map +1 -1
  121. package/dist/record/frame-targets.d.ts.map +1 -1
  122. package/dist/record/frame.d.ts +4 -2
  123. package/dist/record/frame.d.ts.map +1 -1
  124. package/dist/record/main-pass-geometry.d.ts +11 -0
  125. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  126. package/dist/record/main-pass-material.d.ts +8 -5
  127. package/dist/record/main-pass-material.d.ts.map +1 -1
  128. package/dist/record/main-pass-sprite-draws.d.ts +8 -1
  129. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  130. package/dist/record/main-pass.d.ts +2 -0
  131. package/dist/record/main-pass.d.ts.map +1 -1
  132. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  133. package/dist/record/render-context.d.ts +76 -18
  134. package/dist/record/render-context.d.ts.map +1 -1
  135. package/dist/record/shadow-pass.d.ts.map +1 -1
  136. package/dist/record/skybox-post-pass.d.ts +1 -11
  137. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  138. package/dist/record/typed-frame-graph.d.ts +26 -2
  139. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  140. package/dist/record/view-ubo.d.ts +4 -1
  141. package/dist/record/view-ubo.d.ts.map +1 -1
  142. package/dist/render-contract.d.ts +92 -8
  143. package/dist/render-contract.d.ts.map +1 -1
  144. package/dist/render-graph-primitives.d.ts.map +1 -1
  145. package/dist/render-pipeline.d.ts +50 -6
  146. package/dist/render-pipeline.d.ts.map +1 -1
  147. package/dist/render-system-extract.d.ts +29 -5
  148. package/dist/render-system-extract.d.ts.map +1 -1
  149. package/dist/render-system.d.ts +23 -4
  150. package/dist/render-system.d.ts.map +1 -1
  151. package/dist/scene/render-scene.d.ts +36 -2
  152. package/dist/scene/render-scene.d.ts.map +1 -1
  153. package/dist/temporal/coverage.d.ts +42 -0
  154. package/dist/temporal/coverage.d.ts.map +1 -0
  155. package/dist/temporal/frame-coordinator.d.ts +99 -0
  156. package/dist/temporal/frame-coordinator.d.ts.map +1 -0
  157. package/dist/temporal/gpu.d.ts +39 -0
  158. package/dist/temporal/gpu.d.ts.map +1 -0
  159. package/dist/temporal/history.d.ts +37 -0
  160. package/dist/temporal/history.d.ts.map +1 -0
  161. package/dist/temporal/index.d.ts +7 -0
  162. package/dist/temporal/index.d.ts.map +1 -0
  163. package/dist/temporal/index.mjs +8 -0
  164. package/dist/temporal/index.mjs.map +1 -0
  165. package/dist/temporal/inspection.d.ts +36 -0
  166. package/dist/temporal/inspection.d.ts.map +1 -0
  167. package/dist/temporal/scene-data-catalog.d.ts +48 -0
  168. package/dist/temporal/scene-data-catalog.d.ts.map +1 -0
  169. package/dist/temporal/scene-data.d.ts +43 -0
  170. package/dist/temporal/scene-data.d.ts.map +1 -0
  171. package/dist/temporal/standard-scene-data.d.ts +61 -0
  172. package/dist/temporal/standard-scene-data.d.ts.map +1 -0
  173. package/dist/temporal/taa-history-resources.d.ts +22 -0
  174. package/dist/temporal/taa-history-resources.d.ts.map +1 -0
  175. package/dist/temporal/taa-history-store.d.ts +27 -0
  176. package/dist/temporal/taa-history-store.d.ts.map +1 -0
  177. package/dist/temporal/taa-resolve.d.ts +15 -0
  178. package/dist/temporal/taa-resolve.d.ts.map +1 -0
  179. package/dist/temporal/temporal-view.d.ts +40 -0
  180. package/dist/temporal/temporal-view.d.ts.map +1 -0
  181. package/dist/temporal/transaction.d.ts +9 -0
  182. package/dist/temporal/transaction.d.ts.map +1 -0
  183. package/dist/temporal/view.d.ts +56 -0
  184. package/dist/temporal/view.d.ts.map +1 -0
  185. package/dist/transmission/backdrop.d.ts +147 -0
  186. package/dist/transmission/backdrop.d.ts.map +1 -0
  187. package/dist/transmission/inspection.d.ts +57 -0
  188. package/dist/transmission/inspection.d.ts.map +1 -0
  189. package/dist/transmission/oracle.d.ts +42 -0
  190. package/dist/transmission/oracle.d.ts.map +1 -0
  191. package/dist/transmission/projection.d.ts +37 -0
  192. package/dist/transmission/projection.d.ts.map +1 -0
  193. package/dist/typed-render-graph-primitives.d.ts +25 -2
  194. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  195. package/package.json +24 -19
  196. package/src/__tests__/ai-user-cold-start.integration.test.ts +59 -0
  197. package/src/__tests__/ai-user-public-surface.test-d.ts +45 -0
  198. package/src/__tests__/bloom-exact-zero.unit.test.ts +202 -0
  199. package/src/__tests__/bloom-lifecycle.integration.test.ts +125 -0
  200. package/src/__tests__/construct-renderer-identity.unit.test.ts +4 -3
  201. package/src/__tests__/detached-inspection.integration.test.ts +177 -0
  202. package/src/__tests__/environment-fog-lanes.integration.test.ts +219 -0
  203. package/src/__tests__/environment-generation.integration.test.ts +141 -0
  204. package/src/__tests__/environment-selection.unit.test.ts +245 -0
  205. package/src/__tests__/factory-contract.integration.test.ts +1380 -9
  206. package/src/__tests__/frame-plan-contract.unit.test.ts +90 -0
  207. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +7 -0
  208. package/src/__tests__/gpu-driven-production.integration.test.ts +74 -22
  209. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +37 -0
  210. package/src/__tests__/gpu-scene.unit.test.ts +10 -0
  211. package/src/__tests__/injection-kind-owner.test-d.ts +2 -1
  212. package/src/__tests__/material-contract-inventory.unit.test.ts +62 -0
  213. package/src/__tests__/material-cooked-projection.unit.test.ts +18 -146
  214. package/src/__tests__/materials-transmission-validation.unit.test.ts +36 -0
  215. package/src/__tests__/morph-feature-plan.unit.test.ts +7 -0
  216. package/src/__tests__/motion-blur.pixel.integration.test.ts +121 -0
  217. package/src/__tests__/public-surface.test-d.ts +15 -1
  218. package/src/__tests__/render-error-code-owner.test-d.ts +9 -0
  219. package/src/__tests__/render-error-detail-ssot.test-d.ts +11 -2
  220. package/src/__tests__/render-error-exhaustive.test-d.ts +3 -0
  221. package/src/__tests__/render-feature-errors.unit.test.ts +33 -3
  222. package/src/__tests__/render-feature-gpu-work.integration.test.ts +44 -0
  223. package/src/__tests__/render-feature-plan.test-d.ts +22 -89
  224. package/src/__tests__/render-scene-projection.unit.test.ts +28 -0
  225. package/src/__tests__/render-temporal-environment-consumer.browser.test.ts +26 -0
  226. package/src/__tests__/render-temporal-environment-consumer.dawn.test.ts +21 -0
  227. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +395 -1
  228. package/src/__tests__/renderer-frame-transaction.integration.test.ts +405 -0
  229. package/src/__tests__/renderer-lifecycle.integration.test.ts +22 -0
  230. package/src/__tests__/scene-data-catalog.unit.test.ts +59 -0
  231. package/src/__tests__/scene-data-consumer.integration.test.ts +67 -0
  232. package/src/__tests__/scene-data-contract.test-d.ts +35 -0
  233. package/src/__tests__/scene-data-inspection.unit.test.ts +41 -0
  234. package/src/__tests__/scene-data-public-surface.test-d.ts +34 -0
  235. package/src/__tests__/shader-manifest-fixture.ts +111 -0
  236. package/src/__tests__/skinned-shadow-caster.test.ts +102 -0
  237. package/src/__tests__/standard-clustered-pipeline.unit.test.ts +24 -3
  238. package/src/__tests__/standard-pipeline.dawn.test.ts +15 -0
  239. package/src/__tests__/standard-pipeline.integration.test.ts +543 -1
  240. package/src/__tests__/standard-profile-oracle.unit.test.ts +10 -2
  241. package/src/__tests__/standard-temporal-producer.integration.test.ts +35 -0
  242. package/src/__tests__/surface-configuration.unit.test.ts +211 -12
  243. package/src/__tests__/taa-transaction.integration.test.ts +30 -0
  244. package/src/__tests__/temporal-admission.integration.test.ts +40 -0
  245. package/src/__tests__/temporal-coverage.unit.test.ts +35 -0
  246. package/src/__tests__/temporal-demand.unit.test.ts +44 -0
  247. package/src/__tests__/temporal-frame-coordinator.unit.test.ts +64 -0
  248. package/src/__tests__/temporal-graph-topology.unit.test.ts +51 -0
  249. package/src/__tests__/temporal-history-lifecycle.unit.test.ts +170 -0
  250. package/src/__tests__/temporal-performance.integration.test.ts +615 -0
  251. package/src/__tests__/temporal-reset-matrix.unit.test.ts +97 -0
  252. package/src/__tests__/temporal-transaction.integration.test.ts +60 -0
  253. package/src/__tests__/temporal-view.unit.test.ts +152 -0
  254. package/src/__tests__/transmission-prewarm.unit.test.ts +93 -0
  255. package/src/__tests__/typed-pipeline-topology.unit.test.ts +230 -1
  256. package/src/__tests__/urp-pipeline-targets.unit.test.ts +25 -1
  257. package/src/__tests__/urp-pipeline.unit.test.ts +4 -3
  258. package/src/__tests__/visibility-extract.integration.test.ts +27 -1
  259. package/src/__tests__/visibility-producer-matrix.integration.test.ts +10 -0
  260. package/src/assembly/backend-contract.ts +47 -1
  261. package/src/assembly/factory.ts +1224 -505
  262. package/src/assembly/host-contract.ts +4 -0
  263. package/src/assembly/renderer-frame-transaction.ts +75 -0
  264. package/src/assembly/renderer-inspection.ts +112 -0
  265. package/src/assembly/renderer-lifecycle.ts +6 -0
  266. package/src/components/__tests__/motion-blur.unit.test.ts +14 -0
  267. package/src/components/__tests__/schema-contract.unit.test.ts +6 -1
  268. package/src/components/atmosphere.ts +10 -0
  269. package/src/components/camera.ts +2 -1
  270. package/src/components/fog.ts +9 -0
  271. package/src/components/index.ts +3 -0
  272. package/src/components/motion-blur.ts +8 -0
  273. package/src/construct-renderer.ts +40 -3
  274. package/src/device/device-scope.ts +15 -1
  275. package/src/environment/frame.ts +185 -0
  276. package/src/environment/generation.ts +23 -0
  277. package/src/environment/graph.ts +9 -0
  278. package/src/environment/inspection.ts +87 -0
  279. package/src/environment/lifecycle.ts +250 -0
  280. package/src/environment/signature.ts +55 -0
  281. package/src/errors/render.ts +285 -0
  282. package/src/extract/camera.ts +78 -0
  283. package/src/extract/environment.ts +171 -0
  284. package/src/extract/visibility.ts +38 -19
  285. package/src/features/host.ts +36 -5
  286. package/src/features/motion-blur/__tests__/motion-blur-feature.unit.test.ts +67 -0
  287. package/src/features/motion-blur/__tests__/motion-blur-params.unit.test.ts +53 -0
  288. package/src/features/motion-blur/motion-blur-feature.ts +119 -0
  289. package/src/features/motion-blur/motion-blur-params.ts +89 -0
  290. package/src/features/plan.ts +32 -3
  291. package/src/features/prepared-gpu-work.ts +21 -6
  292. package/src/features/prepared-graphics.ts +2 -1
  293. package/src/features/render-graph-raster.ts +2 -1
  294. package/src/features/targets.ts +24 -2
  295. package/src/features/types.ts +13 -0
  296. package/src/fullscreen-post-process-pass.ts +34 -4
  297. package/src/gpu-scene.ts +24 -0
  298. package/src/ibl/skylight-bind-group.ts +30 -38
  299. package/src/index.ts +66 -6
  300. package/src/inspection-types.ts +48 -0
  301. package/src/internal.ts +5 -0
  302. package/src/materials.ts +119 -24
  303. package/src/pbr-pipeline.ts +58 -19
  304. package/src/pipeline/standard-forward-lane.ts +158 -101
  305. package/src/pipeline/standard-pipeline.ts +156 -105
  306. package/src/pipeline/standard-post.ts +373 -0
  307. package/src/pipeline/standard-profile.ts +11 -11
  308. package/src/pipeline-builder.ts +102 -12
  309. package/src/pipeline-spec.ts +9 -0
  310. package/src/plugin.ts +2 -0
  311. package/src/record/__tests__/fullscreen-temporal-routing.unit.test.ts +25 -0
  312. package/src/record/__tests__/main-pass-geometry.unit.test.ts +47 -0
  313. package/src/record/__tests__/material-bg-cache.unit.test.ts +12 -1
  314. package/src/record/__tests__/material-pipeline-pending-cache.unit.test.ts +22 -0
  315. package/src/record/__tests__/sprite-material-abi.unit.test.ts +75 -0
  316. package/src/record/__tests__/standard-pbr-ubo-layout.unit.test.ts +67 -0
  317. package/src/record/__tests__/temporal-payload.unit.test.ts +164 -0
  318. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +127 -0
  319. package/src/record/frame-snapshot.ts +129 -5
  320. package/src/record/frame-targets.ts +15 -6
  321. package/src/record/frame.ts +107 -3
  322. package/src/record/main-pass-geometry.ts +86 -40
  323. package/src/record/main-pass-material.ts +114 -66
  324. package/src/record/main-pass-sprite-draws.ts +78 -101
  325. package/src/record/main-pass.ts +77 -4
  326. package/src/record/mesh-ssbo.ts +22 -3
  327. package/src/record/render-context.ts +189 -23
  328. package/src/record/shadow-pass.ts +113 -23
  329. package/src/record/skybox-post-pass.ts +97 -41
  330. package/src/record/typed-frame-graph.ts +565 -26
  331. package/src/record/view-ubo.ts +52 -4
  332. package/src/render-contract.ts +109 -6
  333. package/src/render-graph-primitives.ts +18 -1
  334. package/src/render-pipeline.ts +100 -27
  335. package/src/render-system-extract.ts +193 -69
  336. package/src/render-system.ts +482 -41
  337. package/src/scene/render-scene.ts +250 -7
  338. package/src/temporal/__tests__/taa-history-resources.unit.test.ts +45 -0
  339. package/src/temporal/coverage.ts +76 -0
  340. package/src/temporal/frame-coordinator.ts +311 -0
  341. package/src/temporal/gpu.ts +287 -0
  342. package/src/temporal/history.ts +92 -0
  343. package/src/temporal/index.ts +6 -0
  344. package/src/temporal/inspection.ts +97 -0
  345. package/src/temporal/scene-data-catalog.ts +200 -0
  346. package/src/temporal/scene-data.ts +149 -0
  347. package/src/temporal/standard-scene-data.ts +182 -0
  348. package/src/temporal/taa-history-resources.ts +128 -0
  349. package/src/temporal/taa-history-store.ts +79 -0
  350. package/src/temporal/taa-resolve.ts +34 -0
  351. package/src/temporal/temporal-view.ts +169 -0
  352. package/src/temporal/transaction.ts +17 -0
  353. package/src/temporal/view.ts +161 -0
  354. package/src/transmission/__tests__/capability.unit.test.ts +83 -0
  355. package/src/transmission/__tests__/composition.integration.test.ts +161 -0
  356. package/src/transmission/__tests__/inspection.unit.test.ts +241 -0
  357. package/src/transmission/__tests__/lifecycle.integration.test.ts +96 -0
  358. package/src/transmission/__tests__/oracle.unit.test.ts +131 -0
  359. package/src/transmission/__tests__/projection.unit.test.ts +71 -0
  360. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +438 -0
  361. package/src/transmission/__tests__/transmission-backdrop-topology.unit.test.ts +109 -0
  362. package/src/transmission/__tests__/transmission-backdrop.dawn.test.ts +105 -0
  363. package/src/transmission/backdrop.ts +572 -0
  364. package/src/transmission/inspection.ts +190 -0
  365. package/src/transmission/oracle.ts +141 -0
  366. package/src/transmission/projection.ts +83 -0
  367. package/src/typed-render-graph-primitives.ts +162 -9
  368. package/dist/__tests__/authoring-path.unit.test.d.ts +0 -2
  369. package/dist/__tests__/authoring-path.unit.test.d.ts.map +0 -1
  370. package/dist/__tests__/backend-selection-rhi-capture.test-d.d.ts +0 -2
  371. package/dist/__tests__/backend-selection-rhi-capture.test-d.d.ts.map +0 -1
  372. package/dist/__tests__/callback-inference.test-d.d.ts +0 -2
  373. package/dist/__tests__/callback-inference.test-d.d.ts.map +0 -1
  374. package/dist/__tests__/cluster-binner.test.d.ts +0 -2
  375. package/dist/__tests__/cluster-binner.test.d.ts.map +0 -1
  376. package/dist/__tests__/cluster-grid-default-surface.unit.test.d.ts +0 -2
  377. package/dist/__tests__/cluster-grid-default-surface.unit.test.d.ts.map +0 -1
  378. package/dist/__tests__/construct-renderer-identity.unit.test.d.ts +0 -2
  379. package/dist/__tests__/construct-renderer-identity.unit.test.d.ts.map +0 -1
  380. package/dist/__tests__/device-scope-lifecycle.unit.test.d.ts +0 -2
  381. package/dist/__tests__/device-scope-lifecycle.unit.test.d.ts.map +0 -1
  382. package/dist/__tests__/device-scope-stale-matrix.unit.test.d.ts +0 -2
  383. package/dist/__tests__/device-scope-stale-matrix.unit.test.d.ts.map +0 -1
  384. package/dist/__tests__/direct-extract-consumer-contract.test-d.d.ts +0 -2
  385. package/dist/__tests__/direct-extract-consumer-contract.test-d.d.ts.map +0 -1
  386. package/dist/__tests__/direct-light-snapshot.unit.test.d.ts +0 -2
  387. package/dist/__tests__/direct-light-snapshot.unit.test.d.ts.map +0 -1
  388. package/dist/__tests__/factory-contract.integration.test.d.ts +0 -2
  389. package/dist/__tests__/factory-contract.integration.test.d.ts.map +0 -1
  390. package/dist/__tests__/fallback-row-stride-surface.unit.test.d.ts +0 -2
  391. package/dist/__tests__/fallback-row-stride-surface.unit.test.d.ts.map +0 -1
  392. package/dist/__tests__/frame-observation.contract.test.d.ts +0 -2
  393. package/dist/__tests__/frame-observation.contract.test.d.ts.map +0 -1
  394. package/dist/__tests__/fullscreen-feature-plan.unit.test.d.ts +0 -2
  395. package/dist/__tests__/fullscreen-feature-plan.unit.test.d.ts.map +0 -1
  396. package/dist/__tests__/glyph-text-layout-recovery.unit.test.d.ts +0 -2
  397. package/dist/__tests__/glyph-text-layout-recovery.unit.test.d.ts.map +0 -1
  398. package/dist/__tests__/gpu-driven-indirect-raster-evidence.d.ts +0 -6
  399. package/dist/__tests__/gpu-driven-indirect-raster-evidence.d.ts.map +0 -1
  400. package/dist/__tests__/gpu-driven-indirect-raster.browser.test.d.ts +0 -2
  401. package/dist/__tests__/gpu-driven-indirect-raster.browser.test.d.ts.map +0 -1
  402. package/dist/__tests__/gpu-driven-indirect-raster.dawn.test.d.ts +0 -2
  403. package/dist/__tests__/gpu-driven-indirect-raster.dawn.test.d.ts.map +0 -1
  404. package/dist/__tests__/gpu-driven-production.integration.test.d.ts +0 -2
  405. package/dist/__tests__/gpu-driven-production.integration.test.d.ts.map +0 -1
  406. package/dist/__tests__/gpu-driven-scaling.unit.test.d.ts +0 -2
  407. package/dist/__tests__/gpu-driven-scaling.unit.test.d.ts.map +0 -1
  408. package/dist/__tests__/gpu-driven-view-gpu-evidence.d.ts +0 -18
  409. package/dist/__tests__/gpu-driven-view-gpu-evidence.d.ts.map +0 -1
  410. package/dist/__tests__/gpu-driven-view-graph.integration.test.d.ts +0 -2
  411. package/dist/__tests__/gpu-driven-view-graph.integration.test.d.ts.map +0 -1
  412. package/dist/__tests__/gpu-driven-view-reference.d.ts +0 -15
  413. package/dist/__tests__/gpu-driven-view-reference.d.ts.map +0 -1
  414. package/dist/__tests__/gpu-driven-view.browser.test.d.ts +0 -2
  415. package/dist/__tests__/gpu-driven-view.browser.test.d.ts.map +0 -1
  416. package/dist/__tests__/gpu-driven-view.dawn.test.d.ts +0 -2
  417. package/dist/__tests__/gpu-driven-view.dawn.test.d.ts.map +0 -1
  418. package/dist/__tests__/gpu-driven-view.unit.test.d.ts +0 -2
  419. package/dist/__tests__/gpu-driven-view.unit.test.d.ts.map +0 -1
  420. package/dist/__tests__/gpu-resource-store-stride.unit.test.d.ts +0 -2
  421. package/dist/__tests__/gpu-resource-store-stride.unit.test.d.ts.map +0 -1
  422. package/dist/__tests__/gpu-scene-render-graph-gpu.d.ts +0 -7
  423. package/dist/__tests__/gpu-scene-render-graph-gpu.d.ts.map +0 -1
  424. package/dist/__tests__/gpu-scene-render-graph.browser.test.d.ts +0 -2
  425. package/dist/__tests__/gpu-scene-render-graph.browser.test.d.ts.map +0 -1
  426. package/dist/__tests__/gpu-scene-render-graph.dawn.test.d.ts +0 -2
  427. package/dist/__tests__/gpu-scene-render-graph.dawn.test.d.ts.map +0 -1
  428. package/dist/__tests__/gpu-scene-schema.unit.test.d.ts +0 -2
  429. package/dist/__tests__/gpu-scene-schema.unit.test.d.ts.map +0 -1
  430. package/dist/__tests__/gpu-scene.dawn.test.d.ts +0 -2
  431. package/dist/__tests__/gpu-scene.dawn.test.d.ts.map +0 -1
  432. package/dist/__tests__/gpu-scene.unit.test.d.ts +0 -2
  433. package/dist/__tests__/gpu-scene.unit.test.d.ts.map +0 -1
  434. package/dist/__tests__/ibl/face-uniforms.unit.test.d.ts +0 -2
  435. package/dist/__tests__/ibl/face-uniforms.unit.test.d.ts.map +0 -1
  436. package/dist/__tests__/infinite-grid-no-vertex-probe.unit.test.d.ts +0 -2
  437. package/dist/__tests__/infinite-grid-no-vertex-probe.unit.test.d.ts.map +0 -1
  438. package/dist/__tests__/injection-kind-owner.test-d.d.ts +0 -2
  439. package/dist/__tests__/injection-kind-owner.test-d.d.ts.map +0 -1
  440. package/dist/__tests__/ktx2-basis-gpu-consumer.dawn.test.d.ts +0 -2
  441. package/dist/__tests__/ktx2-basis-gpu-consumer.dawn.test.d.ts.map +0 -1
  442. package/dist/__tests__/light-buffer-layout.unit.test.d.ts +0 -2
  443. package/dist/__tests__/light-buffer-layout.unit.test.d.ts.map +0 -1
  444. package/dist/__tests__/material-contract-inventory.unit.test.d.ts +0 -2
  445. package/dist/__tests__/material-contract-inventory.unit.test.d.ts.map +0 -1
  446. package/dist/__tests__/material-cooked-projection.unit.test.d.ts +0 -2
  447. package/dist/__tests__/material-cooked-projection.unit.test.d.ts.map +0 -1
  448. package/dist/__tests__/material-snapshot-mutation.integration.test.d.ts +0 -2
  449. package/dist/__tests__/material-snapshot-mutation.integration.test.d.ts.map +0 -1
  450. package/dist/__tests__/material-static-dynamic-route.unit.test.d.ts +0 -2
  451. package/dist/__tests__/material-static-dynamic-route.unit.test.d.ts.map +0 -1
  452. package/dist/__tests__/material-stride-surface.unit.test.d.ts +0 -2
  453. package/dist/__tests__/material-stride-surface.unit.test.d.ts.map +0 -1
  454. package/dist/__tests__/mesh-buffer-usage-surface.unit.test.d.ts +0 -2
  455. package/dist/__tests__/mesh-buffer-usage-surface.unit.test.d.ts.map +0 -1
  456. package/dist/__tests__/mesh-material-bindings.unit.test.d.ts +0 -2
  457. package/dist/__tests__/mesh-material-bindings.unit.test.d.ts.map +0 -1
  458. package/dist/__tests__/mesh-stride-surface.unit.test.d.ts +0 -2
  459. package/dist/__tests__/mesh-stride-surface.unit.test.d.ts.map +0 -1
  460. package/dist/__tests__/morph-culling-reentry.dawn.test.d.ts +0 -2
  461. package/dist/__tests__/morph-culling-reentry.dawn.test.d.ts.map +0 -1
  462. package/dist/__tests__/morph-feature-gpu-work.integration.test.d.ts +0 -2
  463. package/dist/__tests__/morph-feature-gpu-work.integration.test.d.ts.map +0 -1
  464. package/dist/__tests__/morph-feature-plan.unit.test.d.ts +0 -2
  465. package/dist/__tests__/morph-feature-plan.unit.test.d.ts.map +0 -1
  466. package/dist/__tests__/morph-visual-evidence.integration.test.d.ts +0 -2
  467. package/dist/__tests__/morph-visual-evidence.integration.test.d.ts.map +0 -1
  468. package/dist/__tests__/nineslice-handle-surface.unit.test.d.ts +0 -2
  469. package/dist/__tests__/nineslice-handle-surface.unit.test.d.ts.map +0 -1
  470. package/dist/__tests__/post-process-error-policy-owner.unit.test.d.ts +0 -2
  471. package/dist/__tests__/post-process-error-policy-owner.unit.test.d.ts.map +0 -1
  472. package/dist/__tests__/prepared-buffer-kind-owner.test-d.d.ts +0 -2
  473. package/dist/__tests__/prepared-buffer-kind-owner.test-d.d.ts.map +0 -1
  474. package/dist/__tests__/prepared-graphics-capability.unit.test.d.ts +0 -2
  475. package/dist/__tests__/prepared-graphics-capability.unit.test.d.ts.map +0 -1
  476. package/dist/__tests__/prepared-graphics-generation.unit.test.d.ts +0 -2
  477. package/dist/__tests__/prepared-graphics-generation.unit.test.d.ts.map +0 -1
  478. package/dist/__tests__/prepared-graphics-lifecycle.unit.test.d.ts +0 -2
  479. package/dist/__tests__/prepared-graphics-lifecycle.unit.test.d.ts.map +0 -1
  480. package/dist/__tests__/prepared-graphics-pipeline-warmup.unit.test.d.ts +0 -2
  481. package/dist/__tests__/prepared-graphics-pipeline-warmup.unit.test.d.ts.map +0 -1
  482. package/dist/__tests__/prepared-graphics-resolver.unit.test.d.ts +0 -2
  483. package/dist/__tests__/prepared-graphics-resolver.unit.test.d.ts.map +0 -1
  484. package/dist/__tests__/prepared-graphics-snapshot.unit.test.d.ts +0 -2
  485. package/dist/__tests__/prepared-graphics-snapshot.unit.test.d.ts.map +0 -1
  486. package/dist/__tests__/prepared-graphics-store.unit.test.d.ts +0 -2
  487. package/dist/__tests__/prepared-graphics-store.unit.test.d.ts.map +0 -1
  488. package/dist/__tests__/prepared-graphics-validation.unit.test.d.ts +0 -2
  489. package/dist/__tests__/prepared-graphics-validation.unit.test.d.ts.map +0 -1
  490. package/dist/__tests__/profiler-default-off.test.d.ts +0 -2
  491. package/dist/__tests__/profiler-default-off.test.d.ts.map +0 -1
  492. package/dist/__tests__/profiler-phase-catalog.test.d.ts +0 -2
  493. package/dist/__tests__/profiler-phase-catalog.test.d.ts.map +0 -1
  494. package/dist/__tests__/profiler-phase-integration.test.d.ts +0 -2
  495. package/dist/__tests__/profiler-phase-integration.test.d.ts.map +0 -1
  496. package/dist/__tests__/profiler-phase-token.test.d.ts +0 -2
  497. package/dist/__tests__/profiler-phase-token.test.d.ts.map +0 -1
  498. package/dist/__tests__/public-surface.test-d.d.ts +0 -2
  499. package/dist/__tests__/public-surface.test-d.d.ts.map +0 -1
  500. package/dist/__tests__/recover-error-policy-owner.unit.test.d.ts +0 -2
  501. package/dist/__tests__/recover-error-policy-owner.unit.test.d.ts.map +0 -1
  502. package/dist/__tests__/render-error-code-owner.test-d.d.ts +0 -2
  503. package/dist/__tests__/render-error-code-owner.test-d.d.ts.map +0 -1
  504. package/dist/__tests__/render-error-detail-ssot.test-d.d.ts +0 -2
  505. package/dist/__tests__/render-error-detail-ssot.test-d.d.ts.map +0 -1
  506. package/dist/__tests__/render-error-exhaustive.test-d.d.ts +0 -2
  507. package/dist/__tests__/render-error-exhaustive.test-d.d.ts.map +0 -1
  508. package/dist/__tests__/render-feature-assembly.test-d.d.ts +0 -2
  509. package/dist/__tests__/render-feature-assembly.test-d.d.ts.map +0 -1
  510. package/dist/__tests__/render-feature-context.test-d.d.ts +0 -2
  511. package/dist/__tests__/render-feature-context.test-d.d.ts.map +0 -1
  512. package/dist/__tests__/render-feature-contract.test-d.d.ts +0 -2
  513. package/dist/__tests__/render-feature-contract.test-d.d.ts.map +0 -1
  514. package/dist/__tests__/render-feature-diagnostics.unit.test.d.ts +0 -2
  515. package/dist/__tests__/render-feature-diagnostics.unit.test.d.ts.map +0 -1
  516. package/dist/__tests__/render-feature-docs.unit.test.d.ts +0 -2
  517. package/dist/__tests__/render-feature-docs.unit.test.d.ts.map +0 -1
  518. package/dist/__tests__/render-feature-errors.unit.test.d.ts +0 -2
  519. package/dist/__tests__/render-feature-errors.unit.test.d.ts.map +0 -1
  520. package/dist/__tests__/render-feature-gpu-work.integration.test.d.ts +0 -2
  521. package/dist/__tests__/render-feature-gpu-work.integration.test.d.ts.map +0 -1
  522. package/dist/__tests__/render-feature-plan.test-d.d.ts +0 -2
  523. package/dist/__tests__/render-feature-plan.test-d.d.ts.map +0 -1
  524. package/dist/__tests__/render-feature-plan.unit.test.d.ts +0 -2
  525. package/dist/__tests__/render-feature-plan.unit.test.d.ts.map +0 -1
  526. package/dist/__tests__/render-feature-prepared-diagnostics.unit.test.d.ts +0 -2
  527. package/dist/__tests__/render-feature-prepared-diagnostics.unit.test.d.ts.map +0 -1
  528. package/dist/__tests__/render-feature-prepared-errors.test-d.d.ts +0 -2
  529. package/dist/__tests__/render-feature-prepared-errors.test-d.d.ts.map +0 -1
  530. package/dist/__tests__/render-feature-prepared-graphics-docs.unit.test.d.ts +0 -2
  531. package/dist/__tests__/render-feature-prepared-graphics-docs.unit.test.d.ts.map +0 -1
  532. package/dist/__tests__/render-feature-prepared-graphics-isolation.unit.test.d.ts +0 -2
  533. package/dist/__tests__/render-feature-prepared-graphics-isolation.unit.test.d.ts.map +0 -1
  534. package/dist/__tests__/render-feature-prepared-graphics-negative.test-d.d.ts +0 -2
  535. package/dist/__tests__/render-feature-prepared-graphics-negative.test-d.d.ts.map +0 -1
  536. package/dist/__tests__/render-feature-prepared-graphics.test-d.d.ts +0 -2
  537. package/dist/__tests__/render-feature-prepared-graphics.test-d.d.ts.map +0 -1
  538. package/dist/__tests__/render-feature-prepared-graphics.unit.test.d.ts +0 -2
  539. package/dist/__tests__/render-feature-prepared-graphics.unit.test.d.ts.map +0 -1
  540. package/dist/__tests__/render-feature-public-surface.test-d.d.ts +0 -2
  541. package/dist/__tests__/render-feature-public-surface.test-d.d.ts.map +0 -1
  542. package/dist/__tests__/render-feature-retry.unit.test.d.ts +0 -2
  543. package/dist/__tests__/render-feature-retry.unit.test.d.ts.map +0 -1
  544. package/dist/__tests__/render-feature-scheduling.unit.test.d.ts +0 -2
  545. package/dist/__tests__/render-feature-scheduling.unit.test.d.ts.map +0 -1
  546. package/dist/__tests__/render-feature-stage-failed-policy-owner.unit.test.d.ts +0 -2
  547. package/dist/__tests__/render-feature-stage-failed-policy-owner.unit.test.d.ts.map +0 -1
  548. package/dist/__tests__/render-feature-stage-fault-recovery.unit.test.d.ts +0 -2
  549. package/dist/__tests__/render-feature-stage-fault-recovery.unit.test.d.ts.map +0 -1
  550. package/dist/__tests__/render-feature-visibility-context.test-d.d.ts +0 -2
  551. package/dist/__tests__/render-feature-visibility-context.test-d.d.ts.map +0 -1
  552. package/dist/__tests__/render-feature-visibility-context.unit.test.d.ts +0 -2
  553. package/dist/__tests__/render-feature-visibility-context.unit.test.d.ts.map +0 -1
  554. package/dist/__tests__/render-feature-zero-work.unit.test.d.ts +0 -2
  555. package/dist/__tests__/render-feature-zero-work.unit.test.d.ts.map +0 -1
  556. package/dist/__tests__/render-graph-compute-raster-gpu.d.ts +0 -7
  557. package/dist/__tests__/render-graph-compute-raster-gpu.d.ts.map +0 -1
  558. package/dist/__tests__/render-graph-compute-raster.browser.test.d.ts +0 -2
  559. package/dist/__tests__/render-graph-compute-raster.browser.test.d.ts.map +0 -1
  560. package/dist/__tests__/render-graph-compute-raster.dawn.test.d.ts +0 -2
  561. package/dist/__tests__/render-graph-compute-raster.dawn.test.d.ts.map +0 -1
  562. package/dist/__tests__/render-graph-hzb-gpu.d.ts +0 -7
  563. package/dist/__tests__/render-graph-hzb-gpu.d.ts.map +0 -1
  564. package/dist/__tests__/render-graph-hzb.browser.test.d.ts +0 -2
  565. package/dist/__tests__/render-graph-hzb.browser.test.d.ts.map +0 -1
  566. package/dist/__tests__/render-graph-hzb.dawn.test.d.ts +0 -2
  567. package/dist/__tests__/render-graph-hzb.dawn.test.d.ts.map +0 -1
  568. package/dist/__tests__/render-graph-primitives.unit.test.d.ts +0 -2
  569. package/dist/__tests__/render-graph-primitives.unit.test.d.ts.map +0 -1
  570. package/dist/__tests__/render-graph-storage-indirect-gpu.d.ts +0 -12
  571. package/dist/__tests__/render-graph-storage-indirect-gpu.d.ts.map +0 -1
  572. package/dist/__tests__/render-graph-storage-indirect.browser.test.d.ts +0 -2
  573. package/dist/__tests__/render-graph-storage-indirect.browser.test.d.ts.map +0 -1
  574. package/dist/__tests__/render-graph-storage-indirect.dawn.test.d.ts +0 -2
  575. package/dist/__tests__/render-graph-storage-indirect.dawn.test.d.ts.map +0 -1
  576. package/dist/__tests__/render-scene-projection.unit.test.d.ts +0 -2
  577. package/dist/__tests__/render-scene-projection.unit.test.d.ts.map +0 -1
  578. package/dist/__tests__/renderer-factory-material-contract.unit.test.d.ts +0 -2
  579. package/dist/__tests__/renderer-factory-material-contract.unit.test.d.ts.map +0 -1
  580. package/dist/__tests__/renderer-lifecycle.integration.test.d.ts +0 -2
  581. package/dist/__tests__/renderer-lifecycle.integration.test.d.ts.map +0 -1
  582. package/dist/__tests__/rhi-backend-package-boundary.unit.test.d.ts +0 -2
  583. package/dist/__tests__/rhi-backend-package-boundary.unit.test.d.ts.map +0 -1
  584. package/dist/__tests__/scriptable-pack-consumer.test-d.d.ts +0 -2
  585. package/dist/__tests__/scriptable-pack-consumer.test-d.d.ts.map +0 -1
  586. package/dist/__tests__/shader-stage-surface.unit.test.d.ts +0 -2
  587. package/dist/__tests__/shader-stage-surface.unit.test.d.ts.map +0 -1
  588. package/dist/__tests__/ssao-config.unit.test.d.ts +0 -2
  589. package/dist/__tests__/ssao-config.unit.test.d.ts.map +0 -1
  590. package/dist/__tests__/ssao-kernel-surface.unit.test.d.ts +0 -2
  591. package/dist/__tests__/ssao-kernel-surface.unit.test.d.ts.map +0 -1
  592. package/dist/__tests__/standard-clustered-pipeline.unit.test.d.ts +0 -2
  593. package/dist/__tests__/standard-clustered-pipeline.unit.test.d.ts.map +0 -1
  594. package/dist/__tests__/standard-descriptors.test-d.d.ts +0 -2
  595. package/dist/__tests__/standard-descriptors.test-d.d.ts.map +0 -1
  596. package/dist/__tests__/standard-pipeline.dawn.test.d.ts +0 -2
  597. package/dist/__tests__/standard-pipeline.dawn.test.d.ts.map +0 -1
  598. package/dist/__tests__/standard-pipeline.integration.test.d.ts +0 -2
  599. package/dist/__tests__/standard-pipeline.integration.test.d.ts.map +0 -1
  600. package/dist/__tests__/standard-profile-oracle.unit.test.d.ts +0 -2
  601. package/dist/__tests__/standard-profile-oracle.unit.test.d.ts.map +0 -1
  602. package/dist/__tests__/surface-configuration.unit.test.d.ts +0 -2
  603. package/dist/__tests__/surface-configuration.unit.test.d.ts.map +0 -1
  604. package/dist/__tests__/texture-usage-surface.unit.test.d.ts +0 -2
  605. package/dist/__tests__/texture-usage-surface.unit.test.d.ts.map +0 -1
  606. package/dist/__tests__/typed-pipeline-topology.unit.test.d.ts +0 -2
  607. package/dist/__tests__/typed-pipeline-topology.unit.test.d.ts.map +0 -1
  608. package/dist/__tests__/urp-pipeline-targets.unit.test.d.ts +0 -2
  609. package/dist/__tests__/urp-pipeline-targets.unit.test.d.ts.map +0 -1
  610. package/dist/__tests__/urp-pipeline.unit.test.d.ts +0 -2
  611. package/dist/__tests__/urp-pipeline.unit.test.d.ts.map +0 -1
  612. package/dist/__tests__/vertex-color-pipeline.unit.test.d.ts +0 -2
  613. package/dist/__tests__/vertex-color-pipeline.unit.test.d.ts.map +0 -1
  614. package/dist/__tests__/vertex-layout-consumer.unit.test.d.ts +0 -2
  615. package/dist/__tests__/vertex-layout-consumer.unit.test.d.ts.map +0 -1
  616. package/dist/__tests__/visibility-diagnostics.integration.test.d.ts +0 -2
  617. package/dist/__tests__/visibility-diagnostics.integration.test.d.ts.map +0 -1
  618. package/dist/__tests__/visibility-extract.integration.test.d.ts +0 -2
  619. package/dist/__tests__/visibility-extract.integration.test.d.ts.map +0 -1
  620. package/dist/__tests__/visibility-extract.perf.test.d.ts +0 -2
  621. package/dist/__tests__/visibility-extract.perf.test.d.ts.map +0 -1
  622. package/dist/__tests__/visibility-feature-dedup.integration.test.d.ts +0 -2
  623. package/dist/__tests__/visibility-feature-dedup.integration.test.d.ts.map +0 -1
  624. package/dist/__tests__/visibility-hidden-report.unit.test.d.ts +0 -2
  625. package/dist/__tests__/visibility-hidden-report.unit.test.d.ts.map +0 -1
  626. package/dist/__tests__/visibility-instances.integration.test.d.ts +0 -2
  627. package/dist/__tests__/visibility-instances.integration.test.d.ts.map +0 -1
  628. package/dist/__tests__/visibility-multi-world.integration.test.d.ts +0 -2
  629. package/dist/__tests__/visibility-multi-world.integration.test.d.ts.map +0 -1
  630. package/dist/__tests__/visibility-producer-matrix.integration.test.d.ts +0 -2
  631. package/dist/__tests__/visibility-producer-matrix.integration.test.d.ts.map +0 -1
  632. package/dist/__tests__/visibility-producer-matrix.unit.test.d.ts +0 -2
  633. package/dist/__tests__/visibility-producer-matrix.unit.test.d.ts.map +0 -1
  634. package/dist/__tests__/visibility-public-surface.test-d.d.ts +0 -2
  635. package/dist/__tests__/visibility-public-surface.test-d.d.ts.map +0 -1
  636. package/dist/__tests__/visibility-resolver.unit.test.d.ts +0 -2
  637. package/dist/__tests__/visibility-resolver.unit.test.d.ts.map +0 -1
  638. package/dist/__tests__/visibility-resource-short-circuit.unit.test.d.ts +0 -2
  639. package/dist/__tests__/visibility-resource-short-circuit.unit.test.d.ts.map +0 -1
  640. package/dist/__tests__/visibility-snapshot-contract.unit.test.d.ts +0 -2
  641. package/dist/__tests__/visibility-snapshot-contract.unit.test.d.ts.map +0 -1
  642. package/dist/__tests__/vocabulary.unit.test.d.ts +0 -2
  643. package/dist/__tests__/vocabulary.unit.test.d.ts.map +0 -1
  644. package/dist/chunk-CQXZC5XI.mjs.map +0 -1
  645. package/dist/chunk-HCOGPHKS.mjs +0 -93
  646. package/dist/chunk-HCOGPHKS.mjs.map +0 -1
  647. package/dist/chunk-YEJIUW7D.mjs.map +0 -1
  648. package/dist/components/__tests__/points-lines-admission.unit.test.d.ts +0 -2
  649. package/dist/components/__tests__/points-lines-admission.unit.test.d.ts.map +0 -1
  650. package/dist/components/__tests__/points-lines-schema.unit.test.d.ts +0 -2
  651. package/dist/components/__tests__/points-lines-schema.unit.test.d.ts.map +0 -1
  652. package/dist/components/__tests__/schema-contract.unit.test.d.ts +0 -2
  653. package/dist/components/__tests__/schema-contract.unit.test.d.ts.map +0 -1
  654. package/dist/components/__tests__/schema-parity.unit.test.d.ts +0 -2
  655. package/dist/components/__tests__/schema-parity.unit.test.d.ts.map +0 -1
  656. package/dist/components/__tests__/visibility-schema.unit.test.d.ts +0 -2
  657. package/dist/components/__tests__/visibility-schema.unit.test.d.ts.map +0 -1
  658. package/dist/points-lines/__tests__/bounds.unit.test.d.ts +0 -2
  659. package/dist/points-lines/__tests__/bounds.unit.test.d.ts.map +0 -1
  660. package/dist/points-lines/__tests__/cache-recovery.unit.test.d.ts +0 -2
  661. package/dist/points-lines/__tests__/cache-recovery.unit.test.d.ts.map +0 -1
  662. package/dist/points-lines/__tests__/inspection-lanes.integration.test.d.ts +0 -2
  663. package/dist/points-lines/__tests__/inspection-lanes.integration.test.d.ts.map +0 -1
  664. package/dist/points-lines/__tests__/inspection.unit.test.d.ts +0 -2
  665. package/dist/points-lines/__tests__/inspection.unit.test.d.ts.map +0 -1
  666. package/dist/points-lines/__tests__/lane-structural.integration.test.d.ts +0 -2
  667. package/dist/points-lines/__tests__/lane-structural.integration.test.d.ts.map +0 -1
  668. package/dist/points-lines/__tests__/points-lines.bench.d.ts +0 -2
  669. package/dist/points-lines/__tests__/points-lines.bench.d.ts.map +0 -1
  670. package/dist/points-lines/__tests__/raster-lane.integration.test.d.ts +0 -2
  671. package/dist/points-lines/__tests__/raster-lane.integration.test.d.ts.map +0 -1
  672. package/dist/points-lines/__tests__/snapshot.unit.test.d.ts +0 -2
  673. package/dist/points-lines/__tests__/snapshot.unit.test.d.ts.map +0 -1
  674. package/dist/points-lines/__tests__/view-ubo.unit.test.d.ts +0 -2
  675. package/dist/points-lines/__tests__/view-ubo.unit.test.d.ts.map +0 -1
  676. package/dist/record/__tests__/material-bg-cache.unit.test.d.ts +0 -2
  677. package/dist/record/__tests__/material-bg-cache.unit.test.d.ts.map +0 -1
  678. package/dist/record/__tests__/material-slot-plan.unit.test.d.ts +0 -2
  679. package/dist/record/__tests__/material-slot-plan.unit.test.d.ts.map +0 -1
  680. package/dist/record/__tests__/typed-frame-graph-plan.unit.test.d.ts +0 -2
  681. package/dist/record/__tests__/typed-frame-graph-plan.unit.test.d.ts.map +0 -1
  682. package/dist/record/__tests__/video-texture-view.unit.test.d.ts +0 -2
  683. package/dist/record/__tests__/video-texture-view.unit.test.d.ts.map +0 -1
@@ -0,0 +1,125 @@
1
+ import { RenderGraphBuilder } from '@forgeax/engine-render-graph';
2
+ import type { RhiDevice } from '@forgeax/engine-rhi';
3
+ import { rhi } from '@forgeax/engine-rhi-null';
4
+ import { ok } from '@forgeax/engine-types';
5
+ import { beforeAll, describe, expect, it } from 'vitest';
6
+ import { DeviceScope, LifecycleTransaction } from '../device/device-scope';
7
+ import { standardPipeline } from '../pipeline/standard-pipeline';
8
+ import { DEFAULT_STANDARD_PROFILE, STANDARD_PIPELINE_ID } from '../pipeline/standard-profile';
9
+ import type { RenderPipelineFrame, RenderPipelineTopology } from '../render-pipeline';
10
+
11
+ let device: RhiDevice;
12
+
13
+ beforeAll(async () => {
14
+ const adapter = await rhi.requestAdapter();
15
+ if (!adapter.ok) throw adapter.error;
16
+ const result = await adapter.value.requestDevice();
17
+ if (!result.ok) throw result.error;
18
+ device = result.value;
19
+ });
20
+
21
+ function build(bloom: 'off' | 'on', lighting: 'direct' | 'clustered') {
22
+ const topology: RenderPipelineTopology = {
23
+ pipelineId: STANDARD_PIPELINE_ID,
24
+ standardProfile: { ...DEFAULT_STANDARD_PROFILE, lighting },
25
+ config: lighting === 'clustered' ? { ssao: { enabled: false } } : undefined,
26
+ surface: {
27
+ width: 320,
28
+ height: 180,
29
+ storageFormat: 'bgra8unorm',
30
+ viewFormat: 'bgra8unorm-srgb',
31
+ },
32
+ camera: { tonemap: 'aces-filmic', antialias: 'fxaa', bloom },
33
+ shadow: {
34
+ mapSize: 64,
35
+ cascadeCount: 1,
36
+ pointCount: 0,
37
+ pointFaceSize: 64,
38
+ spotCount: 0,
39
+ },
40
+ lane: {
41
+ compute: lighting === 'clustered',
42
+ storageBuffer: lighting === 'clustered',
43
+ multisample: false,
44
+ maxColorAttachments: 8,
45
+ },
46
+ featureTopologySignature: 'none',
47
+ gpuDrivenTopologySignature: '',
48
+ };
49
+ const graph = new RenderGraphBuilder<RenderPipelineFrame>();
50
+ const built = standardPipeline.build(
51
+ {
52
+ graph,
53
+ projectGpuDriven: () => ok(undefined),
54
+ contributeFeatures: () => ok(undefined),
55
+ },
56
+ topology,
57
+ );
58
+ if (!built.ok) throw built.error;
59
+ const compiled = graph.compile({ device, surfaceSize: { width: 320, height: 180 } });
60
+ if (!compiled.ok) throw compiled.error;
61
+ return compiled.value.inspect();
62
+ }
63
+
64
+ function bloomSummary(info: ReturnType<typeof build>) {
65
+ return {
66
+ passes: info.passes.filter((pass) => pass.name.startsWith('bloom-')).map((pass) => pass.name),
67
+ resources: info.resources
68
+ .filter((resource) => resource.label.startsWith('bloom-'))
69
+ .map((resource) => resource.label),
70
+ };
71
+ }
72
+
73
+ describe('Standard Bloom lifecycle contract', () => {
74
+ it.each(['direct', 'clustered'] as const)('supports on -> off -> on for %s', (lighting) => {
75
+ const on = bloomSummary(build('on', lighting));
76
+ const off = bloomSummary(build('off', lighting));
77
+ const recovered = bloomSummary(build('on', lighting));
78
+ expect(on.passes).toHaveLength(4);
79
+ expect(on.resources.length).toBeGreaterThan(0);
80
+ expect(off).toEqual({ passes: [], resources: [] });
81
+ expect(recovered).toEqual(on);
82
+ });
83
+
84
+ it('keeps post order scene -> Bloom -> output transform -> FXAA -> debug', () => {
85
+ const names = build('on', 'clustered').passes.map((pass) => pass.name);
86
+ const order = [
87
+ 'forward',
88
+ 'bloom-bright',
89
+ 'bloom-composite',
90
+ 'output-transform',
91
+ 'fxaa',
92
+ 'debug-overlay',
93
+ ];
94
+ for (let index = 1; index < order.length; index += 1) {
95
+ expect(names.indexOf(order[index] ?? '')).toBeGreaterThan(
96
+ names.indexOf(order[index - 1] ?? ''),
97
+ );
98
+ }
99
+ });
100
+
101
+ it('owns a Bloom transient lease in a child DeviceScope and retires it', async () => {
102
+ const renderer = DeviceScope.create(71, 'renderer');
103
+ const bloom = renderer.createChild('standard-bloom');
104
+ const transaction = new LifecycleTransaction(bloom);
105
+ transaction.add({
106
+ kind: 'texture',
107
+ create: () => ({ label: 'bloom-bright' }),
108
+ cleanup: () => undefined,
109
+ });
110
+ const committed = await transaction.commit();
111
+ expect(committed.ok).toBe(true);
112
+ expect(renderer.resourceDelta()).toBe(0);
113
+ expect(bloom.resourceDelta()).toBe(1);
114
+ bloom.retire();
115
+ expect(bloom.state).toBe('retired');
116
+ expect(bloom.resourceDelta()).toBe(0);
117
+ });
118
+
119
+ it('FALSIFY rejects an injected Bloom contribution on the off path', () => {
120
+ const off = bloomSummary(build('off', 'direct'));
121
+ const injected = { ...off, passes: ['bloom-falsified'] };
122
+ expect(injected).not.toEqual({ passes: [], resources: [] });
123
+ expect(off).toEqual({ passes: [], resources: [] });
124
+ });
125
+ });
@@ -1,5 +1,6 @@
1
1
  import * as render from '@forgeax/engine-render';
2
2
  import {
3
+ type EngineEnvironmentError,
3
4
  constructRendererHost as internalConstructRendererHost,
4
5
  type RendererHostAssembly,
5
6
  } from '@forgeax/engine-render/internal/construct-renderer';
@@ -15,9 +16,9 @@ describe('construct-renderer internal entry', () => {
15
16
 
16
17
  it('freezes the only construct seam as a structured Result factory', () => {
17
18
  type Return = ReturnType<typeof internalConstructRendererHost>;
18
- type Expected = Promise<RenderResult<RendererHostAssembly, RenderError>>;
19
- // This assertion is intentionally red until construction stops rejecting
20
- // and returns the narrow Result contract.
19
+ type Expected = Promise<
20
+ RenderResult<RendererHostAssembly, RenderError | EngineEnvironmentError>
21
+ >;
21
22
  expect(null as unknown as Return satisfies Expected).toBeNull();
22
23
  });
23
24
  });
@@ -0,0 +1,177 @@
1
+ import { World } from '@forgeax/engine-ecs';
2
+ import { rhi } from '@forgeax/engine-rhi-null';
3
+ import { registerPropagateTransforms, Transform } from '@forgeax/engine-scene';
4
+ import { describe, expect, it } from 'vitest';
5
+ import { createRenderer } from '../assembly/factory';
6
+ import {
7
+ ANTIALIAS_FXAA,
8
+ ANTIALIAS_MSAA,
9
+ ANTIALIAS_NONE,
10
+ ANTIALIAS_TAA,
11
+ Camera,
12
+ } from '../components/camera';
13
+ import { DeviceScope } from '../device/device-scope';
14
+ import { renderLifecycleManifestUrl } from './shader-manifest-fixture';
15
+
16
+ function expectDetached(value: unknown, seen = new Set<unknown>()): void {
17
+ if (value === null || typeof value !== 'object' || seen.has(value)) return;
18
+ seen.add(value);
19
+ expect(value).not.toBeInstanceOf(Error);
20
+ expect(value).not.toBeInstanceOf(Map);
21
+ expect(value).not.toBeInstanceOf(Set);
22
+ expect(ArrayBuffer.isView(value)).toBe(false);
23
+ const prototype = Object.getPrototypeOf(value);
24
+ if (prototype !== Object.prototype && prototype !== null && !Array.isArray(value)) {
25
+ throw new Error('detached inspection contains a live class instance');
26
+ }
27
+ for (const child of Object.values(value)) expectDetached(child, seen);
28
+ }
29
+
30
+ describe('detached renderer inspection', () => {
31
+ it('exposes JSON-safe exact-zero cold state', async () => {
32
+ const renderer = await createRenderer(
33
+ { width: 64, height: 64, getContext: () => null },
34
+ { rhi },
35
+ {
36
+ shaderManifestUrl: `data:application/json,${encodeURIComponent(JSON.stringify({ entries: [] }))}`,
37
+ },
38
+ );
39
+ const inspection = renderer.inspect();
40
+ expect(inspection.environment.status).toBe('empty');
41
+ expect(inspection.temporal.mode).toBe('none');
42
+ expect(inspection.bloom).toMatchObject({
43
+ graphStatus: 'empty',
44
+ enabled: false,
45
+ targetCount: 0,
46
+ resourceCount: 0,
47
+ passCount: 0,
48
+ encodeCount: 0,
49
+ bindGroupCount: 0,
50
+ uploadCount: 0,
51
+ residentChildBytes: 0,
52
+ });
53
+ expect(() => JSON.parse(JSON.stringify(inspection))).not.toThrow();
54
+ expectDetached(inspection);
55
+ expect(Object.isFrozen(inspection.environment)).toBe(true);
56
+ expect(Object.isFrozen(inspection.temporal.coverage)).toBe(true);
57
+ expect(() => expectDetached(DeviceScope.create(401, 'live-scope'))).toThrow(
58
+ 'live class instance',
59
+ );
60
+ expect((await renderer.dispose()).ok).toBe(true);
61
+ });
62
+
63
+ it('projects a successful TAA frame into detached PODs', async () => {
64
+ const renderer = await createRenderer(
65
+ { width: 64, height: 64, getContext: () => null },
66
+ { rhi },
67
+ { shaderManifestUrl: renderLifecycleManifestUrl() },
68
+ );
69
+ expect((await renderer.initialization).ok).toBe(true);
70
+ const world = new World();
71
+ const attached = renderer.attach(world);
72
+ expect(attached.ok).toBe(true);
73
+ if (!attached.ok) return;
74
+ registerPropagateTransforms(world);
75
+ const camera = world
76
+ .spawn(
77
+ { component: Transform, data: { pos: [0, 0, 4] } },
78
+ {
79
+ component: Camera,
80
+ data: { fov: 1, aspect: 1, near: 0.1, far: 100, antialias: ANTIALIAS_TAA },
81
+ },
82
+ )
83
+ .unwrap();
84
+ expect(world.update().ok).toBe(true);
85
+ const frameInput = () => ({
86
+ leases: [attached.value],
87
+ camera: { lease: attached.value },
88
+ environment: { lease: attached.value },
89
+ });
90
+ let frame = renderer.draw(frameInput());
91
+ if (!frame.ok) {
92
+ await Promise.resolve();
93
+ frame = renderer.draw(frameInput());
94
+ }
95
+ expect(frame.ok).toBe(true);
96
+ const inspection = renderer.inspect();
97
+ expect(inspection.environment.status).toBe('active');
98
+ expect(inspection.environment.activeSignature).toBeDefined();
99
+ expect(inspection.temporal.mode).toBe('taa');
100
+ expect(inspection.temporal.resources.active).toBeGreaterThan(0);
101
+ expect(inspection.temporal.resources.candidate).toBe(0);
102
+ expect(inspection.temporalTarget).toMatchObject({
103
+ identity: 'standard-scene-temporal',
104
+ producerId: 'forgeax::standard::scene-data',
105
+ schema: 'forgeax::scene-data::temporal-v1',
106
+ targetCount: 1,
107
+ descriptor: {
108
+ format: 'rgba16float',
109
+ width: 64,
110
+ height: 64,
111
+ sampleCount: 1,
112
+ bytes: 64 * 64 * 8,
113
+ },
114
+ });
115
+ const serialized = JSON.parse(JSON.stringify(inspection));
116
+ expect(serialized.temporal.viewIdentity).toBe(inspection.temporal.viewIdentity);
117
+ expectDetached(inspection);
118
+ const originalWidth = inspection.temporal.coverage.width;
119
+ try {
120
+ (inspection.temporal.coverage as { width: number }).width = originalWidth + 1;
121
+ } catch {
122
+ // Frozen detached snapshots reject mutation in strict callers.
123
+ }
124
+ expect(renderer.inspect().temporal.coverage.width).toBe(originalWidth);
125
+ const nestedBefore = renderer.inspect();
126
+ for (const subtree of [
127
+ nestedBefore.environment.active,
128
+ nestedBefore.environment.lkg,
129
+ nestedBefore.environment.lastCandidateFailure?.detail,
130
+ nestedBefore.temporal.resources,
131
+ nestedBefore.temporal.coverage,
132
+ nestedBefore.bloom,
133
+ ]) {
134
+ if (subtree !== undefined) expect(Object.isFrozen(subtree)).toBe(true);
135
+ }
136
+ const detachedBefore = JSON.parse(JSON.stringify(nestedBefore));
137
+ for (const subtree of [
138
+ nestedBefore.environment.active,
139
+ nestedBefore.environment.lkg,
140
+ nestedBefore.environment.lastCandidateFailure?.detail,
141
+ nestedBefore.temporal,
142
+ nestedBefore.temporal.resources,
143
+ nestedBefore.temporal.coverage,
144
+ nestedBefore.bloom,
145
+ ]) {
146
+ if (subtree === undefined) continue;
147
+ try {
148
+ (subtree as Record<string, unknown>).generation = -1;
149
+ (subtree as Record<string, unknown>).detail = { injected: true };
150
+ } catch {
151
+ // Frozen snapshots reject mutation; callers still get detached values.
152
+ }
153
+ }
154
+ expect(JSON.parse(JSON.stringify(renderer.inspect()))).toEqual(detachedBefore);
155
+ world.set(camera, Camera, { antialias: ANTIALIAS_NONE }).unwrap();
156
+ expect(world.update().ok).toBe(true);
157
+ expect(renderer.draw(frameInput()).ok).toBe(true);
158
+ await Promise.resolve();
159
+ await Promise.resolve();
160
+ expect(renderer.inspect().temporal.mode).toBe('none');
161
+ for (const antialias of [ANTIALIAS_FXAA, ANTIALIAS_MSAA]) {
162
+ world.set(camera, Camera, { antialias }).unwrap();
163
+ expect(world.update().ok).toBe(true);
164
+ expect(renderer.draw(frameInput()).ok).toBe(true);
165
+ expect(renderer.inspect().temporal.mode).toBe(antialias === ANTIALIAS_FXAA ? 'fxaa' : 'msaa');
166
+ expect(renderer.inspect().temporal.resources).toEqual({
167
+ active: 0,
168
+ candidate: 0,
169
+ retiring: 0,
170
+ activeBytes: 0,
171
+ candidateBytes: 0,
172
+ retiringBytes: 0,
173
+ });
174
+ }
175
+ await renderer.dispose();
176
+ });
177
+ });
@@ -0,0 +1,219 @@
1
+ import { World } from '@forgeax/engine-ecs';
2
+ import { describe, expect, it } from 'vitest';
3
+ import { Atmosphere } from '../components/atmosphere';
4
+ import { DirectionalLight } from '../components/directional-light';
5
+ import { Fog } from '../components/fog';
6
+ import { DeviceScope } from '../device/device-scope';
7
+ import { selectEnvironment } from '../environment/frame';
8
+ import { EnvironmentLifecycle } from '../environment/lifecycle';
9
+ import { extractFrames } from '../render-system-extract';
10
+
11
+ const frame = selectEnvironment({
12
+ environments: [
13
+ {
14
+ kind: 'atmosphere',
15
+ entityKey: 7,
16
+ sourceKey: 'sky-stable',
17
+ atmosphere: {
18
+ turbidity: 2,
19
+ rayleigh: 1,
20
+ mieCoefficient: 0.005,
21
+ mieDirectionalG: 0.8,
22
+ sunAngularRadius: 0.004675,
23
+ },
24
+ },
25
+ ],
26
+ fogs: [
27
+ {
28
+ entityKey: 8,
29
+ color: [0.2, 0.3, 0.4],
30
+ density: 0.03,
31
+ heightFalloff: 0.2,
32
+ maxOpacity: 0.9,
33
+ },
34
+ ],
35
+ suns: [{ entityKey: 9, direction: [0, -1, 0], color: [1, 1, 1], intensity: 2 }],
36
+ lane: 'direct',
37
+ });
38
+
39
+ describe('Environment and Fog lane graph contract', () => {
40
+ it('extracts all Atmosphere parameters and normalized Sun facts from ECS rows', () => {
41
+ const world = new World();
42
+ world
43
+ .spawn({
44
+ component: Atmosphere,
45
+ data: {
46
+ turbidity: 3,
47
+ rayleigh: 1.2,
48
+ mieCoefficient: 0.006,
49
+ mieDirectionalG: 0.7,
50
+ sunAngularRadius: 0.01,
51
+ },
52
+ })
53
+ .unwrap();
54
+ world
55
+ .spawn({
56
+ component: DirectionalLight,
57
+ data: { direction: [0, -2, 0], intensity: 2 },
58
+ })
59
+ .unwrap();
60
+
61
+ const extracted = extractFrames([world], 0);
62
+ expect(extracted.environment).toBeDefined();
63
+ if (extracted.environment === undefined) throw new Error('expected extracted environment');
64
+ expect(extracted.environment.source.kind).toBe('atmosphere');
65
+ if (extracted.environment.source.kind !== 'atmosphere') {
66
+ throw new Error('expected atmosphere environment source');
67
+ }
68
+ expect(extracted.environment.source.atmosphere?.turbidity).toBeCloseTo(3);
69
+ expect(extracted.environment.source.atmosphere?.rayleigh).toBeCloseTo(1.2);
70
+ expect(extracted.environment.source.atmosphere?.mieCoefficient).toBeCloseTo(0.006);
71
+ expect(extracted.environment.source.atmosphere?.mieDirectionalG).toBeCloseTo(0.7);
72
+ expect(extracted.environment.source.atmosphere?.sunAngularRadius).toBeCloseTo(0.01);
73
+ const signature = JSON.parse(extracted.environment.signature) as {
74
+ environments: [{ atmosphere: Record<string, number> }];
75
+ suns: [{ direction: [number, number, number] }];
76
+ };
77
+ expect(signature.environments[0].atmosphere.turbidity).toBeCloseTo(3);
78
+ expect(signature.environments[0].atmosphere.rayleigh).toBeCloseTo(1.2);
79
+ expect(signature.environments[0].atmosphere.mieCoefficient).toBeCloseTo(0.006);
80
+ expect(signature.environments[0].atmosphere.mieDirectionalG).toBeCloseTo(0.7);
81
+ expect(signature.environments[0].atmosphere.sunAngularRadius).toBeCloseTo(0.01);
82
+ expect(signature.suns[0].direction).toEqual([0, 1, 0]);
83
+ });
84
+
85
+ it('extracts the resource-owner Fog into the frame projection', () => {
86
+ const world = new World();
87
+ const fogEntity = world
88
+ .spawn({
89
+ component: Fog,
90
+ data: {
91
+ color: [0.15, 0.25, 0.35],
92
+ density: 0.04,
93
+ heightFalloff: 0.3,
94
+ maxOpacity: 0.7,
95
+ },
96
+ })
97
+ .unwrap();
98
+
99
+ const first = extractFrames([world], 0);
100
+ expect(first.fog?.entityKey).toBe(fogEntity);
101
+ expect(first.fog?.color[0]).toBeCloseTo(0.15);
102
+ expect(first.fog?.color[1]).toBeCloseTo(0.25);
103
+ expect(first.fog?.color[2]).toBeCloseTo(0.35);
104
+ expect(first.fog?.density).toBeCloseTo(0.04);
105
+ expect(first.fog?.heightFalloff).toBeCloseTo(0.3);
106
+ expect(first.fog?.maxOpacity).toBeCloseTo(0.7);
107
+
108
+ world
109
+ .set(fogEntity, Fog, {
110
+ color: [0.6, 0.5, 0.4],
111
+ density: 0.01,
112
+ heightFalloff: 0,
113
+ maxOpacity: 0.2,
114
+ })
115
+ .unwrap();
116
+ const changed = extractFrames([world], 0);
117
+ expect(changed.fog?.density).toBeCloseTo(0.01);
118
+ expect(changed.fog?.color[0]).toBeCloseTo(0.6);
119
+ expect(changed.fog?.color[1]).toBeCloseTo(0.5);
120
+ expect(changed.fog?.color[2]).toBeCloseTo(0.4);
121
+ });
122
+
123
+ it('uses one signature and generation for direct and clustered consumers', async () => {
124
+ expect(frame.ok).toBe(true);
125
+ if (!frame.ok) return;
126
+ const lifecycle = new EnvironmentLifecycle(DeviceScope.create(3, 'environment-lanes'));
127
+ const direct = await lifecycle.ensure(frame.value, 'direct');
128
+ const clustered = await lifecycle.ensure(frame.value, 'clustered');
129
+ expect(direct.ok).toBe(true);
130
+ expect(clustered.ok).toBe(true);
131
+ if (!direct.ok || !clustered.ok) return;
132
+ expect(clustered.value.generation).toBe(direct.value.generation);
133
+ expect(clustered.value.signature).toBe(direct.value.signature);
134
+ expect(clustered.value.liveHandle).toBe(direct.value.liveHandle);
135
+ });
136
+
137
+ it('keeps failed candidate receipts structured and active/LKG unchanged', async () => {
138
+ expect(frame.ok).toBe(true);
139
+ if (!frame.ok) return;
140
+ const lifecycle = new EnvironmentLifecycle(DeviceScope.create(4, 'environment-recovery'));
141
+ const published = await lifecycle.ensure(frame.value, 'direct');
142
+ expect(published.ok).toBe(true);
143
+ if (!published.ok) return;
144
+ lifecycle.publish(published.value);
145
+ const before = lifecycle.inspect();
146
+ const failed = await lifecycle.ensure(frame.value, { failureAt: 'execute' });
147
+ expect(failed.ok).toBe(false);
148
+ if (failed.ok) return;
149
+ expect(failed.error.code).toBe('environment-generation-failed');
150
+ expect(failed.error.detail).toEqual({ sourceKey: 'sky-stable', stage: 'execute' });
151
+ expect(lifecycle.inspect()).toEqual(before);
152
+ });
153
+
154
+ it('rejects an invalid extracted candidate before lifecycle ensure, then publishes one correction', async () => {
155
+ const world = new World();
156
+ const atmosphereEntity = world
157
+ .spawn({
158
+ component: Atmosphere,
159
+ data: {
160
+ turbidity: 2,
161
+ rayleigh: 1,
162
+ mieCoefficient: 0.005,
163
+ mieDirectionalG: 0.8,
164
+ sunAngularRadius: 0.004675,
165
+ },
166
+ })
167
+ .unwrap();
168
+ world
169
+ .spawn({
170
+ component: DirectionalLight,
171
+ data: { direction: [0, -1, 0], intensity: 1 },
172
+ })
173
+ .unwrap();
174
+ const lifecycle = new EnvironmentLifecycle(DeviceScope.create(5, 'environment-render-path'));
175
+
176
+ const initial = extractFrames([world], 0);
177
+ expect(initial.environmentReady).toBe(true);
178
+ expect(initial.environment).toBeDefined();
179
+ if (initial.environment === undefined) throw new Error('expected initial environment');
180
+ const first = await lifecycle.ensure(initial.environment);
181
+ expect(first.ok).toBe(true);
182
+ if (!first.ok) return;
183
+ lifecycle.publish(first.value);
184
+ const beforeInvalid = lifecycle.inspect();
185
+
186
+ world
187
+ .set(atmosphereEntity, Atmosphere, {
188
+ turbidity: -1,
189
+ rayleigh: 1,
190
+ mieCoefficient: 0.005,
191
+ mieDirectionalG: 0.8,
192
+ sunAngularRadius: 0.004675,
193
+ })
194
+ .unwrap();
195
+ const invalid = extractFrames([world], 0);
196
+ expect(invalid.environmentReady).toBe(false);
197
+ expect(lifecycle.inspect()).toEqual(beforeInvalid);
198
+
199
+ world
200
+ .set(atmosphereEntity, Atmosphere, {
201
+ turbidity: 3,
202
+ rayleigh: 1,
203
+ mieCoefficient: 0.006,
204
+ mieDirectionalG: 0.7,
205
+ sunAngularRadius: 0.01,
206
+ })
207
+ .unwrap();
208
+ const corrected = extractFrames([world], 0);
209
+ expect(corrected.environmentReady).toBe(true);
210
+ expect(corrected.environment).toBeDefined();
211
+ if (corrected.environment === undefined) throw new Error('expected corrected environment');
212
+ const second = await lifecycle.ensure(corrected.environment);
213
+ expect(second.ok).toBe(true);
214
+ if (!second.ok) return;
215
+ expect(second.value.generation).toBeGreaterThan(first.value.generation);
216
+ lifecycle.publish(second.value);
217
+ expect(lifecycle.inspect().activeSignature).toBe(second.value.signature);
218
+ });
219
+ });
@@ -0,0 +1,141 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { DeviceScope } from '../device/device-scope';
3
+ import { selectEnvironment } from '../environment/frame';
4
+ import { EnvironmentLifecycle } from '../environment/lifecycle';
5
+ import type { EnvironmentFrame } from '../extract/environment';
6
+
7
+ function frame(sourceKey: string): EnvironmentFrame {
8
+ const result = selectEnvironment({
9
+ environments: [{ kind: 'image', entityKey: 1, sourceKey }],
10
+ fogs: [],
11
+ suns: [],
12
+ lane: 'direct',
13
+ });
14
+ if (!result.ok) throw result.error;
15
+ return Object.freeze({
16
+ ...result.value,
17
+ resourceDescriptor: Object.freeze({ width: 2, height: 2, bytesPerPixel: 4 }),
18
+ });
19
+ }
20
+
21
+ function emptyFrame(): EnvironmentFrame {
22
+ const result = selectEnvironment({
23
+ environments: [],
24
+ fogs: [],
25
+ suns: [],
26
+ lane: 'direct',
27
+ });
28
+ if (!result.ok) throw result.error;
29
+ return result.value;
30
+ }
31
+
32
+ describe('Environment generation candidate and LKG lifecycle (M2)', () => {
33
+ it.each([
34
+ 'prepare',
35
+ 'build',
36
+ 'execute',
37
+ 'finish',
38
+ 'submit',
39
+ ] as const)('keeps active/LKG unchanged when %s aborts a candidate', async (failureAt) => {
40
+ const lifecycle = new EnvironmentLifecycle(DeviceScope.create(11, 'environment-abort'));
41
+ const initial = await lifecycle.ensure(frame('sky-a'));
42
+ expect(initial.ok).toBe(true);
43
+ if (!initial.ok) return;
44
+ lifecycle.publish(initial.value);
45
+ const before = lifecycle.inspect();
46
+ const failed = await lifecycle.ensure(frame('sky-b'), { failureAt });
47
+ expect(failed.ok).toBe(false);
48
+ expect(lifecycle.inspect()).toEqual(before);
49
+ });
50
+
51
+ it('does not rebuild a stable signature and shares one generation across both lanes', async () => {
52
+ const lifecycle = new EnvironmentLifecycle(DeviceScope.create(1, 'environment'));
53
+ const first = await lifecycle.ensure(frame('sky-a'));
54
+ const stable = await lifecycle.ensure(frame('sky-a'));
55
+ const clustered = await lifecycle.ensure(frame('sky-a'), 'clustered');
56
+
57
+ expect(first.ok).toBe(true);
58
+ expect(stable.ok).toBe(true);
59
+ expect(clustered.ok).toBe(true);
60
+ if (!first.ok || !stable.ok || !clustered.ok) return;
61
+ expect(stable.value).toBe(first.value);
62
+ expect(clustered.value.signature).toBe(first.value.signature);
63
+ expect(clustered.value.generation).toBe(first.value.generation);
64
+ expect(clustered.value.lane).toBe('clustered');
65
+ });
66
+
67
+ it('projects descriptor-derived bytes separately from resource count', async () => {
68
+ const lifecycle = new EnvironmentLifecycle(DeviceScope.create(12, 'environment-bytes'));
69
+ const none = await lifecycle.ensure(emptyFrame());
70
+ expect(none.ok).toBe(true);
71
+ if (!none.ok) return;
72
+ expect(lifecycle.inspect().active).toBeUndefined();
73
+ lifecycle.publish(none.value);
74
+ expect(lifecycle.inspect()).toMatchObject({
75
+ bytes: 0,
76
+ resourceCount: 0,
77
+ residentBytes: 0,
78
+ });
79
+
80
+ const image = await lifecycle.ensure(frame('sky-bytes'));
81
+ expect(image.ok).toBe(true);
82
+ if (!image.ok) return;
83
+ expect(image.value.resourceCount).toBe(1);
84
+ expect(image.value.resourceBytes).toBe(16);
85
+ lifecycle.publish(image.value);
86
+ expect(lifecycle.inspect()).toMatchObject({
87
+ bytes: 16,
88
+ resourceCount: 1,
89
+ residentBytes: 16,
90
+ });
91
+ });
92
+
93
+ it('keeps active and LKG untouched when candidate generation fails, then recovers', async () => {
94
+ const lifecycle = new EnvironmentLifecycle(DeviceScope.create(2, 'environment'));
95
+ const initial = await lifecycle.ensure(frame('sky-a'));
96
+ expect(initial.ok).toBe(true);
97
+ if (!initial.ok) return;
98
+ lifecycle.publish(initial.value);
99
+
100
+ const failed = await lifecycle.ensure(frame('sky-b'), { failureAt: 'build' });
101
+ expect(failed.ok).toBe(false);
102
+ expect(lifecycle.inspect()).toMatchObject({
103
+ activeSignature: initial.value.signature,
104
+ lkgSignature: initial.value.signature,
105
+ });
106
+
107
+ const recovered = await lifecycle.ensure(frame('sky-b'));
108
+ expect(recovered.ok).toBe(true);
109
+ if (!recovered.ok) return;
110
+ lifecycle.publish(recovered.value);
111
+ expect(recovered.value.generation).toBeGreaterThan(initial.value.generation);
112
+ expect(recovered.value.signature).not.toBe(initial.value.signature);
113
+ });
114
+
115
+ it('retires old generations only after leases release and never reuses lost handles', async () => {
116
+ const scope = DeviceScope.create(3, 'environment');
117
+ const lifecycle = new EnvironmentLifecycle(scope);
118
+ const old = await lifecycle.ensure(frame('sky-a'));
119
+ expect(old.ok).toBe(true);
120
+ if (!old.ok) return;
121
+ lifecycle.publish(old.value);
122
+ const lease = lifecycle.acquire();
123
+
124
+ const next = await lifecycle.ensure(frame('sky-b'));
125
+ expect(next.ok).toBe(true);
126
+ if (!next.ok) return;
127
+ lifecycle.publish(next.value);
128
+ expect(old.value.retired).toBe(false);
129
+ expect(lifecycle.inspect().retiringBytes).toBeGreaterThan(0);
130
+ lease.release();
131
+ lifecycle.collectRetired();
132
+ expect(old.value.retired).toBe(true);
133
+ expect(lifecycle.inspect().retiringBytes).toBe(0);
134
+
135
+ const recovered = await lifecycle.recover(DeviceScope.create(4, 'environment'));
136
+ expect(recovered.ok).toBe(true);
137
+ if (!recovered.ok) return;
138
+ expect(recovered.value.generation).not.toBe(old.value.generation);
139
+ expect(recovered.value.liveHandle).not.toBe(old.value.liveHandle);
140
+ });
141
+ });