@crowdedkingdoms/crowdyjs 17.14.0-dev.1 → 18.0.1-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (289) hide show
  1. package/MIGRATION.md +129 -1
  2. package/README.md +97 -164
  3. package/dist/crowdy-client.d.ts +12 -31
  4. package/dist/crowdy-client.d.ts.map +1 -1
  5. package/dist/crowdy-client.js +15 -37
  6. package/dist/crowdy-dsh/bridge.d.ts.map +1 -1
  7. package/dist/crowdy-dsh/bridge.js +3 -6
  8. package/dist/crowdy-studio/controller.d.ts +34 -59
  9. package/dist/crowdy-studio/controller.d.ts.map +1 -1
  10. package/dist/crowdy-studio/controller.js +96 -225
  11. package/dist/crowdy-studio/diagnostics.d.ts +3 -12
  12. package/dist/crowdy-studio/diagnostics.d.ts.map +1 -1
  13. package/dist/crowdy-studio/dom-shell.d.ts +2 -4
  14. package/dist/crowdy-studio/dom-shell.d.ts.map +1 -1
  15. package/dist/crowdy-studio/dom-shell.js +16 -49
  16. package/dist/crowdy-studio/embed/hud-layer.d.ts +1 -2
  17. package/dist/crowdy-studio/embed/hud-layer.d.ts.map +1 -1
  18. package/dist/crowdy-studio/embed/panel.d.ts +3 -13
  19. package/dist/crowdy-studio/embed/panel.d.ts.map +1 -1
  20. package/dist/crowdy-studio/embed/panel.js +3 -6
  21. package/dist/crowdy-studio/index.d.ts +1 -3
  22. package/dist/crowdy-studio/index.d.ts.map +1 -1
  23. package/dist/crowdy-studio/index.js +0 -2
  24. package/dist/crowdy-studio/models.d.ts +3 -4
  25. package/dist/crowdy-studio/models.d.ts.map +1 -1
  26. package/dist/crowdy-studio/starter-projects.d.ts +8 -12
  27. package/dist/crowdy-studio/starter-projects.d.ts.map +1 -1
  28. package/dist/crowdy-studio/starter-projects.js +12 -103
  29. package/dist/domains/appAccess.d.ts +14 -1
  30. package/dist/domains/appAccess.d.ts.map +1 -1
  31. package/dist/domains/appAccess.js +37 -1
  32. package/dist/domains/apps.d.ts +1 -10
  33. package/dist/domains/apps.d.ts.map +1 -1
  34. package/dist/domains/apps.js +1 -16
  35. package/dist/domains/host.d.ts +3 -3
  36. package/dist/domains/host.js +3 -3
  37. package/dist/domains/hosting.d.ts +0 -6
  38. package/dist/domains/hosting.d.ts.map +1 -1
  39. package/dist/domains/hosting.js +1 -16
  40. package/dist/domains/marketplace.d.ts +9 -70
  41. package/dist/domains/marketplace.d.ts.map +1 -1
  42. package/dist/domains/marketplace.js +9 -120
  43. package/dist/domains/organizations.d.ts +1 -9
  44. package/dist/domains/organizations.d.ts.map +1 -1
  45. package/dist/domains/organizations.js +1 -15
  46. package/dist/domains/payments.d.ts +5 -48
  47. package/dist/domains/payments.d.ts.map +1 -1
  48. package/dist/domains/payments.js +5 -57
  49. package/dist/domains/playerWallet.d.ts +6 -12
  50. package/dist/domains/playerWallet.d.ts.map +1 -1
  51. package/dist/domains/playerWallet.js +6 -21
  52. package/dist/domains/quotas.d.ts +20 -7
  53. package/dist/domains/quotas.d.ts.map +1 -1
  54. package/dist/domains/quotas.js +15 -6
  55. package/dist/domains/users.d.ts +7 -74
  56. package/dist/domains/users.d.ts.map +1 -1
  57. package/dist/domains/users.js +7 -105
  58. package/dist/errors.d.ts +7 -13
  59. package/dist/errors.d.ts.map +1 -1
  60. package/dist/errors.js +6 -10
  61. package/dist/generated/graphql.d.ts +955 -8272
  62. package/dist/generated/graphql.d.ts.map +1 -1
  63. package/dist/generated/graphql.js +5 -329
  64. package/dist/grid-mods/exec-client-halves.d.ts +19 -3
  65. package/dist/grid-mods/exec-client-halves.d.ts.map +1 -1
  66. package/dist/grid-mods/exec-client-halves.js +17 -2
  67. package/dist/grid-mods/grid-host-calls.d.ts +29 -17
  68. package/dist/grid-mods/grid-host-calls.d.ts.map +1 -1
  69. package/dist/grid-mods/grid-host-calls.js +40 -46
  70. package/dist/grid-mods/mod-runtime.d.ts +18 -11
  71. package/dist/grid-mods/mod-runtime.d.ts.map +1 -1
  72. package/dist/grid-mods/mod-runtime.js +4 -2
  73. package/dist/grid-scope.d.ts +0 -189
  74. package/dist/grid-scope.d.ts.map +1 -1
  75. package/dist/grid-scope.js +0 -70
  76. package/dist/index.d.ts +12 -18
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +10 -16
  79. package/dist/kit/actions.d.ts +5 -9
  80. package/dist/kit/actions.d.ts.map +1 -1
  81. package/dist/kit/actions.js +5 -9
  82. package/dist/kit/index.d.ts +2 -33
  83. package/dist/kit/index.d.ts.map +1 -1
  84. package/dist/kit/index.js +1 -32
  85. package/dist/kit/kit.d.ts +8 -208
  86. package/dist/kit/kit.d.ts.map +1 -1
  87. package/dist/kit/kit.js +5 -163
  88. package/dist/kit/social.d.ts +1 -3
  89. package/dist/kit/social.d.ts.map +1 -1
  90. package/dist/kit/social.js +1 -3
  91. package/dist/kit/wire.d.ts +16 -5
  92. package/dist/kit/wire.d.ts.map +1 -1
  93. package/dist/kit/wire.js +19 -5
  94. package/dist/live-coding/assets/browser-authoring-index.json +1 -1
  95. package/dist/live-coding/assets/manifest.json +1 -1
  96. package/dist/live-coding/browser-authoring-index.generated.d.ts.map +1 -1
  97. package/dist/live-coding/browser-authoring-index.generated.js +1496 -4386
  98. package/dist/live-coding/rust-analysis.d.ts.map +1 -1
  99. package/dist/live-coding/rust-analysis.js +30 -34
  100. package/dist/player-runtime/client-host-calls.d.ts +8 -0
  101. package/dist/player-runtime/client-host-calls.d.ts.map +1 -0
  102. package/dist/player-runtime/client-host-calls.js +28 -0
  103. package/dist/player-runtime/glue-runtime.d.ts +24 -20
  104. package/dist/player-runtime/glue-runtime.d.ts.map +1 -1
  105. package/dist/player-runtime/glue-runtime.js +26 -55
  106. package/dist/player-runtime/glue-sab.d.ts +2 -2
  107. package/dist/player-runtime/glue-sab.js +2 -2
  108. package/dist/player-runtime/player-code-broker.d.ts +70 -43
  109. package/dist/player-runtime/player-code-broker.d.ts.map +1 -1
  110. package/dist/player-runtime/player-code-broker.js +159 -64
  111. package/dist/player-runtime/player-glue-worker.d.ts +8 -9
  112. package/dist/player-runtime/player-glue-worker.d.ts.map +1 -1
  113. package/dist/player-runtime/player-glue-worker.js +26 -11
  114. package/dist/stores/inbox.d.ts +1 -1
  115. package/dist/stores/inbox.d.ts.map +1 -1
  116. package/dist/stores/index.d.ts +0 -11
  117. package/dist/stores/index.d.ts.map +1 -1
  118. package/dist/stores/index.js +0 -4
  119. package/dist/stores/session.d.ts +0 -2
  120. package/dist/stores/session.d.ts.map +1 -1
  121. package/package.json +1 -1
  122. package/dist/crowdy-studio/model-lint-log.d.ts +0 -76
  123. package/dist/crowdy-studio/model-lint-log.d.ts.map +0 -1
  124. package/dist/crowdy-studio/model-lint-log.js +0 -93
  125. package/dist/crowdy-studio/model-lint.d.ts +0 -61
  126. package/dist/crowdy-studio/model-lint.d.ts.map +0 -1
  127. package/dist/crowdy-studio/model-lint.js +0 -45
  128. package/dist/domains/compute.d.ts +0 -208
  129. package/dist/domains/compute.d.ts.map +0 -1
  130. package/dist/domains/compute.js +0 -274
  131. package/dist/domains/controlPlane.d.ts +0 -38
  132. package/dist/domains/controlPlane.d.ts.map +0 -1
  133. package/dist/domains/controlPlane.js +0 -43
  134. package/dist/domains/gameModel.d.ts +0 -1174
  135. package/dist/domains/gameModel.d.ts.map +0 -1
  136. package/dist/domains/gameModel.js +0 -1333
  137. package/dist/domains/playerCompute.d.ts +0 -91
  138. package/dist/domains/playerCompute.d.ts.map +0 -1
  139. package/dist/domains/playerCompute.js +0 -136
  140. package/dist/domains/playerModel.d.ts +0 -20
  141. package/dist/domains/playerModel.d.ts.map +0 -1
  142. package/dist/domains/playerModel.js +0 -54
  143. package/dist/kit/abilities.d.ts +0 -66
  144. package/dist/kit/abilities.d.ts.map +0 -1
  145. package/dist/kit/abilities.js +0 -71
  146. package/dist/kit/blueprints/combat.d.ts +0 -81
  147. package/dist/kit/blueprints/combat.d.ts.map +0 -1
  148. package/dist/kit/blueprints/combat.js +0 -357
  149. package/dist/kit/blueprints/core.d.ts +0 -222
  150. package/dist/kit/blueprints/core.d.ts.map +0 -1
  151. package/dist/kit/blueprints/core.js +0 -185
  152. package/dist/kit/blueprints/decks.d.ts +0 -50
  153. package/dist/kit/blueprints/decks.d.ts.map +0 -1
  154. package/dist/kit/blueprints/decks.js +0 -163
  155. package/dist/kit/blueprints/economy.d.ts +0 -88
  156. package/dist/kit/blueprints/economy.d.ts.map +0 -1
  157. package/dist/kit/blueprints/economy.js +0 -533
  158. package/dist/kit/blueprints/guild.d.ts +0 -51
  159. package/dist/kit/blueprints/guild.d.ts.map +0 -1
  160. package/dist/kit/blueprints/guild.js +0 -50
  161. package/dist/kit/blueprints/index.d.ts +0 -23
  162. package/dist/kit/blueprints/index.d.ts.map +0 -1
  163. package/dist/kit/blueprints/index.js +0 -22
  164. package/dist/kit/blueprints/inventory.d.ts +0 -84
  165. package/dist/kit/blueprints/inventory.d.ts.map +0 -1
  166. package/dist/kit/blueprints/inventory.js +0 -257
  167. package/dist/kit/blueprints/leaderboards.d.ts +0 -49
  168. package/dist/kit/blueprints/leaderboards.d.ts.map +0 -1
  169. package/dist/kit/blueprints/leaderboards.js +0 -126
  170. package/dist/kit/blueprints/liveops.d.ts +0 -42
  171. package/dist/kit/blueprints/liveops.d.ts.map +0 -1
  172. package/dist/kit/blueprints/liveops.js +0 -170
  173. package/dist/kit/blueprints/locks.d.ts +0 -82
  174. package/dist/kit/blueprints/locks.d.ts.map +0 -1
  175. package/dist/kit/blueprints/locks.js +0 -155
  176. package/dist/kit/blueprints/loot.d.ts +0 -90
  177. package/dist/kit/blueprints/loot.d.ts.map +0 -1
  178. package/dist/kit/blueprints/loot.js +0 -229
  179. package/dist/kit/blueprints/matches.d.ts +0 -84
  180. package/dist/kit/blueprints/matches.d.ts.map +0 -1
  181. package/dist/kit/blueprints/matches.js +0 -349
  182. package/dist/kit/blueprints/moderation.d.ts +0 -32
  183. package/dist/kit/blueprints/moderation.d.ts.map +0 -1
  184. package/dist/kit/blueprints/moderation.js +0 -140
  185. package/dist/kit/blueprints/npcs.d.ts +0 -78
  186. package/dist/kit/blueprints/npcs.d.ts.map +0 -1
  187. package/dist/kit/blueprints/npcs.js +0 -125
  188. package/dist/kit/blueprints/plots.d.ts +0 -63
  189. package/dist/kit/blueprints/plots.d.ts.map +0 -1
  190. package/dist/kit/blueprints/plots.js +0 -151
  191. package/dist/kit/blueprints/progression.d.ts +0 -68
  192. package/dist/kit/blueprints/progression.d.ts.map +0 -1
  193. package/dist/kit/blueprints/progression.js +0 -324
  194. package/dist/kit/blueprints/quests.d.ts +0 -72
  195. package/dist/kit/blueprints/quests.d.ts.map +0 -1
  196. package/dist/kit/blueprints/quests.js +0 -285
  197. package/dist/kit/blueprints/worldsim.d.ts +0 -91
  198. package/dist/kit/blueprints/worldsim.d.ts.map +0 -1
  199. package/dist/kit/blueprints/worldsim.js +0 -468
  200. package/dist/kit/combat.d.ts +0 -141
  201. package/dist/kit/combat.d.ts.map +0 -1
  202. package/dist/kit/combat.js +0 -196
  203. package/dist/kit/decks.d.ts +0 -157
  204. package/dist/kit/decks.d.ts.map +0 -1
  205. package/dist/kit/decks.js +0 -186
  206. package/dist/kit/director.d.ts +0 -88
  207. package/dist/kit/director.d.ts.map +0 -1
  208. package/dist/kit/director.js +0 -86
  209. package/dist/kit/economy.d.ts +0 -289
  210. package/dist/kit/economy.d.ts.map +0 -1
  211. package/dist/kit/economy.js +0 -427
  212. package/dist/kit/engine.d.ts +0 -48
  213. package/dist/kit/engine.d.ts.map +0 -1
  214. package/dist/kit/engine.js +0 -113
  215. package/dist/kit/features.d.ts +0 -60
  216. package/dist/kit/features.d.ts.map +0 -1
  217. package/dist/kit/features.js +0 -65
  218. package/dist/kit/instances.d.ts +0 -52
  219. package/dist/kit/instances.d.ts.map +0 -1
  220. package/dist/kit/instances.js +0 -60
  221. package/dist/kit/inventory.d.ts +0 -129
  222. package/dist/kit/inventory.d.ts.map +0 -1
  223. package/dist/kit/inventory.js +0 -200
  224. package/dist/kit/leaderboards.d.ts +0 -86
  225. package/dist/kit/leaderboards.d.ts.map +0 -1
  226. package/dist/kit/leaderboards.js +0 -133
  227. package/dist/kit/liveops.d.ts +0 -112
  228. package/dist/kit/liveops.d.ts.map +0 -1
  229. package/dist/kit/liveops.js +0 -183
  230. package/dist/kit/loot.d.ts +0 -128
  231. package/dist/kit/loot.d.ts.map +0 -1
  232. package/dist/kit/loot.js +0 -160
  233. package/dist/kit/matches.d.ts +0 -301
  234. package/dist/kit/matches.d.ts.map +0 -1
  235. package/dist/kit/matches.js +0 -458
  236. package/dist/kit/matchmaking.d.ts +0 -57
  237. package/dist/kit/matchmaking.d.ts.map +0 -1
  238. package/dist/kit/matchmaking.js +0 -59
  239. package/dist/kit/minigames.d.ts +0 -30
  240. package/dist/kit/minigames.d.ts.map +0 -1
  241. package/dist/kit/minigames.js +0 -38
  242. package/dist/kit/mobs.d.ts +0 -90
  243. package/dist/kit/mobs.d.ts.map +0 -1
  244. package/dist/kit/mobs.js +0 -98
  245. package/dist/kit/moderation.d.ts +0 -73
  246. package/dist/kit/moderation.d.ts.map +0 -1
  247. package/dist/kit/moderation.js +0 -103
  248. package/dist/kit/movement.d.ts +0 -78
  249. package/dist/kit/movement.d.ts.map +0 -1
  250. package/dist/kit/movement.js +0 -103
  251. package/dist/kit/notifications.d.ts +0 -45
  252. package/dist/kit/notifications.d.ts.map +0 -1
  253. package/dist/kit/notifications.js +0 -67
  254. package/dist/kit/npcs.d.ts +0 -226
  255. package/dist/kit/npcs.d.ts.map +0 -1
  256. package/dist/kit/npcs.js +0 -141
  257. package/dist/kit/objects.d.ts +0 -116
  258. package/dist/kit/objects.d.ts.map +0 -1
  259. package/dist/kit/objects.js +0 -119
  260. package/dist/kit/pets.d.ts +0 -85
  261. package/dist/kit/pets.d.ts.map +0 -1
  262. package/dist/kit/pets.js +0 -96
  263. package/dist/kit/plots.d.ts +0 -85
  264. package/dist/kit/plots.d.ts.map +0 -1
  265. package/dist/kit/plots.js +0 -113
  266. package/dist/kit/progression.d.ts +0 -181
  267. package/dist/kit/progression.d.ts.map +0 -1
  268. package/dist/kit/progression.js +0 -265
  269. package/dist/kit/quests.d.ts +0 -171
  270. package/dist/kit/quests.d.ts.map +0 -1
  271. package/dist/kit/quests.js +0 -237
  272. package/dist/kit/racing.d.ts +0 -85
  273. package/dist/kit/racing.d.ts.map +0 -1
  274. package/dist/kit/racing.js +0 -99
  275. package/dist/kit/shared.d.ts +0 -73
  276. package/dist/kit/shared.d.ts.map +0 -1
  277. package/dist/kit/shared.js +0 -101
  278. package/dist/kit/telemetry.d.ts +0 -66
  279. package/dist/kit/telemetry.d.ts.map +0 -1
  280. package/dist/kit/telemetry.js +0 -133
  281. package/dist/kit/territory.d.ts +0 -97
  282. package/dist/kit/territory.d.ts.map +0 -1
  283. package/dist/kit/territory.js +0 -114
  284. package/dist/kit/worldsim.d.ts +0 -263
  285. package/dist/kit/worldsim.d.ts.map +0 -1
  286. package/dist/kit/worldsim.js +0 -268
  287. package/dist/stores/model.d.ts +0 -81
  288. package/dist/stores/model.d.ts.map +0 -1
  289. package/dist/stores/model.js +0 -163
@@ -1,427 +0,0 @@
1
- import { economyCurrencyFn, economyNames, } from './blueprints/index.js';
2
- import { kitContainerProperties, kitInvoke, } from './shared.js';
3
- /**
4
- * Runtime helpers for the {@link economyBlueprint} conventions: wallets with
5
- * per-currency balances, shop purchases, escrow trades, and player market
6
- * listings. Every movement of currency or items is a single gated invoke —
7
- * balances, stock, item identity, and ownership are all verified
8
- * server-side, and a denial resolves with `success: false` (never an
9
- * exception).
10
- *
11
- * `earn` is a trusted grant: with the default blueprint authority
12
- * (`'server'`) it succeeds only for app admins — call it from studio/backend
13
- * code, or drive grants through automations instead.
14
- *
15
- * Obtained via `client.kit(appId).economy`.
16
- */
17
- export class EconomyKit {
18
- constructor(appId, gameModel, options = {}, engines) {
19
- this.appId = appId;
20
- this.gameModel = gameModel;
21
- /** Shop (admin-priced listings; atomic buys). */
22
- this.shop = {
23
- /**
24
- * Create a shop listing (admin — the type is admin-instantiable).
25
- * `maxStock` feeds the optional restock automation.
26
- */
27
- create: async (input) => {
28
- return this.gameModel.createContainer({
29
- appId: this.appId,
30
- typeName: this.names.listingType,
31
- displayName: input.displayName,
32
- properties: [
33
- { key: 'item_id', valueType: 'string', valueJson: JSON.stringify(input.itemId) },
34
- { key: 'price', valueType: 'int', valueJson: String(input.price) },
35
- { key: 'stock', valueType: 'int', valueJson: String(input.stock ?? 0) },
36
- {
37
- key: 'max_stock',
38
- valueType: 'int',
39
- valueJson: String(input.maxStock ?? input.stock ?? 0),
40
- },
41
- ...(input.properties ?? []),
42
- ],
43
- });
44
- },
45
- /** List shop listings with parsed state. */
46
- list: async () => {
47
- const containers = await this.gameModel.containers({
48
- appId: this.appId,
49
- typeName: this.names.listingType,
50
- });
51
- return Promise.all(containers.map(async (c) => {
52
- const props = await kitContainerProperties(this.gameModel, String(this.appId), c.containerId);
53
- return {
54
- containerId: c.containerId,
55
- displayName: c.displayName,
56
- itemId: String(props.item_id ?? ''),
57
- price: Number(props.price ?? 0),
58
- stock: Number(props.stock ?? 0),
59
- maxStock: Number(props.max_stock ?? 0),
60
- };
61
- }));
62
- },
63
- /**
64
- * Buy one unit: wallet debit + stock decrement + item grant into
65
- * `toStackId` (a stack of the listed item), all in one transaction.
66
- * Resolves with the wallet's remaining balance.
67
- */
68
- buy: async (input) => {
69
- return kitInvoke(this.gameModel, {
70
- appId: String(this.appId),
71
- functionName: this.names.buyListingFn,
72
- selfContainerId: input.listingId,
73
- params: { wallet_id: input.walletId, to_stack_id: input.toStackId },
74
- });
75
- },
76
- };
77
- /** Escrow trades (player↔player item swaps, atomic on accept). */
78
- this.trades = {
79
- /**
80
- * Create a trade offer to another player. The stacks named here are the
81
- * OFFERER's: `giveStackId` is the escrowed source, `receiveStackId`
82
- * receives the wanted items when the trade is accepted. The offer's
83
- * container ownership (server-assigned to the caller) is what the accept
84
- * guards trust — a forged offer over someone else's stacks can never be
85
- * accepted.
86
- */
87
- offer: async (input) => {
88
- return this.gameModel.createContainer({
89
- appId: this.appId,
90
- typeName: this.names.tradeType,
91
- displayName: input.displayName ??
92
- `Trade ${input.giveQty}x ${input.giveItemId} for ${input.wantQty}x ${input.wantItemId}`,
93
- ...(input.sessionId !== undefined ? { sessionId: input.sessionId } : {}),
94
- properties: [
95
- { key: 'to_user_id', valueType: 'int', valueJson: String(input.toUserId) },
96
- {
97
- key: 'give_stack_id',
98
- valueType: 'string',
99
- valueJson: JSON.stringify(input.giveStackId),
100
- },
101
- {
102
- key: 'receive_stack_id',
103
- valueType: 'string',
104
- valueJson: JSON.stringify(input.receiveStackId),
105
- },
106
- {
107
- key: 'give_item_id',
108
- valueType: 'string',
109
- valueJson: JSON.stringify(input.giveItemId),
110
- },
111
- { key: 'give_qty', valueType: 'int', valueJson: String(input.giveQty) },
112
- {
113
- key: 'want_item_id',
114
- valueType: 'string',
115
- valueJson: JSON.stringify(input.wantItemId),
116
- },
117
- { key: 'want_qty', valueType: 'int', valueJson: String(input.wantQty) },
118
- ],
119
- });
120
- },
121
- /**
122
- * Accept a trade as the invited player, supplying YOUR two stacks: the
123
- * one paying the wanted items and the one receiving the given items. The
124
- * offerer's stacks come from the offer record. All four quantity writes
125
- * commit atomically or not at all.
126
- */
127
- accept: async (input) => {
128
- const offer = await this.trades.get(input.offerId);
129
- return kitInvoke(this.gameModel, {
130
- appId: String(this.appId),
131
- functionName: this.names.acceptTradeFn,
132
- selfContainerId: input.offerId,
133
- params: {
134
- give_stack_id: offer.giveStackId,
135
- to_give_stack_id: input.toGiveStackId,
136
- want_stack_id: input.wantStackId,
137
- to_want_stack_id: offer.receiveStackId,
138
- },
139
- });
140
- },
141
- /** Cancel an open trade (either party may). */
142
- cancel: async (offerId) => {
143
- return kitInvoke(this.gameModel, {
144
- appId: String(this.appId),
145
- functionName: this.names.cancelTradeFn,
146
- selfContainerId: offerId,
147
- params: {},
148
- });
149
- },
150
- /** Read one trade offer with parsed state. */
151
- get: async (offerId) => {
152
- const container = await this.gameModel.container({
153
- appId: this.appId,
154
- containerId: offerId,
155
- });
156
- return this.toTrade(container.containerId, container.displayName, container.ownerUserId != null ? String(container.ownerUserId) : null);
157
- },
158
- /** List trades the user created or was invited to (open ones first). */
159
- listMine: async (userId) => {
160
- const containers = await this.gameModel.containers({
161
- appId: this.appId,
162
- typeName: this.names.tradeType,
163
- });
164
- const all = await Promise.all(containers.map((c) => this.toTrade(c.containerId, c.displayName, c.ownerUserId != null ? String(c.ownerUserId) : null)));
165
- const uid = String(userId);
166
- return all
167
- .filter((t) => t.fromUserId === uid || String(t.toUserId) === uid)
168
- .sort((a, b) => Number(b.status === 'open') - Number(a.status === 'open'));
169
- },
170
- };
171
- /** Player market (list a stack for currency; atomic purchases). */
172
- this.market = {
173
- /**
174
- * List items for sale: names YOUR escrowed source stack and the ask
175
- * price. Payment lands straight in your wallet when someone buys.
176
- */
177
- list: async (input) => {
178
- return this.gameModel.createContainer({
179
- appId: this.appId,
180
- typeName: this.names.marketType,
181
- displayName: input.displayName ?? `${input.quantity}x ${input.itemId} for ${input.price}`,
182
- ...(input.sessionId !== undefined ? { sessionId: input.sessionId } : {}),
183
- properties: [
184
- {
185
- key: 'stack_id',
186
- valueType: 'string',
187
- valueJson: JSON.stringify(input.stackId),
188
- },
189
- {
190
- key: 'item_id',
191
- valueType: 'string',
192
- valueJson: JSON.stringify(input.itemId),
193
- },
194
- { key: 'quantity', valueType: 'int', valueJson: String(input.quantity) },
195
- { key: 'price', valueType: 'int', valueJson: String(input.price) },
196
- ],
197
- });
198
- },
199
- /** Browse market listings (active ones only by default). */
200
- browse: async (options = {}) => {
201
- const containers = await this.gameModel.containers({
202
- appId: this.appId,
203
- typeName: this.names.marketType,
204
- });
205
- const all = await Promise.all(containers.map(async (c) => {
206
- const props = await kitContainerProperties(this.gameModel, String(this.appId), c.containerId);
207
- return {
208
- containerId: c.containerId,
209
- displayName: c.displayName,
210
- sellerUserId: c.ownerUserId != null ? String(c.ownerUserId) : null,
211
- stackId: String(props.stack_id ?? ''),
212
- itemId: String(props.item_id ?? ''),
213
- quantity: Number(props.quantity ?? 0),
214
- price: Number(props.price ?? 0),
215
- active: props.active === true,
216
- };
217
- }));
218
- return options.includeInactive ? all : all.filter((l) => l.active);
219
- },
220
- /**
221
- * Buy a market listing: pays the seller's wallet and transfers the items
222
- * into `toStackId` in one transaction. The seller's wallet and source
223
- * stack are resolved from the listing. Resolves with the buyer wallet's
224
- * remaining balance.
225
- */
226
- buy: async (input) => {
227
- const container = await this.gameModel.container({
228
- appId: this.appId,
229
- containerId: input.listingId,
230
- });
231
- const props = await kitContainerProperties(this.gameModel, String(this.appId), input.listingId);
232
- if (container.ownerUserId == null) {
233
- throw new Error('Market listing has no seller (unowned container)');
234
- }
235
- const sellerWallet = await this.ensureSellerWallet(String(container.ownerUserId));
236
- return kitInvoke(this.gameModel, {
237
- appId: String(this.appId),
238
- functionName: this.names.buyMarketFn,
239
- selfContainerId: input.listingId,
240
- params: {
241
- wallet_id: input.walletId,
242
- seller_wallet_id: sellerWallet,
243
- from_stack_id: String(props.stack_id ?? ''),
244
- to_stack_id: input.toStackId,
245
- },
246
- });
247
- },
248
- /** Take a listing down (seller only). */
249
- cancel: async (listingId) => {
250
- return kitInvoke(this.gameModel, {
251
- appId: String(this.appId),
252
- functionName: this.names.cancelMarketFn,
253
- selfContainerId: listingId,
254
- params: {},
255
- });
256
- },
257
- };
258
- this.typePrefix = options.typePrefix ?? '';
259
- this.names = economyNames(this.typePrefix);
260
- this.currencies = options.currencies ?? ['gold'];
261
- this.orderBook = new MarketKit(engines, options.marketModuleName ?? 'market-engine');
262
- }
263
- get defaultCurrency() {
264
- return this.currencies[0];
265
- }
266
- /**
267
- * Find the player's wallet, creating it when absent (member-instantiable;
268
- * the server assigns ownership to the caller). Sets the `owner_user_id`
269
- * mirror property the blueprint's guards read.
270
- *
271
- * @param ownerUserId - The calling player's user id (decimal string).
272
- */
273
- async ensureWallet(ownerUserId, options = {}) {
274
- const existing = await this.gameModel.containers({
275
- appId: this.appId,
276
- typeName: this.names.walletType,
277
- ...(options.sessionId !== undefined ? { sessionId: options.sessionId } : {}),
278
- });
279
- const mine = existing.find((c) => c.ownerUserId != null && String(c.ownerUserId) === String(ownerUserId));
280
- if (mine)
281
- return mine;
282
- return this.gameModel.createContainer({
283
- appId: this.appId,
284
- typeName: this.names.walletType,
285
- displayName: options.displayName ?? `Wallet ${ownerUserId}`,
286
- ...(options.sessionId !== undefined ? { sessionId: options.sessionId } : {}),
287
- properties: [
288
- { key: 'owner_user_id', valueType: 'int', valueJson: String(ownerUserId) },
289
- ],
290
- });
291
- }
292
- /** Read one currency balance (default: the blueprint's first currency). */
293
- async balance(walletId, currency) {
294
- const props = await kitContainerProperties(this.gameModel, String(this.appId), walletId);
295
- return Number(props[currency ?? this.defaultCurrency] ?? 0);
296
- }
297
- /** Read a wallet with every configured currency balance parsed. */
298
- async wallet(walletId) {
299
- const container = await this.gameModel.container({
300
- appId: this.appId,
301
- containerId: walletId,
302
- });
303
- const props = await kitContainerProperties(this.gameModel, String(this.appId), walletId);
304
- const balances = {};
305
- for (const c of this.currencies)
306
- balances[c] = Number(props[c] ?? 0);
307
- return {
308
- containerId: container.containerId,
309
- displayName: container.displayName,
310
- ownerUserId: container.ownerUserId != null ? String(container.ownerUserId) : null,
311
- balances,
312
- };
313
- }
314
- /**
315
- * Mint currency into a wallet — a **trusted** grant (default blueprint
316
- * authority: app admins only). Resolves with the new balance.
317
- */
318
- async earn(walletId, amount, currency) {
319
- return kitInvoke(this.gameModel, {
320
- appId: String(this.appId),
321
- functionName: economyCurrencyFn('earn', currency ?? this.defaultCurrency, this.typePrefix),
322
- selfContainerId: walletId,
323
- params: { amount },
324
- });
325
- }
326
- /**
327
- * Spend currency from the caller's own wallet. The server refuses to
328
- * overdraw. Resolves with the new balance.
329
- */
330
- async spend(walletId, amount, currency) {
331
- return kitInvoke(this.gameModel, {
332
- appId: String(this.appId),
333
- functionName: economyCurrencyFn('spend', currency ?? this.defaultCurrency, this.typePrefix),
334
- selfContainerId: walletId,
335
- params: { amount },
336
- });
337
- }
338
- /** Find an existing wallet container id for a user (no creation). */
339
- async ensureSellerWallet(sellerUserId) {
340
- const wallets = await this.gameModel.containers({
341
- appId: this.appId,
342
- typeName: this.names.walletType,
343
- });
344
- const wallet = wallets.find((c) => c.ownerUserId != null && String(c.ownerUserId) === sellerUserId);
345
- if (!wallet) {
346
- throw new Error(`Seller ${sellerUserId} has no ${this.names.walletType}; they must ensureWallet() before selling`);
347
- }
348
- return wallet.containerId;
349
- }
350
- async toTrade(containerId, displayName, ownerUserId) {
351
- const props = await kitContainerProperties(this.gameModel, String(this.appId), containerId);
352
- return {
353
- containerId,
354
- displayName,
355
- fromUserId: ownerUserId,
356
- toUserId: Number(props.to_user_id ?? 0),
357
- giveStackId: String(props.give_stack_id ?? ''),
358
- receiveStackId: String(props.receive_stack_id ?? ''),
359
- giveItemId: String(props.give_item_id ?? ''),
360
- giveQty: Number(props.give_qty ?? 0),
361
- wantItemId: String(props.want_item_id ?? ''),
362
- wantQty: Number(props.want_qty ?? 0),
363
- status: String(props.status ?? ''),
364
- };
365
- }
366
- }
367
- /**
368
- * Order-book market methods over the market-engine (Wave 2): price-time
369
- * priority matching with escrowed settlement. Deposits/withdrawals bridge
370
- * to the game's wallets via compute events the game layer consumes.
371
- *
372
- * Obtained via `client.kit(appId).economy.market`.
373
- */
374
- export class MarketKit {
375
- constructor(engines, moduleName) {
376
- this.engines = engines;
377
- this.moduleName = moduleName;
378
- }
379
- /** Is the market engine deployed + enabled (cached per session)? */
380
- engineAvailable() {
381
- if (!this.engines)
382
- return Promise.resolve(false);
383
- return this.engines.has(this.moduleName);
384
- }
385
- /** Move coins into your market account (escrow source for bids). */
386
- async depositCoins(amount) {
387
- return this.invoke('deposit_coins', { amount });
388
- }
389
- /** Move items into your market account (escrow source for asks). */
390
- async depositItems(item, quantity) {
391
- return this.invoke('deposit_items', { item, quantity });
392
- }
393
- /** Place a limit bid: locks coins at your limit; fills at maker price. */
394
- async bid(item, price, quantity) {
395
- return this.invoke('place', { item, side: 'buy', price, quantity });
396
- }
397
- /** Place a limit ask: locks items until filled or cancelled. */
398
- async ask(item, price, quantity) {
399
- return this.invoke('place', { item, side: 'sell', price, quantity });
400
- }
401
- /** Cancel a resting order (owner only); escrow refunds instantly. */
402
- async cancel(item, orderId) {
403
- return this.invoke('cancel', { item, orderId });
404
- }
405
- /** Book depth: best bids/asks as [price, quantity] levels. */
406
- async book(item) {
407
- return this.invoke('book', { item });
408
- }
409
- /** Your market account (settled + locked balances). */
410
- async account() {
411
- return this.invoke('account', {});
412
- }
413
- /** Withdraw settled balances back to the game layer. */
414
- async withdraw(input) {
415
- return this.invoke('withdraw', input);
416
- }
417
- async invoke(exportName, params) {
418
- if (!this.engines) {
419
- throw new Error('market engine unavailable: compute domain not wired');
420
- }
421
- const result = await this.engines.invoke(this.moduleName, exportName, params);
422
- if (!result.success) {
423
- throw new Error(`market.${exportName} failed: ${result.reason ?? 'unknown'}`);
424
- }
425
- return result.body;
426
- }
427
- }
@@ -1,48 +0,0 @@
1
- /**
2
- * Compute-engine capability detection + invoke envelope for the kit helpers.
3
- * Games deploy engines (mob-engine, world-engine, bwf-mobs, ...) as compute
4
- * modules; kit helpers probe once per module per session and route through
5
- * the engine when it is present, falling back to the model/automation path
6
- * when it is not — so the same client code works on model-only deployments.
7
- */
8
- import type { ComputeAPI } from '../domains/compute.js';
9
- /** The `{success, ...}` envelope engine invoke exports resolve with. */
10
- export interface EngineInvokeResult<T = Record<string, unknown>> {
11
- success: boolean;
12
- /** The engine's denial reason when `success` is false. */
13
- reason?: string;
14
- /** The parsed result body (includes any extra fields the export returns). */
15
- body: T & Record<string, unknown>;
16
- fuelUsed?: string;
17
- durationUs?: number;
18
- }
19
- /**
20
- * Per-session cached probe of which compute modules an app has enabled.
21
- * Obtained internally by kit helpers; share one via `kit.engines`.
22
- */
23
- export declare class EngineDetector {
24
- private readonly appId;
25
- private readonly compute;
26
- private readonly cache;
27
- constructor(appId: string, compute: ComputeAPI | undefined);
28
- /**
29
- * Is `moduleName` deployed + enabled? Cached per module for the client's
30
- * lifetime ({@link reset} to re-probe after deploys). Resolves false when
31
- * the client has no compute domain wired.
32
- */
33
- has(moduleName: string): Promise<boolean>;
34
- /** Drop cached probes (call after deploying/enabling modules). */
35
- reset(): void;
36
- /**
37
- * Invoke an engine export and parse the `{success, ...}` envelope.
38
- * Envelope failures (denials) resolve; every GraphQL-level error
39
- * (invoke-policy FORBIDDEN, the typed invoke-contract violation —
40
- * `BAD_REQUEST` "Invoke params violate ..." — a disabled module, ...) also
41
- * resolves as `{ success: false, reason }` so kit callers always get
42
- * gameplay-verdict semantics from compute invokes. Only non-GraphQL
43
- * (transport) errors throw.
44
- */
45
- invoke<T = Record<string, unknown>>(moduleName: string, exportName: string, params?: Record<string, unknown>): Promise<EngineInvokeResult<T>>;
46
- private probe;
47
- }
48
- //# sourceMappingURL=engine.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/kit/engine.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,wEAAwE;AACxE,MAAM,WAAW,kBAAkB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC7D,OAAO,EAAE,OAAO,CAAC;IACjB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,qBAAa,cAAc;IAIvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuC;gBAG1C,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,UAAU,GAAG,SAAS;IAGlD;;;;OAIG;IACH,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUzC,kEAAkE;IAClE,KAAK,IAAI,IAAI;IAIb;;;;;;;;OAQG;IACG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;YAwCnB,KAAK;CAmBpB"}
@@ -1,113 +0,0 @@
1
- /**
2
- * Compute-engine capability detection + invoke envelope for the kit helpers.
3
- * Games deploy engines (mob-engine, world-engine, bwf-mobs, ...) as compute
4
- * modules; kit helpers probe once per module per session and route through
5
- * the engine when it is present, falling back to the model/automation path
6
- * when it is not — so the same client code works on model-only deployments.
7
- */
8
- import { CrowdyGraphQLError } from '../errors.js';
9
- /**
10
- * Per-session cached probe of which compute modules an app has enabled.
11
- * Obtained internally by kit helpers; share one via `kit.engines`.
12
- */
13
- export class EngineDetector {
14
- constructor(appId, compute) {
15
- this.appId = appId;
16
- this.compute = compute;
17
- this.cache = new Map();
18
- }
19
- /**
20
- * Is `moduleName` deployed + enabled? Cached per module for the client's
21
- * lifetime ({@link reset} to re-probe after deploys). Resolves false when
22
- * the client has no compute domain wired.
23
- */
24
- has(moduleName) {
25
- if (!this.compute)
26
- return Promise.resolve(false);
27
- let probe = this.cache.get(moduleName);
28
- if (!probe) {
29
- probe = this.probe(moduleName);
30
- this.cache.set(moduleName, probe);
31
- }
32
- return probe;
33
- }
34
- /** Drop cached probes (call after deploying/enabling modules). */
35
- reset() {
36
- this.cache.clear();
37
- }
38
- /**
39
- * Invoke an engine export and parse the `{success, ...}` envelope.
40
- * Envelope failures (denials) resolve; every GraphQL-level error
41
- * (invoke-policy FORBIDDEN, the typed invoke-contract violation —
42
- * `BAD_REQUEST` "Invoke params violate ..." — a disabled module, ...) also
43
- * resolves as `{ success: false, reason }` so kit callers always get
44
- * gameplay-verdict semantics from compute invokes. Only non-GraphQL
45
- * (transport) errors throw.
46
- */
47
- async invoke(moduleName, exportName, params) {
48
- if (!this.compute) {
49
- return {
50
- success: false,
51
- reason: 'compute domain unavailable',
52
- body: {},
53
- };
54
- }
55
- try {
56
- const result = await this.compute.invoke({
57
- appId: this.appId,
58
- moduleName,
59
- exportName,
60
- ...(params !== undefined ? { paramsJson: JSON.stringify(params) } : {}),
61
- });
62
- let body = {};
63
- try {
64
- body = JSON.parse(result.resultJson ?? '{}');
65
- }
66
- catch {
67
- body = {};
68
- }
69
- return {
70
- success: body.success !== false,
71
- reason: typeof body.reason === 'string' ? body.reason : undefined,
72
- body: body,
73
- fuelUsed: result.fuelUsed != null ? String(result.fuelUsed) : undefined,
74
- durationUs: result.durationUs != null ? Number(result.durationUs) : undefined,
75
- };
76
- }
77
- catch (error) {
78
- if (error instanceof CrowdyGraphQLError) {
79
- return {
80
- success: false,
81
- reason: error.message,
82
- body: {},
83
- };
84
- }
85
- throw error;
86
- }
87
- }
88
- async probe(moduleName) {
89
- if (!this.compute)
90
- return false;
91
- try {
92
- const module = await this.compute.module({ appId: this.appId, name: moduleName });
93
- return module != null && module.enabled === true;
94
- }
95
- catch (error) {
96
- if (!(error instanceof CrowdyGraphQLError))
97
- throw error;
98
- if (error.code !== 'FORBIDDEN')
99
- return false;
100
- }
101
- // Player tokens lack view_compute_diagnostics: probe via a status invoke
102
- // (engines all export one). Missing modules reject; denials mean present.
103
- try {
104
- const result = await this.invoke(moduleName, 'status');
105
- if (result.success)
106
- return true;
107
- return !/not found|no such module|not enabled/i.test(result.reason ?? '');
108
- }
109
- catch {
110
- return false;
111
- }
112
- }
113
- }
@@ -1,60 +0,0 @@
1
- import type { GameModelAPI } from '../domains/gameModel.js';
2
- import type { Scalars } from '../generated/graphql.js';
3
- import type { KitInvokePolicy } from './blueprints/index.js';
4
- /**
5
- * Runtime **monetization** helpers — the app feature/tier surface in shop
6
- * terms. Features are string keys (`'vip'`, `'land_owner'`, `'battle_pass'`)
7
- * defined per app and granted to **access tiers** (the management-side
8
- * `appAccess` tiers players buy/hold); any model function whose policy
9
- * carries a `tier_feature` leaf then admits only players on a granted tier.
10
- *
11
- * Gate blueprint functions by composing {@link gate} (=`featureGate`) into a
12
- * builder's `*policyExtra` option, e.g.
13
- * `plotBlueprint({ buyPolicyExtra: kit.features.gate('land_owner') })`.
14
- *
15
- * All methods require the app-admin `manage_apps` permission.
16
- *
17
- * Obtained via `client.kit(appId).features`.
18
- */
19
- export declare class FeaturesKit {
20
- private readonly appId;
21
- private readonly gameModel;
22
- constructor(appId: Scalars['BigInt']['input'], gameModel: GameModelAPI);
23
- /** Define (or re-describe) a feature key for the app. */
24
- define(featureKey: string, description?: string): Promise<{
25
- __typename?: "GmAppFeature";
26
- appId: string;
27
- featureKey: string;
28
- description: string | null;
29
- }>;
30
- /** List the app's defined feature keys. */
31
- list(): Promise<{
32
- __typename?: "GmAppFeature";
33
- appId: string;
34
- featureKey: string;
35
- description: string | null;
36
- }[]>;
37
- /** Grant a feature to an access tier (its holders pass `tier_feature` checks). */
38
- grantToTier(tierId: Scalars['BigInt']['input'], featureKey: string): Promise<{
39
- __typename?: "GmTierFeature";
40
- appId: string;
41
- tierId: string;
42
- featureKey: string;
43
- }>;
44
- /** Revoke a feature from an access tier. */
45
- revokeFromTier(tierId: Scalars['BigInt']['input'], featureKey: string): Promise<boolean>;
46
- /** List tier→feature grants (optionally for one tier). */
47
- tierFeatures(tierId?: Scalars['BigInt']['input']): Promise<{
48
- __typename?: "GmTierFeature";
49
- appId: string;
50
- tierId: string;
51
- featureKey: string;
52
- }[]>;
53
- /**
54
- * A `tier_feature` policy leaf for `feature` — pass it to any blueprint
55
- * builder's `*policyExtra` option to monetization-gate that function.
56
- * (Also exported standalone as `featureGate`.)
57
- */
58
- gate(feature: string): KitInvokePolicy;
59
- }
60
- //# sourceMappingURL=features.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../../src/kit/features.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D;;;;;;;;;;;;;;GAcG;AACH,qBAAa,WAAW;IAEpB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBADT,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EACjC,SAAS,EAAE,YAAY;IAG1C,yDAAyD;IACnD,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM;;;;;;IAQrD,2CAA2C;IACrC,IAAI;;;;;;IAIV,kFAAkF;IAC5E,WAAW,CACf,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAClC,UAAU,EAAE,MAAM;;;;;;IASpB,4CAA4C;IACtC,cAAc,CAClB,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAClC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC;IAQnB,0DAA0D;IACpD,YAAY,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;;;;;;IAOtD;;;;OAIG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe;CAGvC"}