@jgengine/core 0.10.0 → 0.12.0

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 (727) hide show
  1. package/CHANGELOG.md +39 -2
  2. package/LICENSE +203 -661
  3. package/README.md +1 -1
  4. package/dist/ai/crowd.d.ts +55 -0
  5. package/dist/ai/crowd.js +114 -0
  6. package/dist/ai/flock.d.ts +5 -2
  7. package/dist/ai/flock.js +5 -2
  8. package/dist/ai/groupAssist.d.ts +1 -0
  9. package/dist/ai/groupAssist.js +1 -0
  10. package/dist/ai/heatSystem.d.ts +76 -0
  11. package/dist/ai/heatSystem.js +97 -0
  12. package/dist/ai/interestScheduler.d.ts +107 -0
  13. package/dist/ai/interestScheduler.js +118 -0
  14. package/dist/ai/jobBoard.d.ts +1 -0
  15. package/dist/ai/jobBoard.js +1 -0
  16. package/dist/ai/laneSelect.d.ts +5 -2
  17. package/dist/ai/laneSelect.js +5 -2
  18. package/dist/ai/mobBrain.d.ts +1 -0
  19. package/dist/ai/mobBrain.js +1 -0
  20. package/dist/ai/populationDirector.d.ts +103 -0
  21. package/dist/ai/populationDirector.js +190 -0
  22. package/dist/ai/pursuit.d.ts +56 -0
  23. package/dist/ai/pursuit.js +53 -0
  24. package/dist/ai/spawnDirector.d.ts +7 -2
  25. package/dist/ai/spawnDirector.js +18 -15
  26. package/dist/ai/spawnPoint.d.ts +3 -1
  27. package/dist/ai/spawnPoint.js +3 -1
  28. package/dist/ai/targetAcquisition.d.ts +84 -0
  29. package/dist/ai/targetAcquisition.js +92 -0
  30. package/dist/anim/easing.d.ts +19 -0
  31. package/dist/anim/easing.js +19 -0
  32. package/dist/anim/oscillator.d.ts +12 -0
  33. package/dist/anim/oscillator.js +25 -0
  34. package/dist/area/areaEffectField.d.ts +127 -0
  35. package/dist/area/areaEffectField.js +175 -0
  36. package/dist/area/stackPolicy.d.ts +47 -0
  37. package/dist/area/stackPolicy.js +99 -0
  38. package/dist/authoring.d.ts +2 -1
  39. package/dist/authoring.js +2 -1
  40. package/dist/board/laneBoard.d.ts +13 -0
  41. package/dist/board/laneBoard.js +13 -0
  42. package/dist/board/timelineBoard.d.ts +10 -0
  43. package/dist/board/timelineBoard.js +10 -0
  44. package/dist/combat/abilityKit.d.ts +18 -0
  45. package/dist/combat/abilityKit.js +24 -9
  46. package/dist/combat/animationState.d.ts +5 -0
  47. package/dist/combat/animationState.js +5 -0
  48. package/dist/combat/breakMeters.d.ts +10 -0
  49. package/dist/combat/breakMeters.js +10 -0
  50. package/dist/combat/castRunner.d.ts +5 -0
  51. package/dist/combat/castRunner.js +5 -0
  52. package/dist/combat/comboPoints.d.ts +5 -0
  53. package/dist/combat/comboPoints.js +5 -0
  54. package/dist/combat/comboString.d.ts +5 -0
  55. package/dist/combat/comboString.js +5 -0
  56. package/dist/combat/damageInterceptors.d.ts +192 -0
  57. package/dist/combat/damageInterceptors.js +251 -0
  58. package/dist/combat/damageMatchup.d.ts +68 -0
  59. package/dist/combat/damageMatchup.js +42 -0
  60. package/dist/combat/damageResolution.d.ts +63 -0
  61. package/dist/combat/damageResolution.js +50 -0
  62. package/dist/combat/death.d.ts +7 -1
  63. package/dist/combat/death.js +5 -0
  64. package/dist/combat/deathReason.d.ts +14 -0
  65. package/dist/combat/deathReason.js +1 -0
  66. package/dist/combat/defensiveWindow.d.ts +5 -0
  67. package/dist/combat/defensiveWindow.js +5 -0
  68. package/dist/combat/dotField.d.ts +5 -1
  69. package/dist/combat/dotField.js +5 -1
  70. package/dist/combat/downed.d.ts +5 -0
  71. package/dist/combat/downed.js +5 -0
  72. package/dist/combat/effects.d.ts +5 -0
  73. package/dist/combat/effects.js +5 -0
  74. package/dist/combat/encounterSequence.d.ts +258 -0
  75. package/dist/combat/encounterSequence.js +426 -0
  76. package/dist/combat/hitReaction.d.ts +57 -1
  77. package/dist/combat/hitReaction.js +45 -5
  78. package/dist/combat/magazine.d.ts +54 -0
  79. package/dist/combat/magazine.js +96 -0
  80. package/dist/combat/projectiles.d.ts +5 -0
  81. package/dist/combat/projectiles.js +32 -14
  82. package/dist/combat/receivedDamage.d.ts +117 -0
  83. package/dist/combat/receivedDamage.js +92 -0
  84. package/dist/combat/regenShield.d.ts +5 -1
  85. package/dist/combat/regenShield.js +5 -1
  86. package/dist/combat/renderCues.d.ts +51 -0
  87. package/dist/combat/renderCues.js +44 -0
  88. package/dist/combat/resourcePool.d.ts +5 -0
  89. package/dist/combat/resourcePool.js +5 -0
  90. package/dist/combat/rewardAllocation.d.ts +121 -0
  91. package/dist/combat/rewardAllocation.js +251 -0
  92. package/dist/combat/shotOrigin.d.ts +18 -1
  93. package/dist/combat/shotOrigin.js +39 -0
  94. package/dist/combat/statusApplication.d.ts +96 -0
  95. package/dist/combat/statusApplication.js +81 -0
  96. package/dist/combat/telegraph.d.ts +11 -2
  97. package/dist/combat/telegraph.js +11 -2
  98. package/dist/combat/thresholdCrossings.d.ts +85 -0
  99. package/dist/combat/thresholdCrossings.js +116 -0
  100. package/dist/combat.d.ts +35 -0
  101. package/dist/combat.js +35 -0
  102. package/dist/commands/commandRegistry.d.ts +11 -0
  103. package/dist/commands/commandRegistry.js +9 -2
  104. package/dist/crafting/crop.d.ts +18 -0
  105. package/dist/crafting/crop.js +18 -0
  106. package/dist/crafting/production.d.ts +5 -0
  107. package/dist/crafting/production.js +5 -0
  108. package/dist/devtools/controls.d.ts +38 -0
  109. package/dist/devtools/controls.js +181 -0
  110. package/dist/devtools/devtools.d.ts +5 -197
  111. package/dist/devtools/devtools.js +38 -774
  112. package/dist/devtools/discover.d.ts +32 -0
  113. package/dist/devtools/discover.js +240 -0
  114. package/dist/devtools/fallbackSeams.d.ts +50 -0
  115. package/dist/devtools/fallbackSeams.js +111 -0
  116. package/dist/devtools/frame.d.ts +15 -0
  117. package/dist/devtools/frame.js +247 -0
  118. package/dist/devtools/logs.d.ts +15 -0
  119. package/dist/devtools/logs.js +86 -0
  120. package/dist/devtools/overrides.d.ts +16 -0
  121. package/dist/devtools/overrides.js +66 -0
  122. package/dist/devtools/rewriteTunables.d.ts +17 -0
  123. package/dist/devtools/rewriteTunables.js +276 -0
  124. package/dist/devtools/saveEndpoint.d.ts +46 -0
  125. package/dist/devtools/saveEndpoint.js +48 -0
  126. package/dist/devtools/transformTunables.d.ts +3 -0
  127. package/dist/devtools/transformTunables.js +3 -0
  128. package/dist/devtools/tunableSchema.d.ts +31 -0
  129. package/dist/devtools/tunableSchema.js +31 -0
  130. package/dist/devtools/types.d.ts +212 -0
  131. package/dist/devtools/types.js +1 -0
  132. package/dist/economy/auctionBook.d.ts +122 -0
  133. package/dist/economy/auctionBook.js +213 -0
  134. package/dist/economy/currency.d.ts +12 -1
  135. package/dist/economy/currency.js +12 -1
  136. package/dist/economy/listingBook.d.ts +91 -0
  137. package/dist/economy/listingBook.js +144 -0
  138. package/dist/economy/priceHistory.d.ts +44 -0
  139. package/dist/economy/priceHistory.js +89 -0
  140. package/dist/economy/resourceLedger.d.ts +222 -0
  141. package/dist/economy/resourceLedger.js +353 -0
  142. package/dist/economy/sharedWallet.d.ts +14 -0
  143. package/dist/economy/sharedWallet.js +14 -0
  144. package/dist/economy/techTree.d.ts +12 -0
  145. package/dist/economy/techTree.js +12 -0
  146. package/dist/economy/unlockPoints.d.ts +92 -0
  147. package/dist/economy/unlockPoints.js +103 -0
  148. package/dist/economy/wallet.d.ts +26 -2
  149. package/dist/economy/wallet.js +35 -6
  150. package/dist/editor/commandApply.d.ts +5 -0
  151. package/dist/editor/commandApply.js +755 -0
  152. package/dist/editor/commands.d.ts +235 -7
  153. package/dist/editor/commands.js +82 -124
  154. package/dist/editor/directives.d.ts +94 -0
  155. package/dist/editor/directives.js +206 -0
  156. package/dist/editor/document.d.ts +194 -13
  157. package/dist/editor/document.js +1166 -19
  158. package/dist/editor/entityCatalog.d.ts +42 -0
  159. package/dist/editor/entityCatalog.js +101 -0
  160. package/dist/editor/environment.d.ts +74 -0
  161. package/dist/editor/environment.js +169 -0
  162. package/dist/editor/grid.d.ts +229 -0
  163. package/dist/editor/grid.js +366 -0
  164. package/dist/editor/gridAdapters.d.ts +80 -0
  165. package/dist/editor/gridAdapters.js +134 -0
  166. package/dist/editor/index.d.ts +98 -6
  167. package/dist/editor/index.js +13 -2
  168. package/dist/editor/liveSync.d.ts +127 -0
  169. package/dist/editor/liveSync.js +249 -0
  170. package/dist/editor/minimap.d.ts +31 -0
  171. package/dist/editor/minimap.js +73 -0
  172. package/dist/editor/runtimeInspector.d.ts +88 -0
  173. package/dist/editor/runtimeInspector.js +239 -0
  174. package/dist/editor/streamer.d.ts +66 -0
  175. package/dist/editor/streamer.js +68 -0
  176. package/dist/editor/types.d.ts +250 -1
  177. package/dist/editor/world.d.ts +136 -0
  178. package/dist/editor/world.js +303 -0
  179. package/dist/faction/reputation.d.ts +5 -0
  180. package/dist/faction/reputation.js +5 -0
  181. package/dist/format/distance.d.ts +17 -0
  182. package/dist/format/distance.js +18 -0
  183. package/dist/format/duration.d.ts +27 -0
  184. package/dist/format/duration.js +45 -0
  185. package/dist/format/speed.d.ts +17 -0
  186. package/dist/format/speed.js +25 -0
  187. package/dist/game/breeding.d.ts +161 -0
  188. package/dist/game/breeding.js +181 -0
  189. package/dist/game/cameraConfig.d.ts +451 -0
  190. package/dist/game/cameraConfig.js +1 -0
  191. package/dist/game/connectedPlayers.d.ts +6 -4
  192. package/dist/game/connectedPlayers.js +2 -2
  193. package/dist/game/cosmetics.d.ts +9 -0
  194. package/dist/game/cosmetics.js +16 -0
  195. package/dist/game/defineGame.d.ts +110 -5
  196. package/dist/game/defineGame.js +49 -4
  197. package/dist/game/defineSystem.d.ts +90 -0
  198. package/dist/game/defineSystem.js +47 -0
  199. package/dist/game/dialogue.d.ts +33 -0
  200. package/dist/game/dialogue.js +21 -0
  201. package/dist/game/events.d.ts +63 -13
  202. package/dist/game/events.js +5 -0
  203. package/dist/game/feed.d.ts +33 -0
  204. package/dist/game/feed.js +35 -2
  205. package/dist/game/gamePhase.d.ts +11 -0
  206. package/dist/game/gamePhase.js +16 -0
  207. package/dist/game/leaderboard.d.ts +5 -0
  208. package/dist/game/leaderboard.js +5 -0
  209. package/dist/game/loadout.d.ts +5 -0
  210. package/dist/game/loadout.js +5 -0
  211. package/dist/game/lootFilter.d.ts +2 -0
  212. package/dist/game/lootFilter.js +2 -0
  213. package/dist/game/lootPipeline.d.ts +164 -0
  214. package/dist/game/lootPipeline.js +216 -0
  215. package/dist/game/lootTable.d.ts +19 -2
  216. package/dist/game/lootTable.js +15 -5
  217. package/dist/game/objectives.d.ts +43 -0
  218. package/dist/game/objectives.js +36 -0
  219. package/dist/game/paramLayers.d.ts +148 -0
  220. package/dist/game/paramLayers.js +185 -0
  221. package/dist/game/ping.d.ts +5 -0
  222. package/dist/game/ping.js +5 -0
  223. package/dist/game/playableGame.d.ts +116 -432
  224. package/dist/game/playableGame.js +1 -1
  225. package/dist/game/progression.d.ts +35 -0
  226. package/dist/game/progression.js +19 -0
  227. package/dist/game/quest.d.ts +8 -0
  228. package/dist/game/quest.js +30 -3
  229. package/dist/game/race.d.ts +141 -0
  230. package/dist/game/race.js +169 -0
  231. package/dist/game/recordBook.d.ts +3 -1
  232. package/dist/game/recordBook.js +4 -1
  233. package/dist/game/ruleSelection.d.ts +75 -0
  234. package/dist/game/ruleSelection.js +127 -0
  235. package/dist/game/runDraft.d.ts +5 -0
  236. package/dist/game/runDraft.js +5 -0
  237. package/dist/game/saveStore.d.ts +111 -0
  238. package/dist/game/saveStore.js +312 -0
  239. package/dist/game/snapshotHistory.d.ts +67 -0
  240. package/dist/game/snapshotHistory.js +95 -0
  241. package/dist/game/social.d.ts +38 -1
  242. package/dist/game/social.js +71 -0
  243. package/dist/game/spawnPoints.d.ts +5 -0
  244. package/dist/game/spawnPoints.js +5 -0
  245. package/dist/game/systemRuntime.d.ts +50 -0
  246. package/dist/game/systemRuntime.js +157 -0
  247. package/dist/game/systemSchedule.d.ts +72 -0
  248. package/dist/game/systemSchedule.js +242 -0
  249. package/dist/game/toasts.d.ts +43 -0
  250. package/dist/game/toasts.js +44 -0
  251. package/dist/game/trade.d.ts +10 -0
  252. package/dist/game/trade.js +10 -0
  253. package/dist/game/tribe.d.ts +184 -0
  254. package/dist/game/tribe.js +432 -0
  255. package/dist/game/unlocks.d.ts +8 -0
  256. package/dist/game/unlocks.js +16 -0
  257. package/dist/game/vfxInstance.d.ts +138 -0
  258. package/dist/game/vfxInstance.js +96 -0
  259. package/dist/game/worldItem.d.ts +17 -4
  260. package/dist/game/worldItem.js +17 -4
  261. package/dist/gameplay.d.ts +93 -0
  262. package/dist/gameplay.js +93 -0
  263. package/dist/index.d.ts +5 -14
  264. package/dist/index.js +5 -14
  265. package/dist/input/actionBindings.d.ts +23 -6
  266. package/dist/input/actionBindings.js +23 -6
  267. package/dist/input/axisInput.d.ts +7 -2
  268. package/dist/input/axisInput.js +7 -2
  269. package/dist/input/controlGroups.d.ts +67 -0
  270. package/dist/input/controlGroups.js +41 -0
  271. package/dist/input/touchScheme.d.ts +82 -6
  272. package/dist/input/touchScheme.js +123 -10
  273. package/dist/interaction/lockpick.d.ts +61 -0
  274. package/dist/interaction/lockpick.js +168 -0
  275. package/dist/interaction/proximityPrompt.d.ts +2 -0
  276. package/dist/interaction/proximityPrompt.js +2 -0
  277. package/dist/interaction/qte.d.ts +5 -0
  278. package/dist/interaction/qte.js +5 -0
  279. package/dist/interaction/skillCheck.d.ts +5 -0
  280. package/dist/interaction/skillCheck.js +5 -0
  281. package/dist/inventory/encumbrance.d.ts +69 -0
  282. package/dist/inventory/encumbrance.js +68 -0
  283. package/dist/inventory/inventoryModel.d.ts +12 -0
  284. package/dist/inventory/inventoryModel.js +12 -0
  285. package/dist/inventory/shapedGrid.d.ts +16 -0
  286. package/dist/inventory/shapedGrid.js +16 -0
  287. package/dist/inventory/slotModel.d.ts +10 -0
  288. package/dist/inventory/slotModel.js +10 -0
  289. package/dist/item/durability.d.ts +5 -0
  290. package/dist/item/durability.js +6 -3
  291. package/dist/item/itemIdentity.d.ts +171 -0
  292. package/dist/item/itemIdentity.js +138 -0
  293. package/dist/item/itemInstanceRegistry.d.ts +32 -0
  294. package/dist/item/itemInstanceRegistry.js +34 -0
  295. package/dist/item/itemgen.d.ts +163 -0
  296. package/dist/item/itemgen.js +151 -0
  297. package/dist/item/modularItem.d.ts +5 -0
  298. package/dist/item/modularItem.js +5 -0
  299. package/dist/item/use.d.ts +5 -0
  300. package/dist/item/use.js +5 -0
  301. package/dist/item/useBehavior.d.ts +142 -0
  302. package/dist/item/useBehavior.js +105 -0
  303. package/dist/item/weapon.d.ts +5 -0
  304. package/dist/item/weapon.js +5 -0
  305. package/dist/math/scalar.d.ts +25 -0
  306. package/dist/math/scalar.js +47 -0
  307. package/dist/meta/changelog.d.ts +4 -1
  308. package/dist/meta/changelog.js +39 -2
  309. package/dist/movement/avoidance.d.ts +45 -0
  310. package/dist/movement/avoidance.js +123 -0
  311. package/dist/movement/cameraRig.d.ts +8 -0
  312. package/dist/movement/cameraRig.js +8 -0
  313. package/dist/movement/dash.d.ts +11 -0
  314. package/dist/movement/dash.js +11 -0
  315. package/dist/movement/formation.d.ts +135 -0
  316. package/dist/movement/formation.js +194 -0
  317. package/dist/movement/glideModel.d.ts +5 -0
  318. package/dist/movement/glideModel.js +5 -0
  319. package/dist/movement/grappleSwing.d.ts +5 -0
  320. package/dist/movement/grappleSwing.js +5 -0
  321. package/dist/movement/leaderTrail.d.ts +5 -0
  322. package/dist/movement/leaderTrail.js +5 -0
  323. package/dist/movement/movementModel.d.ts +50 -9
  324. package/dist/movement/movementModel.js +75 -29
  325. package/dist/movement/playerMovement.js +167 -12
  326. package/dist/movement/poseState.d.ts +13 -0
  327. package/dist/movement/poseState.js +16 -0
  328. package/dist/movement/steering.d.ts +8 -0
  329. package/dist/movement/steering.js +18 -0
  330. package/dist/multiplayer/combatSnapshot.d.ts +3 -0
  331. package/dist/multiplayer/combatSnapshot.js +16 -8
  332. package/dist/multiplayer/lagCompensation.d.ts +5 -0
  333. package/dist/multiplayer/lagCompensation.js +5 -0
  334. package/dist/multiplayer/presenceModel.d.ts +11 -1
  335. package/dist/multiplayer/presenceModel.js +17 -1
  336. package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
  337. package/dist/multiplayer/simultaneousCommit.js +3 -0
  338. package/dist/multiplayer.d.ts +11 -0
  339. package/dist/multiplayer.js +11 -0
  340. package/dist/nav/pathFollow.d.ts +57 -0
  341. package/dist/nav/pathFollow.js +109 -0
  342. package/dist/orders/orderKinds.d.ts +156 -0
  343. package/dist/orders/orderKinds.js +197 -0
  344. package/dist/orders/orderQueue.d.ts +208 -0
  345. package/dist/orders/orderQueue.js +211 -0
  346. package/dist/physics/drivableVehicle.d.ts +31 -0
  347. package/dist/physics/drivableVehicle.js +16 -0
  348. package/dist/physics/flightDynamics.d.ts +82 -0
  349. package/dist/physics/flightDynamics.js +165 -0
  350. package/dist/physics/gravityField.d.ts +25 -0
  351. package/dist/physics/gravityField.js +41 -0
  352. package/dist/physics/kinematicVehicle.d.ts +108 -1
  353. package/dist/physics/kinematicVehicle.js +212 -15
  354. package/dist/physics/physicsWorld.d.ts +50 -12
  355. package/dist/physics/physicsWorld.js +120 -122
  356. package/dist/physics/radialImpulse.d.ts +25 -0
  357. package/dist/physics/radialImpulse.js +27 -0
  358. package/dist/physics/vehicleObstacles.d.ts +44 -0
  359. package/dist/physics/vehicleObstacles.js +115 -0
  360. package/dist/procedural.d.ts +3 -0
  361. package/dist/procedural.js +3 -0
  362. package/dist/progression/statGraph.d.ts +116 -0
  363. package/dist/progression/statGraph.js +318 -0
  364. package/dist/puzzle/cellGrid.d.ts +9 -0
  365. package/dist/puzzle/cellGrid.js +9 -0
  366. package/dist/puzzle/fallingPiece.d.ts +9 -0
  367. package/dist/puzzle/fallingPiece.js +9 -0
  368. package/dist/puzzle/nonogram.d.ts +39 -0
  369. package/dist/puzzle/nonogram.js +136 -0
  370. package/dist/random/nameGen.d.ts +5 -0
  371. package/dist/random/nameGen.js +5 -0
  372. package/dist/random/pick.d.ts +8 -0
  373. package/dist/random/pick.js +31 -0
  374. package/dist/random/rng.d.ts +26 -1
  375. package/dist/random/rng.js +32 -9
  376. package/dist/random/seedLink.d.ts +4 -0
  377. package/dist/random/seedLink.js +4 -0
  378. package/dist/relation/keyedValues.d.ts +54 -0
  379. package/dist/relation/keyedValues.js +115 -0
  380. package/dist/relation/thresholds.d.ts +62 -0
  381. package/dist/relation/thresholds.js +62 -0
  382. package/dist/render/color.d.ts +12 -0
  383. package/dist/render/color.js +26 -0
  384. package/dist/render/lookPreset.d.ts +41 -0
  385. package/dist/render/lookPreset.js +29 -0
  386. package/dist/render/postProcessing.d.ts +20 -0
  387. package/dist/render/postProcessing.js +21 -1
  388. package/dist/rules/predicate.d.ts +53 -0
  389. package/dist/rules/predicate.js +64 -0
  390. package/dist/rules/ruleEffects.d.ts +38 -0
  391. package/dist/rules/ruleEffects.js +37 -0
  392. package/dist/rules/triggeredRules.d.ts +160 -0
  393. package/dist/rules/triggeredRules.js +241 -0
  394. package/dist/runtime/adapter.d.ts +55 -3
  395. package/dist/runtime/adapter.js +57 -1
  396. package/dist/runtime/cameraDirector.d.ts +1 -0
  397. package/dist/runtime/cameraDirector.js +1 -0
  398. package/dist/runtime/commandRunner.d.ts +1 -0
  399. package/dist/runtime/commandRunner.js +1 -0
  400. package/dist/runtime/context/combat.d.ts +51 -0
  401. package/dist/runtime/context/combat.js +130 -0
  402. package/dist/runtime/context/combatFx.d.ts +23 -0
  403. package/dist/runtime/context/combatFx.js +161 -0
  404. package/dist/runtime/context/deathLoot.d.ts +30 -0
  405. package/dist/runtime/context/deathLoot.js +39 -0
  406. package/dist/runtime/context/player.d.ts +48 -0
  407. package/dist/runtime/context/player.js +125 -0
  408. package/dist/runtime/context/registries.d.ts +13 -0
  409. package/dist/runtime/context/registries.js +84 -0
  410. package/dist/runtime/context/scene.d.ts +59 -0
  411. package/dist/runtime/context/scene.js +291 -0
  412. package/dist/runtime/context/snapshotCodecs.d.ts +12 -0
  413. package/dist/runtime/context/snapshotCodecs.js +26 -0
  414. package/dist/runtime/context/worldItems.d.ts +21 -0
  415. package/dist/runtime/context/worldItems.js +37 -0
  416. package/dist/runtime/descriptors/baseline.d.ts +48 -0
  417. package/dist/runtime/descriptors/baseline.js +157 -0
  418. package/dist/runtime/descriptors/features.d.ts +79 -0
  419. package/dist/runtime/descriptors/features.js +299 -0
  420. package/dist/runtime/gameContext.d.ts +2 -327
  421. package/dist/runtime/gameContext.js +273 -778
  422. package/dist/runtime/gameContextTypes.d.ts +467 -0
  423. package/dist/runtime/gameContextTypes.js +1 -0
  424. package/dist/runtime/gameRuntime.d.ts +1 -0
  425. package/dist/runtime/gameRuntime.js +1 -0
  426. package/dist/runtime/headlessRunner.d.ts +62 -0
  427. package/dist/runtime/headlessRunner.js +45 -0
  428. package/dist/runtime/hostPersistence.d.ts +12 -0
  429. package/dist/runtime/hostPersistence.js +12 -0
  430. package/dist/runtime/hostPolicy.d.ts +51 -0
  431. package/dist/runtime/hostPolicy.js +68 -0
  432. package/dist/runtime/hostedGameRunner.d.ts +11 -4
  433. package/dist/runtime/hostedGameRunner.js +27 -3
  434. package/dist/runtime/hostedWorldSession.d.ts +15 -5
  435. package/dist/runtime/hostedWorldSession.js +12 -4
  436. package/dist/runtime/inputSnapshot.d.ts +8 -3
  437. package/dist/runtime/inputSnapshot.js +6 -2
  438. package/dist/runtime/motionIntents.d.ts +11 -2
  439. package/dist/runtime/motionIntents.js +16 -2
  440. package/dist/runtime/perContext.d.ts +15 -0
  441. package/dist/runtime/perContext.js +21 -0
  442. package/dist/runtime/runtimeSave.d.ts +79 -0
  443. package/dist/runtime/runtimeSave.js +105 -0
  444. package/dist/runtime/save.d.ts +4 -0
  445. package/dist/runtime/save.js +4 -0
  446. package/dist/runtime/snapshot.d.ts +7 -0
  447. package/dist/runtime/snapshot.js +7 -0
  448. package/dist/runtime/visibility.d.ts +2 -1
  449. package/dist/runtime/visibility.js +2 -1
  450. package/dist/runtime/worldChannel.d.ts +7 -3
  451. package/dist/runtime/worldChannel.js +51 -6
  452. package/dist/runtime/worldMirror.d.ts +14 -2
  453. package/dist/runtime/worldMirror.js +15 -2
  454. package/dist/runtime/worldProjection.d.ts +47 -0
  455. package/dist/runtime/worldProjection.js +52 -0
  456. package/dist/runtime/worldReplication.d.ts +30 -7
  457. package/dist/runtime/worldReplication.js +41 -9
  458. package/dist/runtime/worldSnapshot.d.ts +42 -3
  459. package/dist/runtime/worldSnapshot.js +34 -7
  460. package/dist/scene/assetCatalog.d.ts +26 -0
  461. package/dist/scene/assetCatalog.js +4 -0
  462. package/dist/scene/assetDiagnostics.d.ts +69 -0
  463. package/dist/scene/assetDiagnostics.js +110 -0
  464. package/dist/scene/assetGenerator.d.ts +65 -0
  465. package/dist/scene/assetGenerator.js +64 -0
  466. package/dist/scene/assetSpace.d.ts +137 -0
  467. package/dist/scene/assetSpace.js +257 -0
  468. package/dist/scene/authoredTriggers.d.ts +219 -0
  469. package/dist/scene/authoredTriggers.js +454 -0
  470. package/dist/scene/behaviorRuntime.d.ts +75 -0
  471. package/dist/scene/behaviorRuntime.js +217 -0
  472. package/dist/scene/behaviors.d.ts +14 -2
  473. package/dist/scene/behaviors.js +7 -2
  474. package/dist/scene/bodyBind.d.ts +60 -0
  475. package/dist/scene/bodyBind.js +51 -0
  476. package/dist/scene/builtinSceneKinds.d.ts +5 -0
  477. package/dist/scene/builtinSceneKinds.js +67 -0
  478. package/dist/scene/colliders.d.ts +71 -1
  479. package/dist/scene/colliders.js +145 -1
  480. package/dist/scene/collisionMesh.d.ts +94 -0
  481. package/dist/scene/collisionMesh.js +699 -0
  482. package/dist/scene/companion.d.ts +147 -0
  483. package/dist/scene/companion.js +193 -0
  484. package/dist/scene/entityStats.d.ts +18 -11
  485. package/dist/scene/entityStats.js +21 -16
  486. package/dist/scene/entityStore.d.ts +12 -1
  487. package/dist/scene/entityStore.js +15 -0
  488. package/dist/scene/facing.d.ts +18 -0
  489. package/dist/scene/facing.js +26 -0
  490. package/dist/scene/modelSockets.d.ts +33 -0
  491. package/dist/scene/modelSockets.js +29 -0
  492. package/dist/scene/objectQuery.d.ts +2 -0
  493. package/dist/scene/objectQuery.js +2 -0
  494. package/dist/scene/objectStore.d.ts +4 -0
  495. package/dist/scene/objectStore.js +6 -0
  496. package/dist/scene/possession.d.ts +8 -0
  497. package/dist/scene/possession.js +14 -0
  498. package/dist/scene/roster.d.ts +3 -0
  499. package/dist/scene/roster.js +12 -0
  500. package/dist/scene/sceneKinds.d.ts +256 -0
  501. package/dist/scene/sceneKinds.js +218 -0
  502. package/dist/scene/sceneOwnership.d.ts +169 -0
  503. package/dist/scene/sceneOwnership.js +179 -0
  504. package/dist/scene/sceneRaycast.js +15 -0
  505. package/dist/scene/selectionBookmarks.d.ts +93 -0
  506. package/dist/scene/selectionBookmarks.js +122 -0
  507. package/dist/scene/vehicleSeat.d.ts +68 -0
  508. package/dist/scene/vehicleSeat.js +59 -0
  509. package/dist/sensor/concealment.d.ts +3 -0
  510. package/dist/sensor/concealment.js +3 -0
  511. package/dist/sensor/freezeMonitor.d.ts +1 -0
  512. package/dist/sensor/freezeMonitor.js +1 -0
  513. package/dist/sensor/frustumSensor.d.ts +7 -3
  514. package/dist/sensor/frustumSensor.js +7 -3
  515. package/dist/sensor/hiddenStateProbe.d.ts +5 -2
  516. package/dist/sensor/hiddenStateProbe.js +5 -2
  517. package/dist/sensor/recordingBuffer.d.ts +2 -1
  518. package/dist/sensor/recordingBuffer.js +2 -1
  519. package/dist/sensor/replayLoop.d.ts +6 -2
  520. package/dist/sensor/replayLoop.js +6 -2
  521. package/dist/sensor/revealQuery.d.ts +2 -1
  522. package/dist/sensor/revealQuery.js +2 -1
  523. package/dist/sensor/visionCone.d.ts +10 -3
  524. package/dist/sensor/visionCone.js +10 -3
  525. package/dist/session/contestedChannel.d.ts +1 -0
  526. package/dist/session/contestedChannel.js +1 -0
  527. package/dist/session/extraction.d.ts +1 -0
  528. package/dist/session/extraction.js +1 -0
  529. package/dist/session/roles.d.ts +6 -0
  530. package/dist/session/roles.js +6 -0
  531. package/dist/session/roundState.d.ts +8 -0
  532. package/dist/session/roundState.js +2 -0
  533. package/dist/settings/settingsModel.d.ts +1 -0
  534. package/dist/settings/settingsModel.js +1 -0
  535. package/dist/stats/accumulatorMeter.d.ts +6 -0
  536. package/dist/stats/accumulatorMeter.js +6 -0
  537. package/dist/stats/eventMeter.d.ts +5 -0
  538. package/dist/stats/eventMeter.js +5 -0
  539. package/dist/stats/rollCheck.d.ts +5 -0
  540. package/dist/stats/rollCheck.js +5 -0
  541. package/dist/stats/spawnLevelStats.d.ts +110 -0
  542. package/dist/stats/spawnLevelStats.js +140 -0
  543. package/dist/stats/statModifiers.d.ts +5 -0
  544. package/dist/stats/statModifiers.js +5 -0
  545. package/dist/stats/statPool.d.ts +70 -0
  546. package/dist/stats/statPool.js +59 -0
  547. package/dist/store/changeSignal.d.ts +3 -0
  548. package/dist/store/changeSignal.js +2 -0
  549. package/dist/store/defineKeyedStore.d.ts +38 -0
  550. package/dist/store/defineKeyedStore.js +42 -0
  551. package/dist/store/defineStore.d.ts +33 -0
  552. package/dist/store/defineStore.js +35 -0
  553. package/dist/store/observableKeyedStore.d.ts +7 -0
  554. package/dist/store/observableKeyedStore.js +35 -2
  555. package/dist/survival/decayMeter.d.ts +55 -0
  556. package/dist/survival/decayMeter.js +130 -57
  557. package/dist/survival/moodle.d.ts +2 -0
  558. package/dist/survival/regionHealth.d.ts +6 -0
  559. package/dist/survival/regionHealth.js +6 -3
  560. package/dist/tactics/fallingGrid.d.ts +4 -2
  561. package/dist/tactics/fallingGrid.js +4 -2
  562. package/dist/tactics/predictiveQuery.d.ts +3 -0
  563. package/dist/tactics/predictiveQuery.js +3 -0
  564. package/dist/tactics/snapshot.d.ts +2 -0
  565. package/dist/tactics/snapshot.js +2 -0
  566. package/dist/tactics/surface.d.ts +1 -0
  567. package/dist/tactics/surface.js +1 -0
  568. package/dist/tactics/tacticalGrid.d.ts +1 -0
  569. package/dist/tactics/tacticalGrid.js +1 -0
  570. package/dist/time/beatClock.d.ts +14 -4
  571. package/dist/time/beatClock.js +14 -4
  572. package/dist/time/calendarClock.d.ts +3 -0
  573. package/dist/time/calendarClock.js +3 -0
  574. package/dist/time/idleProgress.d.ts +4 -0
  575. package/dist/time/idleProgress.js +4 -0
  576. package/dist/time/simClock.d.ts +2 -0
  577. package/dist/time/simClock.js +20 -5
  578. package/dist/ui/actionModel.d.ts +110 -0
  579. package/dist/ui/actionModel.js +159 -0
  580. package/dist/ui/gameLayout.d.ts +30 -11
  581. package/dist/ui/gameLayout.js +30 -11
  582. package/dist/ui/hudDocument.d.ts +114 -0
  583. package/dist/ui/hudDocument.js +220 -0
  584. package/dist/ui/hudLayout.d.ts +38 -1
  585. package/dist/ui/hudLayout.js +220 -17
  586. package/dist/ui/selectionModel.d.ts +92 -0
  587. package/dist/ui/selectionModel.js +88 -0
  588. package/dist/ui/tooltipModel.d.ts +63 -0
  589. package/dist/ui/tooltipModel.js +82 -0
  590. package/dist/ui.d.ts +15 -0
  591. package/dist/ui.js +15 -0
  592. package/dist/visibility/bounds.d.ts +8 -1
  593. package/dist/visibility/bounds.js +8 -1
  594. package/dist/visibility/frustum.d.ts +12 -3
  595. package/dist/visibility/frustum.js +12 -3
  596. package/dist/work/jobQueue.d.ts +201 -0
  597. package/dist/work/jobQueue.js +253 -0
  598. package/dist/work/unitTraining.d.ts +58 -0
  599. package/dist/work/unitTraining.js +52 -0
  600. package/dist/world/authoredEntities.d.ts +29 -0
  601. package/dist/world/authoredEntities.js +29 -0
  602. package/dist/world/authoredObjects.d.ts +72 -0
  603. package/dist/world/authoredObjects.js +81 -0
  604. package/dist/world/authoredSpawn.d.ts +39 -0
  605. package/dist/world/authoredSpawn.js +37 -0
  606. package/dist/world/buildSockets.d.ts +152 -0
  607. package/dist/world/buildSockets.js +188 -0
  608. package/dist/world/buildingGenerator.d.ts +18 -0
  609. package/dist/world/buildingGenerator.js +62 -0
  610. package/dist/world/buildings.d.ts +5 -0
  611. package/dist/world/buildings.js +5 -0
  612. package/dist/world/catenary.d.ts +22 -0
  613. package/dist/world/catenary.js +69 -0
  614. package/dist/world/cityBlocks.d.ts +152 -0
  615. package/dist/world/cityBlocks.js +670 -0
  616. package/dist/world/cityContent.d.ts +77 -0
  617. package/dist/world/cityContent.js +261 -0
  618. package/dist/world/cityGeometry.d.ts +114 -0
  619. package/dist/world/cityGeometry.js +573 -0
  620. package/dist/world/cityKind.d.ts +314 -0
  621. package/dist/world/cityKind.js +1578 -0
  622. package/dist/world/features.d.ts +133 -10
  623. package/dist/world/features.js +66 -6
  624. package/dist/world/footprintGrid.d.ts +59 -0
  625. package/dist/world/footprintGrid.js +141 -0
  626. package/dist/world/geometry.d.ts +64 -0
  627. package/dist/world/geometry.js +94 -0
  628. package/dist/world/grassKind.d.ts +51 -0
  629. package/dist/world/grassKind.js +101 -0
  630. package/dist/world/markers.d.ts +50 -4
  631. package/dist/world/markers.js +49 -0
  632. package/dist/world/massing.js +1 -1
  633. package/dist/world/minimapBake.d.ts +78 -0
  634. package/dist/world/minimapBake.js +208 -0
  635. package/dist/world/minimapTrack.d.ts +17 -0
  636. package/dist/world/minimapTrack.js +22 -0
  637. package/dist/world/pathInstances.d.ts +27 -0
  638. package/dist/world/pathInstances.js +27 -0
  639. package/dist/world/pathNetwork.d.ts +159 -0
  640. package/dist/world/pathNetwork.js +684 -0
  641. package/dist/world/pathTerrain.d.ts +80 -0
  642. package/dist/world/pathTerrain.js +142 -0
  643. package/dist/world/place.d.ts +166 -0
  644. package/dist/world/place.js +96 -0
  645. package/dist/world/placeAsset.d.ts +81 -0
  646. package/dist/world/placeAsset.js +79 -0
  647. package/dist/world/placement.d.ts +4 -0
  648. package/dist/world/placement.js +4 -0
  649. package/dist/world/placementController.d.ts +6 -0
  650. package/dist/world/placementController.js +6 -0
  651. package/dist/world/poleLineKind.d.ts +40 -0
  652. package/dist/world/poleLineKind.js +97 -0
  653. package/dist/world/polyline.d.ts +34 -0
  654. package/dist/world/polyline.js +88 -0
  655. package/dist/world/resourceNode.d.ts +109 -0
  656. package/dist/world/resourceNode.js +140 -0
  657. package/dist/world/roads.d.ts +8 -0
  658. package/dist/world/roads.js +38 -0
  659. package/dist/world/scatter.js +2 -20
  660. package/dist/world/scatterRegion.d.ts +164 -0
  661. package/dist/world/scatterRegion.js +409 -0
  662. package/dist/world/sceneShapes.d.ts +43 -0
  663. package/dist/world/sceneShapes.js +1 -0
  664. package/dist/world/segment.d.ts +27 -0
  665. package/dist/world/segment.js +43 -0
  666. package/dist/world/soilKind.d.ts +48 -0
  667. package/dist/world/soilKind.js +92 -0
  668. package/dist/world/spatialSample.d.ts +241 -0
  669. package/dist/world/spatialSample.js +465 -0
  670. package/dist/world/streets.d.ts +29 -0
  671. package/dist/world/streets.js +55 -0
  672. package/dist/world/terraform.d.ts +213 -1
  673. package/dist/world/terraform.js +627 -22
  674. package/dist/world/terrain.d.ts +164 -20
  675. package/dist/world/terrain.js +325 -41
  676. package/dist/world/terrainGuides.d.ts +182 -0
  677. package/dist/world/terrainGuides.js +343 -0
  678. package/dist/world/vec2.d.ts +81 -0
  679. package/dist/world/vec2.js +128 -0
  680. package/dist/world/vec3.d.ts +49 -0
  681. package/dist/world/vec3.js +76 -0
  682. package/dist/world/vegetation.d.ts +71 -0
  683. package/dist/world/vegetation.js +151 -0
  684. package/dist/world/visibilityField.d.ts +154 -0
  685. package/dist/world/visibilityField.js +271 -0
  686. package/dist/world/volumetricClouds.d.ts +52 -0
  687. package/dist/world/volumetricClouds.js +43 -0
  688. package/dist/world/walls.d.ts +9 -0
  689. package/dist/world/walls.js +9 -0
  690. package/dist/world/waterKind.d.ts +55 -0
  691. package/dist/world/waterKind.js +99 -0
  692. package/dist/world.d.ts +141 -0
  693. package/dist/world.js +141 -0
  694. package/package.json +32 -8
  695. package/skills/game-design/SKILL.md +28 -0
  696. package/skills/game-design/agents/openai.yaml +4 -0
  697. package/skills/game-design/references/application-playbook.md +170 -0
  698. package/skills/game-design/references/field-guide.md +288 -0
  699. package/skills/jgengine/SKILL.md +54 -0
  700. package/skills/jgengine/api.md +527 -0
  701. package/skills/jgengine/capabilities.md +131 -0
  702. package/skills/jgengine/recipes/minimal-game.md +88 -0
  703. package/skills/jgengine-combat/SKILL.md +38 -0
  704. package/skills/jgengine-combat/api.md +585 -0
  705. package/skills/jgengine-combat/capabilities.md +213 -0
  706. package/skills/jgengine-combat/recipes/portable-stat-pools.md +122 -0
  707. package/skills/jgengine-combat/reference.md +108 -0
  708. package/skills/jgengine-gameplay/SKILL.md +39 -0
  709. package/skills/jgengine-gameplay/api.md +1920 -0
  710. package/skills/jgengine-gameplay/capabilities.md +454 -0
  711. package/skills/jgengine-gameplay/reference-systems.md +56 -0
  712. package/skills/jgengine-world/SKILL.md +51 -0
  713. package/skills/jgengine-world/api.md +3056 -0
  714. package/skills/jgengine-world/capabilities.md +476 -0
  715. package/skills/jgengine-world/recipes/commanding-entities.md +128 -0
  716. package/skills/jgengine-world/reference.md +261 -0
  717. package/dist/cartridge/runtime.d.ts +0 -15
  718. package/dist/cartridge/runtime.js +0 -556
  719. package/dist/cartridge/spec.d.ts +0 -188
  720. package/dist/cartridge/spec.js +0 -19
  721. package/dist/cartridge/validate.d.ts +0 -2
  722. package/dist/cartridge/validate.js +0 -78
  723. package/dist/store/engineStore.d.ts +0 -22
  724. package/dist/store/engineStore.js +0 -50
  725. package/dist/store/features.d.ts +0 -10
  726. package/dist/store/features.js +0 -23
  727. package/llms.txt +0 -5389
@@ -1,798 +1,62 @@
1
1
  import { createChangeSignal } from "../store/changeSignal.js";
2
- import { CONTROL_SCHEMA_VERSION, MAX_SCAN_DEPTH, MAX_SCAN_TARGETS, MAX_TABLE_ENTRIES, OVERRIDES_FORMAT_VERSION, choiceValues, cloneValue, discoverableKind, expandAxisMeta, inferKind, isScannableContainer, joinTunablePath, normalizeColorValue, ownWritableDataKeys, parseOverridesPayload, resolveChoices, sliderBounds, validateControlValue, } from "./tunableSchema.js";
2
+ import { createFrameModule, nowMs } from "./frame.js";
3
+ import { createLogsModule } from "./logs.js";
4
+ import { createControlsModule } from "./controls.js";
5
+ import { createDiscoverModule } from "./discover.js";
6
+ import { createOverridesModule } from "./overrides.js";
3
7
  export { CONTROL_SCHEMA_VERSION, OVERRIDES_FORMAT_VERSION, convertAngle, escapePathSegment, formatColor, joinTunablePath, normalizeAngle, normalizeColorValue, parseColor, parseOverridesPayload, splitTunablePath, unescapePathSegment, validateControlValue, } from "./tunableSchema.js";
4
- const FRAME_CAPACITY = 240;
5
- const RECENT_FRAMES = 60;
6
- export const LONG_FRAME_MS = 33.4;
7
- const LATENCY_CAPACITY = 120;
8
- const LOG_CAPACITY = 200;
9
- const LOG_MESSAGE_MAX = 400;
10
- const LONG_FRAME_CAPACITY = 40;
11
- const MAX_PHASES_PER_FRAME = 24;
12
- const MAX_LONG_FRAME_PHASES = 8;
13
- const PHASE_HOT_MS = 2;
14
- function nowMs() {
15
- const perf = globalThis.performance;
16
- return perf !== undefined ? perf.now() : Date.now();
17
- }
18
- function formatLogArg(arg) {
19
- if (typeof arg === "string")
20
- return arg;
21
- if (arg instanceof Error)
22
- return `${arg.name}: ${arg.message}`;
23
- try {
24
- return JSON.stringify(arg) ?? String(arg);
25
- }
26
- catch {
27
- return String(arg);
28
- }
29
- }
30
- export function formatLogMessage(args) {
31
- const message = args.map(formatLogArg).join(" ");
32
- return message.length > LOG_MESSAGE_MAX ? `${message.slice(0, LOG_MESSAGE_MAX)}…` : message;
33
- }
34
- function percentile(sorted, fraction) {
35
- if (sorted.length === 0)
36
- return 0;
37
- const index = Math.min(sorted.length - 1, Math.floor(sorted.length * fraction));
38
- return sorted[index];
39
- }
40
- function clampMs(value) {
41
- return value > 0 && Number.isFinite(value) ? value : 0;
42
- }
43
- function rankPhases(phases) {
44
- const entries = Object.entries(phases)
45
- .filter(([, ms]) => Number.isFinite(ms) && ms > 0)
46
- .map(([name, ms]) => ({ name, ms }))
47
- .sort((a, b) => b.ms - a.ms)
48
- .slice(0, MAX_LONG_FRAME_PHASES);
49
- const total = entries.reduce((sum, entry) => sum + entry.ms, 0);
50
- return entries.map((entry) => ({
51
- name: entry.name,
52
- ms: entry.ms,
53
- pct: total > 0 ? (entry.ms / total) * 100 : 0,
54
- }));
55
- }
56
- function explainLongFrame(frameMs, simMs, outsideMs, ranked) {
57
- const top = ranked[0] ?? null;
58
- const topPhaseMs = top?.ms ?? 0;
59
- const phaseBits = ranked
60
- .filter((entry) => entry.ms >= PHASE_HOT_MS)
61
- .slice(0, 3)
62
- .map((entry) => `${entry.name} ${entry.ms.toFixed(1)}ms`);
63
- const outsideDominates = outsideMs > topPhaseMs && outsideMs >= simMs * 0.55 && outsideMs >= frameMs * 0.4;
64
- if (outsideDominates) {
65
- const detail = phaseBits.length > 0 ? ` · sim was ${phaseBits.join(", ")}` : simMs > 1 ? ` · sim ${simMs.toFixed(1)}ms` : "";
66
- return {
67
- topPhase: top?.name ?? null,
68
- culprit: "outside-sim",
69
- reason: `display/render/browser hitch ${outsideMs.toFixed(1)}ms outside sim${detail}`,
70
- };
71
- }
72
- if (top !== null && top.ms >= PHASE_HOT_MS) {
73
- const rest = phaseBits.slice(1);
74
- const restText = rest.length > 0 ? ` · also ${rest.join(", ")}` : "";
75
- const outsideText = outsideMs >= PHASE_HOT_MS ? ` · +${outsideMs.toFixed(1)}ms outside sim` : "";
76
- return {
77
- topPhase: top.name,
78
- culprit: top.name,
79
- reason: `${top.name} ${top.ms.toFixed(1)}ms (${top.pct.toFixed(0)}% of timed sim)${restText}${outsideText}`,
80
- };
81
- }
82
- if (simMs >= frameMs * 0.5) {
83
- return {
84
- topPhase: null,
85
- culprit: "sim",
86
- reason: `sim ${simMs.toFixed(1)}ms with no named phase ≥${PHASE_HOT_MS}ms — wrap hot work in measure("name", fn)`,
87
- };
88
- }
89
- return {
90
- topPhase: null,
91
- culprit: "outside-sim",
92
- reason: `frame ${frameMs.toFixed(1)}ms · sim ${simMs.toFixed(1)}ms · outside ${outsideMs.toFixed(1)}ms (render/React/GC/tab throttle)`,
93
- };
94
- }
95
- function collectScanTargets(root, meta) {
96
- const skipped = [];
97
- if (!isScannableContainer(root)) {
98
- if (root !== null && typeof root === "object") {
99
- skipped.push({ path: "", reason: "not a plain object or array" });
100
- }
101
- return { targets: [], skipped };
102
- }
103
- const out = [];
104
- const visited = new Set([root]);
105
- let frontier = [{ path: "", target: root }];
106
- for (let depth = 0; depth <= MAX_SCAN_DEPTH && frontier.length > 0; depth += 1) {
107
- const next = [];
108
- for (const { path, target } of frontier) {
109
- const keys = ownWritableDataKeys(target);
110
- let scalarCount = 0;
111
- for (const key of keys) {
112
- const value = target[key];
113
- const childPath = joinTunablePath(path, key);
114
- const fieldMeta = meta?.[childPath];
115
- const kind = discoverableKind(value, fieldMeta);
116
- if (kind !== null) {
117
- scalarCount += 1;
118
- if (scalarCount > MAX_TABLE_ENTRIES) {
119
- skipped.push({ path: path === "" ? "*" : path, reason: `more than ${MAX_TABLE_ENTRIES} scalar entries` });
120
- scalarCount = -1;
121
- break;
122
- }
123
- }
124
- }
125
- if (scalarCount < 0)
126
- continue;
127
- for (const key of keys) {
128
- const value = target[key];
129
- const childPath = joinTunablePath(path, key);
130
- const fieldMeta = meta?.[childPath];
131
- const kind = discoverableKind(value, fieldMeta);
132
- if (kind !== null) {
133
- if (out.length >= MAX_SCAN_TARGETS) {
134
- skipped.push({ path: childPath, reason: `scan cap ${MAX_SCAN_TARGETS}` });
135
- return { targets: out, skipped };
136
- }
137
- out.push({ path: childPath, target, key, kind, options: fieldMeta });
138
- continue;
139
- }
140
- if (value !== null && typeof value === "object") {
141
- if (!isScannableContainer(value)) {
142
- skipped.push({ path: childPath, reason: "unsupported structure" });
143
- continue;
144
- }
145
- if (visited.has(value)) {
146
- skipped.push({ path: childPath, reason: "cycle" });
147
- continue;
148
- }
149
- if (depth === MAX_SCAN_DEPTH) {
150
- skipped.push({ path: childPath, reason: `depth > ${MAX_SCAN_DEPTH}` });
151
- continue;
152
- }
153
- visited.add(value);
154
- next.push({ path: childPath, target: value });
155
- }
156
- }
157
- }
158
- frontier = next;
159
- }
160
- return { targets: out, skipped };
161
- }
8
+ export { LONG_FRAME_MS } from "./frame.js";
9
+ export { formatLogMessage } from "./logs.js";
162
10
  export function createDevtools() {
163
11
  const signal = createChangeSignal();
164
- const frameMsBuffer = new Float64Array(FRAME_CAPACITY);
165
- const simMsBuffer = new Float64Array(FRAME_CAPACITY);
166
- const outsideMsBuffer = new Float64Array(FRAME_CAPACITY);
167
- let frameIndex = 0;
168
- let frameCount = 0;
169
- let renderSample = null;
170
- const logEntries = [];
171
- let consoleCaptured = false;
172
- const latencySamples = [];
173
- const longFrameEvents = [];
174
- const phaseAccumulators = new Map();
175
- let currentPhases = {};
176
- let currentPhaseCount = 0;
177
- const controlRecords = new Map();
178
- const discoveredRecords = new Map();
179
- const probeReaders = new Map();
180
- let boundProps = new WeakMap();
181
- let discoverySkips = [];
182
- const readProbes = () => {
183
- const values = {};
184
- for (const [name, read] of probeReaders) {
185
- try {
186
- values[name] = read();
187
- }
188
- catch (error) {
189
- values[name] = `probe failed: ${formatLogArg(error)}`;
190
- }
191
- }
192
- return values;
193
- };
194
- const pushLog = (level, message) => {
195
- logEntries.push({ at: Date.now(), level, message });
196
- if (logEntries.length > LOG_CAPACITY)
197
- logEntries.splice(0, logEntries.length - LOG_CAPACITY);
198
- };
199
- const addPhaseMs = (name, ms) => {
200
- const elapsed = clampMs(ms);
201
- if (elapsed === 0 || name.length === 0)
202
- return;
203
- if (currentPhases[name] === undefined) {
204
- if (currentPhaseCount >= MAX_PHASES_PER_FRAME)
205
- return;
206
- currentPhaseCount += 1;
207
- currentPhases[name] = elapsed;
208
- return;
209
- }
210
- currentPhases[name] = currentPhases[name] + elapsed;
211
- };
212
- const resetCurrentPhases = () => {
213
- currentPhases = {};
214
- currentPhaseCount = 0;
215
- };
216
- const recordPhaseStats = (phases) => {
217
- for (const [name, ms] of Object.entries(phases)) {
218
- const elapsed = clampMs(ms);
219
- if (elapsed === 0)
220
- continue;
221
- const existing = phaseAccumulators.get(name);
222
- if (existing === undefined) {
223
- phaseAccumulators.set(name, { sumMs: elapsed, maxMs: elapsed, lastMs: elapsed, samples: 1 });
224
- }
225
- else {
226
- existing.sumMs += elapsed;
227
- existing.maxMs = Math.max(existing.maxMs, elapsed);
228
- existing.lastMs = elapsed;
229
- existing.samples += 1;
230
- }
231
- }
232
- };
233
- const phaseStatsList = (avgSimMs) => {
234
- const list = [];
235
- for (const [name, acc] of phaseAccumulators) {
236
- const avgMs = acc.sumMs / acc.samples;
237
- list.push({
238
- name,
239
- avgMs,
240
- maxMs: acc.maxMs,
241
- lastMs: acc.lastMs,
242
- samples: acc.samples,
243
- pctOfSim: avgSimMs > 0 ? (avgMs / avgSimMs) * 100 : 0,
244
- });
245
- }
246
- list.sort((a, b) => b.avgMs - a.avgMs);
247
- return list;
248
- };
249
- const frameStats = () => {
250
- if (frameCount === 0)
251
- return null;
252
- const size = Math.min(frameCount, FRAME_CAPACITY);
253
- const frames = [];
254
- const sims = [];
255
- const outsides = [];
256
- for (let offset = 0; offset < size; offset += 1) {
257
- const at = (frameIndex - size + offset + FRAME_CAPACITY) % FRAME_CAPACITY;
258
- frames.push(frameMsBuffer[at]);
259
- sims.push(simMsBuffer[at]);
260
- outsides.push(outsideMsBuffer[at]);
261
- }
262
- const recent = frames.slice(-RECENT_FRAMES);
263
- const recentAvg = recent.reduce((sum, ms) => sum + ms, 0) / recent.length;
264
- const sorted = [...frames].sort((a, b) => a - b);
265
- const avgSimMs = sims.reduce((sum, ms) => sum + ms, 0) / sims.length;
266
- return {
267
- fps: recentAvg > 0 ? 1000 / recentAvg : 0,
268
- avgFrameMs: frames.reduce((sum, ms) => sum + ms, 0) / frames.length,
269
- p95FrameMs: percentile(sorted, 0.95),
270
- maxFrameMs: sorted[sorted.length - 1],
271
- avgSimMs,
272
- maxSimMs: sims.reduce((max, ms) => Math.max(max, ms), 0),
273
- avgOutsideMs: outsides.reduce((sum, ms) => sum + ms, 0) / outsides.length,
274
- maxOutsideMs: outsides.reduce((max, ms) => Math.max(max, ms), 0),
275
- longFrames: frames.filter((ms) => ms > LONG_FRAME_MS).length,
276
- samples: size,
277
- recentFrameMs: recent,
278
- phases: phaseStatsList(avgSimMs),
279
- };
280
- };
281
- const recordFrame = (sample) => {
282
- const frameMs = clampMs(sample.frameMs);
283
- const simMs = clampMs(sample.simMs);
284
- const outsideMs = clampMs(frameMs - simMs);
285
- const phases = sample.phases !== undefined
286
- ? Object.fromEntries(Object.entries(sample.phases)
287
- .filter(([, ms]) => Number.isFinite(ms) && ms > 0)
288
- .slice(0, MAX_PHASES_PER_FRAME))
289
- : { ...currentPhases };
290
- frameMsBuffer[frameIndex] = frameMs;
291
- simMsBuffer[frameIndex] = simMs;
292
- outsideMsBuffer[frameIndex] = outsideMs;
293
- frameIndex = (frameIndex + 1) % FRAME_CAPACITY;
294
- frameCount += 1;
295
- recordPhaseStats(phases);
296
- if (frameMs > LONG_FRAME_MS) {
297
- const ranked = rankPhases(phases);
298
- const explained = explainLongFrame(frameMs, simMs, outsideMs, ranked);
299
- longFrameEvents.push({
300
- at: Date.now(),
301
- frameMs,
302
- simMs,
303
- outsideMs,
304
- phases: ranked,
305
- topPhase: explained.topPhase,
306
- culprit: explained.culprit,
307
- reason: explained.reason,
308
- probes: readProbes(),
309
- render: renderSample,
310
- });
311
- if (longFrameEvents.length > LONG_FRAME_CAPACITY) {
312
- longFrameEvents.splice(0, longFrameEvents.length - LONG_FRAME_CAPACITY);
313
- }
314
- }
315
- resetCurrentPhases();
316
- };
317
- const latencyStats = () => {
318
- if (latencySamples.length === 0)
319
- return null;
320
- let min = Number.POSITIVE_INFINITY;
321
- let max = 0;
322
- let sum = 0;
323
- for (const ms of latencySamples) {
324
- min = Math.min(min, ms);
325
- max = Math.max(max, ms);
326
- sum += ms;
327
- }
328
- return {
329
- lastMs: latencySamples[latencySamples.length - 1],
330
- avgMs: sum / latencySamples.length,
331
- minMs: min,
332
- maxMs: max,
333
- samples: latencySamples.length,
334
- };
335
- };
336
- const validationContext = (record) => ({
337
- min: record.min,
338
- max: record.max,
339
- step: record.step,
340
- integer: record.integer,
341
- unit: record.unit,
342
- wrap: record.wrap,
343
- choices: record.choices,
344
- options: record.options,
345
- axisBounds: record.axisBounds,
346
- alpha: record.hasAlpha,
12
+ const controls = createControlsModule({ signal });
13
+ const discover = createDiscoverModule({
14
+ signal,
15
+ register: controls.register,
16
+ controlRecords: controls.controlRecords,
347
17
  });
348
- const toControl = (record) => ({
349
- name: record.name,
350
- kind: record.kind,
351
- label: record.label,
352
- group: record.group,
353
- initial: record.initial,
354
- min: record.min,
355
- max: record.max,
356
- step: record.step,
357
- options: record.options ?? choiceValues(record.choices),
358
- choices: record.choices,
359
- unit: record.unit,
360
- displayUnit: record.displayUnit,
361
- wrap: record.wrap,
362
- integer: record.integer,
363
- axisLabels: record.axisBounds?.labels,
364
- axisMin: record.axisBounds?.min,
365
- axisMax: record.axisBounds?.max,
366
- axisStep: record.axisBounds?.step,
367
- hasAlpha: record.hasAlpha,
368
- schemaVersion: record.schemaVersion,
369
- read: () => record.value,
370
- write: (value) => writeControl(record, value),
371
- reset: () => {
372
- writeControl(record, cloneValue(record.initial));
373
- },
18
+ const frame = createFrameModule({ readProbes: discover.readProbes });
19
+ const logs = createLogsModule({ signal });
20
+ const overrides = createOverridesModule({
21
+ signal,
22
+ controlRecords: controls.controlRecords,
23
+ writeControl: controls.writeControl,
24
+ discoveredRecords: discover.discoveredRecords,
25
+ enableDiscovered: discover.enableDiscovered,
374
26
  });
375
- const writeControl = (record, raw) => {
376
- const validated = validateControlValue(record.kind, raw, validationContext(record));
377
- if (!validated.ok)
378
- return false;
379
- const next = validated.value;
380
- if (record.kind === "vec2" || record.kind === "vec3" || record.kind === "vec4" || record.kind === "interval") {
381
- if (JSON.stringify(record.value) === JSON.stringify(next))
382
- return true;
383
- record.value = cloneValue(next);
384
- }
385
- else {
386
- if (Object.is(record.value, next))
387
- return true;
388
- record.value = next;
389
- }
390
- for (const listener of record.listeners)
391
- listener(record.value);
392
- signal.notify();
393
- return true;
394
- };
395
- const hydrateRecord = (record, initial, options, kind) => {
396
- record.kind = kind;
397
- record.initial = cloneValue(initial);
398
- record.min = undefined;
399
- record.max = undefined;
400
- record.step = undefined;
401
- record.options = options?.options;
402
- record.choices = resolveChoices(options?.options, options?.choices);
403
- record.unit = options?.unit;
404
- record.displayUnit = options?.displayUnit ?? options?.unit;
405
- record.wrap = options?.wrap;
406
- record.integer = options?.integer;
407
- record.axisBounds = undefined;
408
- record.hasAlpha = undefined;
409
- record.schemaVersion = CONTROL_SCHEMA_VERSION;
410
- if (kind === "slider" || kind === "angle") {
411
- const bounds = sliderBounds(initial, options);
412
- record.min = bounds.min;
413
- record.max = bounds.max;
414
- record.step = bounds.step;
415
- if (kind === "angle") {
416
- record.unit = options?.unit ?? "rad";
417
- record.displayUnit = options?.displayUnit ?? "deg";
418
- }
419
- }
420
- else if (kind === "vec2" || kind === "vec3" || kind === "vec4") {
421
- const sample = Array.isArray(initial) ? initial : [];
422
- record.axisBounds = expandAxisMeta(sample.length, options?.axisLabels, options?.axisMin ?? options?.min, options?.axisMax ?? options?.max, options?.axisStep ?? options?.step, sample);
423
- }
424
- else if (kind === "interval") {
425
- record.min = options?.min;
426
- record.max = options?.max;
427
- record.step = options?.step;
428
- record.integer = options?.integer;
429
- }
430
- else if (kind === "color") {
431
- const normalized = normalizeColorValue(initial, options?.alpha);
432
- if (normalized !== null) {
433
- record.initial = normalized;
434
- if (Object.is(record.value, initial) || record.value === initial) {
435
- record.value = normalized;
436
- }
437
- record.hasAlpha = options?.alpha === true || normalized.length === 9;
438
- }
439
- }
440
- };
441
- const register = (name, initial, options) => {
442
- const kind = inferKind(initial, options);
443
- const existing = controlRecords.get(name);
444
- const slashIndex = name.indexOf("/");
445
- const derivedGroup = slashIndex > 0 ? name.slice(0, slashIndex) : "general";
446
- const derivedLabel = slashIndex > 0 ? name.slice(slashIndex + 1) : name;
447
- const record = existing !== undefined && existing.kind === kind
448
- ? existing
449
- : {
450
- name,
451
- kind,
452
- label: "",
453
- group: "",
454
- initial: cloneValue(initial),
455
- value: cloneValue(initial),
456
- schemaVersion: CONTROL_SCHEMA_VERSION,
457
- listeners: new Set(),
458
- };
459
- if (existing === undefined || existing.kind !== kind) {
460
- record.value = cloneValue(initial);
461
- }
462
- record.label = options?.label ?? derivedLabel;
463
- record.group = options?.group ?? derivedGroup;
464
- hydrateRecord(record, initial, options, kind);
465
- if (options?.onChange !== undefined)
466
- record.listeners.add(options.onChange);
467
- controlRecords.set(name, record);
468
- signal.notify();
469
- return {
470
- name,
471
- kind,
472
- initial: record.initial,
473
- get value() {
474
- return record.value;
475
- },
476
- set: (value) => writeControl(record, value),
477
- reset: () => {
478
- writeControl(record, cloneValue(record.initial));
479
- },
480
- subscribe: (listener) => {
481
- record.listeners.add(listener);
482
- return () => record.listeners.delete(listener);
483
- },
484
- };
485
- };
486
- const bindDiscovered = (table, key, kind, accessor, source, options) => {
487
- const id = `${table}/${key}`;
488
- const existing = discoveredRecords.get(id);
489
- if (existing === undefined) {
490
- discoveredRecords.set(id, {
491
- id,
492
- table,
493
- key,
494
- kind,
495
- initial: cloneValue(accessor.initial),
496
- enabled: false,
497
- source,
498
- options,
499
- get: accessor.get,
500
- set: accessor.set,
501
- });
502
- return true;
503
- }
504
- if (source !== null && existing.source === source)
505
- return false;
506
- existing.source = source;
507
- existing.get = accessor.get;
508
- existing.set = accessor.set;
509
- existing.kind = kind;
510
- existing.options = options ?? existing.options;
511
- const control = controlRecords.get(id);
512
- if (existing.enabled && control !== undefined)
513
- accessor.set(cloneValue(control.value));
514
- return true;
515
- };
516
- const scanTable = (table, candidate, meta) => {
517
- const { targets, skipped } = collectScanTargets(candidate, meta);
518
- discoverySkips = [
519
- ...discoverySkips.filter((entry) => entry.path !== table && !entry.path.startsWith(`${table}/`)),
520
- ...skipped.map((entry) => ({
521
- path: entry.path === "" ? table : `${table}/${entry.path}`,
522
- reason: entry.reason,
523
- })),
524
- ];
525
- if (targets.length === 0)
526
- return 0;
527
- let changed = false;
528
- let bound = 0;
529
- for (const { path, target, key, kind, options } of targets) {
530
- const boundKeys = boundProps.get(target);
531
- if (boundKeys?.has(key) === true && !discoveredRecords.has(`${table}/${path}`))
532
- continue;
533
- const accessor = {
534
- initial: cloneValue(target[key]),
535
- get: () => target[key],
536
- set: (value) => {
537
- target[key] = value;
538
- },
539
- };
540
- if (bindDiscovered(table, path, kind, accessor, target, options))
541
- changed = true;
542
- bound += 1;
543
- if (boundKeys === undefined)
544
- boundProps.set(target, new Set([key]));
545
- else
546
- boundKeys.add(key);
547
- }
548
- if (changed)
549
- signal.notify();
550
- return bound;
551
- };
552
- const enableDiscovered = (id) => {
553
- const record = discoveredRecords.get(id);
554
- if (record === undefined || record.enabled)
555
- return;
556
- record.enabled = true;
557
- const current = record.get();
558
- const handle = register(id, record.initial, {
559
- ...(record.options ?? {}),
560
- group: record.options?.group ?? record.table,
561
- label: record.options?.label ?? record.key,
562
- kind: record.kind,
563
- });
564
- handle.subscribe((value) => record.set(cloneValue(value)));
565
- if (JSON.stringify(current) !== JSON.stringify(record.initial))
566
- handle.set(current);
567
- };
568
27
  return {
569
- frame: {
570
- record: recordFrame,
571
- stats: frameStats,
572
- longFrames: () => longFrameEvents,
573
- clearLongFrames() {
574
- longFrameEvents.length = 0;
575
- },
576
- },
577
- profile: {
578
- begin(name) {
579
- const start = nowMs();
580
- return () => addPhaseMs(name, nowMs() - start);
581
- },
582
- measure(name, fn) {
583
- const start = nowMs();
584
- try {
585
- return fn();
586
- }
587
- finally {
588
- addPhaseMs(name, nowMs() - start);
589
- }
590
- },
591
- add: addPhaseMs,
592
- current: () => ({ ...currentPhases }),
593
- reset: resetCurrentPhases,
594
- },
595
- render: {
596
- record(sample) {
597
- renderSample = sample;
598
- },
599
- latest: () => renderSample,
600
- },
601
- logs: {
602
- push: pushLog,
603
- captureConsole() {
604
- if (consoleCaptured)
605
- return;
606
- const globalConsole = globalThis.console;
607
- if (globalConsole === undefined)
608
- return;
609
- consoleCaptured = true;
610
- const levels = ["log", "info", "warn", "error"];
611
- for (const level of levels) {
612
- const original = globalConsole[level].bind(globalConsole);
613
- globalConsole[level] = (...args) => {
614
- pushLog(level, formatLogMessage(args));
615
- original(...args);
616
- };
617
- }
618
- },
619
- list: () => logEntries,
620
- clear() {
621
- logEntries.length = 0;
622
- signal.notify();
623
- },
624
- },
625
- latency: {
626
- record(ms) {
627
- latencySamples.push(ms);
628
- if (latencySamples.length > LATENCY_CAPACITY)
629
- latencySamples.splice(0, latencySamples.length - LATENCY_CAPACITY);
630
- },
631
- stats: latencyStats,
632
- },
633
- controls: {
634
- register,
635
- list: () => [...controlRecords.values()].map(toControl),
636
- get: (name) => {
637
- const record = controlRecords.get(name);
638
- return record === undefined ? null : toControl(record);
639
- },
640
- remove(name) {
641
- if (controlRecords.delete(name))
642
- signal.notify();
643
- },
644
- resetAll() {
645
- for (const record of controlRecords.values())
646
- writeControl(record, cloneValue(record.initial));
647
- },
648
- },
649
- discover: {
650
- bind(table, key, accessor, options) {
651
- const kind = discoverableKind(accessor.initial, options);
652
- if (kind === null)
653
- return;
654
- if (bindDiscovered(table, key, kind, accessor, null, options))
655
- signal.notify();
656
- },
657
- scanTable,
658
- scanModule(exports, meta) {
659
- let total = 0;
660
- for (const [name, value] of Object.entries(exports)) {
661
- total += scanTable(name, value, meta);
662
- }
663
- return total;
664
- },
665
- list: () => [...discoveredRecords.values()].map((record) => ({
666
- id: record.id,
667
- table: record.table,
668
- key: record.key,
669
- kind: record.kind,
670
- initial: record.initial,
671
- enabled: record.enabled,
672
- read: () => record.get(),
673
- })),
674
- skipped: () => discoverySkips,
675
- enable(id) {
676
- enableDiscovered(id);
677
- signal.notify();
678
- },
679
- disable(id) {
680
- const record = discoveredRecords.get(id);
681
- if (record === undefined || !record.enabled)
682
- return;
683
- record.enabled = false;
684
- record.set(cloneValue(record.initial));
685
- controlRecords.delete(id);
686
- signal.notify();
687
- },
688
- clear() {
689
- for (const record of discoveredRecords.values()) {
690
- if (record.enabled) {
691
- record.set(cloneValue(record.initial));
692
- controlRecords.delete(record.id);
693
- }
694
- }
695
- discoveredRecords.clear();
696
- discoverySkips = [];
697
- boundProps = new WeakMap();
698
- signal.notify();
699
- },
700
- },
701
- overrides: {
702
- export() {
703
- const enabled = [...discoveredRecords.values()].filter((r) => r.enabled).map((r) => r.id);
704
- const values = {};
705
- const schemas = {};
706
- for (const record of controlRecords.values()) {
707
- schemas[record.name] = { kind: record.kind, schemaVersion: record.schemaVersion };
708
- const same = record.kind === "vec2" ||
709
- record.kind === "vec3" ||
710
- record.kind === "vec4" ||
711
- record.kind === "interval"
712
- ? JSON.stringify(record.value) === JSON.stringify(record.initial)
713
- : Object.is(record.value, record.initial);
714
- if (!same)
715
- values[record.name] = cloneValue(record.value);
716
- }
717
- return {
718
- version: OVERRIDES_FORMAT_VERSION,
719
- enabled,
720
- values,
721
- schemas,
722
- };
723
- },
724
- apply(raw) {
725
- const parsed = parseOverridesPayload(raw);
726
- const diagnostics = [...parsed.diagnostics];
727
- const skipped = [];
728
- if (parsed.overrides === null) {
729
- return { applied: 0, skipped, diagnostics };
730
- }
731
- const overrides = parsed.overrides;
732
- let applied = 0;
733
- for (const id of overrides.enabled) {
734
- if (!discoveredRecords.has(id) && !controlRecords.has(id)) {
735
- skipped.push({ id, reason: "unknown control id" });
736
- continue;
737
- }
738
- enableDiscovered(id);
739
- applied += 1;
740
- }
741
- for (const [name, value] of Object.entries(overrides.values)) {
742
- const record = controlRecords.get(name);
743
- if (record === undefined) {
744
- skipped.push({ id: name, reason: "control not registered" });
745
- continue;
746
- }
747
- const schema = overrides.schemas?.[name];
748
- if (schema !== undefined && schema.kind !== record.kind) {
749
- skipped.push({ id: name, reason: `kind mismatch stored=${schema.kind} current=${record.kind}` });
750
- continue;
751
- }
752
- if (!writeControl(record, value)) {
753
- skipped.push({ id: name, reason: "value failed validation" });
754
- continue;
755
- }
756
- applied += 1;
757
- }
758
- signal.notify();
759
- return { applied, skipped, diagnostics };
760
- },
761
- },
762
- probes: {
763
- register(name, read) {
764
- probeReaders.set(name, read);
765
- signal.notify();
766
- return () => {
767
- probeReaders.delete(name);
768
- signal.notify();
769
- };
770
- },
771
- read: readProbes,
772
- },
28
+ frame: frame.frame,
29
+ profile: frame.profile,
30
+ render: frame.render,
31
+ logs: logs.logs,
32
+ latency: logs.latency,
33
+ controls: controls.controls,
34
+ discover: discover.discover,
35
+ overrides: overrides.overrides,
36
+ probes: discover.probes,
773
37
  signal,
774
38
  snapshot() {
775
39
  return {
776
40
  at: Date.now(),
777
- frame: frameStats(),
778
- render: renderSample,
779
- latency: latencyStats(),
780
- longFrames: [...longFrameEvents],
781
- logs: [...logEntries],
782
- probes: readProbes(),
783
- controls: [...controlRecords.values()].map((record) => ({
41
+ frame: frame.frame.stats(),
42
+ render: frame.render.latest(),
43
+ latency: logs.latency.stats(),
44
+ longFrames: [...frame.frame.longFrames()],
45
+ logs: [...logs.logs.list()],
46
+ probes: discover.readProbes(),
47
+ controls: [...controls.controlRecords.values()].map((record) => ({
784
48
  name: record.name,
785
49
  kind: record.kind,
786
50
  value: record.value,
787
51
  initial: record.initial,
788
52
  })),
789
- discovered: [...discoveredRecords.values()].map((record) => ({
53
+ discovered: [...discover.discoveredRecords.values()].map((record) => ({
790
54
  id: record.id,
791
55
  kind: record.kind,
792
56
  value: record.get(),
793
57
  enabled: record.enabled,
794
58
  })),
795
- skipped: [...discoverySkips],
59
+ skipped: [...discover.getDiscoverySkips()],
796
60
  };
797
61
  },
798
62
  };