aigpu 0.3.1

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 (491) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +85 -0
  3. package/bin/aigpu.js +15 -0
  4. package/client.d.ts +15 -0
  5. package/dist/agent-tools.d.ts +61 -0
  6. package/dist/agent-tools.d.ts.map +1 -0
  7. package/dist/agent-tools.js +107 -0
  8. package/dist/agent-tools.js.map +1 -0
  9. package/dist/agent.d.ts +56 -0
  10. package/dist/agent.d.ts.map +1 -0
  11. package/dist/agent.js +243 -0
  12. package/dist/agent.js.map +1 -0
  13. package/dist/api-types.d.ts +56 -0
  14. package/dist/api-types.d.ts.map +1 -0
  15. package/dist/api-types.js +2 -0
  16. package/dist/api-types.js.map +1 -0
  17. package/dist/bind-cache.d.ts +19 -0
  18. package/dist/bind-cache.d.ts.map +1 -0
  19. package/dist/bind-cache.js +43 -0
  20. package/dist/bind-cache.js.map +1 -0
  21. package/dist/bundle.d.ts +30 -0
  22. package/dist/bundle.d.ts.map +1 -0
  23. package/dist/bundle.js +127 -0
  24. package/dist/bundle.js.map +1 -0
  25. package/dist/claim-validation-encode.d.ts +14 -0
  26. package/dist/claim-validation-encode.d.ts.map +1 -0
  27. package/dist/claim-validation-encode.js +28 -0
  28. package/dist/claim-validation-encode.js.map +1 -0
  29. package/dist/claim-validation.d.ts +73 -0
  30. package/dist/claim-validation.d.ts.map +1 -0
  31. package/dist/claim-validation.js +135 -0
  32. package/dist/claim-validation.js.map +1 -0
  33. package/dist/cli/bin/aigpu.js +101 -0
  34. package/dist/cli/lib/check/run.js +153 -0
  35. package/dist/cli/lib/docs/commands/cat.js +12 -0
  36. package/dist/cli/lib/docs/commands/find.js +180 -0
  37. package/dist/cli/lib/docs/commands/grep.js +49 -0
  38. package/dist/cli/lib/docs/commands/ls.js +41 -0
  39. package/dist/cli/lib/docs/commands/path.js +12 -0
  40. package/dist/cli/lib/docs/commands/resolve.js +41 -0
  41. package/dist/cli/lib/docs/commands/shared.js +13 -0
  42. package/dist/cli/lib/docs/commands/symbols.js +25 -0
  43. package/dist/cli/lib/docs/errors.js +8 -0
  44. package/dist/cli/lib/docs/generate/check-drift.js +61 -0
  45. package/dist/cli/lib/docs/generate/cli.js +12 -0
  46. package/dist/cli/lib/docs/generate/generate.js +113 -0
  47. package/dist/cli/lib/docs/generate/manifest.js +218 -0
  48. package/dist/cli/lib/docs/generate/skill.js +150 -0
  49. package/dist/cli/lib/docs/help.js +21 -0
  50. package/dist/cli/lib/docs/index.js +62 -0
  51. package/dist/cli/lib/docs/model.js +7 -0
  52. package/dist/cli/lib/docs/run.js +24 -0
  53. package/dist/cli/lib/docs/service.js +119 -0
  54. package/dist/cli/lib/doctor/run.js +236 -0
  55. package/dist/cli/lib/examples/errors.js +13 -0
  56. package/dist/cli/lib/examples/hashing.js +9 -0
  57. package/dist/cli/lib/examples/help.js +13 -0
  58. package/dist/cli/lib/examples/local-source.js +142 -0
  59. package/dist/cli/lib/examples/paths.js +12 -0
  60. package/dist/cli/lib/examples/pull.js +58 -0
  61. package/dist/cli/lib/examples/run.js +71 -0
  62. package/dist/cli/lib/examples/search.js +6 -0
  63. package/dist/cli/lib/examples/service.js +118 -0
  64. package/dist/cli/lib/generated/docs-manifest.generated.js +4758 -0
  65. package/dist/cli/lib/install-dawn/run.js +24 -0
  66. package/dist/cli/lib/install-software-renderer/run.js +17 -0
  67. package/dist/cli/lib/mcp/http.js +93 -0
  68. package/dist/cli/lib/mcp/server.js +258 -0
  69. package/dist/cli/lib/mcp/stdio.js +34 -0
  70. package/dist/cli/lib/snapshot/png.js +62 -0
  71. package/dist/cli/lib/snapshot/render.js +22 -0
  72. package/dist/cli/lib/snapshot/run.js +79 -0
  73. package/dist/cli/lib/snapshot/shaders.js +11 -0
  74. package/dist/cli/package.json +4 -0
  75. package/dist/client.d.ts +12 -0
  76. package/dist/client.d.ts.map +1 -0
  77. package/dist/client.js +2 -0
  78. package/dist/client.js.map +1 -0
  79. package/dist/clock.d.ts +26 -0
  80. package/dist/clock.d.ts.map +1 -0
  81. package/dist/clock.js +50 -0
  82. package/dist/clock.js.map +1 -0
  83. package/dist/compute.d.ts +41 -0
  84. package/dist/compute.d.ts.map +1 -0
  85. package/dist/compute.js +132 -0
  86. package/dist/compute.js.map +1 -0
  87. package/dist/core/render-bundle.d.ts +30 -0
  88. package/dist/core/render-bundle.d.ts.map +1 -0
  89. package/dist/core/render-bundle.js +39 -0
  90. package/dist/core/render-bundle.js.map +1 -0
  91. package/dist/core/storage-buffer.d.ts +81 -0
  92. package/dist/core/storage-buffer.d.ts.map +1 -0
  93. package/dist/core/storage-buffer.js +91 -0
  94. package/dist/core/storage-buffer.js.map +1 -0
  95. package/dist/core/structured-uniform.d.ts +33 -0
  96. package/dist/core/structured-uniform.d.ts.map +1 -0
  97. package/dist/core/structured-uniform.js +110 -0
  98. package/dist/core/structured-uniform.js.map +1 -0
  99. package/dist/core/uniform-pool-internals.d.ts +12 -0
  100. package/dist/core/uniform-pool-internals.d.ts.map +1 -0
  101. package/dist/core/uniform-pool-internals.js +24 -0
  102. package/dist/core/uniform-pool-internals.js.map +1 -0
  103. package/dist/core/uniform-pool-types.d.ts +22 -0
  104. package/dist/core/uniform-pool-types.d.ts.map +1 -0
  105. package/dist/core/uniform-pool-types.js +2 -0
  106. package/dist/core/uniform-pool-types.js.map +1 -0
  107. package/dist/core/uniform-pool.d.ts +22 -0
  108. package/dist/core/uniform-pool.d.ts.map +1 -0
  109. package/dist/core/uniform-pool.js +128 -0
  110. package/dist/core/uniform-pool.js.map +1 -0
  111. package/dist/core/uniform.d.ts +55 -0
  112. package/dist/core/uniform.d.ts.map +1 -0
  113. package/dist/core/uniform.js +64 -0
  114. package/dist/core/uniform.js.map +1 -0
  115. package/dist/core/wgsl-alignment.d.ts +24 -0
  116. package/dist/core/wgsl-alignment.d.ts.map +1 -0
  117. package/dist/core/wgsl-alignment.js +81 -0
  118. package/dist/core/wgsl-alignment.js.map +1 -0
  119. package/dist/core.d.ts +13 -0
  120. package/dist/core.d.ts.map +1 -0
  121. package/dist/core.js +7 -0
  122. package/dist/core.js.map +1 -0
  123. package/dist/dom.d.ts +37 -0
  124. package/dist/dom.d.ts.map +1 -0
  125. package/dist/dom.js +81 -0
  126. package/dist/dom.js.map +1 -0
  127. package/dist/draw-protocols.d.ts +36 -0
  128. package/dist/draw-protocols.d.ts.map +1 -0
  129. package/dist/draw-protocols.js +10 -0
  130. package/dist/draw-protocols.js.map +1 -0
  131. package/dist/draw.d.ts +248 -0
  132. package/dist/draw.d.ts.map +1 -0
  133. package/dist/draw.js +890 -0
  134. package/dist/draw.js.map +1 -0
  135. package/dist/effect.d.ts +53 -0
  136. package/dist/effect.d.ts.map +1 -0
  137. package/dist/effect.js +75 -0
  138. package/dist/effect.js.map +1 -0
  139. package/dist/entry-metadata.d.ts +16 -0
  140. package/dist/entry-metadata.d.ts.map +1 -0
  141. package/dist/entry-metadata.js +27 -0
  142. package/dist/entry-metadata.js.map +1 -0
  143. package/dist/errors.d.ts +96 -0
  144. package/dist/errors.d.ts.map +1 -0
  145. package/dist/errors.js +616 -0
  146. package/dist/errors.js.map +1 -0
  147. package/dist/frame-protocols.d.ts +107 -0
  148. package/dist/frame-protocols.d.ts.map +1 -0
  149. package/dist/frame-protocols.js +20 -0
  150. package/dist/frame-protocols.js.map +1 -0
  151. package/dist/frame-state.d.ts +32 -0
  152. package/dist/frame-state.d.ts.map +1 -0
  153. package/dist/frame-state.js +62 -0
  154. package/dist/frame-state.js.map +1 -0
  155. package/dist/frame.d.ts +127 -0
  156. package/dist/frame.d.ts.map +1 -0
  157. package/dist/frame.js +645 -0
  158. package/dist/frame.js.map +1 -0
  159. package/dist/group-claim.d.ts +9 -0
  160. package/dist/group-claim.d.ts.map +1 -0
  161. package/dist/group-claim.js +7 -0
  162. package/dist/group-claim.js.map +1 -0
  163. package/dist/index.d.ts +41 -0
  164. package/dist/index.d.ts.map +1 -0
  165. package/dist/index.js +27 -0
  166. package/dist/index.js.map +1 -0
  167. package/dist/indirect.d.ts +39 -0
  168. package/dist/indirect.d.ts.map +1 -0
  169. package/dist/indirect.js +61 -0
  170. package/dist/indirect.js.map +1 -0
  171. package/dist/init-from-device.d.ts +11 -0
  172. package/dist/init-from-device.d.ts.map +1 -0
  173. package/dist/init-from-device.js +56 -0
  174. package/dist/init-from-device.js.map +1 -0
  175. package/dist/init.d.ts +12 -0
  176. package/dist/init.d.ts.map +1 -0
  177. package/dist/init.js +7 -0
  178. package/dist/init.js.map +1 -0
  179. package/dist/kernel.d.ts +104 -0
  180. package/dist/kernel.d.ts.map +1 -0
  181. package/dist/kernel.js +151 -0
  182. package/dist/kernel.js.map +1 -0
  183. package/dist/lifecycle.d.ts +10 -0
  184. package/dist/lifecycle.d.ts.map +1 -0
  185. package/dist/lifecycle.js +21 -0
  186. package/dist/lifecycle.js.map +1 -0
  187. package/dist/live-kernel.d.ts +48 -0
  188. package/dist/live-kernel.d.ts.map +1 -0
  189. package/dist/live-kernel.js +67 -0
  190. package/dist/live-kernel.js.map +1 -0
  191. package/dist/mock.d.ts +42 -0
  192. package/dist/mock.d.ts.map +1 -0
  193. package/dist/mock.js +29 -0
  194. package/dist/mock.js.map +1 -0
  195. package/dist/node.d.ts +48 -0
  196. package/dist/node.d.ts.map +1 -0
  197. package/dist/node.js +36 -0
  198. package/dist/node.js.map +1 -0
  199. package/dist/ping-pong.d.ts +19 -0
  200. package/dist/ping-pong.d.ts.map +1 -0
  201. package/dist/ping-pong.js +67 -0
  202. package/dist/ping-pong.js.map +1 -0
  203. package/dist/pipeline-store.d.ts +89 -0
  204. package/dist/pipeline-store.d.ts.map +1 -0
  205. package/dist/pipeline-store.js +366 -0
  206. package/dist/pipeline-store.js.map +1 -0
  207. package/dist/query-ring.d.ts +91 -0
  208. package/dist/query-ring.d.ts.map +1 -0
  209. package/dist/query-ring.js +178 -0
  210. package/dist/query-ring.js.map +1 -0
  211. package/dist/render-service.d.ts +23 -0
  212. package/dist/render-service.d.ts.map +1 -0
  213. package/dist/render-service.js +37 -0
  214. package/dist/render-service.js.map +1 -0
  215. package/dist/sampler.d.ts +19 -0
  216. package/dist/sampler.d.ts.map +1 -0
  217. package/dist/sampler.js +46 -0
  218. package/dist/sampler.js.map +1 -0
  219. package/dist/scene/camera.d.ts +91 -0
  220. package/dist/scene/camera.d.ts.map +1 -0
  221. package/dist/scene/camera.js +221 -0
  222. package/dist/scene/camera.js.map +1 -0
  223. package/dist/scene/geometries.d.ts +26 -0
  224. package/dist/scene/geometries.d.ts.map +1 -0
  225. package/dist/scene/geometries.js +26 -0
  226. package/dist/scene/geometries.js.map +1 -0
  227. package/dist/scene/geometry-descriptor.d.ts +120 -0
  228. package/dist/scene/geometry-descriptor.d.ts.map +1 -0
  229. package/dist/scene/geometry-descriptor.js +378 -0
  230. package/dist/scene/geometry-descriptor.js.map +1 -0
  231. package/dist/scene/geometry-recipe.d.ts +41 -0
  232. package/dist/scene/geometry-recipe.d.ts.map +1 -0
  233. package/dist/scene/geometry-recipe.js +40 -0
  234. package/dist/scene/geometry-recipe.js.map +1 -0
  235. package/dist/scene/geometry-src/camera-math.d.ts +6 -0
  236. package/dist/scene/geometry-src/camera-math.d.ts.map +1 -0
  237. package/dist/scene/geometry-src/camera-math.js +47 -0
  238. package/dist/scene/geometry-src/camera-math.js.map +1 -0
  239. package/dist/scene/geometry-src/camera.d.ts +10 -0
  240. package/dist/scene/geometry-src/camera.d.ts.map +1 -0
  241. package/dist/scene/geometry-src/camera.js +2 -0
  242. package/dist/scene/geometry-src/camera.js.map +1 -0
  243. package/dist/scene/geometry-src/capsule-data.d.ts +10 -0
  244. package/dist/scene/geometry-src/capsule-data.d.ts.map +1 -0
  245. package/dist/scene/geometry-src/capsule-data.js +61 -0
  246. package/dist/scene/geometry-src/capsule-data.js.map +1 -0
  247. package/dist/scene/geometry-src/cone-data.d.ts +13 -0
  248. package/dist/scene/geometry-src/cone-data.d.ts.map +1 -0
  249. package/dist/scene/geometry-src/cone-data.js +52 -0
  250. package/dist/scene/geometry-src/cone-data.js.map +1 -0
  251. package/dist/scene/geometry-src/cylinder-data.d.ts +14 -0
  252. package/dist/scene/geometry-src/cylinder-data.d.ts.map +1 -0
  253. package/dist/scene/geometry-src/cylinder-data.js +58 -0
  254. package/dist/scene/geometry-src/cylinder-data.js.map +1 -0
  255. package/dist/scene/geometry-src/deg-to-rad.d.ts +2 -0
  256. package/dist/scene/geometry-src/deg-to-rad.d.ts.map +1 -0
  257. package/dist/scene/geometry-src/deg-to-rad.js +4 -0
  258. package/dist/scene/geometry-src/deg-to-rad.js.map +1 -0
  259. package/dist/scene/geometry-src/disk-data.d.ts +12 -0
  260. package/dist/scene/geometry-src/disk-data.d.ts.map +1 -0
  261. package/dist/scene/geometry-src/disk-data.js +21 -0
  262. package/dist/scene/geometry-src/disk-data.js.map +1 -0
  263. package/dist/scene/geometry-src/errors.d.ts +3 -0
  264. package/dist/scene/geometry-src/errors.d.ts.map +1 -0
  265. package/dist/scene/geometry-src/errors.js +5 -0
  266. package/dist/scene/geometry-src/errors.js.map +1 -0
  267. package/dist/scene/geometry-src/icosphere-data.d.ts +8 -0
  268. package/dist/scene/geometry-src/icosphere-data.d.ts.map +1 -0
  269. package/dist/scene/geometry-src/icosphere-data.js +58 -0
  270. package/dist/scene/geometry-src/icosphere-data.js.map +1 -0
  271. package/dist/scene/geometry-src/index.d.ts +36 -0
  272. package/dist/scene/geometry-src/index.d.ts.map +1 -0
  273. package/dist/scene/geometry-src/index.js +21 -0
  274. package/dist/scene/geometry-src/index.js.map +1 -0
  275. package/dist/scene/geometry-src/mesh-box.d.ts +8 -0
  276. package/dist/scene/geometry-src/mesh-box.d.ts.map +1 -0
  277. package/dist/scene/geometry-src/mesh-box.js +57 -0
  278. package/dist/scene/geometry-src/mesh-box.js.map +1 -0
  279. package/dist/scene/geometry-src/mesh-cache.d.ts +4 -0
  280. package/dist/scene/geometry-src/mesh-cache.d.ts.map +1 -0
  281. package/dist/scene/geometry-src/mesh-cache.js +14 -0
  282. package/dist/scene/geometry-src/mesh-cache.js.map +1 -0
  283. package/dist/scene/geometry-src/mesh-capsule.d.ts +14 -0
  284. package/dist/scene/geometry-src/mesh-capsule.d.ts.map +1 -0
  285. package/dist/scene/geometry-src/mesh-capsule.js +52 -0
  286. package/dist/scene/geometry-src/mesh-capsule.js.map +1 -0
  287. package/dist/scene/geometry-src/mesh-cone.d.ts +16 -0
  288. package/dist/scene/geometry-src/mesh-cone.d.ts.map +1 -0
  289. package/dist/scene/geometry-src/mesh-cone.js +54 -0
  290. package/dist/scene/geometry-src/mesh-cone.js.map +1 -0
  291. package/dist/scene/geometry-src/mesh-cylinder.d.ts +18 -0
  292. package/dist/scene/geometry-src/mesh-cylinder.d.ts.map +1 -0
  293. package/dist/scene/geometry-src/mesh-cylinder.js +67 -0
  294. package/dist/scene/geometry-src/mesh-cylinder.js.map +1 -0
  295. package/dist/scene/geometry-src/mesh-disk.d.ts +11 -0
  296. package/dist/scene/geometry-src/mesh-disk.d.ts.map +1 -0
  297. package/dist/scene/geometry-src/mesh-disk.js +45 -0
  298. package/dist/scene/geometry-src/mesh-disk.js.map +1 -0
  299. package/dist/scene/geometry-src/mesh-dodecahedron.d.ts +4 -0
  300. package/dist/scene/geometry-src/mesh-dodecahedron.d.ts.map +1 -0
  301. package/dist/scene/geometry-src/mesh-dodecahedron.js +10 -0
  302. package/dist/scene/geometry-src/mesh-dodecahedron.js.map +1 -0
  303. package/dist/scene/geometry-src/mesh-fullscreen-quad.d.ts +7 -0
  304. package/dist/scene/geometry-src/mesh-fullscreen-quad.d.ts.map +1 -0
  305. package/dist/scene/geometry-src/mesh-fullscreen-quad.js +39 -0
  306. package/dist/scene/geometry-src/mesh-fullscreen-quad.js.map +1 -0
  307. package/dist/scene/geometry-src/mesh-icosahedron.d.ts +4 -0
  308. package/dist/scene/geometry-src/mesh-icosahedron.d.ts.map +1 -0
  309. package/dist/scene/geometry-src/mesh-icosahedron.js +10 -0
  310. package/dist/scene/geometry-src/mesh-icosahedron.js.map +1 -0
  311. package/dist/scene/geometry-src/mesh-icosphere.d.ts +11 -0
  312. package/dist/scene/geometry-src/mesh-icosphere.d.ts.map +1 -0
  313. package/dist/scene/geometry-src/mesh-icosphere.js +47 -0
  314. package/dist/scene/geometry-src/mesh-icosphere.js.map +1 -0
  315. package/dist/scene/geometry-src/mesh-octahedron.d.ts +4 -0
  316. package/dist/scene/geometry-src/mesh-octahedron.d.ts.map +1 -0
  317. package/dist/scene/geometry-src/mesh-octahedron.js +10 -0
  318. package/dist/scene/geometry-src/mesh-octahedron.js.map +1 -0
  319. package/dist/scene/geometry-src/mesh-plane.d.ts +13 -0
  320. package/dist/scene/geometry-src/mesh-plane.d.ts.map +1 -0
  321. package/dist/scene/geometry-src/mesh-plane.js +51 -0
  322. package/dist/scene/geometry-src/mesh-plane.js.map +1 -0
  323. package/dist/scene/geometry-src/mesh-ring.d.ts +12 -0
  324. package/dist/scene/geometry-src/mesh-ring.d.ts.map +1 -0
  325. package/dist/scene/geometry-src/mesh-ring.js +47 -0
  326. package/dist/scene/geometry-src/mesh-ring.js.map +1 -0
  327. package/dist/scene/geometry-src/mesh-sphere.d.ts +10 -0
  328. package/dist/scene/geometry-src/mesh-sphere.d.ts.map +1 -0
  329. package/dist/scene/geometry-src/mesh-sphere.js +51 -0
  330. package/dist/scene/geometry-src/mesh-sphere.js.map +1 -0
  331. package/dist/scene/geometry-src/mesh-tetrahedron.d.ts +5 -0
  332. package/dist/scene/geometry-src/mesh-tetrahedron.d.ts.map +1 -0
  333. package/dist/scene/geometry-src/mesh-tetrahedron.js +10 -0
  334. package/dist/scene/geometry-src/mesh-tetrahedron.js.map +1 -0
  335. package/dist/scene/geometry-src/mesh-torus.d.ts +17 -0
  336. package/dist/scene/geometry-src/mesh-torus.d.ts.map +1 -0
  337. package/dist/scene/geometry-src/mesh-torus.js +56 -0
  338. package/dist/scene/geometry-src/mesh-torus.js.map +1 -0
  339. package/dist/scene/geometry-src/mesh-types.d.ts +38 -0
  340. package/dist/scene/geometry-src/mesh-types.d.ts.map +1 -0
  341. package/dist/scene/geometry-src/mesh-types.js +2 -0
  342. package/dist/scene/geometry-src/mesh-types.js.map +1 -0
  343. package/dist/scene/geometry-src/mesh.d.ts +61 -0
  344. package/dist/scene/geometry-src/mesh.d.ts.map +1 -0
  345. package/dist/scene/geometry-src/mesh.js +49 -0
  346. package/dist/scene/geometry-src/mesh.js.map +1 -0
  347. package/dist/scene/geometry-src/orthographic-camera.d.ts +14 -0
  348. package/dist/scene/geometry-src/orthographic-camera.d.ts.map +1 -0
  349. package/dist/scene/geometry-src/orthographic-camera.js +9 -0
  350. package/dist/scene/geometry-src/orthographic-camera.js.map +1 -0
  351. package/dist/scene/geometry-src/perspective-camera.d.ts +12 -0
  352. package/dist/scene/geometry-src/perspective-camera.d.ts.map +1 -0
  353. package/dist/scene/geometry-src/perspective-camera.js +9 -0
  354. package/dist/scene/geometry-src/perspective-camera.js.map +1 -0
  355. package/dist/scene/geometry-src/plane-data.d.ts +12 -0
  356. package/dist/scene/geometry-src/plane-data.d.ts.map +1 -0
  357. package/dist/scene/geometry-src/plane-data.js +25 -0
  358. package/dist/scene/geometry-src/plane-data.js.map +1 -0
  359. package/dist/scene/geometry-src/polyhedron-data.d.ts +7 -0
  360. package/dist/scene/geometry-src/polyhedron-data.d.ts.map +1 -0
  361. package/dist/scene/geometry-src/polyhedron-data.js +42 -0
  362. package/dist/scene/geometry-src/polyhedron-data.js.map +1 -0
  363. package/dist/scene/geometry-src/polyhedron-mesh.d.ts +10 -0
  364. package/dist/scene/geometry-src/polyhedron-mesh.d.ts.map +1 -0
  365. package/dist/scene/geometry-src/polyhedron-mesh.js +37 -0
  366. package/dist/scene/geometry-src/polyhedron-mesh.js.map +1 -0
  367. package/dist/scene/geometry-src/polyhedron-seeds.d.ts +6 -0
  368. package/dist/scene/geometry-src/polyhedron-seeds.d.ts.map +1 -0
  369. package/dist/scene/geometry-src/polyhedron-seeds.js +51 -0
  370. package/dist/scene/geometry-src/polyhedron-seeds.js.map +1 -0
  371. package/dist/scene/geometry-src/primitive-data-utils.d.ts +9 -0
  372. package/dist/scene/geometry-src/primitive-data-utils.d.ts.map +1 -0
  373. package/dist/scene/geometry-src/primitive-data-utils.js +36 -0
  374. package/dist/scene/geometry-src/primitive-data-utils.js.map +1 -0
  375. package/dist/scene/geometry-src/ring-data.d.ts +13 -0
  376. package/dist/scene/geometry-src/ring-data.d.ts.map +1 -0
  377. package/dist/scene/geometry-src/ring-data.js +24 -0
  378. package/dist/scene/geometry-src/ring-data.js.map +1 -0
  379. package/dist/scene/geometry-src/sphere-data.d.ts +11 -0
  380. package/dist/scene/geometry-src/sphere-data.d.ts.map +1 -0
  381. package/dist/scene/geometry-src/sphere-data.js +31 -0
  382. package/dist/scene/geometry-src/sphere-data.js.map +1 -0
  383. package/dist/scene/geometry-src/srgb.d.ts +5 -0
  384. package/dist/scene/geometry-src/srgb.d.ts.map +1 -0
  385. package/dist/scene/geometry-src/srgb.js +23 -0
  386. package/dist/scene/geometry-src/srgb.js.map +1 -0
  387. package/dist/scene/geometry-src/torus-data.d.ts +11 -0
  388. package/dist/scene/geometry-src/torus-data.d.ts.map +1 -0
  389. package/dist/scene/geometry-src/torus-data.js +38 -0
  390. package/dist/scene/geometry-src/torus-data.js.map +1 -0
  391. package/dist/scene/geometry-src/vertex-layout.d.ts +2 -0
  392. package/dist/scene/geometry-src/vertex-layout.d.ts.map +1 -0
  393. package/dist/scene/geometry-src/vertex-layout.js +2 -0
  394. package/dist/scene/geometry-src/vertex-layout.js.map +1 -0
  395. package/dist/scene/geometry.d.ts +70 -0
  396. package/dist/scene/geometry.d.ts.map +1 -0
  397. package/dist/scene/geometry.js +71 -0
  398. package/dist/scene/geometry.js.map +1 -0
  399. package/dist/scene/orbit.d.ts +9 -0
  400. package/dist/scene/orbit.d.ts.map +1 -0
  401. package/dist/scene/orbit.js +15 -0
  402. package/dist/scene/orbit.js.map +1 -0
  403. package/dist/scene/tree/errors.d.ts +4 -0
  404. package/dist/scene/tree/errors.d.ts.map +1 -0
  405. package/dist/scene/tree/errors.js +19 -0
  406. package/dist/scene/tree/errors.js.map +1 -0
  407. package/dist/scene/tree/light.d.ts +42 -0
  408. package/dist/scene/tree/light.d.ts.map +1 -0
  409. package/dist/scene/tree/light.js +102 -0
  410. package/dist/scene/tree/light.js.map +1 -0
  411. package/dist/scene/tree/material.d.ts +79 -0
  412. package/dist/scene/tree/material.d.ts.map +1 -0
  413. package/dist/scene/tree/material.js +117 -0
  414. package/dist/scene/tree/material.js.map +1 -0
  415. package/dist/scene/tree/math.d.ts +26 -0
  416. package/dist/scene/tree/math.d.ts.map +1 -0
  417. package/dist/scene/tree/math.js +217 -0
  418. package/dist/scene/tree/math.js.map +1 -0
  419. package/dist/scene/tree/mesh-node.d.ts +17 -0
  420. package/dist/scene/tree/mesh-node.d.ts.map +1 -0
  421. package/dist/scene/tree/mesh-node.js +24 -0
  422. package/dist/scene/tree/mesh-node.js.map +1 -0
  423. package/dist/scene/tree/node.d.ts +70 -0
  424. package/dist/scene/tree/node.d.ts.map +1 -0
  425. package/dist/scene/tree/node.js +220 -0
  426. package/dist/scene/tree/node.js.map +1 -0
  427. package/dist/scene/tree/orbit-controls.d.ts +69 -0
  428. package/dist/scene/tree/orbit-controls.d.ts.map +1 -0
  429. package/dist/scene/tree/orbit-controls.js +226 -0
  430. package/dist/scene/tree/orbit-controls.js.map +1 -0
  431. package/dist/scene.d.ts +21 -0
  432. package/dist/scene.d.ts.map +1 -0
  433. package/dist/scene.js +11 -0
  434. package/dist/scene.js.map +1 -0
  435. package/dist/set-core.d.ts +50 -0
  436. package/dist/set-core.d.ts.map +1 -0
  437. package/dist/set-core.js +268 -0
  438. package/dist/set-core.js.map +1 -0
  439. package/dist/set-layouts.d.ts +20 -0
  440. package/dist/set-layouts.d.ts.map +1 -0
  441. package/dist/set-layouts.js +103 -0
  442. package/dist/set-layouts.js.map +1 -0
  443. package/dist/set-packing.d.ts +4 -0
  444. package/dist/set-packing.d.ts.map +1 -0
  445. package/dist/set-packing.js +82 -0
  446. package/dist/set-packing.js.map +1 -0
  447. package/dist/set-resources.d.ts +20 -0
  448. package/dist/set-resources.d.ts.map +1 -0
  449. package/dist/set-resources.js +140 -0
  450. package/dist/set-resources.js.map +1 -0
  451. package/dist/shader-source.d.ts +4 -0
  452. package/dist/shader-source.d.ts.map +1 -0
  453. package/dist/shader-source.js +21 -0
  454. package/dist/shader-source.js.map +1 -0
  455. package/dist/storage.d.ts +38 -0
  456. package/dist/storage.d.ts.map +1 -0
  457. package/dist/storage.js +76 -0
  458. package/dist/storage.js.map +1 -0
  459. package/dist/surface.d.ts +89 -0
  460. package/dist/surface.d.ts.map +1 -0
  461. package/dist/surface.js +243 -0
  462. package/dist/surface.js.map +1 -0
  463. package/dist/target-offscreen.d.ts +41 -0
  464. package/dist/target-offscreen.d.ts.map +1 -0
  465. package/dist/target-offscreen.js +115 -0
  466. package/dist/target-offscreen.js.map +1 -0
  467. package/dist/target-utils.d.ts +37 -0
  468. package/dist/target-utils.d.ts.map +1 -0
  469. package/dist/target-utils.js +103 -0
  470. package/dist/target-utils.js.map +1 -0
  471. package/dist/target.d.ts +65 -0
  472. package/dist/target.d.ts.map +1 -0
  473. package/dist/target.js +2 -0
  474. package/dist/target.js.map +1 -0
  475. package/dist/timer.d.ts +78 -0
  476. package/dist/timer.d.ts.map +1 -0
  477. package/dist/timer.js +261 -0
  478. package/dist/timer.js.map +1 -0
  479. package/dist/uniforms-layout.d.ts +8 -0
  480. package/dist/uniforms-layout.d.ts.map +1 -0
  481. package/dist/uniforms-layout.js +84 -0
  482. package/dist/uniforms-layout.js.map +1 -0
  483. package/dist/uniforms.d.ts +43 -0
  484. package/dist/uniforms.d.ts.map +1 -0
  485. package/dist/uniforms.js +176 -0
  486. package/dist/uniforms.js.map +1 -0
  487. package/dist/visibility.d.ts +118 -0
  488. package/dist/visibility.d.ts.map +1 -0
  489. package/dist/visibility.js +290 -0
  490. package/dist/visibility.js.map +1 -0
  491. package/package.json +131 -0
package/dist/frame.js ADDED
@@ -0,0 +1,645 @@
1
+ import { claimedGroupValidationDone, discardClaimedGroupValidationResults, discardClaimedGroupValidationScopes, popLastClaimedGroupValidationScope, preferClaimedGroupValidationResult, pushClaimedGroupValidationScope, submittedWorkDone } from "./claim-validation.js";
2
+ import { endRenderPassWithClaimValidation } from "./claim-validation-encode.js";
3
+ import { assertDeviceUsable } from "./lifecycle.js";
4
+ import { claimedGroupNativeValidationError, frameAlreadySubmittedError, frameCanceledError, framePassActiveError, frameReentrantError, passClearDepthInvalidError, passClearStencilInvalidError, passDepthReadOnlyError, passDepthReadOnlyMsaaError, passPreserveClearDepthError, passPreserveClearStencilError, passPreserveMsaaError, passScissorInvalidError, passViewportInvalidError, queryNestedError, queryNoVisibilityError, surfaceNotInFrameError, targetRequiredError, timerInvalidError, AIGpuError, visibilityInvalidError } from "./errors.js";
5
+ import { enterFrame, isSurface, isSurfaceResizeCallbackActive, leaveFrame } from "./surface.js";
6
+ import { BUILT_IN_CLEAR_COLOR, hasStencilAspect, isTarget } from "./target-utils.js";
7
+ import { FRAME_PASS_ATTACHMENT, frameBundleOf, frameDrawableOf, framePassAttachmentOf } from "./frame-protocols.js";
8
+ import { frameState } from "./frame-state.js";
9
+ import { liveKernel } from "./live-kernel.js";
10
+ import { serviceToken } from "./kernel.js";
11
+ /**
12
+ * Opens a frame on `gpu`: advances the frame clock, runs `cb` against a fresh command encoder and
13
+ * submits it when the callback returns (or on the way out of a throw).
14
+ *
15
+ * Without a callback the frame is yours: encode passes at your own pace and finish it with
16
+ * `frame.submit()` or `frame.cancel()` — an unfinished frame holds every retain its passes took.
17
+ * Frames are not reentrant: opening one from inside another (or from a surface resize callback)
18
+ * throws `AIGPU-FRAME-REENTRANT`.
19
+ */
20
+ export function frame(gpu, cb) {
21
+ return frameRunner(liveKernel(gpu, "frame")).frame(cb);
22
+ }
23
+ /**
24
+ * Runs `cb` once per animation frame until the returned handle is stopped.
25
+ *
26
+ * The loop belongs to the gpu's `scheduler` phase, so `gpu.dispose()` stops it before anything it
27
+ * could encode against is torn down; a loop that stops on its own drops that registration.
28
+ */
29
+ export function frameLoop(gpu, cb, opts = {}) {
30
+ return frameRunner(liveKernel(gpu, "frameLoop")).loop(cb, opts);
31
+ }
32
+ /**
33
+ * One runner per gpu: it carries the reentrancy guard, the frame clock and the loop registrations,
34
+ * so `frame()` and `frameLoop()` share the same state. Created on the first frame, never at `init()`.
35
+ */
36
+ const frameRunnerToken = serviceToken("frame-runner");
37
+ function frameRunner(kernel) {
38
+ return kernel.service(frameRunnerToken, (self) => {
39
+ const state = frameState(self);
40
+ return new FrameRunner(() => {
41
+ let release = () => { };
42
+ const frame = new Frame(self.device, undefined, (error) => self.reportError(error), (promise) => { void self.trackDelivery(promise); }, () => release());
43
+ release = self.own("scheduler", () => frame.cancel());
44
+ return frame;
45
+ }, () => state.tick(), (handle) => self.own("scheduler", () => handle.stop()));
46
+ });
47
+ }
48
+ export class Frame {
49
+ device;
50
+ defaultTarget;
51
+ errorSink;
52
+ trackSettled;
53
+ releaseLifecycle;
54
+ /**
55
+ * Resolves after submitted GPU work completes and raw claimed-bind-group
56
+ * validation has been delivered to `gpu.onError`.
57
+ *
58
+ * This is a completion/timing signal only; it never rejects and is not an error
59
+ * channel.
60
+ */
61
+ done = Promise.resolve();
62
+ #encoder;
63
+ #validations = [];
64
+ /**
65
+ * Everything a pass of this frame attached, as opaque {@link FrameOwner}s: timers and
66
+ * visibilities today, scene view generations later. The frame never learns what they are — it
67
+ * only guarantees each one sees exactly one `frameSubmitted` or `frameAbandoned`.
68
+ */
69
+ #owners = new Set();
70
+ /**
71
+ * Owners whose per-frame bookkeeping a failed pass invalidated: their frame is neither finalized
72
+ * nor read back, so a throwing pass callback cannot leave a phantom result. Kept alongside the
73
+ * live set so a later pass re-attaching the same instance in this frame stays dropped too — the
74
+ * failed pass's span/slots are still in that instance's frame bookkeeping.
75
+ */
76
+ #discardedOwners = new Set();
77
+ #submitted = false;
78
+ #canceled = false;
79
+ #passActive = false;
80
+ constructor(device, defaultTarget, errorSink, trackSettled, releaseLifecycle) {
81
+ this.device = device;
82
+ this.defaultTarget = defaultTarget;
83
+ this.errorSink = errorSink;
84
+ this.trackSettled = trackSettled;
85
+ this.releaseLifecycle = releaseLifecycle;
86
+ assertDeviceUsable(device, "Frame.constructor");
87
+ this.#encoder = device.gpu.createCommandEncoder({ label: "aigpu.frame" });
88
+ }
89
+ pass(target, body) {
90
+ // A canceled frame dropped its encoder: encoding into it would silently never run (and would
91
+ // re-take the telemetry retains cancel() just released), so reject the call instead. Checked
92
+ // before the device: `gpu.dispose()` cancels outstanding frames and *then* drops the device, so
93
+ // cancellation is the proximate cause there and names it better than a generic disposed device.
94
+ if (this.#canceled)
95
+ throw frameCanceledError("Frame.pass");
96
+ assertDeviceUsable(this.device, "Frame.pass");
97
+ const targetOnly = isTarget(target);
98
+ const cb = typeof body === "function" ? body : (p) => p.draw(body);
99
+ const resolvedTarget = targetOnly ? target : target.target ?? this.defaultTarget;
100
+ if (!resolvedTarget)
101
+ throw targetRequiredError("Frame.pass");
102
+ if (isSurface(resolvedTarget) && this.#submitted)
103
+ throw surfaceNotInFrameError("Frame.pass");
104
+ const clear = targetOnly ? undefined : target.clear;
105
+ const preserve = clear === false;
106
+ if (preserve && resolvedTarget.sampleCount === 4)
107
+ throw passPreserveMsaaError();
108
+ const clearDepth = targetOnly ? undefined : target.clearDepth;
109
+ if (clearDepth !== undefined) {
110
+ if (typeof clearDepth !== "number" || !(clearDepth >= 0 && clearDepth <= 1))
111
+ throw passClearDepthInvalidError(clearDepth);
112
+ if (preserve)
113
+ throw passPreserveClearDepthError();
114
+ // Dead-option rule, same as clearStencil below: without a depth attachment there is no
115
+ // depthClearValue in the descriptor, so clearDepth would silently do nothing.
116
+ if (!resolvedTarget.depth) {
117
+ throw passClearDepthInvalidError(clearDepth, "but the target has no depth attachment, so clearDepth would have no effect.", "Create the target with depth: true (or a depth format), or drop clearDepth.");
118
+ }
119
+ }
120
+ const clearStencil = targetOnly ? undefined : target.clearStencil;
121
+ if (clearStencil !== undefined) {
122
+ // WebGPU stencilClearValue is GPUStencilValue ([EnforceRange] u32); in-range values are masked to the stencil
123
+ // aspect's bit width by taking the LSBs, so values above 0xFF on stencil8 aspects are legal, not errors.
124
+ if (typeof clearStencil !== "number" || !Number.isInteger(clearStencil) || clearStencil < 0 || clearStencil > 0xFFFFFFFF) {
125
+ throw passClearStencilInvalidError(`received ${String(clearStencil)}; expected an integer in [0, 0xFFFFFFFF] (WebGPU GPUStencilValue).`);
126
+ }
127
+ if (preserve)
128
+ throw passPreserveClearStencilError();
129
+ const depthFormat = resolvedTarget.depth?.format;
130
+ if (!hasStencilAspect(depthFormat))
131
+ throw passClearStencilInvalidError(`received ${String(clearStencil)}, but the target's depth format ${depthFormat ? `"${depthFormat}"` : "(none)"} has no stencil aspect, so clearStencil would have no effect.`);
132
+ }
133
+ const depthReadOnly = targetOnly ? undefined : target.depthReadOnly;
134
+ if (depthReadOnly !== undefined && typeof depthReadOnly !== "boolean") {
135
+ throw passDepthReadOnlyError(`received ${previewValue(depthReadOnly)}; expected a boolean.`, "Pass depthReadOnly: true to open the pass with a read-only depth attachment, or omit it.");
136
+ }
137
+ if (depthReadOnly) {
138
+ // Dead-option and contradiction rules: color attachments still load/clear normally in a read-only
139
+ // pass, so clear (color) stays legal, but the read-only depth/stencil aspects omit their ops entirely
140
+ // and can never be cleared.
141
+ if (!resolvedTarget.depth)
142
+ throw passDepthReadOnlyError("is set, but the target has no depth attachment, so there is nothing to make read-only.", "Create the target with depth: true (or a depth format), or drop depthReadOnly.");
143
+ // Symmetric to the clear:false MSAA rule: an MSAA target's depth aspect is stored with
144
+ // storeOp "discard" (target-utils depthAttachment), so nothing survives the pass that wrote
145
+ // it. Reading it back read-only would depth-test every draw against discarded contents —
146
+ // silent garbage (with visibility attached, every query reports "hidden").
147
+ if (resolvedTarget.sampleCount === 4)
148
+ throw passDepthReadOnlyMsaaError();
149
+ if (clearDepth !== undefined)
150
+ throw passDepthReadOnlyError("cannot be combined with clearDepth; a read-only depth aspect omits its load/store ops and is never cleared.", "Remove clearDepth, or drop depthReadOnly.");
151
+ if (clearStencil !== undefined)
152
+ throw passDepthReadOnlyError("cannot be combined with clearStencil; a read-only stencil aspect omits its load/store ops and is never cleared.", "Remove clearStencil, or drop depthReadOnly.");
153
+ }
154
+ const viewport = targetOnly ? undefined : validatedViewport(target.viewport, this.device.gpu.limits, resolvedTarget.size);
155
+ const scissor = targetOnly ? undefined : validatedScissor(target.scissor, resolvedTarget.size);
156
+ // Owners this pass attached, in attach order: the rollback set if anything below throws.
157
+ const attached = [];
158
+ let encoder;
159
+ try {
160
+ // Attaching telemetry mutates per-frame bookkeeping before the native pass opens. Keep the whole
161
+ // attach/setup/body sequence atomic so any later validation/native setup failure rolls it back,
162
+ // not only exceptions thrown by the user callback.
163
+ const timer = targetOnly || target.timer === undefined ? undefined : this.#attach(target.timer, resolvedTarget, attached, timerAttachmentInvalidError);
164
+ const visibility = targetOnly || target.visibility === undefined ? undefined : this.#attach(target.visibility, resolvedTarget, attached, visibilityAttachmentInvalidError);
165
+ const occlusion = visibility?.occlusion;
166
+ // timestampWrites and occlusionQuerySet are target-independent pass state: decorate the descriptor after obtaining it from the target.
167
+ // Clear color precedence: the pass color, then the target's own default, then the built-in.
168
+ let descriptor = resolvedTarget.renderPassDescriptor({ clear: clear === undefined || clear === true || clear === false ? resolvedTarget.clearColor ?? BUILT_IN_CLEAR_COLOR : clear, preserve, clearDepth, clearStencil, depthReadOnly });
169
+ if (timer?.timestampWrites)
170
+ descriptor = { ...descriptor, timestampWrites: timer.timestampWrites };
171
+ // Mirrors the WebGPU pass descriptor rule: occlusionQuerySet must be a valid query set of type "occlusion".
172
+ if (occlusion)
173
+ descriptor = { ...descriptor, occlusionQuerySet: occlusion.querySet };
174
+ encoder = this.#encoder.beginRenderPass(descriptor);
175
+ if (viewport)
176
+ encoder.setViewport(viewport.x, viewport.y, viewport.width, viewport.height, viewport.minDepth, viewport.maxDepth);
177
+ if (scissor)
178
+ encoder.setScissorRect(scissor[0], scissor[1], scissor[2], scissor[3]);
179
+ this.#passActive = true;
180
+ try {
181
+ cb(new FramePass(encoder, resolvedTarget, this.#validations, depthReadOnly === true, occlusion, this, (where) => {
182
+ // Retained external devices can be destroyed mid-pass, so every FramePass entry point
183
+ // re-checks the device here instead of taking it as a separate constructor argument.
184
+ assertDeviceUsable(this.device, where);
185
+ if (this.#canceled)
186
+ throw frameCanceledError(where);
187
+ }));
188
+ }
189
+ finally {
190
+ this.#passActive = false;
191
+ }
192
+ }
193
+ catch (error) {
194
+ // A failed pass — during setup or in its body — never ran successfully. Leaving telemetry
195
+ // registered makes submit() resolve unwritten queries as phantom results.
196
+ this.#discardOwners(attached);
197
+ discardClaimedGroupValidationResults(this.#validations);
198
+ this.#validations.length = 0;
199
+ discardClaimedGroupValidationScopes(this.device);
200
+ try {
201
+ encoder?.end();
202
+ }
203
+ catch { /* ignore cleanup failure after encode failure */ }
204
+ throw error;
205
+ }
206
+ endRenderPassWithClaimValidation(this.device, encoder, this.#validations);
207
+ }
208
+ submit() {
209
+ // Closed either way: a re-submit has nothing left to flush, and a canceled frame dropped its
210
+ // encoder. Both are silent no-ops so `frame(gpu, cb)`'s submit-in-finally never masks a cancel()
211
+ // (or an exception) from inside the callback. Checked before the device so that submitting an
212
+ // already-closed frame stays a no-op even after `gpu.dispose()` took the device with it.
213
+ if (this.#submitted || this.#canceled)
214
+ return;
215
+ assertDeviceUsable(this.device, "Frame.submit");
216
+ this.#submitted = true;
217
+ this.releaseLifecycle?.();
218
+ // Timed and occlusion-queried frames append one resolveQuerySet of each instance's contiguous
219
+ // used range (plus the staging copy) to the still-open frame encoder — zero extra submissions.
220
+ for (const owner of this.#liveOwners())
221
+ owner.finalizeFrame(this, this.#encoder);
222
+ let commandBuffer;
223
+ const finishContext = this.#validations[0]?.context;
224
+ if (finishContext)
225
+ pushClaimedGroupValidationScope(this.device, finishContext);
226
+ try {
227
+ commandBuffer = this.#encoder.finish();
228
+ }
229
+ catch (error) {
230
+ // finish() failed, so the resolves encoded above never reach the queue: nothing may be read
231
+ // back, but every instance still has to release the retain it took when it was attached.
232
+ this.#abandonOwners(this.#frameOwners());
233
+ const result = finishContext ? popLastClaimedGroupValidationScope(this.device) : undefined;
234
+ discardClaimedGroupValidationResults(this.#validations);
235
+ if (result)
236
+ discardClaimedGroupValidationResults([result]);
237
+ const context = result?.context ?? finishContext;
238
+ if (!context)
239
+ throw error;
240
+ this.done = this.#trackDone(this.#deliverValidationError(context.label, context.group, error));
241
+ return;
242
+ }
243
+ if (finishContext) {
244
+ const result = popLastClaimedGroupValidationScope(this.device);
245
+ if (result)
246
+ this.#validations[0] = this.#validations[0] ? preferClaimedGroupValidationResult(result, this.#validations[0]) : result;
247
+ }
248
+ const submitContext = this.#validations[0]?.context;
249
+ if (submitContext)
250
+ pushClaimedGroupValidationScope(this.device, submitContext);
251
+ try {
252
+ this.device.gpu.queue.submit([commandBuffer]);
253
+ }
254
+ catch (error) {
255
+ // Same as the finish() failure: the command buffer never ran, so release the retains and read
256
+ // nothing back — the resolve's staging bytes are stale, not this frame's results.
257
+ this.#abandonOwners(this.#frameOwners());
258
+ const result = submitContext ? popLastClaimedGroupValidationScope(this.device) : undefined;
259
+ discardClaimedGroupValidationResults(this.#validations);
260
+ if (result)
261
+ discardClaimedGroupValidationResults([result]);
262
+ const context = result?.context ?? submitContext;
263
+ if (!context)
264
+ throw error;
265
+ this.done = this.#trackDone(this.#deliverValidationError(context.label, context.group, error));
266
+ return;
267
+ }
268
+ if (submitContext) {
269
+ const result = popLastClaimedGroupValidationScope(this.device);
270
+ if (result)
271
+ this.#validations[0] = this.#validations[0] ? preferClaimedGroupValidationResult(result, this.#validations[0]) : result;
272
+ }
273
+ // The submit succeeded: start each owner's non-blocking readback of this frame's resolve.
274
+ for (const owner of this.#liveOwners())
275
+ owner.frameSubmitted(this);
276
+ // Instances a failed pass dropped are skipped above, so they still hold this frame's retain.
277
+ this.#abandonOwners(this.#discardedOwners);
278
+ this.done = this.#trackDone(claimedGroupValidationDone(this.device, this.#validations, { errorSink: this.errorSink }));
279
+ }
280
+ /**
281
+ * Discards the frame without submitting it: the command encoder is dropped (nothing this frame
282
+ * encoded ever runs) and every telemetry instance it attached releases the retain it took on its
283
+ * query ring, so a `timer(gpu)` / `visibility(gpu)` can be disposed for good without waiting for
284
+ * `gpu.dispose()`. This is the explicit way out of the leak a manual `frame(gpu)` would otherwise
285
+ * hold: a frame is never assumed abandoned, because an old frame can still be submitted.
286
+ *
287
+ * Idempotent, like `submit()`: cancelling twice is a no-op, and `submit()` after `cancel()` does
288
+ * nothing. Cancelling a frame that was already submitted throws `AIGPU-FRAME-SUBMITTED` — its work
289
+ * is on the queue and cannot be taken back, so silently accepting the call would hide a real
290
+ * lifecycle bug.
291
+ */
292
+ cancel() {
293
+ if (this.#canceled)
294
+ return;
295
+ if (this.#submitted)
296
+ throw frameAlreadySubmittedError("Frame.cancel");
297
+ // An active pass descriptor still references telemetry query sets. Releasing their retains here
298
+ // could destroy them before encoder.end(), and the callback could keep encoding after cancel.
299
+ if (this.#passActive)
300
+ throw framePassActiveError("Frame.cancel");
301
+ this.#canceled = true;
302
+ this.releaseLifecycle?.();
303
+ // Nothing is finalized and nothing is read back: the encoded passes never reach the queue, so
304
+ // decoding a resolve would report stale staging bytes as a phantom duration or "hidden".
305
+ this.#abandonOwners(this.#frameOwners());
306
+ this.#owners.clear();
307
+ this.#discardedOwners.clear();
308
+ // The claimed-group validation promises of the dropped encoder are never delivered: no draw of
309
+ // this frame ran, so any native error they carry is about work that was thrown away.
310
+ discardClaimedGroupValidationResults(this.#validations);
311
+ this.#validations.length = 0;
312
+ }
313
+ /**
314
+ * Ends the frame for telemetry instances that will never see a real frameSubmitted: a pass whose
315
+ * callback threw, a frame whose finish/submit failed, or a canceled frame. Each one took a retain
316
+ * on its query ring when it was attached to a pass descriptor (so a mid-frame dispose() cannot
317
+ * destroy a set the frame still points at); without the matching release, a dispose() after the
318
+ * failure leaves the ring alive forever. frameAbandoned() drops the instance's pending encoded
319
+ * state as it releases: a resolve that never reached the queue must not be decoded — its staging
320
+ * buffer holds stale bytes, which would surface as a phantom duration or a phantom "hidden".
321
+ */
322
+ #abandonOwners(owners) {
323
+ for (const owner of [...owners])
324
+ owner.frameAbandoned(this);
325
+ }
326
+ /** Every owner this frame attached, discarded ones included. */
327
+ #frameOwners() {
328
+ return [...this.#owners, ...this.#discardedOwners];
329
+ }
330
+ /** Moves owners out of this frame's live set: they are neither finalized nor read back. */
331
+ #discardOwners(owners) {
332
+ for (const owner of [...owners]) {
333
+ this.#owners.delete(owner);
334
+ this.#discardedOwners.add(owner);
335
+ }
336
+ }
337
+ #liveOwners() {
338
+ return [...this.#owners].filter((owner) => !this.#discardedOwners.has(owner));
339
+ }
340
+ /**
341
+ * Attaches one `FramePassOptions` telemetry value to this pass through the nominal attachment
342
+ * protocol, so the frame never learns whether it is a timer span, a visibility or a future
343
+ * scene-view generation: it only records the owner it must settle exactly once.
344
+ */
345
+ #attach(value, target, attached, invalid) {
346
+ const attachment = framePassAttachmentOf(value);
347
+ if (!attachment)
348
+ throw invalid(value);
349
+ let result;
350
+ try {
351
+ result = attachment[FRAME_PASS_ATTACHMENT]({ frame: this, device: this.device, target });
352
+ }
353
+ catch (error) {
354
+ // A duplicate/capacity failure can land after the same instance already contributed an
355
+ // earlier pass to this frame, and a failed attach cannot report whose bookkeeping it left
356
+ // half-written. Drop every owner of the frame rather than let submit() report the earlier
357
+ // pass as a successful partial frame.
358
+ this.#discardOwners(this.#owners);
359
+ throw error;
360
+ }
361
+ this.#owners.add(result.owner);
362
+ attached.push(result.owner);
363
+ return result;
364
+ }
365
+ async #deliverValidationError(label, group, cause) {
366
+ await submittedWorkDone(this.device);
367
+ assertDeviceUsable(this.device, "Frame.validation");
368
+ const error = claimedGroupNativeValidationError(label, group, cause);
369
+ if (this.errorSink)
370
+ await this.errorSink(error);
371
+ else
372
+ console.error(error);
373
+ }
374
+ #trackDone(promise) {
375
+ this.trackSettled?.(promise);
376
+ return promise;
377
+ }
378
+ }
379
+ export class FramePass {
380
+ encoder;
381
+ target;
382
+ validations;
383
+ depthReadOnly;
384
+ occlusionSource;
385
+ frame;
386
+ assertFrameOpen;
387
+ #occlusionActive = false;
388
+ constructor(encoder, target, validations, depthReadOnly = false, occlusionSource, frame, assertFrameOpen) {
389
+ this.encoder = encoder;
390
+ this.target = target;
391
+ this.validations = validations;
392
+ this.depthReadOnly = depthReadOnly;
393
+ this.occlusionSource = occlusionSource;
394
+ this.frame = frame;
395
+ this.assertFrameOpen = assertFrameOpen;
396
+ }
397
+ draw(drawable, opts = {}) {
398
+ this.assertFrameOpen?.("FramePass.draw");
399
+ const encodable = frameDrawable(drawable);
400
+ if (this.depthReadOnly)
401
+ assertDrawableAllowedInReadOnlyPass(encodable, this.target);
402
+ encodable.encode(this.encoder, this.target, opts, (result) => this.validations.push(result));
403
+ }
404
+ /**
405
+ * Wraps one or more draws in begin/endOcclusionQuery. The body ALWAYS executes; condition your
406
+ * real draws on `q.hidden` outside.
407
+ */
408
+ occlusion(query, body) {
409
+ this.assertFrameOpen?.("FramePass.occlusion");
410
+ if (!this.occlusionSource)
411
+ throw queryNoVisibilityError();
412
+ // WebGPU beginOcclusionQuery: "no occlusion query must be active for this" — one scope at a time.
413
+ if (this.#occlusionActive)
414
+ throw queryNestedError();
415
+ const index = this.occlusionSource.beginQuery(query, this.frame);
416
+ this.encoder.beginOcclusionQuery(index);
417
+ this.#occlusionActive = true;
418
+ try {
419
+ if (typeof body === "function")
420
+ body();
421
+ else
422
+ this.draw(body);
423
+ }
424
+ finally {
425
+ // aigpu's scope shape makes an unclosed query structurally impossible: end in finally, so a
426
+ // throwing body can never leave a query open at pass end (which would invalidate the encoder).
427
+ this.#occlusionActive = false;
428
+ this.encoder.endOcclusionQuery();
429
+ }
430
+ }
431
+ bundles(...bundles) {
432
+ this.assertFrameOpen?.("FramePass.bundles");
433
+ // WebGPU executeBundles: "If this.[[depthReadOnly]] is true, bundle.[[depthReadOnly]] must be true.
434
+ // If this.[[stencilReadOnly]] is true, bundle.[[stencilReadOnly]] must be true." bundle always
435
+ // records bundles with both flags false, so no recorded bundle can replay into a read-only pass;
436
+ // reject up front instead of leaving it to native validation.
437
+ if (this.depthReadOnly)
438
+ throw passDepthReadOnlyError("pass cannot replay bundles: bundle records bundles with writable depth/stencil, and WebGPU only executes read-only-recorded bundles in a read-only pass.", "Encode the draws directly with pass.draw(...) inside the depthReadOnly pass.", "FramePass.bundles");
439
+ const recorded = bundles.map((entry) => frameBundleOf(entry) ?? invalidBundle());
440
+ // Staleness is checked for every bundle before the first one replays: a pass either replays the
441
+ // whole list or none of it.
442
+ for (const entry of recorded)
443
+ entry.assertReplayable(this.target);
444
+ this.encoder.executeBundles(recorded.map((entry) => entry.gpu));
445
+ }
446
+ }
447
+ /**
448
+ * Early equivalent of the WebGPU setPipeline device-timeline checks: "If pipeline.[[writesDepth]]:
449
+ * this.[[depthReadOnly]] must be false. If pipeline.[[writesStencil]]: this.[[stencilReadOnly]] must be
450
+ * false." A depthReadOnly pass marks the stencil aspect read-only too (combined formats), so both are
451
+ * validated here with actionable errors before encoding.
452
+ */
453
+ function assertDrawableAllowedInReadOnlyPass(drawable, target) {
454
+ if (drawable.writesDepth()) {
455
+ throw passDepthReadOnlyError(`pass cannot encode draw '${drawable.label}': its depth state writes depth (the default is write: true). Give the draw depth: { write: false } (or depth: false to disable depth testing).`, "Use depth: { write: false } on the draw, or open the pass without depthReadOnly.", "FramePass.draw");
456
+ }
457
+ if (hasStencilAspect(target.depth?.format)) {
458
+ const ops = drawable.stencilWritingOps();
459
+ if (ops.length) {
460
+ throw passDepthReadOnlyError(`pass cannot encode draw '${drawable.label}': its stencil ops can write (${ops.join(", ")}), and the pass's stencil aspect is read-only too.`, `Use "keep" for those ops or stencil writeMask: 0, or open the pass without depthReadOnly.`, "FramePass.draw");
461
+ }
462
+ }
463
+ }
464
+ /** Nominal drawable protocol of a `Draw` or an `Effect`; the frame never imports either module. */
465
+ function frameDrawable(drawable) {
466
+ const encodable = frameDrawableOf(drawable);
467
+ // Historical message kept: "Invalid Effect instance" is what an unrecognized drawable reported
468
+ // when the frame resolved it by shape.
469
+ if (!encodable)
470
+ throw new TypeError("Invalid Effect instance: pass.draw() expects a Draw or an Effect created by this library.");
471
+ return encodable;
472
+ }
473
+ function invalidBundle() {
474
+ throw new AIGpuError({ code: "AIGPU-R3-BUNDLE-INVALID", message: "p.bundles() expected bundles created by bundle(gpu, { target }, cb).", where: "FramePass.bundles" });
475
+ }
476
+ function timerAttachmentInvalidError(value) {
477
+ return timerInvalidError(`FramePassOptions.timer received ${previewValue(value)}; expected a TimerSpan from timer.span(name).`, `Create const passTimer = timer(gpu) once, then pass passTimer.span("name") per pass.`, "Frame.pass");
478
+ }
479
+ function visibilityAttachmentInvalidError(value) {
480
+ return visibilityInvalidError(`FramePassOptions.visibility received ${previewValue(value)}; expected a Visibility from visibility(gpu).`, "Create const vis = visibility(gpu) once, then pass { target, visibility: vis } per pass.", "Frame.pass");
481
+ }
482
+ /**
483
+ * Mirrors the WebGPU setViewport device-timeline validation (arguments are floats;
484
+ * bounds check against device limits, not the attachment): with maxViewportRange =
485
+ * maxTextureDimension2D × 2, requires x ≥ -maxViewportRange, y ≥ -maxViewportRange,
486
+ * 0 ≤ width/height ≤ maxTextureDimension2D, x + width ≤ maxViewportRange − 1,
487
+ * y + height ≤ maxViewportRange − 1, 0 ≤ minDepth ≤ 1, 0 ≤ maxDepth ≤ 1, and
488
+ * minDepth ≤ maxDepth.
489
+ */
490
+ function validatedViewport(viewport, limits, targetSize) {
491
+ if (viewport === undefined)
492
+ return undefined;
493
+ if (typeof viewport !== "object" || viewport === null || Array.isArray(viewport))
494
+ throw passViewportInvalidError(`received ${previewValue(viewport)}; expected { x?, y?, width, height, minDepth?, maxDepth? }.`);
495
+ const { x = 0, y = 0, width, height, minDepth = 0, maxDepth = 1 } = viewport;
496
+ for (const [name, value] of [["x", x], ["y", y], ["width", width], ["height", height], ["minDepth", minDepth], ["maxDepth", maxDepth]]) {
497
+ if (typeof value !== "number" || !Number.isFinite(value))
498
+ throw passViewportInvalidError(`${name} received ${previewValue(value)}; expected a finite number.`);
499
+ }
500
+ const max = limits.maxTextureDimension2D;
501
+ const maxViewportRange = max * 2;
502
+ const sizeNote = `target is ${targetSize[0]}x${targetSize[1]}px, device maxTextureDimension2D is ${max}`;
503
+ if (!(width >= 0 && width <= max))
504
+ throw passViewportInvalidError(`width ${width} is outside [0, ${max}] (${sizeNote}).`);
505
+ if (!(height >= 0 && height <= max))
506
+ throw passViewportInvalidError(`height ${height} is outside [0, ${max}] (${sizeNote}).`);
507
+ if (!(x >= -maxViewportRange && x + width <= maxViewportRange - 1))
508
+ throw passViewportInvalidError(`x ${x} with width ${width} is outside [${-maxViewportRange}, ${maxViewportRange - 1}] (${sizeNote}).`);
509
+ if (!(y >= -maxViewportRange && y + height <= maxViewportRange - 1))
510
+ throw passViewportInvalidError(`y ${y} with height ${height} is outside [${-maxViewportRange}, ${maxViewportRange - 1}] (${sizeNote}).`);
511
+ if (!(minDepth >= 0 && minDepth <= 1))
512
+ throw passViewportInvalidError(`minDepth ${minDepth} is outside [0, 1].`);
513
+ if (!(maxDepth >= 0 && maxDepth <= 1))
514
+ throw passViewportInvalidError(`maxDepth ${maxDepth} is outside [0, 1].`);
515
+ if (!(minDepth <= maxDepth))
516
+ throw passViewportInvalidError(`minDepth ${minDepth} exceeds maxDepth ${maxDepth}.`);
517
+ return { x, y, width, height, minDepth, maxDepth };
518
+ }
519
+ /**
520
+ * Mirrors the WebGPU setScissorRect validation: arguments are GPUIntegerCoordinate
521
+ * (non-negative integers), and the rectangle must satisfy x + width ≤ attachment
522
+ * width and y + height ≤ attachment height against the target's current size.
523
+ */
524
+ function validatedScissor(scissor, targetSize) {
525
+ if (scissor === undefined)
526
+ return undefined;
527
+ if (!Array.isArray(scissor) || scissor.length !== 4)
528
+ throw passScissorInvalidError(`received ${previewValue(scissor)}; expected [x, y, width, height].`);
529
+ const [x, y, width, height] = scissor;
530
+ for (const [name, value] of [["x", x], ["y", y], ["width", width], ["height", height]]) {
531
+ if (typeof value !== "number" || !Number.isInteger(value) || value < 0)
532
+ throw passScissorInvalidError(`${name} received ${previewValue(value)}; expected a non-negative integer.`);
533
+ }
534
+ const [targetWidth, targetHeight] = targetSize;
535
+ if (x + width > targetWidth || y + height > targetHeight) {
536
+ throw passScissorInvalidError(`[${x}, ${y}, ${width}, ${height}] exceeds the target's current size ${targetWidth}x${targetHeight}px (x + width <= ${targetWidth}, y + height <= ${targetHeight}).`);
537
+ }
538
+ return [x, y, width, height];
539
+ }
540
+ function previewValue(value) {
541
+ if (typeof value === "string")
542
+ return `'${value}'`;
543
+ if (Array.isArray(value))
544
+ return `[${value.map((entry) => previewValue(entry)).join(", ")}]`;
545
+ if (typeof value === "object" && value !== null)
546
+ return "an object";
547
+ return String(value);
548
+ }
549
+ /** True for the "the device this frame belongs to is gone" errors raised by the liveness guards. */
550
+ function isDeviceGoneError(error) {
551
+ const code = error?.code;
552
+ return code === "AIGPU-DEVICE-DISPOSED" || code === "AIGPU-DEVICE-LOST";
553
+ }
554
+ export class FrameRunner {
555
+ createFrame;
556
+ advance;
557
+ trackLoop;
558
+ #running = false;
559
+ /**
560
+ * @param trackLoop Lifecycle hook for the owning gpu: called with each started loop handle and
561
+ * returns the untrack function the handle runs when it stops on its own, so `gpu.dispose()` can
562
+ * stop the loops still running without holding on to the ones already stopped.
563
+ */
564
+ constructor(createFrame, advance, trackLoop) {
565
+ this.createFrame = createFrame;
566
+ this.advance = advance;
567
+ this.trackLoop = trackLoop;
568
+ }
569
+ frame(cb) {
570
+ if (this.#running || isSurfaceResizeCallbackActive())
571
+ throw frameReentrantError();
572
+ this.#running = true;
573
+ enterFrame();
574
+ try {
575
+ this.advance();
576
+ const frame = this.createFrame();
577
+ if (cb) {
578
+ try {
579
+ cb(frame);
580
+ }
581
+ finally {
582
+ // A callback is allowed to dispose the owning gpu (gpu.dispose() inside a loop tick does
583
+ // exactly that). The device is then gone and the frame has nothing left to flush, so this
584
+ // implicit submit swallows that one error instead of throwing over the callback's own
585
+ // intent — the same reason a canceled frame submits as a no-op. An explicit
586
+ // frame.submit() on a dead device still reports it.
587
+ try {
588
+ frame.submit();
589
+ }
590
+ catch (error) {
591
+ if (!isDeviceGoneError(error))
592
+ throw error;
593
+ }
594
+ }
595
+ }
596
+ return frame;
597
+ }
598
+ finally {
599
+ leaveFrame();
600
+ this.#running = false;
601
+ }
602
+ }
603
+ loop(cb, opts = {}) {
604
+ let stopped = false;
605
+ const request = globalThis.requestAnimationFrame ?? ((fn) => setTimeout(() => fn(performance.now()), 16));
606
+ const cancel = globalThis.cancelAnimationFrame ?? ((id) => clearTimeout(id));
607
+ const minIntervalMs = opts.fps && opts.fps > 0 ? 1000 / opts.fps : 0;
608
+ let lastFrameMs;
609
+ let id = 0;
610
+ const tick = (timestamp) => {
611
+ if (stopped)
612
+ return;
613
+ if (shouldRunFrame(timestamp, lastFrameMs, minIntervalMs)) {
614
+ lastFrameMs = timestamp;
615
+ this.frame(cb);
616
+ }
617
+ // The callback may dispose the owning gpu, which stops this loop while the current tick is
618
+ // running. Do not enqueue one last (no-op) tick after stop() already canceled the old id.
619
+ if (!stopped)
620
+ id = request(tick);
621
+ };
622
+ id = request(tick);
623
+ // Registered with the owning gpu so gpu.dispose() stops it: a loop left running would keep
624
+ // encoding frames against a disposed device. Stopping is idempotent and drops the registration.
625
+ let untrack;
626
+ const handle = {
627
+ stop() {
628
+ stopped = true;
629
+ cancel(id);
630
+ untrack?.();
631
+ untrack = undefined;
632
+ },
633
+ };
634
+ untrack = this.trackLoop?.(handle);
635
+ return handle;
636
+ }
637
+ }
638
+ function shouldRunFrame(timestamp, lastFrameMs, minIntervalMs) {
639
+ if (lastFrameMs === undefined)
640
+ return true;
641
+ if (minIntervalMs <= 0)
642
+ return true;
643
+ return timestamp - lastFrameMs >= minIntervalMs;
644
+ }
645
+ //# sourceMappingURL=frame.js.map