mppx 0.5.7 → 0.5.9

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 (102) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/Challenge.d.ts +3 -2
  3. package/dist/Challenge.d.ts.map +1 -1
  4. package/dist/Challenge.js +27 -9
  5. package/dist/Challenge.js.map +1 -1
  6. package/dist/Method.d.ts +32 -14
  7. package/dist/Method.d.ts.map +1 -1
  8. package/dist/Method.js.map +1 -1
  9. package/dist/Store.d.ts +68 -2
  10. package/dist/Store.d.ts.map +1 -1
  11. package/dist/Store.js +41 -4
  12. package/dist/Store.js.map +1 -1
  13. package/dist/mcp-sdk/server/Transport.d.ts.map +1 -1
  14. package/dist/mcp-sdk/server/Transport.js +7 -0
  15. package/dist/mcp-sdk/server/Transport.js.map +1 -1
  16. package/dist/server/Mppx.d.ts +1 -1
  17. package/dist/server/Mppx.d.ts.map +1 -1
  18. package/dist/server/Mppx.js +133 -70
  19. package/dist/server/Mppx.js.map +1 -1
  20. package/dist/server/Transport.d.ts +8 -2
  21. package/dist/server/Transport.d.ts.map +1 -1
  22. package/dist/server/Transport.js +26 -1
  23. package/dist/server/Transport.js.map +1 -1
  24. package/dist/tempo/client/SessionManager.d.ts +13 -2
  25. package/dist/tempo/client/SessionManager.d.ts.map +1 -1
  26. package/dist/tempo/client/SessionManager.js +429 -4
  27. package/dist/tempo/client/SessionManager.js.map +1 -1
  28. package/dist/tempo/internal/fee-payer.d.ts +28 -0
  29. package/dist/tempo/internal/fee-payer.d.ts.map +1 -1
  30. package/dist/tempo/internal/fee-payer.js +89 -0
  31. package/dist/tempo/internal/fee-payer.js.map +1 -1
  32. package/dist/tempo/server/Charge.d.ts +4 -1
  33. package/dist/tempo/server/Charge.d.ts.map +1 -1
  34. package/dist/tempo/server/Charge.js +90 -66
  35. package/dist/tempo/server/Charge.js.map +1 -1
  36. package/dist/tempo/server/Methods.d.ts +3 -0
  37. package/dist/tempo/server/Methods.d.ts.map +1 -1
  38. package/dist/tempo/server/Methods.js +3 -0
  39. package/dist/tempo/server/Methods.js.map +1 -1
  40. package/dist/tempo/server/Session.d.ts +8 -2
  41. package/dist/tempo/server/Session.d.ts.map +1 -1
  42. package/dist/tempo/server/Session.js.map +1 -1
  43. package/dist/tempo/server/index.d.ts +1 -0
  44. package/dist/tempo/server/index.d.ts.map +1 -1
  45. package/dist/tempo/server/index.js +1 -0
  46. package/dist/tempo/server/index.js.map +1 -1
  47. package/dist/tempo/server/internal/html.gen.d.ts +1 -1
  48. package/dist/tempo/server/internal/html.gen.d.ts.map +1 -1
  49. package/dist/tempo/server/internal/html.gen.js +1 -1
  50. package/dist/tempo/server/internal/html.gen.js.map +1 -1
  51. package/dist/tempo/server/internal/transport.d.ts.map +1 -1
  52. package/dist/tempo/server/internal/transport.js +16 -6
  53. package/dist/tempo/server/internal/transport.js.map +1 -1
  54. package/dist/tempo/session/ChannelStore.d.ts +12 -1
  55. package/dist/tempo/session/ChannelStore.d.ts.map +1 -1
  56. package/dist/tempo/session/ChannelStore.js +55 -14
  57. package/dist/tempo/session/ChannelStore.js.map +1 -1
  58. package/dist/tempo/session/Sse.d.ts +11 -2
  59. package/dist/tempo/session/Sse.d.ts.map +1 -1
  60. package/dist/tempo/session/Sse.js +66 -25
  61. package/dist/tempo/session/Sse.js.map +1 -1
  62. package/dist/tempo/session/Ws.d.ts +87 -0
  63. package/dist/tempo/session/Ws.d.ts.map +1 -0
  64. package/dist/tempo/session/Ws.js +428 -0
  65. package/dist/tempo/session/Ws.js.map +1 -0
  66. package/dist/tempo/session/index.d.ts +1 -0
  67. package/dist/tempo/session/index.d.ts.map +1 -1
  68. package/dist/tempo/session/index.js +1 -0
  69. package/dist/tempo/session/index.js.map +1 -1
  70. package/package.json +2 -2
  71. package/src/Challenge.test.ts +1 -1
  72. package/src/Challenge.ts +28 -9
  73. package/src/Method.ts +61 -20
  74. package/src/Store.test-d.ts +80 -2
  75. package/src/Store.test.ts +150 -13
  76. package/src/Store.ts +140 -3
  77. package/src/mcp-sdk/server/Transport.test.ts +12 -0
  78. package/src/mcp-sdk/server/Transport.ts +8 -0
  79. package/src/server/Mppx.test.ts +105 -0
  80. package/src/server/Mppx.ts +178 -88
  81. package/src/server/Transport.test.ts +31 -0
  82. package/src/server/Transport.ts +31 -2
  83. package/src/tempo/client/SessionManager.ts +510 -7
  84. package/src/tempo/internal/fee-payer.test.ts +115 -1
  85. package/src/tempo/internal/fee-payer.ts +138 -1
  86. package/src/tempo/server/AtomicStore.test-d.ts +34 -0
  87. package/src/tempo/server/Charge.test.ts +128 -0
  88. package/src/tempo/server/Charge.ts +118 -93
  89. package/src/tempo/server/Methods.ts +3 -0
  90. package/src/tempo/server/Session.test.ts +1044 -47
  91. package/src/tempo/server/Session.ts +8 -2
  92. package/src/tempo/server/Sse.test.ts +29 -0
  93. package/src/tempo/server/index.ts +1 -0
  94. package/src/tempo/server/internal/html/main.ts +9 -10
  95. package/src/tempo/server/internal/html.gen.ts +1 -1
  96. package/src/tempo/server/internal/transport.ts +19 -6
  97. package/src/tempo/session/ChannelStore.test.ts +20 -1
  98. package/src/tempo/session/ChannelStore.ts +77 -14
  99. package/src/tempo/session/Sse.ts +77 -24
  100. package/src/tempo/session/Ws.test.ts +410 -0
  101. package/src/tempo/session/Ws.ts +563 -0
  102. package/src/tempo/session/index.ts +1 -0
@@ -310,8 +310,14 @@ export declare namespace session {
310
310
  * the failure.
311
311
  */
312
312
  waitForConfirmation?: boolean | undefined
313
- /** Store backend for channel state. */
314
- store?: Store.Store | undefined
313
+ /**
314
+ * Atomic store backend for channel state.
315
+ *
316
+ * Session state mutations must be linearizable across instances, so this
317
+ * requires a {@link Store.AtomicStore}. Use `Store.memory()` for tests or
318
+ * local single-process usage.
319
+ */
320
+ store?: Store.AtomicStore | undefined
315
321
  /**
316
322
  * Enable SSE streaming.
317
323
  *
@@ -242,6 +242,35 @@ describe('Sse.serve', () => {
242
242
  expect(channel!.units).toBe(0)
243
243
  })
244
244
 
245
+ test('drops reserved charges when a generator never emits a chunk', async () => {
246
+ const store = memoryStore()
247
+ await seedChannel(store, 1000000n)
248
+
249
+ const response = toResponse(
250
+ serve({
251
+ store,
252
+ channelId,
253
+ challengeId,
254
+ tickCost,
255
+ generate: async function* (stream) {
256
+ await stream.charge()
257
+ yield* []
258
+ },
259
+ }),
260
+ )
261
+
262
+ const output = await readStream(response.body!)
263
+ const receiptRaw = output.split('event: payment-receipt\ndata: ')[1]?.split('\n\n')[0]
264
+ const receipt = JSON.parse(receiptRaw!)
265
+
266
+ expect(receipt.spent).toBe('0')
267
+ expect(receipt.units).toBe(0)
268
+
269
+ const channel = await store.getChannel(channelId)
270
+ expect(channel!.spent).toBe(0n)
271
+ expect(channel!.units).toBe(0)
272
+ })
273
+
245
274
  test('allows tickCost override', async () => {
246
275
  const store = memoryStore()
247
276
  await seedChannel(store, 500n)
@@ -1,5 +1,6 @@
1
1
  export * as ChannelStore from '../session/ChannelStore.js'
2
2
  export * as Sse from '../session/Sse.js'
3
+ export * as Ws from '../session/Ws.js'
3
4
  export { charge } from './Charge.js'
4
5
  export { tempo } from './Methods.js'
5
6
  export { session, settle } from './Session.js'
@@ -86,16 +86,15 @@ button.onclick = async () => {
86
86
  const result = await provider.request({ method: 'wallet_connect' })
87
87
  return result.accounts[0]?.address
88
88
  })()
89
- const method = tempo({
90
- account,
91
- getClient(opts) {
92
- const chainId = opts.chainId ?? c.challenge.request.methodDetails?.chainId
93
- const chain = [...(provider?.chains ?? []), tempoModerato, tempoLocalnet].find(
94
- (x) => x.id === chainId,
95
- )
96
- return createClient({ chain, transport: custom(provider) })
97
- },
98
- })[0]
89
+ type TempoParameters = NonNullable<Parameters<typeof tempo>[0]>
90
+ const getClient: NonNullable<TempoParameters['getClient']> = (opts) => {
91
+ const chainId = opts.chainId ?? c.challenge.request.methodDetails?.chainId
92
+ const chain = [...(provider?.chains ?? []), tempoModerato, tempoLocalnet].find(
93
+ (x) => x.id === chainId,
94
+ )
95
+ return createClient({ chain, transport: custom(provider) }) as never
96
+ }
97
+ const method = tempo({ account, getClient })[0]
99
98
 
100
99
  const credential = await method.createCredential({ challenge: c.challenge, context: {} })
101
100
  await c.submit(credential)