@forgeax/engine-app 0.0.0-dev.8d955ade1c79

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 (348) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +424 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/__tests__/animation-asset-lookup.unit.test.d.ts +2 -0
  5. package/dist/__tests__/animation-asset-lookup.unit.test.d.ts.map +1 -0
  6. package/dist/__tests__/callback-deletion.unit.test.d.ts +2 -0
  7. package/dist/__tests__/callback-deletion.unit.test.d.ts.map +1 -0
  8. package/dist/__tests__/callback-inference.test-d.d.ts +2 -0
  9. package/dist/__tests__/callback-inference.test-d.d.ts.map +1 -0
  10. package/dist/__tests__/component-introspection.unit.test.d.ts +2 -0
  11. package/dist/__tests__/component-introspection.unit.test.d.ts.map +1 -0
  12. package/dist/__tests__/consumer-migration.unit.test.d.ts +2 -0
  13. package/dist/__tests__/consumer-migration.unit.test.d.ts.map +1 -0
  14. package/dist/__tests__/create-app-error-retention.integration.test.d.ts +2 -0
  15. package/dist/__tests__/create-app-error-retention.integration.test.d.ts.map +1 -0
  16. package/dist/__tests__/create-app-features.test.d.ts +2 -0
  17. package/dist/__tests__/create-app-features.test.d.ts.map +1 -0
  18. package/dist/__tests__/create-app-listener-sync.test.d.ts +2 -0
  19. package/dist/__tests__/create-app-listener-sync.test.d.ts.map +1 -0
  20. package/dist/__tests__/create-app-lock-provider.test.d.ts +2 -0
  21. package/dist/__tests__/create-app-lock-provider.test.d.ts.map +1 -0
  22. package/dist/__tests__/create-app-physics-plugin-failure.integration.test.d.ts +2 -0
  23. package/dist/__tests__/create-app-physics-plugin-failure.integration.test.d.ts.map +1 -0
  24. package/dist/__tests__/create-app-plugin.test.d.ts +2 -0
  25. package/dist/__tests__/create-app-plugin.test.d.ts.map +1 -0
  26. package/dist/__tests__/create-app-stop.test.d.ts +2 -0
  27. package/dist/__tests__/create-app-stop.test.d.ts.map +1 -0
  28. package/dist/__tests__/create-app-time.unit.test.d.ts +2 -0
  29. package/dist/__tests__/create-app-time.unit.test.d.ts.map +1 -0
  30. package/dist/__tests__/create-app.test-d.d.ts +2 -0
  31. package/dist/__tests__/create-app.test-d.d.ts.map +1 -0
  32. package/dist/__tests__/create-app.test.d.ts +2 -0
  33. package/dist/__tests__/create-app.test.d.ts.map +1 -0
  34. package/dist/__tests__/create-renderer-error.integration.test.d.ts +2 -0
  35. package/dist/__tests__/create-renderer-error.integration.test.d.ts.map +1 -0
  36. package/dist/__tests__/create-renderer-lifecycle.integration.test.d.ts +2 -0
  37. package/dist/__tests__/create-renderer-lifecycle.integration.test.d.ts.map +1 -0
  38. package/dist/__tests__/docs-gate-green.unit.test.d.ts +2 -0
  39. package/dist/__tests__/docs-gate-green.unit.test.d.ts.map +1 -0
  40. package/dist/__tests__/draw-source-injected-world-update-visibility.test.d.ts +2 -0
  41. package/dist/__tests__/draw-source-injected-world-update-visibility.test.d.ts.map +1 -0
  42. package/dist/__tests__/draw-source-single-world-regression.test.d.ts +2 -0
  43. package/dist/__tests__/draw-source-single-world-regression.test.d.ts.map +1 -0
  44. package/dist/__tests__/engine-worker-bootstrap-channel.unit.test.d.ts +2 -0
  45. package/dist/__tests__/engine-worker-bootstrap-channel.unit.test.d.ts.map +1 -0
  46. package/dist/__tests__/engine-worker-world-swap.unit.test.d.ts +2 -0
  47. package/dist/__tests__/engine-worker-world-swap.unit.test.d.ts.map +1 -0
  48. package/dist/__tests__/errors-pointer-lock-failed.test.d.ts +2 -0
  49. package/dist/__tests__/errors-pointer-lock-failed.test.d.ts.map +1 -0
  50. package/dist/__tests__/execution-bootstrap-isolation.unit.test.d.ts +2 -0
  51. package/dist/__tests__/execution-bootstrap-isolation.unit.test.d.ts.map +1 -0
  52. package/dist/__tests__/execution-error-detail.test-d.d.ts +2 -0
  53. package/dist/__tests__/execution-error-detail.test-d.d.ts.map +1 -0
  54. package/dist/__tests__/execution-error-detail.unit.test.d.ts +2 -0
  55. package/dist/__tests__/execution-error-detail.unit.test.d.ts.map +1 -0
  56. package/dist/__tests__/execution-frame-order.unit.test.d.ts +2 -0
  57. package/dist/__tests__/execution-frame-order.unit.test.d.ts.map +1 -0
  58. package/dist/__tests__/execution-frame-protocol.unit.test.d.ts +2 -0
  59. package/dist/__tests__/execution-frame-protocol.unit.test.d.ts.map +1 -0
  60. package/dist/__tests__/execution-input-sample.contract.test.d.ts +2 -0
  61. package/dist/__tests__/execution-input-sample.contract.test.d.ts.map +1 -0
  62. package/dist/__tests__/execution-measurement.unit.test.d.ts +2 -0
  63. package/dist/__tests__/execution-measurement.unit.test.d.ts.map +1 -0
  64. package/dist/__tests__/execution-public-api.test-d.d.ts +2 -0
  65. package/dist/__tests__/execution-public-api.test-d.d.ts.map +1 -0
  66. package/dist/__tests__/execution-public-api.unit.test.d.ts +2 -0
  67. package/dist/__tests__/execution-public-api.unit.test.d.ts.map +1 -0
  68. package/dist/__tests__/execution-rebuild.contract.test.d.ts +2 -0
  69. package/dist/__tests__/execution-rebuild.contract.test.d.ts.map +1 -0
  70. package/dist/__tests__/execution-report.contract.test.d.ts +2 -0
  71. package/dist/__tests__/execution-report.contract.test.d.ts.map +1 -0
  72. package/dist/__tests__/execution-report.types.test-d.d.ts +2 -0
  73. package/dist/__tests__/execution-report.types.test-d.d.ts.map +1 -0
  74. package/dist/__tests__/execution-schema-freshness.unit.test.d.ts +2 -0
  75. package/dist/__tests__/execution-schema-freshness.unit.test.d.ts.map +1 -0
  76. package/dist/__tests__/execution-selector.unit.test.d.ts +2 -0
  77. package/dist/__tests__/execution-selector.unit.test.d.ts.map +1 -0
  78. package/dist/__tests__/execution-shared-kernel.unit.test.d.ts +2 -0
  79. package/dist/__tests__/execution-shared-kernel.unit.test.d.ts.map +1 -0
  80. package/dist/__tests__/fallback-camera.unit.test.d.ts +2 -0
  81. package/dist/__tests__/fallback-camera.unit.test.d.ts.map +1 -0
  82. package/dist/__tests__/frame-loop-time-elapsed.test.d.ts +2 -0
  83. package/dist/__tests__/frame-loop-time-elapsed.test.d.ts.map +1 -0
  84. package/dist/__tests__/frame-loop-time.unit.test.d.ts +2 -0
  85. package/dist/__tests__/frame-loop-time.unit.test.d.ts.map +1 -0
  86. package/dist/__tests__/frame-loop-world-array.test.d.ts +2 -0
  87. package/dist/__tests__/frame-loop-world-array.test.d.ts.map +1 -0
  88. package/dist/__tests__/kernel-worker-runtime.unit.test.d.ts +2 -0
  89. package/dist/__tests__/kernel-worker-runtime.unit.test.d.ts.map +1 -0
  90. package/dist/__tests__/migration-surface-inventory.unit.test.d.ts +2 -0
  91. package/dist/__tests__/migration-surface-inventory.unit.test.d.ts.map +1 -0
  92. package/dist/__tests__/plugin-policy.integration.test.d.ts +2 -0
  93. package/dist/__tests__/plugin-policy.integration.test.d.ts.map +1 -0
  94. package/dist/__tests__/plugin-profiles.unit.test.d.ts +2 -0
  95. package/dist/__tests__/plugin-profiles.unit.test.d.ts.map +1 -0
  96. package/dist/__tests__/profiler-default-off.test.d.ts +2 -0
  97. package/dist/__tests__/profiler-default-off.test.d.ts.map +1 -0
  98. package/dist/__tests__/profiler-frame-token.test.d.ts +2 -0
  99. package/dist/__tests__/profiler-frame-token.test.d.ts.map +1 -0
  100. package/dist/__tests__/profiler-phase-catalog.test.d.ts +2 -0
  101. package/dist/__tests__/profiler-phase-catalog.test.d.ts.map +1 -0
  102. package/dist/__tests__/profiler-phase-integration.test.d.ts +2 -0
  103. package/dist/__tests__/profiler-phase-integration.test.d.ts.map +1 -0
  104. package/dist/__tests__/profiler-remote-bridge.test.d.ts +2 -0
  105. package/dist/__tests__/profiler-remote-bridge.test.d.ts.map +1 -0
  106. package/dist/__tests__/remote-integration.test.d.ts +2 -0
  107. package/dist/__tests__/remote-integration.test.d.ts.map +1 -0
  108. package/dist/__tests__/rhi-capture-capability.test-d.d.ts +2 -0
  109. package/dist/__tests__/rhi-capture-capability.test-d.d.ts.map +1 -0
  110. package/dist/__tests__/rhi-capture-host.integration.test.d.ts +2 -0
  111. package/dist/__tests__/rhi-capture-host.integration.test.d.ts.map +1 -0
  112. package/dist/__tests__/rhi-capture.browser.test.d.ts +2 -0
  113. package/dist/__tests__/rhi-capture.browser.test.d.ts.map +1 -0
  114. package/dist/__tests__/surface-handoff.test.d.ts +2 -0
  115. package/dist/__tests__/surface-handoff.test.d.ts.map +1 -0
  116. package/dist/__tests__/types-m2.test-d.d.ts +2 -0
  117. package/dist/__tests__/types-m2.test-d.d.ts.map +1 -0
  118. package/dist/__tests__/visibility-remote.integration.test.d.ts +2 -0
  119. package/dist/__tests__/visibility-remote.integration.test.d.ts.map +1 -0
  120. package/dist/__tests__/worker-execution-stop.test.d.ts +2 -0
  121. package/dist/__tests__/worker-execution-stop.test.d.ts.map +1 -0
  122. package/dist/animation-asset-lookup.d.ts +7 -0
  123. package/dist/animation-asset-lookup.d.ts.map +1 -0
  124. package/dist/browser-frame-signal.d.ts +17 -0
  125. package/dist/browser-frame-signal.d.ts.map +1 -0
  126. package/dist/canvas-policy.d.ts +4 -0
  127. package/dist/canvas-policy.d.ts.map +1 -0
  128. package/dist/create-app.d.ts +78 -0
  129. package/dist/create-app.d.ts.map +1 -0
  130. package/dist/engine-worker-runtime.mjs +827 -0
  131. package/dist/engine-worker-runtime.mjs.map +1 -0
  132. package/dist/errors.d.ts +254 -0
  133. package/dist/errors.d.ts.map +1 -0
  134. package/dist/execution/attached-world-swap.d.ts +10 -0
  135. package/dist/execution/attached-world-swap.d.ts.map +1 -0
  136. package/dist/execution/bootstrap-entry.d.ts +30 -0
  137. package/dist/execution/bootstrap-entry.d.ts.map +1 -0
  138. package/dist/execution/bootstrap-url.d.ts +5 -0
  139. package/dist/execution/bootstrap-url.d.ts.map +1 -0
  140. package/dist/execution/capabilities.d.ts +5 -0
  141. package/dist/execution/capabilities.d.ts.map +1 -0
  142. package/dist/execution/control.d.ts +12 -0
  143. package/dist/execution/control.d.ts.map +1 -0
  144. package/dist/execution/engine-worker-runtime.d.ts +2 -0
  145. package/dist/execution/engine-worker-runtime.d.ts.map +1 -0
  146. package/dist/execution/engine-worker.d.ts +24 -0
  147. package/dist/execution/engine-worker.d.ts.map +1 -0
  148. package/dist/execution/host-controller.d.ts +16 -0
  149. package/dist/execution/host-controller.d.ts.map +1 -0
  150. package/dist/execution/index.d.ts +10 -0
  151. package/dist/execution/index.d.ts.map +1 -0
  152. package/dist/execution/kernel-pool.d.ts +14 -0
  153. package/dist/execution/kernel-pool.d.ts.map +1 -0
  154. package/dist/execution/kernel-worker-runtime.d.ts +2 -0
  155. package/dist/execution/kernel-worker-runtime.d.ts.map +1 -0
  156. package/dist/execution/measurement.d.ts +7 -0
  157. package/dist/execution/measurement.d.ts.map +1 -0
  158. package/dist/execution/protocol.d.ts +87 -0
  159. package/dist/execution/protocol.d.ts.map +1 -0
  160. package/dist/execution/report.d.ts +5 -0
  161. package/dist/execution/report.d.ts.map +1 -0
  162. package/dist/execution/schema.d.ts +4 -0
  163. package/dist/execution/schema.d.ts.map +1 -0
  164. package/dist/execution/selector.d.ts +10 -0
  165. package/dist/execution/selector.d.ts.map +1 -0
  166. package/dist/execution/types.d.ts +123 -0
  167. package/dist/execution/types.d.ts.map +1 -0
  168. package/dist/fallback-camera.d.ts +8 -0
  169. package/dist/fallback-camera.d.ts.map +1 -0
  170. package/dist/game-context.d.ts +98 -0
  171. package/dist/game-context.d.ts.map +1 -0
  172. package/dist/index.d.ts +27 -0
  173. package/dist/index.d.ts.map +1 -0
  174. package/dist/index.mjs +3980 -0
  175. package/dist/index.mjs.map +1 -0
  176. package/dist/input-map-plugin.d.ts +5 -0
  177. package/dist/input-map-plugin.d.ts.map +1 -0
  178. package/dist/input-plugin.d.ts +4 -0
  179. package/dist/input-plugin.d.ts.map +1 -0
  180. package/dist/internal/assembled-engine-profile.d.ts +5 -0
  181. package/dist/internal/assembled-engine-profile.d.ts.map +1 -0
  182. package/dist/internal/assets-world-plugin.d.ts +7 -0
  183. package/dist/internal/assets-world-plugin.d.ts.map +1 -0
  184. package/dist/internal/browser-remote-bridge.d.ts +24 -0
  185. package/dist/internal/browser-remote-bridge.d.ts.map +1 -0
  186. package/dist/internal/browser-rhi-debug-runtime.d.ts +18 -0
  187. package/dist/internal/browser-rhi-debug-runtime.d.ts.map +1 -0
  188. package/dist/internal/component-introspection.d.ts +24 -0
  189. package/dist/internal/component-introspection.d.ts.map +1 -0
  190. package/dist/internal/debug-draw.d.ts +9 -0
  191. package/dist/internal/debug-draw.d.ts.map +1 -0
  192. package/dist/internal/ecs-import.d.ts +6 -0
  193. package/dist/internal/ecs-import.d.ts.map +1 -0
  194. package/dist/internal/engine-profile-common.d.ts +9 -0
  195. package/dist/internal/engine-profile-common.d.ts.map +1 -0
  196. package/dist/internal/error-fanout.d.ts +66 -0
  197. package/dist/internal/error-fanout.d.ts.map +1 -0
  198. package/dist/internal/frame-loop.d.ts +38 -0
  199. package/dist/internal/frame-loop.d.ts.map +1 -0
  200. package/dist/internal/input-attach.d.ts +44 -0
  201. package/dist/internal/input-attach.d.ts.map +1 -0
  202. package/dist/internal/main-engine-profile.d.ts +19 -0
  203. package/dist/internal/main-engine-profile.d.ts.map +1 -0
  204. package/dist/internal/remote-serve-flag.d.ts +19 -0
  205. package/dist/internal/remote-serve-flag.d.ts.map +1 -0
  206. package/dist/internal/remote-server-plugin.d.ts +8 -0
  207. package/dist/internal/remote-server-plugin.d.ts.map +1 -0
  208. package/dist/internal/rhi-capture.d.ts +19 -0
  209. package/dist/internal/rhi-capture.d.ts.map +1 -0
  210. package/dist/internal/rhi-debug-flag.d.ts +18 -0
  211. package/dist/internal/rhi-debug-flag.d.ts.map +1 -0
  212. package/dist/internal/worker-engine-profile.d.ts +15 -0
  213. package/dist/internal/worker-engine-profile.d.ts.map +1 -0
  214. package/dist/kernel-worker-runtime.mjs +69 -0
  215. package/dist/kernel-worker-runtime.mjs.map +1 -0
  216. package/dist/load-game-errors.d.ts +131 -0
  217. package/dist/load-game-errors.d.ts.map +1 -0
  218. package/dist/load-game.d.ts +34 -0
  219. package/dist/load-game.d.ts.map +1 -0
  220. package/dist/plugin-factories.d.ts +3 -0
  221. package/dist/plugin-factories.d.ts.map +1 -0
  222. package/dist/renderer-plugin.d.ts +25 -0
  223. package/dist/renderer-plugin.d.ts.map +1 -0
  224. package/dist/tool-preview/bootstrap.d.ts +113 -0
  225. package/dist/tool-preview/bootstrap.d.ts.map +1 -0
  226. package/dist/tool-preview/evidence.d.ts +20 -0
  227. package/dist/tool-preview/evidence.d.ts.map +1 -0
  228. package/dist/tool-preview/framing.d.ts +13 -0
  229. package/dist/tool-preview/framing.d.ts.map +1 -0
  230. package/dist/tool-preview/recipe.d.ts +54 -0
  231. package/dist/tool-preview/recipe.d.ts.map +1 -0
  232. package/dist/types.d.ts +404 -0
  233. package/dist/types.d.ts.map +1 -0
  234. package/package.json +85 -0
  235. package/schema/execution-report.schema.json +168 -0
  236. package/src/__tests__/animation-asset-lookup.unit.test.ts +20 -0
  237. package/src/__tests__/callback-deletion.unit.test.ts +14 -0
  238. package/src/__tests__/callback-inference.test-d.ts +36 -0
  239. package/src/__tests__/component-introspection.unit.test.ts +56 -0
  240. package/src/__tests__/consumer-migration.unit.test.ts +34 -0
  241. package/src/__tests__/create-app-error-retention.integration.test.ts +125 -0
  242. package/src/__tests__/create-app-features.test.ts +51 -0
  243. package/src/__tests__/create-app-listener-sync.test.ts +381 -0
  244. package/src/__tests__/create-app-lock-provider.test.ts +212 -0
  245. package/src/__tests__/create-app-physics-plugin-failure.integration.test.ts +142 -0
  246. package/src/__tests__/create-app-plugin.test.ts +217 -0
  247. package/src/__tests__/create-app-stop.test.ts +609 -0
  248. package/src/__tests__/create-app-time.unit.test.ts +26 -0
  249. package/src/__tests__/create-app.test-d.ts +83 -0
  250. package/src/__tests__/create-app.test.ts +287 -0
  251. package/src/__tests__/create-renderer-error.integration.test.ts +25 -0
  252. package/src/__tests__/create-renderer-lifecycle.integration.test.ts +24 -0
  253. package/src/__tests__/docs-gate-green.unit.test.ts +61 -0
  254. package/src/__tests__/draw-source-injected-world-update-visibility.test.ts +176 -0
  255. package/src/__tests__/draw-source-single-world-regression.test.ts +184 -0
  256. package/src/__tests__/engine-worker-bootstrap-channel.unit.test.ts +82 -0
  257. package/src/__tests__/engine-worker-world-swap.unit.test.ts +69 -0
  258. package/src/__tests__/errors-pointer-lock-failed.test.ts +265 -0
  259. package/src/__tests__/execution-bootstrap-isolation.unit.test.ts +79 -0
  260. package/src/__tests__/execution-error-detail.test-d.ts +13 -0
  261. package/src/__tests__/execution-error-detail.unit.test.ts +35 -0
  262. package/src/__tests__/execution-frame-order.unit.test.ts +38 -0
  263. package/src/__tests__/execution-frame-protocol.unit.test.ts +60 -0
  264. package/src/__tests__/execution-input-sample.contract.test.ts +23 -0
  265. package/src/__tests__/execution-measurement.unit.test.ts +20 -0
  266. package/src/__tests__/execution-public-api.test-d.ts +14 -0
  267. package/src/__tests__/execution-public-api.unit.test.ts +9 -0
  268. package/src/__tests__/execution-rebuild.contract.test.ts +36 -0
  269. package/src/__tests__/execution-report.contract.test.ts +50 -0
  270. package/src/__tests__/execution-report.types.test-d.ts +16 -0
  271. package/src/__tests__/execution-schema-freshness.unit.test.ts +20 -0
  272. package/src/__tests__/execution-selector.unit.test.ts +72 -0
  273. package/src/__tests__/execution-shared-kernel.unit.test.ts +180 -0
  274. package/src/__tests__/fallback-camera.unit.test.ts +32 -0
  275. package/src/__tests__/frame-loop-time-elapsed.test.ts +115 -0
  276. package/src/__tests__/frame-loop-time.unit.test.ts +61 -0
  277. package/src/__tests__/frame-loop-world-array.test.ts +450 -0
  278. package/src/__tests__/kernel-worker-runtime.unit.test.ts +50 -0
  279. package/src/__tests__/migration-surface-inventory.unit.test.ts +13 -0
  280. package/src/__tests__/plugin-policy.integration.test.ts +15 -0
  281. package/src/__tests__/plugin-profiles.unit.test.ts +190 -0
  282. package/src/__tests__/profiler-default-off.test.ts +53 -0
  283. package/src/__tests__/profiler-frame-token.test.ts +235 -0
  284. package/src/__tests__/profiler-phase-catalog.test.ts +30 -0
  285. package/src/__tests__/profiler-phase-integration.test.ts +117 -0
  286. package/src/__tests__/profiler-remote-bridge.test.ts +31 -0
  287. package/src/__tests__/remote-integration.test.ts +224 -0
  288. package/src/__tests__/rhi-capture-capability.test-d.ts +22 -0
  289. package/src/__tests__/rhi-capture-host.integration.test.ts +157 -0
  290. package/src/__tests__/rhi-capture.browser.test.ts +51 -0
  291. package/src/__tests__/surface-handoff.test.ts +89 -0
  292. package/src/__tests__/types-m2.test-d.ts +81 -0
  293. package/src/__tests__/visibility-remote.integration.test.ts +116 -0
  294. package/src/__tests__/worker-execution-stop.test.ts +173 -0
  295. package/src/animation-asset-lookup.ts +13 -0
  296. package/src/browser-frame-signal.ts +44 -0
  297. package/src/canvas-policy.ts +16 -0
  298. package/src/create-app.ts +1264 -0
  299. package/src/errors.ts +442 -0
  300. package/src/execution/attached-world-swap.ts +33 -0
  301. package/src/execution/bootstrap-entry.ts +122 -0
  302. package/src/execution/bootstrap-url.ts +25 -0
  303. package/src/execution/capabilities.ts +102 -0
  304. package/src/execution/control.ts +48 -0
  305. package/src/execution/engine-worker-runtime.ts +383 -0
  306. package/src/execution/engine-worker.ts +163 -0
  307. package/src/execution/host-controller.ts +460 -0
  308. package/src/execution/index.ts +44 -0
  309. package/src/execution/kernel-pool.ts +236 -0
  310. package/src/execution/kernel-worker-runtime.ts +103 -0
  311. package/src/execution/measurement.ts +39 -0
  312. package/src/execution/protocol.ts +134 -0
  313. package/src/execution/report.ts +66 -0
  314. package/src/execution/schema.ts +168 -0
  315. package/src/execution/selector.ts +98 -0
  316. package/src/execution/types.ts +163 -0
  317. package/src/fallback-camera.ts +20 -0
  318. package/src/game-context.ts +126 -0
  319. package/src/index.ts +190 -0
  320. package/src/input-map-plugin.ts +21 -0
  321. package/src/input-plugin.ts +26 -0
  322. package/src/internal/assembled-engine-profile.ts +14 -0
  323. package/src/internal/assets-world-plugin.ts +33 -0
  324. package/src/internal/browser-remote-bridge.ts +269 -0
  325. package/src/internal/browser-rhi-debug-runtime.ts +67 -0
  326. package/src/internal/component-introspection.ts +116 -0
  327. package/src/internal/debug-draw.ts +38 -0
  328. package/src/internal/ecs-import.ts +41 -0
  329. package/src/internal/engine-profile-common.ts +9 -0
  330. package/src/internal/error-fanout.ts +129 -0
  331. package/src/internal/frame-loop.ts +539 -0
  332. package/src/internal/input-attach.ts +104 -0
  333. package/src/internal/main-engine-profile.ts +84 -0
  334. package/src/internal/remote-serve-flag.ts +41 -0
  335. package/src/internal/remote-server-plugin.ts +16 -0
  336. package/src/internal/rhi-capture.ts +211 -0
  337. package/src/internal/rhi-debug-flag.ts +40 -0
  338. package/src/internal/worker-engine-profile.ts +47 -0
  339. package/src/load-game-errors.ts +211 -0
  340. package/src/load-game.ts +115 -0
  341. package/src/plugin-factories.ts +2 -0
  342. package/src/renderer-plugin.ts +96 -0
  343. package/src/tool-preview/bootstrap.ts +835 -0
  344. package/src/tool-preview/evidence.ts +59 -0
  345. package/src/tool-preview/framing.ts +52 -0
  346. package/src/tool-preview/recipe.ts +137 -0
  347. package/src/types.ts +450 -0
  348. package/src/vite-env.d.ts +10 -0
@@ -0,0 +1,460 @@
1
+ import { createHostAudioConsumer } from '@forgeax/engine-audio-webaudio';
2
+ import { attachBrowserInputBackend, type InputBackend } from '@forgeax/engine-input';
3
+ import { err, ok, type Result } from '@forgeax/engine-types';
4
+ import { APP_ERROR_HINTS, APP_EXPECTED, AppError, type AppError as AppErrorType } from '../errors';
5
+ import { ErrorFanoutRegistry } from '../internal/error-fanout';
6
+ import type { BundlerOptions, CanvasDrawingBufferSize } from '../types';
7
+ import {
8
+ APP_PHASE_CATALOG,
9
+ type AppDispatchError,
10
+ type CreateAppOptions,
11
+ type ExecutionApp,
12
+ } from '../types';
13
+ import { normalizeExecutionBootstrapUrl } from './bootstrap-url';
14
+ import { cloneExecutionReport } from './control';
15
+ import { type EngineWorkerSession, startEngineWorker } from './engine-worker';
16
+ import { createMeasurementSeries } from './measurement';
17
+ import {
18
+ type EngineToHostMessage,
19
+ type ExecutionFaultMessage,
20
+ FrameCreditLedger,
21
+ } from './protocol';
22
+ import { createExecutionReport, executionAudioReport } from './report';
23
+ import type {
24
+ ExecutionCapabilities,
25
+ ExecutionControl,
26
+ ExecutionReport,
27
+ ExecutionSelection,
28
+ } from './types';
29
+
30
+ export interface CreateWorkerExecutionAppOptions {
31
+ readonly canvas: HTMLCanvasElement;
32
+ readonly appOptions: CreateAppOptions;
33
+ /** Host-owned resize policy applied before each frame sent to the worker. */
34
+ readonly syncCanvas?: () => CanvasDrawingBufferSize;
35
+ readonly bundler?: BundlerOptions;
36
+ readonly capabilities: ExecutionCapabilities;
37
+ readonly selection: ExecutionSelection;
38
+ }
39
+
40
+ function lifecycleError(code: 'app-not-started' | 'app-already-running'): AppErrorType {
41
+ return new AppError({
42
+ code,
43
+ expected: APP_EXPECTED[code],
44
+ hint: APP_ERROR_HINTS[code],
45
+ detail: {},
46
+ });
47
+ }
48
+
49
+ function runtimeError(message: ExecutionFaultMessage): AppErrorType {
50
+ if (message.code === 'shared-kernel-failed' && message.worldIdentity !== null) {
51
+ return new AppError({
52
+ code: 'app-execution-kernel-failed',
53
+ expected: APP_EXPECTED['app-execution-kernel-failed'],
54
+ hint: APP_ERROR_HINTS['app-execution-kernel-failed'],
55
+ detail: {
56
+ kernelName: (message.detail as { kernelName?: string })?.kernelName ?? 'unknown',
57
+ worldIdentity: message.worldIdentity,
58
+ cause: message.detail,
59
+ partialWrite: true,
60
+ retryable: false,
61
+ },
62
+ });
63
+ }
64
+ return new AppError({
65
+ code: 'app-system-update-failed',
66
+ expected: APP_EXPECTED['app-system-update-failed'],
67
+ hint: APP_ERROR_HINTS['app-system-update-failed'],
68
+ detail: { cause: message.detail },
69
+ });
70
+ }
71
+
72
+ export async function createWorkerExecutionApp(
73
+ options: CreateWorkerExecutionAppOptions,
74
+ ): Promise<Result<ExecutionApp, AppErrorType>> {
75
+ const executionOptions = options.appOptions.execution;
76
+ if (executionOptions === undefined) throw new Error('execution options are required');
77
+ const normalizedBootstrap = normalizeExecutionBootstrapUrl(executionOptions.bootstrap);
78
+ if (!normalizedBootstrap.ok) return normalizedBootstrap;
79
+ const bootstrapUrl = normalizedBootstrap.value;
80
+ const startupTimeoutMs = executionOptions.startupTimeoutMs ?? 10_000;
81
+ const frameTimeoutMs = executionOptions.frameTimeoutMs ?? 2_000;
82
+ const syncCanvas = options.syncCanvas;
83
+ const started = await startEngineWorker({
84
+ canvas: options.canvas,
85
+ bootstrapUrl,
86
+ ...(executionOptions.bootstrapData === undefined
87
+ ? {}
88
+ : { bootstrapData: executionOptions.bootstrapData }),
89
+ ...(executionOptions.bootstrapPort === undefined
90
+ ? {}
91
+ : { bootstrapPort: executionOptions.bootstrapPort }),
92
+ ...(executionOptions.assetCatalog === undefined
93
+ ? {}
94
+ : { assetCatalog: executionOptions.assetCatalog }),
95
+ ...(options.bundler?.shaderManifestUrl !== undefined
96
+ ? { shaderManifestUrl: options.bundler.shaderManifestUrl }
97
+ : {}),
98
+ ...(options.appOptions.time !== undefined ? { time: options.appOptions.time } : {}),
99
+ timeoutMs: startupTimeoutMs,
100
+ tier: options.selection.actualTier,
101
+ });
102
+ if (!started.ok) return started;
103
+
104
+ const session: EngineWorkerSession = started.value;
105
+ const profiler = options.appOptions.profiler;
106
+ const phaseCatalogRegistration = profiler?.registerPhaseCatalog('app', APP_PHASE_CATALOG);
107
+ let releasePhaseCatalog =
108
+ phaseCatalogRegistration?.ok === true ? phaseCatalogRegistration.value : undefined;
109
+ const fanout = new ErrorFanoutRegistry(
110
+ options.appOptions.silenceUnhandledErrors === undefined
111
+ ? {}
112
+ : { silenceUnhandledErrors: options.appOptions.silenceUnhandledErrors },
113
+ );
114
+ const inputHandle =
115
+ options.appOptions.input === undefined
116
+ ? attachBrowserInputBackend(options.canvas, {
117
+ ...(options.appOptions.uiRoot !== undefined ? { uiRoot: options.appOptions.uiRoot } : {}),
118
+ ...(options.appOptions.pointerLockAllowed !== undefined
119
+ ? { pointerLockAllowed: options.appOptions.pointerLockAllowed }
120
+ : {}),
121
+ ...(options.appOptions.virtualJoysticks !== undefined
122
+ ? { virtualJoysticks: options.appOptions.virtualJoysticks }
123
+ : {}),
124
+ ...(options.appOptions.lockProvider !== undefined
125
+ ? { lockProvider: options.appOptions.lockProvider }
126
+ : {}),
127
+ onLockError: (detail) =>
128
+ fanout.fire(
129
+ new AppError({
130
+ code: 'app-pointer-lock-failed',
131
+ expected: APP_EXPECTED['app-pointer-lock-failed'],
132
+ hint: APP_ERROR_HINTS['app-pointer-lock-failed'],
133
+ detail,
134
+ }),
135
+ ),
136
+ })
137
+ : undefined;
138
+ const input: InputBackend = options.appOptions.input ??
139
+ inputHandle?.backend ?? {
140
+ sample: () => ({
141
+ downKeys: new Set(),
142
+ upKeys: new Set(),
143
+ buttons: [false, false, false],
144
+ movementX: 0,
145
+ movementY: 0,
146
+ wheelDelta: 0,
147
+ focused: true,
148
+ pointerLocked: false,
149
+ }),
150
+ detach: () => {},
151
+ };
152
+
153
+ let report: ExecutionReport = {
154
+ ...createExecutionReport(
155
+ executionOptions.tier ?? 'auto',
156
+ options.capabilities,
157
+ options.selection,
158
+ ),
159
+ engine: { realm: 'worker', health: 'idle' },
160
+ world: {
161
+ identity: session.ready.worldIdentity,
162
+ health: 'healthy',
163
+ partialWrite: false,
164
+ retryable: true,
165
+ },
166
+ };
167
+ let state: 'idle' | 'running' | 'paused' | 'stopped' | 'faulted' = 'idle';
168
+ let ledger = new FrameCreditLedger(session.ready.worldIdentity);
169
+ let rafId = 0;
170
+ let lastTimestamp = 0;
171
+ let frameDeadline: ReturnType<typeof setTimeout> | undefined;
172
+ let lastError: AppDispatchError | undefined;
173
+ let rebuildResolve: ((result: Result<ExecutionReport, AppErrorType>) => void) | undefined;
174
+ let rebuildInFlight: Promise<Result<ExecutionReport, AppErrorType>> | undefined;
175
+ const hostFrameMeasurements = createMeasurementSeries();
176
+ const engineMeasurements = createMeasurementSeries();
177
+ const kernelMeasurements = createMeasurementSeries();
178
+ const audioMeasurements = createMeasurementSeries();
179
+ let audio = createHostAudioConsumer();
180
+ let frameSentAt = 0;
181
+ let profilerCaptureId: string | undefined;
182
+ let profilerFrameId = 0;
183
+ let frameProfile = profiler?.activeSession();
184
+ let profileFrameOpen = false;
185
+ let hostFrameOpen = false;
186
+
187
+ const setEngineHealth = (health: ExecutionReport['engine']['health']): void => {
188
+ report = { ...report, engine: { ...report.engine, health } };
189
+ };
190
+
191
+ const finishProfile = (): void => {
192
+ if (hostFrameOpen) frameProfile?.endPhase();
193
+ if (profileFrameOpen) frameProfile?.endFrame();
194
+ frameProfile = undefined;
195
+ profileFrameOpen = false;
196
+ hostFrameOpen = false;
197
+ try {
198
+ profiler?.activeSession()?.finish();
199
+ } catch {}
200
+ releasePhaseCatalog?.();
201
+ releasePhaseCatalog = undefined;
202
+ };
203
+
204
+ const terminalFault = (message: ExecutionFaultMessage): void => {
205
+ if (frameDeadline !== undefined) {
206
+ clearTimeout(frameDeadline);
207
+ frameDeadline = undefined;
208
+ }
209
+ const error = runtimeError(message);
210
+ lastError = error;
211
+ state = message.partialWrite ? 'faulted' : 'stopped';
212
+ report = {
213
+ ...report,
214
+ engine: { ...report.engine, health: 'faulted' },
215
+ world: {
216
+ identity: message.worldIdentity,
217
+ health: message.partialWrite ? 'poisoned' : report.world.health,
218
+ partialWrite: message.partialWrite,
219
+ retryable: message.retryable,
220
+ },
221
+ kernelDispatch: {
222
+ ...report.kernelDispatch,
223
+ reason: message.partialWrite ? 'poisoned' : report.kernelDispatch.reason,
224
+ },
225
+ fault: {
226
+ source: message.source,
227
+ code: message.code,
228
+ expected: message.expected,
229
+ hint: message.hint,
230
+ detail: message.detail,
231
+ partialWrite: message.partialWrite,
232
+ retryable: message.retryable,
233
+ },
234
+ };
235
+ fanout.fire(error);
236
+ if (!message.partialWrite) {
237
+ audio.dispose();
238
+ session.dispose();
239
+ }
240
+ finishProfile();
241
+ };
242
+
243
+ const scheduleFrame = (): void => {
244
+ rafId = requestAnimationFrame((timestamp) => {
245
+ if (state !== 'running') return;
246
+ const deltaSeconds =
247
+ lastTimestamp === 0 ? 0 : Math.max(0, (timestamp - lastTimestamp) / 1_000);
248
+ lastTimestamp = timestamp;
249
+ const canvasSize =
250
+ syncCanvas?.() ??
251
+ ({
252
+ width: options.canvas.width,
253
+ height: options.canvas.height,
254
+ } satisfies CanvasDrawingBufferSize);
255
+ const frame = ledger.issue(deltaSeconds, () => input.sample(), canvasSize);
256
+ if (frame === undefined) return;
257
+ frameProfile = profiler?.activeSession();
258
+ if (frameProfile !== undefined && profilerCaptureId !== frameProfile.captureId) {
259
+ profilerCaptureId = frameProfile.captureId;
260
+ profilerFrameId = 0;
261
+ }
262
+ profileFrameOpen = frameProfile?.beginFrame(++profilerFrameId).ok ?? false;
263
+ hostFrameOpen = profileFrameOpen
264
+ ? (frameProfile?.beginPhase('app', 'host-frame').ok ?? false)
265
+ : false;
266
+ session.post(frame);
267
+ frameSentAt = performance.now();
268
+ frameDeadline = setTimeout(() => {
269
+ if (state !== 'running') return;
270
+ terminalFault({
271
+ kind: 'fault',
272
+ worldIdentity: report.world.identity,
273
+ source: 'runtime',
274
+ code: 'app-execution-deadline-exceeded',
275
+ expected: APP_EXPECTED['app-execution-deadline-exceeded'],
276
+ hint: APP_ERROR_HINTS['app-execution-deadline-exceeded'],
277
+ detail: { phase: 'frame', timeoutMs: frameTimeoutMs },
278
+ partialWrite: false,
279
+ retryable: false,
280
+ });
281
+ }, frameTimeoutMs);
282
+ });
283
+ };
284
+
285
+ session.listen((message: EngineToHostMessage) => {
286
+ if (message.kind === 'frame-complete') {
287
+ if (ledger.complete(message) !== 'accepted') return;
288
+ if (frameDeadline !== undefined) clearTimeout(frameDeadline);
289
+ if (hostFrameOpen) frameProfile?.endPhase();
290
+ if (profileFrameOpen) {
291
+ frameProfile?.recordSkip({
292
+ source: 'app',
293
+ phase: 'engine-update',
294
+ reason: `worker-report:${message.engineUpdateMs.toFixed(3)}ms`,
295
+ });
296
+ frameProfile?.recordSkip({
297
+ source: 'app',
298
+ phase: 'kernel-wait',
299
+ reason: `worker-report:${message.kernelWaitMs.toFixed(3)}ms`,
300
+ });
301
+ }
302
+ const audioStarted = performance.now();
303
+ const audioProfileOpen = profileFrameOpen
304
+ ? (frameProfile?.beginPhase('app', 'host-audio').ok ?? false)
305
+ : false;
306
+ for (const intent of message.audioIntents ?? []) audio.consume(intent);
307
+ if (audioProfileOpen) frameProfile?.endPhase();
308
+ const audioMs = performance.now() - audioStarted;
309
+ report = {
310
+ ...report,
311
+ performance: {
312
+ ...report.performance,
313
+ hostFrameMs: hostFrameMeasurements.add(performance.now() - frameSentAt),
314
+ engineUpdateMs: engineMeasurements.add(message.engineUpdateMs),
315
+ kernelWaitMs: kernelMeasurements.add(message.kernelWaitMs),
316
+ hostAudioMs: audioMeasurements.add(audioMs),
317
+ },
318
+ };
319
+ if (message.kernelDispatch !== undefined) {
320
+ report = { ...report, kernelDispatch: message.kernelDispatch };
321
+ }
322
+ if (profileFrameOpen) frameProfile?.endFrame();
323
+ frameProfile = undefined;
324
+ profileFrameOpen = false;
325
+ hostFrameOpen = false;
326
+ if (state === 'running') scheduleFrame();
327
+ } else if (message.kind === 'fault') {
328
+ terminalFault(message);
329
+ } else if (message.kind === 'rebuilt') {
330
+ audio.dispose();
331
+ audio = createHostAudioConsumer();
332
+ ledger = new FrameCreditLedger(message.worldIdentity);
333
+ hostFrameMeasurements.clear();
334
+ engineMeasurements.clear();
335
+ kernelMeasurements.clear();
336
+ audioMeasurements.clear();
337
+ state = 'idle';
338
+ report = {
339
+ ...report,
340
+ engine: { ...report.engine, health: 'idle' },
341
+ world: {
342
+ identity: message.worldIdentity,
343
+ health: 'healthy',
344
+ partialWrite: false,
345
+ retryable: true,
346
+ },
347
+ kernelDispatch: {
348
+ eligible: false,
349
+ usedShared: false,
350
+ reason: 'no-eligible-kernel',
351
+ dispatched: 0,
352
+ completed: 0,
353
+ },
354
+ fault: null,
355
+ performance: {
356
+ hostFrameMs: null,
357
+ engineUpdateMs: null,
358
+ kernelWaitMs: null,
359
+ hostAudioMs: null,
360
+ },
361
+ };
362
+ rebuildResolve?.(ok(cloneExecutionReport(report)));
363
+ rebuildResolve = undefined;
364
+ rebuildInFlight = undefined;
365
+ } else if (message.kind === 'host-control') {
366
+ if (message.command === 'set-pointer-lock-allowed') {
367
+ input.setPointerLockAllowed?.(message.allowed);
368
+ }
369
+ }
370
+ });
371
+
372
+ const execution: ExecutionControl = {
373
+ report: () =>
374
+ cloneExecutionReport({
375
+ ...report,
376
+ audio: executionAudioReport(audio.state()),
377
+ }),
378
+ rebuild: () => {
379
+ if (rebuildInFlight !== undefined) return rebuildInFlight;
380
+ if (state !== 'faulted' || report.world.identity === null) {
381
+ return Promise.resolve(
382
+ err(
383
+ new AppError({
384
+ code: 'app-execution-rebuild-failed',
385
+ expected: APP_EXPECTED['app-execution-rebuild-failed'],
386
+ hint: APP_ERROR_HINTS['app-execution-rebuild-failed'],
387
+ detail: {
388
+ worldIdentity: report.world.identity,
389
+ cause: new Error('World is not in a rebuildable poisoned state.'),
390
+ },
391
+ }),
392
+ ),
393
+ );
394
+ }
395
+ rebuildInFlight = new Promise((resolve) => {
396
+ rebuildResolve = resolve;
397
+ session.post({ kind: 'rebuild', worldIdentity: report.world.identity as string });
398
+ setTimeout(() => {
399
+ if (rebuildResolve !== resolve) return;
400
+ rebuildResolve = undefined;
401
+ rebuildInFlight = undefined;
402
+ resolve(
403
+ err(
404
+ new AppError({
405
+ code: 'app-execution-deadline-exceeded',
406
+ expected: APP_EXPECTED['app-execution-deadline-exceeded'],
407
+ hint: APP_ERROR_HINTS['app-execution-deadline-exceeded'],
408
+ detail: { phase: 'handshake', timeoutMs: startupTimeoutMs },
409
+ }),
410
+ ),
411
+ );
412
+ }, startupTimeoutMs);
413
+ });
414
+ return rebuildInFlight;
415
+ },
416
+ };
417
+
418
+ const app: ExecutionApp = {
419
+ execution,
420
+ input,
421
+ start: () => {
422
+ if (state === 'running') return err(lifecycleError('app-already-running'));
423
+ if (state === 'stopped' || state === 'faulted') return err(lifecycleError('app-not-started'));
424
+ state = 'running';
425
+ setEngineHealth('running');
426
+ lastTimestamp = 0;
427
+ scheduleFrame();
428
+ return ok(undefined);
429
+ },
430
+ stop: () => {
431
+ if (state !== 'running' && state !== 'paused') return err(lifecycleError('app-not-started'));
432
+ if (state === 'running') cancelAnimationFrame(rafId);
433
+ state = 'stopped';
434
+ inputHandle?.();
435
+ audio.dispose();
436
+ session.dispose();
437
+ setEngineHealth('stopped');
438
+ finishProfile();
439
+ return ok(undefined);
440
+ },
441
+ pause: () => {
442
+ if (state !== 'running') return err(lifecycleError('app-not-started'));
443
+ state = 'paused';
444
+ cancelAnimationFrame(rafId);
445
+ return ok(undefined);
446
+ },
447
+ resume: () => {
448
+ if (state !== 'paused') return err(lifecycleError('app-not-started'));
449
+ state = 'running';
450
+ lastTimestamp = 0;
451
+ scheduleFrame();
452
+ return ok(undefined);
453
+ },
454
+ onError: (listener) => fanout.add(listener),
455
+ get lastError() {
456
+ return lastError;
457
+ },
458
+ };
459
+ return ok(app);
460
+ }
@@ -0,0 +1,44 @@
1
+ export type {
2
+ ExecutionBootstrapEntry,
3
+ ExecutionBootstrapHost,
4
+ PreparedExecutionBootstrap,
5
+ } from './bootstrap-entry';
6
+ export {
7
+ executionBootstrapHostPlugin,
8
+ loadBootstrapEntry,
9
+ prepareBootstrapEntry,
10
+ validateExecutionBootstrapData,
11
+ } from './bootstrap-entry';
12
+ export {
13
+ missingExecutionCapabilities,
14
+ probeExecutionCapabilities,
15
+ unavailableExecutionCapabilities,
16
+ } from './capabilities';
17
+ export { cloneExecutionReport } from './control';
18
+ export { createExecutionReport } from './report';
19
+ export { EXECUTION_REPORT_SCHEMA_VERSION, isExecutionReport } from './schema';
20
+ export { type ExecutionSelectionInput, selectExecutionTier } from './selector';
21
+ export type {
22
+ ExecutionAssetCatalog,
23
+ ExecutionBootstrapValue,
24
+ ExecutionCapabilities,
25
+ ExecutionCapabilityFact,
26
+ ExecutionCapabilityName,
27
+ ExecutionControl,
28
+ ExecutionEngineHealth,
29
+ ExecutionFault,
30
+ ExecutionMeasurement,
31
+ ExecutionOptions,
32
+ ExecutionReport,
33
+ ExecutionRequestedTier,
34
+ ExecutionSelection,
35
+ ExecutionSelectionReason,
36
+ ExecutionTier,
37
+ ExecutionWorldHealth,
38
+ KernelDispatchReason,
39
+ } from './types';
40
+ export {
41
+ EXECUTION_CAPABILITY_NAMES,
42
+ EXECUTION_REQUESTED_TIERS,
43
+ EXECUTION_TIERS,
44
+ } from './types';