@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,827 @@
1
+ import { createAudioIntentBackend, audioBackendPlugin } from '@forgeax/engine-audio';
2
+ import { World, createWorldContext, Update } from '@forgeax/engine-ecs';
3
+ import { constructRuntimeRendererHost } from '@forgeax/engine-runtime/internal/renderer-host';
4
+ import { renderComponentsPlugin, Camera, CAMERA_PROJECTION_PERSPECTIVE } from '@forgeax/engine-render';
5
+ import { animationPayloadsPlugin, animationRuntimePlugin } from '@forgeax/engine-animation';
6
+ import { inputBackendPlugin, INPUT_BACKEND_KEY, InputSet, InputFrameStartScan } from '@forgeax/engine-input';
7
+ import { scenePlugin } from '@forgeax/engine-scene';
8
+ import { statePlugin } from '@forgeax/engine-state';
9
+ import { err, ok } from '@forgeax/engine-types';
10
+ import { splitSharedSpan, bindSharedSpan, isSharedSpan } from '@forgeax/engine-ecs/shared';
11
+
12
+ // src/execution/engine-worker-runtime.ts
13
+
14
+ // src/animation-asset-lookup.ts
15
+ function createAnimationPayloadLookup(source) {
16
+ return (guid) => source?.lookup(guid);
17
+ }
18
+ function syncCameraAspect(world, canvasW, canvasH) {
19
+ if (canvasW <= 0 || canvasH <= 0) return;
20
+ const aspect = canvasW / canvasH;
21
+ const query = world.query({ with: [Camera] }).unwrap();
22
+ for (const row of query) {
23
+ const camera = world.get(row.entity, Camera);
24
+ if (!camera.ok) continue;
25
+ if (camera.value.autoAspect !== true) continue;
26
+ if (camera.value.projection !== CAMERA_PROJECTION_PERSPECTIVE) continue;
27
+ world.set(row.entity, Camera, { aspect });
28
+ }
29
+ }
30
+ function inputPlugin() {
31
+ return {
32
+ name: "input",
33
+ inject: ["world", "input"],
34
+ apply(ctx) {
35
+ const world = ctx.world;
36
+ const input = ctx.input;
37
+ if (input === void 0) throw new Error("Cordis activated input without its provider");
38
+ ctx.effect(() => {
39
+ world.insertResource(INPUT_BACKEND_KEY, input);
40
+ return () => {
41
+ world.removeResource(INPUT_BACKEND_KEY);
42
+ };
43
+ }, "input/resource");
44
+ ctx.effect(() => {
45
+ world.addSystems(Update, InputSet, [InputFrameStartScan]).unwrap();
46
+ return () => world.removeSystem(Update, InputFrameStartScan.name);
47
+ }, "input/frame-start-scan");
48
+ }
49
+ };
50
+ }
51
+
52
+ // src/renderer-plugin.ts
53
+ function createRenderFeatureHost(host) {
54
+ return {
55
+ async installFeature(feature) {
56
+ const installed = await host.installRenderFeature(feature);
57
+ if (!installed.ok) return installed;
58
+ let released = false;
59
+ return {
60
+ ok: true,
61
+ value: {
62
+ release: async () => {
63
+ if (released) return { ok: true, value: void 0 };
64
+ released = true;
65
+ return host.uninstallRenderFeature(feature);
66
+ }
67
+ }
68
+ };
69
+ }
70
+ };
71
+ }
72
+ function ownedRendererPlugin(renderer2) {
73
+ return {
74
+ name: "renderer",
75
+ provide: "renderer",
76
+ apply(ctx) {
77
+ ctx.provide("renderer", renderer2);
78
+ ctx.effect(() => () => renderer2.dispose(), "render/renderer");
79
+ }
80
+ };
81
+ }
82
+ function renderFeatureHostPlugin(host) {
83
+ return {
84
+ name: "render-feature-host",
85
+ provide: "renderFeatureHost",
86
+ apply(ctx) {
87
+ ctx.provide("renderFeatureHost", host);
88
+ }
89
+ };
90
+ }
91
+
92
+ // src/internal/assets-world-plugin.ts
93
+ var ASSET_REGISTRY_RESOURCE_KEY = "AssetRegistry";
94
+ function rendererAssetsPlugin(assets2) {
95
+ return {
96
+ name: "renderer-assets",
97
+ inject: ["renderer"],
98
+ provide: "assets",
99
+ apply(ctx) {
100
+ if (assets2 !== void 0) ctx.provide("assets", assets2);
101
+ }
102
+ };
103
+ }
104
+ function assetsWorldPlugin() {
105
+ return {
106
+ name: "assets-world",
107
+ inject: ["world", "assets"],
108
+ apply(ctx) {
109
+ if (ctx.assets === void 0) return;
110
+ ctx.effect(() => {
111
+ ctx.world.insertResource(ASSET_REGISTRY_RESOURCE_KEY, ctx.assets);
112
+ return () => {
113
+ ctx.world.removeResource(ASSET_REGISTRY_RESOURCE_KEY);
114
+ };
115
+ }, "assets/world-resource");
116
+ }
117
+ };
118
+ }
119
+
120
+ // src/internal/worker-engine-profile.ts
121
+ function workerEngineProfile(options) {
122
+ return [
123
+ ownedRendererPlugin(options.renderer),
124
+ renderComponentsPlugin(),
125
+ ...options.rendererFeatureHost === void 0 ? [] : [renderFeatureHostPlugin(options.rendererFeatureHost)],
126
+ rendererAssetsPlugin(options.assets),
127
+ assetsWorldPlugin(),
128
+ inputBackendPlugin(options.input),
129
+ audioBackendPlugin(options.audio),
130
+ scenePlugin(),
131
+ animationPayloadsPlugin(options.animationPayloads),
132
+ animationRuntimePlugin(),
133
+ statePlugin(),
134
+ inputPlugin(),
135
+ ...options.extensions ?? []
136
+ ];
137
+ }
138
+
139
+ // src/execution/attached-world-swap.ts
140
+ var SerializedRebuildQueue = class {
141
+ tail = Promise.resolve();
142
+ enqueue(action) {
143
+ const current = this.tail.then(action, action);
144
+ this.tail = current.catch(() => void 0);
145
+ return current;
146
+ }
147
+ };
148
+ async function commitAttachedWorld(renderer2, nextWorld, initializeCandidate) {
149
+ const attached = renderer2.attach(nextWorld);
150
+ if (!attached.ok) throw attached.error;
151
+ try {
152
+ if (!await initializeCandidate()) {
153
+ attached.value.dispose();
154
+ return false;
155
+ }
156
+ } catch (cause) {
157
+ attached.value.dispose();
158
+ throw cause;
159
+ }
160
+ return true;
161
+ }
162
+
163
+ // src/errors.ts
164
+ function summarizeCause(cause) {
165
+ if (cause === null || cause === void 0) return String(cause);
166
+ if (typeof cause !== "object") return String(cause);
167
+ const r = cause;
168
+ const name = typeof r.name === "string" && r.name.length > 0 ? r.name : "Error";
169
+ const code = typeof r.code === "string" && r.code.length > 0 ? r.code : "";
170
+ const message = typeof r.message === "string" ? r.message : "";
171
+ const head = code !== "" ? `${name} ${code}` : name;
172
+ const body = message !== "" ? `: ${message}` : "";
173
+ return `${head}${body}`.replace(/\s*\n+\s*/g, " / ");
174
+ }
175
+ var AppErrorClass = class extends Error {
176
+ code;
177
+ expected;
178
+ hint;
179
+ detail;
180
+ constructor(args) {
181
+ let causeSuffix = "";
182
+ if (args.code === "app-system-update-failed") {
183
+ const d = args.detail;
184
+ const sys = typeof d.systemName === "string" && d.systemName.length > 0 ? ` (system=${d.systemName})` : "";
185
+ causeSuffix = `; cause: ${summarizeCause(d.cause)}${sys}`;
186
+ } else if (args.code === "app-pointer-lock-failed") {
187
+ const d = args.detail;
188
+ causeSuffix = `; path: ${d.path}; cause: ${summarizeCause(d.cause)}`;
189
+ } else if (args.code === "app-plugin-activation-failed") {
190
+ const d = args.detail;
191
+ causeSuffix = `; cause: ${summarizeCause(d.cause)}`;
192
+ } else if (args.code === "app-execution-bootstrap-failed") {
193
+ const d = args.detail;
194
+ causeSuffix = `; phase: ${d.phase}; cause: ${summarizeCause(d.cause)}`;
195
+ } else if (args.code === "app-execution-kernel-failed") {
196
+ const d = args.detail;
197
+ causeSuffix = `; kernel: ${d.kernelName}; cause: ${summarizeCause(d.cause)}`;
198
+ } else if (args.code === "app-execution-rebuild-failed") {
199
+ const d = args.detail;
200
+ causeSuffix = `; cause: ${summarizeCause(d.cause)}`;
201
+ }
202
+ super(`[AppError ${args.code}] expected: ${args.expected}; hint: ${args.hint}${causeSuffix}`);
203
+ this.name = "AppError";
204
+ this.code = args.code;
205
+ this.expected = args.expected;
206
+ this.hint = args.hint;
207
+ this.detail = args.detail;
208
+ }
209
+ };
210
+ var AppError = AppErrorClass;
211
+ var appErrorPolicy = {
212
+ "app-not-started": {
213
+ expected: 'state must be "running" or "paused" to accept stop/pause/resume; "idle" / "stopped" terminal sinks reject',
214
+ hint: "check getState() before calling stop/pause/resume; rebuild the handle via createApp({...}) when the previous one terminated on device-lost"
215
+ },
216
+ "app-already-running": {
217
+ expected: 'state must be "idle" or "paused" to start; "running" handles ignore subsequent start() calls',
218
+ hint: "call stop() first or audit start() call sites; the second start() is a no-op so state is preserved"
219
+ },
220
+ "app-canvas-detached": {
221
+ expected: "canvas.isConnected === true at createApp(canvas) entry",
222
+ hint: "append the canvas to the document tree before calling createApp(canvas), or use the assemble entry createApp({ renderer, world }) when the host already manages canvas lifetime"
223
+ },
224
+ "app-frame-step-invalid": {
225
+ expected: "stepFrame(deltaSeconds) runs only while the App is paused and deltaSeconds is finite and non-negative",
226
+ hint: "pause the App before deterministic stepping and pass an explicit finite delta; resume after the bounded step sequence completes"
227
+ },
228
+ "app-system-update-failed": {
229
+ expected: "world.update(world), renderer.draw(world), and frame-loop callbacks complete without failure",
230
+ hint: "inspect detail.cause for the original thrown value (EcsError / RhiError / host system bug); detail.systemName names the offending system when the call site can supply it"
231
+ },
232
+ "app-pointer-lock-failed": {
233
+ expected: "pointer-lock request (W3C requestPointerLock or host lockProvider.requestLock) to succeed; failure signals the browser rejected the lock or the host provider threw",
234
+ hint: 'remain in unlocked state; the next trusted click will automatically retry the lock request. inspect detail.path ("w3c" or "provider") and detail.cause to determine the root cause'
235
+ },
236
+ "app-plugin-activation-failed": {
237
+ expected: "every requested Cordis plugin fiber reaches a stable active or pending state",
238
+ hint: "inspect detail.cause and the plugin fiber effects; repair the failing activation before creating the App again"
239
+ },
240
+ "app-execution-tier-unavailable": {
241
+ expected: "the explicitly requested execution tier has every required observed capability and the shipped shared evidence gate",
242
+ hint: 'inspect detail.missingCapabilities and detail.sharedEvidencePassed; use tier="auto" only when an observed fallback is acceptable'
243
+ },
244
+ "app-execution-bootstrap-failed": {
245
+ expected: "the bootstrap URL imports a module whose default export completes as an ExecutionBootstrapEntry in the selected Engine Realm",
246
+ hint: "inspect detail.phase, moduleUrl and cause; export one default ExecutionBootstrapEntry that creates only realm-local engine state"
247
+ },
248
+ "app-execution-deadline-exceeded": {
249
+ expected: "the execution startup, handshake or frame completes within its configured bounded deadline",
250
+ hint: "inspect detail.phase and timeoutMs; the timed-out Worker has been terminated, so fix startup or frame work before creating a new App"
251
+ },
252
+ "app-execution-kernel-failed": {
253
+ expected: "a shared kernel completes every dispatched shard without leaving a possibly partial World write",
254
+ hint: "do not retry or draw the poisoned World; inspect detail.kernelName and cause, then call app.execution.rebuild()"
255
+ },
256
+ "app-execution-stale-world": {
257
+ expected: "every execution message targets the currently active World identity before it can write",
258
+ hint: "discard the late message and keep the current World; inspect expectedIdentity, receivedIdentity and messageKind"
259
+ },
260
+ "app-execution-rebuild-failed": {
261
+ expected: "explicit rebuild disposes the poisoned World and bootstraps a fresh World identity in the surviving Engine Realm",
262
+ hint: "inspect detail.cause; this App remains stopped, so fix the bootstrap failure or create a new App explicitly"
263
+ }
264
+ };
265
+ var APP_EXPECTED = Object.fromEntries(
266
+ Object.entries(appErrorPolicy).map(([code, policy]) => [code, policy.expected])
267
+ );
268
+ var APP_ERROR_HINTS = Object.fromEntries(
269
+ Object.entries(appErrorPolicy).map(([code, policy]) => [code, policy.hint])
270
+ );
271
+
272
+ // src/execution/bootstrap-entry.ts
273
+ function executionBootstrapHostPlugin(host) {
274
+ return {
275
+ name: "execution-bootstrap-host",
276
+ provide: "executionBootstrapHost",
277
+ apply(ctx) {
278
+ ctx.provide("executionBootstrapHost", host);
279
+ if (host.port !== void 0) {
280
+ ctx.effect(() => () => host.port?.close(), "execution/bootstrap-port");
281
+ }
282
+ }
283
+ };
284
+ }
285
+ function bootstrapError(phase, moduleUrl, cause) {
286
+ return new AppError({
287
+ code: "app-execution-bootstrap-failed",
288
+ expected: APP_EXPECTED["app-execution-bootstrap-failed"],
289
+ hint: APP_ERROR_HINTS["app-execution-bootstrap-failed"],
290
+ detail: { phase, moduleUrl, cause }
291
+ });
292
+ }
293
+ function validateExecutionBootstrapData(data, moduleUrl) {
294
+ if (data === void 0) return ok(void 0);
295
+ try {
296
+ structuredClone(data);
297
+ return ok(void 0);
298
+ } catch (cause) {
299
+ return err(bootstrapError("data", moduleUrl, cause));
300
+ }
301
+ }
302
+ async function loadBootstrapEntry(moduleUrl) {
303
+ let loaded;
304
+ try {
305
+ loaded = await import(
306
+ /* @vite-ignore */
307
+ moduleUrl
308
+ );
309
+ } catch (cause) {
310
+ return err(bootstrapError("import", moduleUrl, cause));
311
+ }
312
+ const entry = loaded.default;
313
+ if (typeof entry !== "function") {
314
+ return err(
315
+ bootstrapError(
316
+ "export",
317
+ moduleUrl,
318
+ new TypeError("default export is not an ExecutionBootstrapEntry function")
319
+ )
320
+ );
321
+ }
322
+ return ok(entry);
323
+ }
324
+ async function prepareBootstrapEntry(moduleUrl, data) {
325
+ const valid = validateExecutionBootstrapData(data, moduleUrl);
326
+ if (!valid.ok) return valid;
327
+ const loaded = await loadBootstrapEntry(moduleUrl);
328
+ if (!loaded.ok) return loaded;
329
+ try {
330
+ const prepared = await loaded.value(data);
331
+ if (typeof prepared !== "object" || prepared === null || prepared.features !== void 0 && !Array.isArray(prepared.features) || prepared.plugins !== void 0 && !Array.isArray(prepared.plugins)) {
332
+ return err(
333
+ bootstrapError(
334
+ "prepare",
335
+ moduleUrl,
336
+ new TypeError("execution bootstrap must return an object with feature and plugin arrays")
337
+ )
338
+ );
339
+ }
340
+ return ok(prepared);
341
+ } catch (cause) {
342
+ return err(bootstrapError("prepare", moduleUrl, cause));
343
+ }
344
+ }
345
+ function createKernelPool(options = {}) {
346
+ const hardware = globalThis.navigator?.hardwareConcurrency ?? 2;
347
+ const laneCount = Math.max(1, Math.min(options.lanes ?? hardware - 1, 8));
348
+ const timeoutMs = options.timeoutMs ?? 5e3;
349
+ const workers = Array.from(
350
+ { length: laneCount },
351
+ () => options.workerFactory?.() ?? new Worker(new URL("./kernel-worker-runtime.mjs", import.meta.url), {
352
+ type: "module",
353
+ name: "forgeax-kernel"
354
+ })
355
+ );
356
+ let latest = null;
357
+ let ready = false;
358
+ const preflights = /* @__PURE__ */ new Map();
359
+ const readyControl = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
360
+ const initMessage = { kind: "kernel-init", ready: readyControl };
361
+ for (const worker of workers) worker.postMessage(initMessage);
362
+ const waitFor = (control, expected, label) => new Promise((resolve, reject) => {
363
+ const started = performance.now();
364
+ const poll = () => {
365
+ if (Atomics.load(control, 0) === expected) {
366
+ resolve();
367
+ return;
368
+ }
369
+ if (performance.now() - started >= timeoutMs) {
370
+ for (const worker of workers) worker.terminate();
371
+ reject(new Error(`${label} did not complete within ${timeoutMs}ms.`));
372
+ return;
373
+ }
374
+ setTimeout(poll, 1);
375
+ };
376
+ poll();
377
+ });
378
+ const readyPromise = waitFor(
379
+ readyControl,
380
+ workers.length,
381
+ "SharedKernel worker initialization"
382
+ ).then(async () => {
383
+ for (const [moduleUrl, preflight] of preflights) {
384
+ await waitFor(
385
+ preflight.control,
386
+ workers.length,
387
+ `SharedKernel module preflight for ${moduleUrl}`
388
+ );
389
+ if (preflight.status.some((status) => status !== 1)) {
390
+ throw new Error(`SharedKernel module preflight failed for ${moduleUrl}.`);
391
+ }
392
+ }
393
+ ready = true;
394
+ });
395
+ return {
396
+ laneCount,
397
+ ready: () => readyPromise,
398
+ warmup(kernel) {
399
+ if (preflights.has(kernel.moduleUrl)) return;
400
+ const control = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
401
+ const status = new Int32Array(
402
+ new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * workers.length)
403
+ );
404
+ preflights.set(kernel.moduleUrl, { control, status });
405
+ for (const [jobIndex, worker] of workers.entries()) {
406
+ const message = {
407
+ kind: "kernel-preload",
408
+ moduleUrl: kernel.moduleUrl,
409
+ control,
410
+ status,
411
+ jobIndex
412
+ };
413
+ worker.postMessage(message);
414
+ }
415
+ },
416
+ takeLastDispatch: () => {
417
+ const dispatch = latest;
418
+ latest = null;
419
+ return dispatch;
420
+ },
421
+ execute(kernel, spans) {
422
+ const preflight = preflights.get(kernel.moduleUrl);
423
+ if (preflight === void 0) {
424
+ this.warmup?.(kernel);
425
+ latest = { mode: "forced-inline", dispatched: 0, completed: 0, waitMs: 0 };
426
+ return {
427
+ cause: new Error("SharedKernel module was not preflighted before frame dispatch."),
428
+ dispatched: 0,
429
+ completed: 0,
430
+ partialWrite: false
431
+ };
432
+ }
433
+ if (Atomics.load(preflight.control, 0) !== workers.length || preflight.status.some((status2) => status2 !== 1)) {
434
+ latest = { mode: "forced-inline", dispatched: 0, completed: 0, waitMs: 0 };
435
+ return {
436
+ cause: new Error("SharedKernel module preflight is incomplete or failed."),
437
+ dispatched: 0,
438
+ completed: 0,
439
+ partialWrite: false
440
+ };
441
+ }
442
+ if (!ready && Atomics.load(readyControl, 0) === workers.length) ready = true;
443
+ if (!ready) {
444
+ latest = { mode: "forced-inline", dispatched: 0, completed: 0, waitMs: 0 };
445
+ return {
446
+ cause: new Error("SharedKernel workers were not warmed before frame dispatch."),
447
+ dispatched: 0,
448
+ completed: 0,
449
+ partialWrite: false
450
+ };
451
+ }
452
+ const bindings = spans.flatMap(
453
+ ({ queryIndex, span }) => splitSharedSpan(bindSharedSpan(kernel, span, queryIndex), laneCount)
454
+ );
455
+ if (bindings.length === 0) {
456
+ latest = { mode: "forced-inline", dispatched: 0, completed: 0, waitMs: 0 };
457
+ return latest;
458
+ }
459
+ if (!bindings.every(isSharedSpan)) {
460
+ latest = { mode: "forced-inline", dispatched: 0, completed: 0, waitMs: 0 };
461
+ return {
462
+ cause: new Error("SharedKernel received a non-SAB QuerySpan."),
463
+ dispatched: 0,
464
+ completed: 0,
465
+ partialWrite: false
466
+ };
467
+ }
468
+ const control = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
469
+ const status = new Int32Array(
470
+ new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * bindings.length)
471
+ );
472
+ const started = performance.now();
473
+ for (const [index, binding] of bindings.entries()) {
474
+ const message = {
475
+ kind: "kernel-job",
476
+ moduleUrl: kernel.moduleUrl,
477
+ binding,
478
+ control,
479
+ status,
480
+ jobIndex: index
481
+ };
482
+ workers[index % workers.length]?.postMessage(message);
483
+ }
484
+ while (Atomics.load(control, 0) < bindings.length) {
485
+ const observed = Atomics.load(control, 0);
486
+ const wait = Atomics.wait(control, 0, observed, timeoutMs);
487
+ if (wait === "timed-out") {
488
+ for (const worker of workers) worker.terminate();
489
+ return {
490
+ cause: new Error(`SharedKernel deadline exceeded after ${timeoutMs}ms.`),
491
+ dispatched: bindings.length,
492
+ completed: observed,
493
+ partialWrite: bindings.length > 0
494
+ };
495
+ }
496
+ }
497
+ const completed = status.reduce((count, value) => count + (value === 1 ? 1 : 0), 0);
498
+ const failed = status.some((value) => value === -1);
499
+ if (failed) {
500
+ return {
501
+ cause: new Error("SharedKernel worker failed."),
502
+ dispatched: bindings.length,
503
+ completed,
504
+ partialWrite: bindings.length > 0
505
+ };
506
+ }
507
+ latest = {
508
+ mode: "shared",
509
+ dispatched: bindings.length,
510
+ completed,
511
+ waitMs: performance.now() - started
512
+ };
513
+ return latest;
514
+ },
515
+ dispose() {
516
+ for (const worker of workers) worker.terminate();
517
+ }
518
+ };
519
+ }
520
+
521
+ // src/execution/engine-worker-runtime.ts
522
+ var scope = globalThis;
523
+ var renderer;
524
+ var assets;
525
+ var currentSample = {
526
+ downKeys: /* @__PURE__ */ new Set(),
527
+ upKeys: /* @__PURE__ */ new Set(),
528
+ buttons: [false, false, false],
529
+ movementX: 0,
530
+ movementY: 0,
531
+ wheelDelta: 0,
532
+ focused: true,
533
+ pointerLocked: false
534
+ };
535
+ var lastFrameId = 0;
536
+ var engineCanvas;
537
+ var realm;
538
+ var rebuildQueue = new SerializedRebuildQueue();
539
+ var inputBackend = {
540
+ sample: () => currentSample,
541
+ detach: () => {
542
+ }
543
+ };
544
+ function sharedKernelPlugin(target) {
545
+ return {
546
+ name: "shared-kernel-executor",
547
+ inject: ["world"],
548
+ apply(ctx) {
549
+ const executor = {
550
+ warmup(kernel) {
551
+ target.kernelPool ??= createKernelPool();
552
+ target.kernelPool.warmup?.(kernel);
553
+ },
554
+ execute(kernel, spans) {
555
+ target.kernelPool ??= createKernelPool();
556
+ return target.kernelPool.execute(kernel, spans);
557
+ }
558
+ };
559
+ ctx.effect(() => {
560
+ ctx.world.insertResource("SharedKernelExecutor", executor);
561
+ return () => {
562
+ ctx.world.removeResource("SharedKernelExecutor");
563
+ target.kernelPool?.dispose();
564
+ target.kernelPool = void 0;
565
+ };
566
+ }, "execution/shared-kernel");
567
+ }
568
+ };
569
+ }
570
+ function serializableCause(cause) {
571
+ return cause instanceof Error ? { name: cause.name, message: cause.message } : { name: "Error", message: String(cause) };
572
+ }
573
+ function serializableDetail(cause) {
574
+ if (cause instanceof Error) return serializableCause(cause);
575
+ if (Array.isArray(cause)) return cause.map(serializableDetail);
576
+ if (typeof cause === "object" && cause !== null) {
577
+ return Object.fromEntries(
578
+ Object.entries(cause).map(([key, value]) => [key, serializableDetail(value)])
579
+ );
580
+ }
581
+ return cause;
582
+ }
583
+ function postFault(source, code, expected, hint, cause, partialWrite = false) {
584
+ scope.postMessage({
585
+ kind: "fault",
586
+ worldIdentity: realm?.world.identity ?? null,
587
+ source,
588
+ code,
589
+ expected,
590
+ hint,
591
+ detail: serializableDetail(cause),
592
+ partialWrite,
593
+ retryable: false
594
+ });
595
+ }
596
+ async function disposeRealm(target) {
597
+ await target.pluginContext?.fiber.dispose();
598
+ target.pluginContext = void 0;
599
+ target.pendingAudioIntents = [];
600
+ }
601
+ function postBootstrapFault(error) {
602
+ postFault("bootstrap", error.code, error.expected, error.hint, error.detail);
603
+ }
604
+ async function createRealm(init) {
605
+ const preparedResult = await prepareBootstrapEntry(init.bootstrapUrl, init.bootstrapData);
606
+ if (!preparedResult.ok) {
607
+ postBootstrapFault(preparedResult.error);
608
+ return false;
609
+ }
610
+ const prepared = preparedResult.value;
611
+ const nextWorld = new World({
612
+ ...init.time !== void 0 ? { time: init.time } : {},
613
+ storage: init.tier === "shared" ? "shared" : "local"
614
+ });
615
+ const candidate = {
616
+ world: nextWorld,
617
+ init,
618
+ pendingAudioIntents: [],
619
+ kernelPool: void 0,
620
+ pluginContext: void 0
621
+ };
622
+ const audioBackend = createAudioIntentBackend({
623
+ emit: (intent) => candidate.pendingAudioIntents.push(intent)
624
+ });
625
+ let candidateRenderer;
626
+ let rendererLifecycleTransferred = false;
627
+ const previousRenderer = renderer;
628
+ let previousSurfaceReleased = false;
629
+ try {
630
+ if (previousRenderer !== void 0) {
631
+ const released = previousRenderer.releaseSurface();
632
+ if (!released.ok) throw released.error;
633
+ previousSurfaceReleased = true;
634
+ }
635
+ const constructed = await constructRuntimeRendererHost(
636
+ init.canvas,
637
+ prepared.features === void 0 ? {} : { features: prepared.features },
638
+ init.shaderManifestUrl === void 0 ? void 0 : { shaderManifestUrl: init.shaderManifestUrl }
639
+ );
640
+ if (!constructed.ok) throw constructed.error;
641
+ candidateRenderer = constructed.value.renderer;
642
+ assets = constructed.value.assets;
643
+ rendererLifecycleTransferred = true;
644
+ const pluginContext = await createWorldContext(
645
+ nextWorld,
646
+ workerEngineProfile({
647
+ renderer: candidateRenderer,
648
+ rendererFeatureHost: createRenderFeatureHost(constructed.value.featureHost),
649
+ assets,
650
+ input: inputBackend,
651
+ audio: audioBackend,
652
+ animationPayloads: createAnimationPayloadLookup(assets),
653
+ extensions: [
654
+ ...init.tier === "shared" ? [sharedKernelPlugin(candidate)] : [],
655
+ executionBootstrapHostPlugin({
656
+ ...init.bootstrapPort === void 0 ? {} : { port: init.bootstrapPort },
657
+ setPointerLockAllowed(allowed) {
658
+ scope.postMessage({
659
+ kind: "host-control",
660
+ command: "set-pointer-lock-allowed",
661
+ allowed
662
+ });
663
+ }
664
+ }),
665
+ ...prepared.plugins ?? []
666
+ ]
667
+ })
668
+ );
669
+ candidate.pluginContext = pluginContext;
670
+ const activeRenderer = candidateRenderer;
671
+ const previousRealm = realm;
672
+ const committed = await commitAttachedWorld(candidateRenderer, nextWorld, async () => {
673
+ await candidate.kernelPool?.ready();
674
+ return true;
675
+ });
676
+ if (!committed) {
677
+ await disposeRealm(candidate);
678
+ if (previousSurfaceReleased) previousRenderer?.restoreSurface();
679
+ return false;
680
+ }
681
+ realm = candidate;
682
+ renderer = activeRenderer;
683
+ lastFrameId = 0;
684
+ if (previousRealm !== void 0) await disposeRealm(previousRealm);
685
+ return true;
686
+ } catch (cause) {
687
+ await disposeRealm(candidate);
688
+ if (!rendererLifecycleTransferred) candidateRenderer?.dispose();
689
+ if (previousSurfaceReleased) previousRenderer?.restoreSurface();
690
+ throw cause;
691
+ }
692
+ }
693
+ async function initialize(message) {
694
+ try {
695
+ engineCanvas = message.canvas;
696
+ if (!await createRealm(message)) return;
697
+ scope.postMessage({
698
+ kind: "ready",
699
+ worldIdentity: realm?.world.identity ?? "",
700
+ realm: "worker",
701
+ workerWebGpu: typeof navigator === "object" && navigator.gpu !== void 0
702
+ });
703
+ } catch (cause) {
704
+ postFault(
705
+ "bootstrap",
706
+ "app-execution-bootstrap-failed",
707
+ "Engine Worker creates a realm-local World, Renderer and GPU owner",
708
+ "inspect the worker bootstrap cause and module URL",
709
+ cause
710
+ );
711
+ }
712
+ }
713
+ function runFrame(message) {
714
+ const activeRealm = realm;
715
+ if (activeRealm === void 0 || renderer === void 0) return;
716
+ const { world } = activeRealm;
717
+ if (message.worldIdentity !== world.identity || message.frameId <= lastFrameId) return;
718
+ currentSample = message.inputSample;
719
+ const canvasWidth = Number.isFinite(message.canvasWidth) && message.canvasWidth > 0 ? Math.max(1, Math.floor(message.canvasWidth)) : void 0;
720
+ const canvasHeight = Number.isFinite(message.canvasHeight) && message.canvasHeight > 0 ? Math.max(1, Math.floor(message.canvasHeight)) : void 0;
721
+ if (canvasWidth !== void 0 && canvasHeight !== void 0) {
722
+ if (engineCanvas !== void 0) {
723
+ if (engineCanvas.width !== canvasWidth) engineCanvas.width = canvasWidth;
724
+ if (engineCanvas.height !== canvasHeight) engineCanvas.height = canvasHeight;
725
+ }
726
+ syncCameraAspect(world, canvasWidth, canvasHeight);
727
+ }
728
+ const started = performance.now();
729
+ try {
730
+ const update = world.update(message.deltaSeconds);
731
+ if (!update.ok) throw update.error;
732
+ if (world.execution.health === "poisoned") {
733
+ const fault = world.execution.fault;
734
+ postFault(
735
+ "world",
736
+ fault?.code ?? "world-poisoned",
737
+ "World remains healthy through update",
738
+ "rebuild the poisoned World explicitly",
739
+ fault,
740
+ fault?.partialWrite ?? true
741
+ );
742
+ return;
743
+ }
744
+ const updateFinished = performance.now();
745
+ const attached = renderer.attach(world);
746
+ if (!attached.ok) throw attached.error;
747
+ const draw = renderer.draw({
748
+ leases: [attached.value],
749
+ camera: { lease: attached.value },
750
+ environment: { lease: attached.value }
751
+ });
752
+ if (!draw.ok) throw draw.error;
753
+ lastFrameId = message.frameId;
754
+ const kernelDispatch = activeRealm.kernelPool?.takeLastDispatch() ?? null;
755
+ const audioIntents = activeRealm.pendingAudioIntents;
756
+ activeRealm.pendingAudioIntents = [];
757
+ scope.postMessage({
758
+ kind: "frame-complete",
759
+ worldIdentity: world.identity,
760
+ frameId: message.frameId,
761
+ engineUpdateMs: updateFinished - started,
762
+ kernelWaitMs: kernelDispatch?.waitMs ?? 0,
763
+ ...audioIntents.length > 0 ? { audioIntents } : {},
764
+ ...kernelDispatch !== null ? {
765
+ kernelDispatch: {
766
+ eligible: true,
767
+ usedShared: kernelDispatch.mode === "shared",
768
+ reason: kernelDispatch.mode === "shared" ? "shared" : "forced-inline",
769
+ dispatched: kernelDispatch.dispatched,
770
+ completed: kernelDispatch.completed
771
+ }
772
+ } : {}
773
+ });
774
+ } catch (cause) {
775
+ const fault = world.execution.fault;
776
+ postFault(
777
+ fault === null ? "runtime" : "world",
778
+ fault?.code ?? "app-system-update-failed",
779
+ "World update completes before Renderer draw",
780
+ fault === null ? "inspect the runtime cause" : "rebuild the poisoned World explicitly",
781
+ cause,
782
+ fault?.partialWrite ?? false
783
+ );
784
+ }
785
+ }
786
+ async function rebuild(message) {
787
+ const activeRealm = realm;
788
+ if (activeRealm === void 0 || renderer === void 0 || message.worldIdentity !== activeRealm.world.identity)
789
+ return;
790
+ const previousWorldIdentity = activeRealm.world.identity;
791
+ try {
792
+ if (engineCanvas === void 0) return;
793
+ const init = { ...activeRealm.init, canvas: engineCanvas };
794
+ if (!await createRealm(init)) return;
795
+ scope.postMessage({
796
+ kind: "rebuilt",
797
+ previousWorldIdentity,
798
+ worldIdentity: realm?.world.identity ?? ""
799
+ });
800
+ } catch (cause) {
801
+ postFault(
802
+ "rebuild",
803
+ "app-execution-rebuild-failed",
804
+ "bootstrap creates a fresh World identity",
805
+ "inspect the bootstrap cause or create a new App",
806
+ cause
807
+ );
808
+ }
809
+ }
810
+ scope.onmessage = (event) => {
811
+ const message = event.data;
812
+ if (message.kind === "init") void initialize(message);
813
+ else if (message.kind === "frame") runFrame(message);
814
+ else if (message.kind === "rebuild") {
815
+ void rebuildQueue.enqueue(() => rebuild(message));
816
+ } else if (message.kind === "dispose") {
817
+ void (async () => {
818
+ if (realm !== void 0) {
819
+ await disposeRealm(realm);
820
+ realm = void 0;
821
+ }
822
+ scope.close();
823
+ })();
824
+ }
825
+ };
826
+ //# sourceMappingURL=engine-worker-runtime.mjs.map
827
+ //# sourceMappingURL=engine-worker-runtime.mjs.map