@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
@@ -0,0 +1,222 @@
1
+ import { type Curve } from "../game/progression.js";
2
+ /**
3
+ * How cycles that came due between two {@link advanceLedger} calls are settled:
4
+ * - `"each"` — replay every missed cycle as its own transaction (bounded by the limits below);
5
+ * - `"sum"` — collapse the missed cycles into one transaction of the combined amount;
6
+ * - `"skip"` — apply only the most recent cycle and discard the rest (idle income that does not bank).
7
+ */
8
+ export type CatchUpPolicy = "each" | "sum" | "skip";
9
+ /**
10
+ * A serializable recurring resource flow. Every field is plain JSON so the whole
11
+ * {@link ResourceLedger} round-trips through `structuredClone`/`JSON`. Dynamic, context-aware
12
+ * behaviour (providers, tax curves, affordability caps) lives in the runtime
13
+ * {@link ResourcePolicy} pipeline, never in this data.
14
+ */
15
+ export interface ScheduledRule {
16
+ /** Stable id, unique within a ledger. */
17
+ id: string;
18
+ /** Resource/currency key that moves. */
19
+ currency: string;
20
+ /** Positive nominal amount moved per cycle before policies run. */
21
+ amount: number;
22
+ /** Cadence in game-seconds; must be `> 0`. */
23
+ everySeconds: number;
24
+ /** First due time in game-seconds; defaults to the ledger clock when the rule is added. */
25
+ startSeconds?: number;
26
+ /** Inclusive end time; omitted means the rule never expires. */
27
+ endSeconds?: number;
28
+ /** Account debited each cycle; omitted mints the amount from an external source (production). */
29
+ source?: string;
30
+ /** Account credited each cycle; omitted burns the amount into an external sink (upkeep/tax). */
31
+ recipient?: string;
32
+ /** Finite reserve consumed by the nominal amount each cycle; the rule depletes when it empties. */
33
+ reserve?: number;
34
+ /** Catch-up settlement policy; defaults to `"each"`. */
35
+ catchUp?: CatchUpPolicy;
36
+ /** Per-rule offline limit: due cycles beyond this in one advance are dropped, not banked. */
37
+ maxCatchUpCycles?: number;
38
+ }
39
+ /** Mutable per-rule progress, kept separate from the immutable {@link ScheduledRule} definition. */
40
+ export interface RuleCursor {
41
+ /** Absolute time of the next cycle that has not yet been settled. */
42
+ nextDueSeconds: number;
43
+ /** Remaining finite reserve, when the rule declared one. */
44
+ reserveRemaining?: number;
45
+ /** Total cycles fired so far — a stable, monotonic cycle index. */
46
+ fired: number;
47
+ /** Paused rules keep their cursor but fire nothing until resumed. */
48
+ paused: boolean;
49
+ /** Set once the rule expired or fully depleted; it never fires again. */
50
+ done: boolean;
51
+ }
52
+ /** Fully serializable scheduled-transaction state: clock, balances, rule definitions, and cursors. */
53
+ export interface ResourceLedger {
54
+ nowSeconds: number;
55
+ accounts: Record<string, Record<string, number>>;
56
+ rules: Record<string, ScheduledRule>;
57
+ cursors: Record<string, RuleCursor>;
58
+ }
59
+ /** One resource movement produced by a due cycle, before it is applied to balances. */
60
+ export interface ResourceTransaction {
61
+ ruleId: string;
62
+ currency: string;
63
+ amount: number;
64
+ source?: string;
65
+ recipient?: string;
66
+ /** Which cycle of the rule produced this (from {@link RuleCursor.fired}). */
67
+ cycleIndex: number;
68
+ atSeconds: number;
69
+ /** Ordered provenance tags appended by the policy pipeline. */
70
+ provenance: readonly string[];
71
+ }
72
+ /** Read-only context handed to every {@link ResourcePolicy} for a transaction. */
73
+ export interface PolicyContext {
74
+ /** The rule that scheduled this flow. */
75
+ rule: ScheduledRule;
76
+ /** Current balance snapshot (reflects transactions already applied this advance). */
77
+ balanceOf(account: string, currency: string): number;
78
+ /** Caller-supplied numeric context bag read by threshold/curve modifiers. */
79
+ vars: Readonly<Record<string, number>>;
80
+ nowSeconds: number;
81
+ }
82
+ /**
83
+ * A composable transform over one transaction. Return the transactions to keep:
84
+ * `[]` rejects it, `[txn]` passes/transforms it, and multiple entries split it.
85
+ */
86
+ export type ResourcePolicy = (txn: ResourceTransaction, ctx: PolicyContext) => readonly ResourceTransaction[];
87
+ /** Deterministic rounding applied to every transaction amount before it touches balances. */
88
+ export interface Precision {
89
+ /** Quantisation step, e.g. `1` for whole units or `0.01` for cents. */
90
+ quantum: number;
91
+ /** Rounding mode; defaults to `"round"`. */
92
+ mode?: "floor" | "round" | "ceil";
93
+ }
94
+ /** A `{ min, factor }` band for {@link thresholdScale}; the highest band whose `min` is met wins. */
95
+ export interface ThresholdBand {
96
+ min: number;
97
+ factor: number;
98
+ }
99
+ /** Per-advance settings: the policy pipeline, caller context, rounding, and safety bounds. */
100
+ export interface AdvanceOptions {
101
+ /** Policy pipeline applied to every transaction, in order. */
102
+ policies?: readonly ResourcePolicy[];
103
+ /** Numeric context exposed to policies via {@link PolicyContext.vars}. */
104
+ vars?: Readonly<Record<string, number>>;
105
+ /** Rounding applied to each transaction amount before it hits balances. */
106
+ precision?: Precision;
107
+ /** Global safety bound on individual cycles settled per rule per advance; defaults to `10000`. */
108
+ maxCyclesPerRule?: number;
109
+ }
110
+ /** The kinds of lifecycle signal {@link advanceLedger} can emit for a rule. */
111
+ export type LedgerEventKind = "started" | "fired" | "skipped" | "depleted" | "ended";
112
+ /** Lifecycle signal emitted by {@link advanceLedger}. */
113
+ export interface LedgerEvent {
114
+ kind: LedgerEventKind;
115
+ ruleId: string;
116
+ atSeconds: number;
117
+ /** Cycle count for `fired`/`skipped`, or the consumed reserve for `depleted`. */
118
+ detail: number;
119
+ }
120
+ /** A {@link ResourceTransaction} after policies and rounding, as actually applied to balances. */
121
+ export type AppliedTransaction = ResourceTransaction;
122
+ /** The outcome of {@link advanceLedger}: the new ledger plus applied transactions and events. */
123
+ export interface AdvanceResult {
124
+ ledger: ResourceLedger;
125
+ applied: AppliedTransaction[];
126
+ events: LedgerEvent[];
127
+ }
128
+ /**
129
+ * Create an empty scheduled-transaction ledger, or hydrate one from a saved snapshot.
130
+ * State is plain data: production, depletion, tax, and upkeep are all expressed as
131
+ * {@link ScheduledRule}s settled deterministically by {@link advanceLedger}.
132
+ *
133
+ * @capability resource-ledger schedule recurring resource transactions with policy transforms
134
+ */
135
+ export declare function createResourceLedger(init?: Partial<ResourceLedger>): ResourceLedger;
136
+ /** Read a single balance; unknown account/currency pairs read as `0`. */
137
+ export declare function balanceOf(ledger: ResourceLedger, account: string, currency: string): number;
138
+ /**
139
+ * Register a recurring rule and seed its cursor. Returns a new ledger; the rule's first cycle
140
+ * is due at `rule.startSeconds` (defaulting to the current clock).
141
+ */
142
+ export declare function addScheduledRule(ledger: ResourceLedger, rule: ScheduledRule): ResourceLedger;
143
+ /**
144
+ * Remove a rule and its cursor entirely (hard cancellation).
145
+ *
146
+ * @capability cancel-scheduled-rule remove a scheduled rule and its cursor entirely
147
+ */
148
+ export declare function cancelRule(ledger: ResourceLedger, ruleId: string): ResourceLedger;
149
+ /**
150
+ * Pause a rule: its cursor is retained but it fires nothing until {@link resumeRule}.
151
+ *
152
+ * @capability pause-scheduled-rule stop a scheduled rule from firing while retaining its cursor
153
+ */
154
+ export declare function pauseRule(ledger: ResourceLedger, ruleId: string): ResourceLedger;
155
+ /**
156
+ * Resume a paused rule. Its `nextDueSeconds` is unchanged, so the paused span counts as missed
157
+ * cycles that the rule's {@link CatchUpPolicy} decides how to settle on the next advance.
158
+ *
159
+ * @capability resume-scheduled-rule resume a paused scheduled rule, deferring missed cycles to its catch-up policy
160
+ */
161
+ export declare function resumeRule(ledger: ResourceLedger, ruleId: string): ResourceLedger;
162
+ /**
163
+ * Advance the ledger clock to `toSeconds`, settling every due cycle deterministically.
164
+ * Rules are processed in sorted-id order; cycle counts are integer math; large deltas are
165
+ * bounded by `catchUp`, `maxCatchUpCycles`, and `maxCyclesPerRule`. Every produced transaction
166
+ * flows through the policy pipeline (transform, cap, reject, split, redirect, annotate) before it
167
+ * is quantised and applied to balances.
168
+ *
169
+ * @capability advance-ledger settle due scheduled transactions through a policy pipeline
170
+ */
171
+ export declare function advanceLedger(ledger: ResourceLedger, toSeconds: number, options?: AdvanceOptions): AdvanceResult;
172
+ /** Reader over policy context: a `vars` key or a function of the context. */
173
+ export type PolicyRead = string | ((ctx: PolicyContext) => number);
174
+ /**
175
+ * Clamp a transaction's amount to at most `max` (a fixed number or a function of context).
176
+ *
177
+ * @capability policy-cap cap a scheduled transaction amount by context
178
+ */
179
+ export declare function capAmount(max: number | ((ctx: PolicyContext) => number)): ResourcePolicy;
180
+ /**
181
+ * Take a fraction of the amount. With `to`, the taxed portion is split off into a second
182
+ * transaction toward that recipient (a transfer/tax); without it, the fraction is simply removed.
183
+ *
184
+ * @capability policy-tax split off a fraction of a transaction as tax or transfer
185
+ */
186
+ export declare function taxFraction(fraction: number, to?: string): ResourcePolicy;
187
+ /**
188
+ * Override the source and/or recipient accounts of a transaction.
189
+ *
190
+ * @capability policy-redirect redirect a scheduled transaction's source or recipient
191
+ */
192
+ export declare function redirect(endpoints: {
193
+ source?: string;
194
+ recipient?: string;
195
+ }): ResourcePolicy;
196
+ /**
197
+ * Drop a transaction when `predicate` holds — the reject arm of the pipeline.
198
+ *
199
+ * @capability policy-reject reject scheduled transactions by predicate
200
+ */
201
+ export declare function rejectWhen(predicate: (txn: ResourceTransaction, ctx: PolicyContext) => boolean): ResourcePolicy;
202
+ /**
203
+ * Append a provenance tag to a transaction without changing its value.
204
+ *
205
+ * @capability policy-annotate tag a scheduled transaction's provenance without changing its value
206
+ */
207
+ export declare function annotate(tag: string): ResourcePolicy;
208
+ /**
209
+ * Scale the amount by the highest {@link ThresholdBand} whose `min` the read value meets — a
210
+ * generic bracket modifier (progressive tax, tiered upkeep) over caller data, with no built-in
211
+ * currencies or brackets.
212
+ *
213
+ * @capability policy-threshold scale a transaction by a context threshold band
214
+ */
215
+ export declare function thresholdScale(read: PolicyRead, bands: readonly ThresholdBand[]): ResourcePolicy;
216
+ /**
217
+ * Scale the amount by a {@link Curve} evaluated at the read value — a generic curve modifier
218
+ * (population upkeep, depletion falloff, difficulty income) over caller-provided context.
219
+ *
220
+ * @capability policy-curve scale a transaction by a curve over context
221
+ */
222
+ export declare function curveScale(read: PolicyRead, shape: Curve): ResourcePolicy;
@@ -0,0 +1,353 @@
1
+ import { evalCurve } from "../game/progression.js";
2
+ const EPSILON = 1e-9;
3
+ /**
4
+ * Create an empty scheduled-transaction ledger, or hydrate one from a saved snapshot.
5
+ * State is plain data: production, depletion, tax, and upkeep are all expressed as
6
+ * {@link ScheduledRule}s settled deterministically by {@link advanceLedger}.
7
+ *
8
+ * @capability resource-ledger schedule recurring resource transactions with policy transforms
9
+ */
10
+ export function createResourceLedger(init) {
11
+ return {
12
+ nowSeconds: init?.nowSeconds ?? 0,
13
+ accounts: cloneAccounts(init?.accounts ?? {}),
14
+ rules: { ...(init?.rules ?? {}) },
15
+ cursors: { ...(init?.cursors ?? {}) },
16
+ };
17
+ }
18
+ /** Read a single balance; unknown account/currency pairs read as `0`. */
19
+ export function balanceOf(ledger, account, currency) {
20
+ return ledger.accounts[account]?.[currency] ?? 0;
21
+ }
22
+ /**
23
+ * Register a recurring rule and seed its cursor. Returns a new ledger; the rule's first cycle
24
+ * is due at `rule.startSeconds` (defaulting to the current clock).
25
+ */
26
+ export function addScheduledRule(ledger, rule) {
27
+ if (!(rule.everySeconds > 0)) {
28
+ throw new RangeError(`rule ${rule.id} everySeconds must be positive, got ${rule.everySeconds}`);
29
+ }
30
+ if (!Number.isFinite(rule.amount) || rule.amount < 0) {
31
+ throw new RangeError(`rule ${rule.id} amount must be a non-negative finite number, got ${rule.amount}`);
32
+ }
33
+ const cursor = {
34
+ nextDueSeconds: rule.startSeconds ?? ledger.nowSeconds,
35
+ reserveRemaining: rule.reserve,
36
+ fired: 0,
37
+ paused: false,
38
+ done: false,
39
+ };
40
+ return {
41
+ ...ledger,
42
+ rules: { ...ledger.rules, [rule.id]: { ...rule } },
43
+ cursors: { ...ledger.cursors, [rule.id]: cursor },
44
+ };
45
+ }
46
+ /**
47
+ * Remove a rule and its cursor entirely (hard cancellation).
48
+ *
49
+ * @capability cancel-scheduled-rule remove a scheduled rule and its cursor entirely
50
+ */
51
+ export function cancelRule(ledger, ruleId) {
52
+ if (ledger.rules[ruleId] === undefined)
53
+ return ledger;
54
+ const rules = { ...ledger.rules };
55
+ const cursors = { ...ledger.cursors };
56
+ delete rules[ruleId];
57
+ delete cursors[ruleId];
58
+ return { ...ledger, rules, cursors };
59
+ }
60
+ /**
61
+ * Pause a rule: its cursor is retained but it fires nothing until {@link resumeRule}.
62
+ *
63
+ * @capability pause-scheduled-rule stop a scheduled rule from firing while retaining its cursor
64
+ */
65
+ export function pauseRule(ledger, ruleId) {
66
+ return setPaused(ledger, ruleId, true);
67
+ }
68
+ /**
69
+ * Resume a paused rule. Its `nextDueSeconds` is unchanged, so the paused span counts as missed
70
+ * cycles that the rule's {@link CatchUpPolicy} decides how to settle on the next advance.
71
+ *
72
+ * @capability resume-scheduled-rule resume a paused scheduled rule, deferring missed cycles to its catch-up policy
73
+ */
74
+ export function resumeRule(ledger, ruleId) {
75
+ return setPaused(ledger, ruleId, false);
76
+ }
77
+ function setPaused(ledger, ruleId, paused) {
78
+ const cursor = ledger.cursors[ruleId];
79
+ if (cursor === undefined || cursor.paused === paused)
80
+ return ledger;
81
+ return { ...ledger, cursors: { ...ledger.cursors, [ruleId]: { ...cursor, paused } } };
82
+ }
83
+ /**
84
+ * Advance the ledger clock to `toSeconds`, settling every due cycle deterministically.
85
+ * Rules are processed in sorted-id order; cycle counts are integer math; large deltas are
86
+ * bounded by `catchUp`, `maxCatchUpCycles`, and `maxCyclesPerRule`. Every produced transaction
87
+ * flows through the policy pipeline (transform, cap, reject, split, redirect, annotate) before it
88
+ * is quantised and applied to balances.
89
+ *
90
+ * @capability advance-ledger settle due scheduled transactions through a policy pipeline
91
+ */
92
+ export function advanceLedger(ledger, toSeconds, options = {}) {
93
+ if (toSeconds < ledger.nowSeconds) {
94
+ throw new RangeError(`advanceLedger cannot rewind: ${toSeconds} < ${ledger.nowSeconds}`);
95
+ }
96
+ const accounts = cloneAccounts(ledger.accounts);
97
+ const cursors = { ...ledger.cursors };
98
+ const applied = [];
99
+ const events = [];
100
+ const policies = options.policies ?? [];
101
+ const vars = options.vars ?? {};
102
+ const maxCycles = options.maxCyclesPerRule ?? 10_000;
103
+ const ctxBalance = (account, currency) => accounts[account]?.[currency] ?? 0;
104
+ for (const id of Object.keys(ledger.rules).sort()) {
105
+ const rule = ledger.rules[id];
106
+ const cursor = { ...cursors[id] };
107
+ if (cursor.done || cursor.paused)
108
+ continue;
109
+ const end = rule.endSeconds ?? Number.POSITIVE_INFINITY;
110
+ const windowEnd = Math.min(toSeconds, end);
111
+ if (cursor.nextDueSeconds <= windowEnd) {
112
+ const wasFirstFire = cursor.fired === 0;
113
+ const dueCount = Math.floor((windowEnd - cursor.nextDueSeconds) / rule.everySeconds + EPSILON) + 1;
114
+ const firstDue = cursor.nextDueSeconds;
115
+ const perRuleLimit = rule.maxCatchUpCycles ?? Number.POSITIVE_INFINITY;
116
+ const catchUp = rule.catchUp ?? "each";
117
+ // Reserve-capped nominal amount per candidate cycle, in chronological order.
118
+ const nominal = reserveCappedAmounts(dueCount, rule.amount, cursor.reserveRemaining);
119
+ const depleted = cursor.reserveRemaining !== undefined && nominal.remaining <= EPSILON;
120
+ const cycles = buildCycles(catchUp, nominal.amounts, firstDue, rule.everySeconds, perRuleLimit, maxCycles);
121
+ if (wasFirstFire && cycles.settled.length > 0) {
122
+ events.push({ kind: "started", ruleId: id, atSeconds: cycles.settled[0].atSeconds, detail: 0 });
123
+ }
124
+ for (const cycle of cycles.settled) {
125
+ const seed = {
126
+ ruleId: id,
127
+ currency: rule.currency,
128
+ amount: cycle.amount,
129
+ source: rule.source,
130
+ recipient: rule.recipient,
131
+ cycleIndex: cursor.fired,
132
+ atSeconds: cycle.atSeconds,
133
+ provenance: [],
134
+ };
135
+ cursor.fired += 1;
136
+ const context = { rule, balanceOf: ctxBalance, vars, nowSeconds: cycle.atSeconds };
137
+ for (const txn of runPolicies(seed, policies, context)) {
138
+ const amount = quantize(txn.amount, options.precision);
139
+ if (amount === 0)
140
+ continue;
141
+ const finalTxn = { ...txn, amount };
142
+ applyTransaction(accounts, finalTxn);
143
+ applied.push(finalTxn);
144
+ events.push({ kind: "fired", ruleId: id, atSeconds: finalTxn.atSeconds, detail: amount });
145
+ }
146
+ }
147
+ if (cycles.skipped > 0) {
148
+ events.push({ kind: "skipped", ruleId: id, atSeconds: windowEnd, detail: cycles.skipped });
149
+ }
150
+ if (cursor.reserveRemaining !== undefined)
151
+ cursor.reserveRemaining = nominal.remaining;
152
+ // Time always moves past every due cycle in the window, whether settled or skipped.
153
+ cursor.nextDueSeconds = firstDue + dueCount * rule.everySeconds;
154
+ if (depleted) {
155
+ cursor.done = true;
156
+ events.push({ kind: "depleted", ruleId: id, atSeconds: windowEnd, detail: nominal.consumed });
157
+ }
158
+ }
159
+ if (!cursor.done && Number.isFinite(end) && cursor.nextDueSeconds > end) {
160
+ cursor.done = true;
161
+ events.push({ kind: "ended", ruleId: id, atSeconds: end, detail: cursor.fired });
162
+ }
163
+ cursors[id] = cursor;
164
+ }
165
+ return {
166
+ ledger: { nowSeconds: toSeconds, accounts, rules: { ...ledger.rules }, cursors },
167
+ applied,
168
+ events,
169
+ };
170
+ }
171
+ function buildCycles(catchUp, amounts, firstDue, everySeconds, perRuleLimit, maxCycles) {
172
+ const available = amounts.length;
173
+ if (available === 0)
174
+ return { settled: [], skipped: 0 };
175
+ const timeOf = (index) => firstDue + index * everySeconds;
176
+ if (catchUp === "skip") {
177
+ const last = available - 1;
178
+ return { settled: [{ atSeconds: timeOf(last), amount: amounts[last] }], skipped: last };
179
+ }
180
+ if (catchUp === "sum") {
181
+ const kept = Math.min(available, perRuleLimit);
182
+ let total = 0;
183
+ for (let i = 0; i < kept; i += 1)
184
+ total += amounts[i];
185
+ const skipped = available - kept;
186
+ if (kept === 0)
187
+ return { settled: [], skipped };
188
+ return { settled: [{ atSeconds: timeOf(kept - 1), amount: total }], skipped };
189
+ }
190
+ // "each"
191
+ const kept = Math.min(available, perRuleLimit, maxCycles);
192
+ const settled = [];
193
+ for (let i = 0; i < kept; i += 1)
194
+ settled.push({ atSeconds: timeOf(i), amount: amounts[i] });
195
+ return { settled, skipped: available - kept };
196
+ }
197
+ function reserveCappedAmounts(count, amount, reserveRemaining) {
198
+ if (reserveRemaining === undefined) {
199
+ return { amounts: new Array(count).fill(amount), remaining: Number.POSITIVE_INFINITY, consumed: count * amount };
200
+ }
201
+ const amounts = [];
202
+ let remaining = reserveRemaining;
203
+ for (let i = 0; i < count && remaining > EPSILON; i += 1) {
204
+ const take = Math.min(amount, remaining);
205
+ amounts.push(take);
206
+ remaining -= take;
207
+ }
208
+ if (remaining < EPSILON)
209
+ remaining = 0;
210
+ return { amounts, remaining, consumed: reserveRemaining - remaining };
211
+ }
212
+ function runPolicies(seed, policies, ctx) {
213
+ let current = [seed];
214
+ for (const policy of policies) {
215
+ const next = [];
216
+ for (const txn of current) {
217
+ for (const out of policy(txn, ctx))
218
+ next.push(out);
219
+ }
220
+ current = next;
221
+ if (current.length === 0)
222
+ break;
223
+ }
224
+ return current;
225
+ }
226
+ function applyTransaction(accounts, txn) {
227
+ if (txn.source !== undefined)
228
+ addBalance(accounts, txn.source, txn.currency, -txn.amount);
229
+ if (txn.recipient !== undefined)
230
+ addBalance(accounts, txn.recipient, txn.currency, txn.amount);
231
+ }
232
+ function addBalance(accounts, account, currency, delta) {
233
+ const wallet = accounts[account] ?? (accounts[account] = {});
234
+ wallet[currency] = (wallet[currency] ?? 0) + delta;
235
+ }
236
+ function quantize(value, precision) {
237
+ if (precision === undefined || !(precision.quantum > 0))
238
+ return value;
239
+ const steps = value / precision.quantum;
240
+ const rounded = Math.round(steps * 1e9) / 1e9;
241
+ const mode = precision.mode ?? "round";
242
+ const n = mode === "floor" ? Math.floor(rounded) : mode === "ceil" ? Math.ceil(rounded) : Math.round(rounded);
243
+ return n * precision.quantum;
244
+ }
245
+ function cloneAccounts(accounts) {
246
+ const out = {};
247
+ for (const account of Object.keys(accounts))
248
+ out[account] = { ...accounts[account] };
249
+ return out;
250
+ }
251
+ function readValue(read, ctx) {
252
+ return typeof read === "function" ? read(ctx) : (ctx.vars[read] ?? 0);
253
+ }
254
+ function tagged(txn, tag) {
255
+ return [...txn.provenance, tag];
256
+ }
257
+ /**
258
+ * Clamp a transaction's amount to at most `max` (a fixed number or a function of context).
259
+ *
260
+ * @capability policy-cap cap a scheduled transaction amount by context
261
+ */
262
+ export function capAmount(max) {
263
+ return (txn, ctx) => {
264
+ const limit = typeof max === "function" ? max(ctx) : max;
265
+ if (txn.amount <= limit)
266
+ return [txn];
267
+ return [{ ...txn, amount: limit, provenance: tagged(txn, "capped") }];
268
+ };
269
+ }
270
+ /**
271
+ * Take a fraction of the amount. With `to`, the taxed portion is split off into a second
272
+ * transaction toward that recipient (a transfer/tax); without it, the fraction is simply removed.
273
+ *
274
+ * @capability policy-tax split off a fraction of a transaction as tax or transfer
275
+ */
276
+ export function taxFraction(fraction, to) {
277
+ const rate = Math.max(0, Math.min(1, fraction));
278
+ return (txn) => {
279
+ const taxed = txn.amount * rate;
280
+ const kept = txn.amount - taxed;
281
+ const out = [];
282
+ if (kept > 0)
283
+ out.push({ ...txn, amount: kept, provenance: tagged(txn, "taxed") });
284
+ if (taxed > 0 && to !== undefined) {
285
+ out.push({ ...txn, amount: taxed, recipient: to, provenance: tagged(txn, `tax->${to}`) });
286
+ }
287
+ return out;
288
+ };
289
+ }
290
+ /**
291
+ * Override the source and/or recipient accounts of a transaction.
292
+ *
293
+ * @capability policy-redirect redirect a scheduled transaction's source or recipient
294
+ */
295
+ export function redirect(endpoints) {
296
+ return (txn) => [
297
+ {
298
+ ...txn,
299
+ source: endpoints.source ?? txn.source,
300
+ recipient: endpoints.recipient ?? txn.recipient,
301
+ provenance: tagged(txn, "redirected"),
302
+ },
303
+ ];
304
+ }
305
+ /**
306
+ * Drop a transaction when `predicate` holds — the reject arm of the pipeline.
307
+ *
308
+ * @capability policy-reject reject scheduled transactions by predicate
309
+ */
310
+ export function rejectWhen(predicate) {
311
+ return (txn, ctx) => (predicate(txn, ctx) ? [] : [txn]);
312
+ }
313
+ /**
314
+ * Append a provenance tag to a transaction without changing its value.
315
+ *
316
+ * @capability policy-annotate tag a scheduled transaction's provenance without changing its value
317
+ */
318
+ export function annotate(tag) {
319
+ return (txn) => [{ ...txn, provenance: tagged(txn, tag) }];
320
+ }
321
+ /**
322
+ * Scale the amount by the highest {@link ThresholdBand} whose `min` the read value meets — a
323
+ * generic bracket modifier (progressive tax, tiered upkeep) over caller data, with no built-in
324
+ * currencies or brackets.
325
+ *
326
+ * @capability policy-threshold scale a transaction by a context threshold band
327
+ */
328
+ export function thresholdScale(read, bands) {
329
+ const sorted = [...bands].sort((a, b) => a.min - b.min);
330
+ return (txn, ctx) => {
331
+ const value = readValue(read, ctx);
332
+ let factor = 1;
333
+ for (const band of sorted) {
334
+ if (value >= band.min)
335
+ factor = band.factor;
336
+ else
337
+ break;
338
+ }
339
+ return [{ ...txn, amount: txn.amount * factor, provenance: tagged(txn, `threshold:${factor}`) }];
340
+ };
341
+ }
342
+ /**
343
+ * Scale the amount by a {@link Curve} evaluated at the read value — a generic curve modifier
344
+ * (population upkeep, depletion falloff, difficulty income) over caller-provided context.
345
+ *
346
+ * @capability policy-curve scale a transaction by a curve over context
347
+ */
348
+ export function curveScale(read, shape) {
349
+ return (txn, ctx) => {
350
+ const factor = evalCurve(shape, readValue(read, ctx));
351
+ return [{ ...txn, amount: txn.amount * factor, provenance: tagged(txn, "curve") }];
352
+ };
353
+ }
@@ -6,8 +6,11 @@ export type WalletScope = {
6
6
  kind: "group";
7
7
  groupId: string;
8
8
  };
9
+ /** @internal */
9
10
  export declare function scopeKey(scope: WalletScope): string;
11
+ /** @internal */
10
12
  export declare function userScope(userId: string): WalletScope;
13
+ /** @internal */
11
14
  export declare function groupScope(groupId: string): WalletScope;
12
15
  export interface WalletBook {
13
16
  scopes: Readonly<Record<string, WalletState>>;
@@ -20,9 +23,20 @@ export type BookChargeResult = {
20
23
  status: "rejected";
21
24
  reason: "insufficient-funds";
22
25
  };
26
+ /**
27
+ * Shared or group currency pools that track each member's contribution to a common balance.
28
+ *
29
+ * @capability shared-wallet shared/group currency pools tracking per-member contributions
30
+ * @internal
31
+ */
23
32
  export declare function createWalletBook(): WalletBook;
33
+ /** @internal */
24
34
  export declare function balanceIn(book: WalletBook, scope: WalletScope, currency: string): number;
35
+ /** @internal */
25
36
  export declare function grantTo(book: WalletBook, scope: WalletScope, currency: string, amount: number, by?: string): WalletBook;
37
+ /** @internal */
26
38
  export declare function chargeFrom(book: WalletBook, scope: WalletScope, currency: string, amount: number, by?: string): BookChargeResult;
39
+ /** @internal */
27
40
  export declare function contributionOf(book: WalletBook, groupId: string, userId: string): Readonly<Record<string, number>>;
41
+ /** @internal */
28
42
  export declare function contributorsOf(book: WalletBook, groupId: string): string[];
@@ -1,19 +1,29 @@
1
1
  import { balance, charge, createEmptyWallet, grant } from "./wallet.js";
2
+ /** @internal */
2
3
  export function scopeKey(scope) {
3
4
  return scope.kind === "user" ? `user:${scope.userId}` : `group:${scope.groupId}`;
4
5
  }
6
+ /** @internal */
5
7
  export function userScope(userId) {
6
8
  return { kind: "user", userId };
7
9
  }
10
+ /** @internal */
8
11
  export function groupScope(groupId) {
9
12
  return { kind: "group", groupId };
10
13
  }
14
+ /**
15
+ * Shared or group currency pools that track each member's contribution to a common balance.
16
+ *
17
+ * @capability shared-wallet shared/group currency pools tracking per-member contributions
18
+ * @internal
19
+ */
11
20
  export function createWalletBook() {
12
21
  return { scopes: {}, contributions: {} };
13
22
  }
14
23
  function scopeState(book, key) {
15
24
  return book.scopes[key] ?? createEmptyWallet();
16
25
  }
26
+ /** @internal */
17
27
  export function balanceIn(book, scope, currency) {
18
28
  return balance(scopeState(book, scopeKey(scope)), currency);
19
29
  }
@@ -35,6 +45,7 @@ function recordContribution(book, groupKey, userId, currency, delta) {
35
45
  },
36
46
  };
37
47
  }
48
+ /** @internal */
38
49
  export function grantTo(book, scope, currency, amount, by) {
39
50
  const key = scopeKey(scope);
40
51
  let next = withScope(book, key, grant(scopeState(book, key), currency, amount));
@@ -43,6 +54,7 @@ export function grantTo(book, scope, currency, amount, by) {
43
54
  }
44
55
  return next;
45
56
  }
57
+ /** @internal */
46
58
  export function chargeFrom(book, scope, currency, amount, by) {
47
59
  const key = scopeKey(scope);
48
60
  const result = charge(scopeState(book, key), currency, amount);
@@ -54,9 +66,11 @@ export function chargeFrom(book, scope, currency, amount, by) {
54
66
  }
55
67
  return { status: "ok", book: next };
56
68
  }
69
+ /** @internal */
57
70
  export function contributionOf(book, groupId, userId) {
58
71
  return book.contributions[scopeKey(groupScope(groupId))]?.[userId] ?? {};
59
72
  }
73
+ /** @internal */
60
74
  export function contributorsOf(book, groupId) {
61
75
  return Object.keys(book.contributions[scopeKey(groupScope(groupId))] ?? {});
62
76
  }