@moqtap/codec 0.2.3 → 0.3.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 (299) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +100 -99
  3. package/dist/{chunk-RZHAPEXO.js → chunk-2A57DRXV.js} +36 -10
  4. package/dist/{chunk-73MWUKSJ.js → chunk-2UTVXWFF.js} +190 -102
  5. package/dist/{chunk-JTVCOMBI.cjs → chunk-3XKO6PCR.cjs} +290 -183
  6. package/dist/{chunk-ACQ4CUJP.cjs → chunk-4BDEU3D4.cjs} +237 -158
  7. package/dist/{chunk-4N4INRE7.cjs → chunk-4HBKHNU2.cjs} +144 -110
  8. package/dist/{chunk-2ZT6CVSE.js → chunk-4IVZZOY3.js} +269 -162
  9. package/dist/{chunk-GLBQDG4L.cjs → chunk-5O764MBD.cjs} +508 -117
  10. package/dist/chunk-7KBAWOBA.js +1212 -0
  11. package/dist/{chunk-JSQM2MG3.js → chunk-7QOPNSDF.js} +44 -12
  12. package/dist/{chunk-SYHW3FLI.cjs → chunk-7RE6KSIY.cjs} +28 -8
  13. package/dist/{chunk-YG5KJESI.js → chunk-AY6IAHUM.js} +28 -8
  14. package/dist/{chunk-EFM5T7OM.js → chunk-BLQDWOSG.js} +36 -10
  15. package/dist/{chunk-UYXTY6ZQ.cjs → chunk-E65QKRSN.cjs} +20 -12
  16. package/dist/{chunk-BISI45MN.cjs → chunk-EAHE3IOG.cjs} +44 -12
  17. package/dist/{chunk-PZBPH2D7.js → chunk-GCBFHZW6.js} +216 -137
  18. package/dist/{chunk-GXEW4COZ.cjs → chunk-H5NSL4MO.cjs} +36 -10
  19. package/dist/chunk-HZHSO7EW.cjs +1212 -0
  20. package/dist/{chunk-KZCYQ7ED.cjs → chunk-IILNSDEQ.cjs} +69 -41
  21. package/dist/{chunk-4XYGE53S.cjs → chunk-J3XCPBW3.cjs} +36 -10
  22. package/dist/{chunk-6AEHWULA.cjs → chunk-JKOEJZ5B.cjs} +28 -8
  23. package/dist/{chunk-RUPCJTC3.cjs → chunk-JL3NEW3O.cjs} +23 -1
  24. package/dist/{chunk-G7GI7LJA.js → chunk-LORZMJJB.js} +36 -10
  25. package/dist/{chunk-DUBCL3WF.cjs → chunk-LV5C6MEC.cjs} +36 -10
  26. package/dist/{chunk-ENURAVHI.cjs → chunk-MYXAD5JC.cjs} +44 -12
  27. package/dist/{chunk-FXZ2MYKJ.js → chunk-MZ7HUCGJ.js} +20 -12
  28. package/dist/{chunk-S74DWJE2.cjs → chunk-OKG2HT25.cjs} +277 -88
  29. package/dist/{chunk-BGWGVINJ.cjs → chunk-PKEOQSSZ.cjs} +144 -110
  30. package/dist/{chunk-2GODRVT5.js → chunk-Q46ZURKX.js} +325 -48
  31. package/dist/{chunk-UR6JKS56.js → chunk-Q7IGWV3P.js} +41 -9
  32. package/dist/{chunk-XSNX2IUJ.js → chunk-RW4UG7CN.js} +121 -87
  33. package/dist/{chunk-DWK5ZQZ4.js → chunk-RZTLQAKF.js} +28 -8
  34. package/dist/{chunk-UNS34PTA.cjs → chunk-S6IPIN66.cjs} +44 -12
  35. package/dist/{chunk-YIG2C3LF.cjs → chunk-SDWRXXOO.cjs} +214 -126
  36. package/dist/{chunk-CEH7ESNC.js → chunk-SHMA4PBY.js} +121 -87
  37. package/dist/{chunk-MC7W6PMI.js → chunk-U3ZVLT5L.js} +483 -135
  38. package/dist/{chunk-VJUUZ4W2.cjs → chunk-UJU63EFY.cjs} +374 -97
  39. package/dist/{chunk-7L43FE6P.js → chunk-VOU7PNHI.js} +23 -1
  40. package/dist/{chunk-E6E3NQYU.js → chunk-WRHGCVYN.js} +44 -12
  41. package/dist/{chunk-FPISPJ5N.cjs → chunk-XNWYLVGU.cjs} +529 -181
  42. package/dist/{chunk-U3IPZYPX.js → chunk-XS77RBY7.js} +228 -39
  43. package/dist/{chunk-JGG7CMSZ.cjs → chunk-XZE5R57R.cjs} +144 -110
  44. package/dist/{chunk-77MNXX3M.js → chunk-Y6KCSM3V.js} +121 -87
  45. package/dist/{chunk-TLYNOOQP.cjs → chunk-YTPZZI2M.cjs} +41 -9
  46. package/dist/{chunk-7DUBLRXC.js → chunk-YWRCSQBA.js} +44 -12
  47. package/dist/{chunk-MRJWLGYH.js → chunk-Z3VKP3PJ.js} +69 -41
  48. package/dist/{chunk-E6P74GDT.js → chunk-Z6U26IRI.js} +464 -73
  49. package/dist/{codec-FvGCxIhr.d.ts → codec-25u4_1HS.d.ts} +4 -4
  50. package/dist/{codec-DRcsBCsb.d.ts → codec-3Ppy_5Gd.d.ts} +4 -4
  51. package/dist/{codec-BdVMRMOI.d.ts → codec-BB0U8MF2.d.cts} +4 -4
  52. package/dist/{codec-B2cH-f5V.d.cts → codec-BHHfBTnV.d.ts} +4 -4
  53. package/dist/{codec-B5K73Bdj.d.ts → codec-BN6jk0Td.d.cts} +4 -4
  54. package/dist/{codec-R8GrCPt2.d.ts → codec-BU0gaSZm.d.ts} +4 -4
  55. package/dist/{codec-Bq-tLtfP.d.ts → codec-C-Yk2RNa.d.ts} +4 -4
  56. package/dist/codec-CFWQY9Lj.d.cts +18 -0
  57. package/dist/{codec-CPlK3Pi5.d.ts → codec-COy4uuPO.d.cts} +4 -4
  58. package/dist/codec-CewFCsEy.d.ts +18 -0
  59. package/dist/{codec-KXHvXZVb.d.cts → codec-Ck7ZwFF1.d.cts} +4 -4
  60. package/dist/{codec-DZhZSIii.d.cts → codec-D2QVSH9D.d.ts} +4 -4
  61. package/dist/{codec-BwFgpeQu.d.ts → codec-DDUBJGn0.d.cts} +4 -4
  62. package/dist/{codec-BFeliJFc.d.ts → codec-DNfml-se.d.ts} +4 -4
  63. package/dist/{codec-C4n1PS09.d.cts → codec-DoOGjjDq.d.cts} +4 -4
  64. package/dist/{codec-Bap882Fh.d.cts → codec-J7ekOSMc.d.ts} +4 -4
  65. package/dist/{codec-SKBeHQk7.d.ts → codec-R9TJCq-E.d.cts} +4 -4
  66. package/dist/{codec-DNUIgLqc.d.cts → codec-ZwV-Njt6.d.ts} +4 -4
  67. package/dist/{codec-HgBgHkFI.d.cts → codec-j819z_hL.d.cts} +4 -4
  68. package/dist/{codec-DY4QH364.d.cts → codec-w8z2j_uo.d.cts} +4 -4
  69. package/dist/{codec-CPvPq0sb.d.cts → codec-wtt6WF1K.d.ts} +4 -4
  70. package/dist/{codec-BUMjz0J4.d.cts → codec-z6_2PSzi.d.cts} +4 -4
  71. package/dist/draft10-session.cjs +2 -2
  72. package/dist/draft10-session.d.cts +6 -6
  73. package/dist/draft10-session.d.ts +6 -6
  74. package/dist/draft10-session.js +1 -1
  75. package/dist/draft10.cjs +8 -5
  76. package/dist/draft10.d.cts +14 -12
  77. package/dist/draft10.d.ts +14 -12
  78. package/dist/draft10.js +16 -13
  79. package/dist/draft11-session.cjs +2 -2
  80. package/dist/draft11-session.d.cts +6 -6
  81. package/dist/draft11-session.d.ts +6 -6
  82. package/dist/draft11-session.js +1 -1
  83. package/dist/draft11.cjs +8 -5
  84. package/dist/draft11.d.cts +14 -12
  85. package/dist/draft11.d.ts +14 -12
  86. package/dist/draft11.js +16 -13
  87. package/dist/draft12-session.cjs +2 -2
  88. package/dist/draft12-session.d.cts +6 -6
  89. package/dist/draft12-session.d.ts +6 -6
  90. package/dist/draft12-session.js +1 -1
  91. package/dist/draft12.cjs +8 -5
  92. package/dist/draft12.d.cts +16 -14
  93. package/dist/draft12.d.ts +16 -14
  94. package/dist/draft12.js +16 -13
  95. package/dist/draft13-session.cjs +2 -2
  96. package/dist/draft13-session.d.cts +6 -6
  97. package/dist/draft13-session.d.ts +6 -6
  98. package/dist/draft13-session.js +1 -1
  99. package/dist/draft13.cjs +8 -5
  100. package/dist/draft13.d.cts +16 -14
  101. package/dist/draft13.d.ts +16 -14
  102. package/dist/draft13.js +16 -13
  103. package/dist/draft14-session.cjs +2 -2
  104. package/dist/draft14-session.d.cts +6 -6
  105. package/dist/draft14-session.d.ts +6 -6
  106. package/dist/draft14-session.js +1 -1
  107. package/dist/draft14.cjs +14 -5
  108. package/dist/draft14.d.cts +14 -12
  109. package/dist/draft14.d.ts +14 -12
  110. package/dist/draft14.js +13 -4
  111. package/dist/draft15-session.cjs +2 -2
  112. package/dist/draft15-session.d.cts +6 -6
  113. package/dist/draft15-session.d.ts +6 -6
  114. package/dist/draft15-session.js +1 -1
  115. package/dist/draft15.cjs +8 -5
  116. package/dist/draft15.d.cts +14 -12
  117. package/dist/draft15.d.ts +14 -12
  118. package/dist/draft15.js +16 -13
  119. package/dist/draft16-session.cjs +2 -2
  120. package/dist/draft16-session.d.cts +6 -6
  121. package/dist/draft16-session.d.ts +6 -6
  122. package/dist/draft16-session.js +1 -1
  123. package/dist/draft16.cjs +8 -5
  124. package/dist/draft16.d.cts +14 -12
  125. package/dist/draft16.d.ts +14 -12
  126. package/dist/draft16.js +16 -13
  127. package/dist/draft17-session.cjs +2 -2
  128. package/dist/draft17-session.d.cts +7 -7
  129. package/dist/draft17-session.d.ts +7 -7
  130. package/dist/draft17-session.js +1 -1
  131. package/dist/draft17.cjs +8 -5
  132. package/dist/draft17.d.cts +11 -9
  133. package/dist/draft17.d.ts +11 -9
  134. package/dist/draft17.js +16 -13
  135. package/dist/draft7-session.cjs +2 -2
  136. package/dist/draft7-session.d.cts +6 -5
  137. package/dist/draft7-session.d.ts +6 -5
  138. package/dist/draft7-session.js +1 -1
  139. package/dist/draft7.cjs +71 -14
  140. package/dist/draft7.d.cts +53 -134
  141. package/dist/draft7.d.ts +53 -134
  142. package/dist/draft7.js +76 -19
  143. package/dist/draft8-session.cjs +2 -2
  144. package/dist/draft8-session.d.cts +6 -6
  145. package/dist/draft8-session.d.ts +6 -6
  146. package/dist/draft8-session.js +1 -1
  147. package/dist/draft8.cjs +8 -5
  148. package/dist/draft8.d.cts +14 -12
  149. package/dist/draft8.d.ts +14 -12
  150. package/dist/draft8.js +7 -4
  151. package/dist/draft9-session.cjs +2 -2
  152. package/dist/draft9-session.d.cts +6 -6
  153. package/dist/draft9-session.d.ts +6 -6
  154. package/dist/draft9-session.js +1 -1
  155. package/dist/draft9.cjs +8 -5
  156. package/dist/draft9.d.cts +14 -12
  157. package/dist/draft9.d.ts +14 -12
  158. package/dist/draft9.js +7 -4
  159. package/dist/index.cjs +52 -74
  160. package/dist/index.d.cts +41 -60
  161. package/dist/index.d.ts +41 -60
  162. package/dist/index.js +40 -62
  163. package/dist/{session-types-CJIFbTPd.d.ts → session-types-C7UONex5.d.cts} +28 -27
  164. package/dist/{session-types-Cbq8IGCP.d.cts → session-types-X-IYEGoG.d.ts} +28 -27
  165. package/dist/session.cjs +46 -13
  166. package/dist/session.d.cts +28 -9
  167. package/dist/session.d.ts +28 -9
  168. package/dist/session.js +46 -13
  169. package/dist/{types-DxSFvL2b.d.cts → types--Q7_DcvP.d.cts} +43 -39
  170. package/dist/{types-DxSFvL2b.d.ts → types--Q7_DcvP.d.ts} +43 -39
  171. package/dist/{types-B0FT5Qs2.d.ts → types-0IWbU9Z_.d.cts} +36 -36
  172. package/dist/{types-B0FT5Qs2.d.cts → types-0IWbU9Z_.d.ts} +36 -36
  173. package/dist/{types-gQsr0AAA.d.cts → types-B3g5G9KP.d.cts} +36 -36
  174. package/dist/{types-gQsr0AAA.d.ts → types-B3g5G9KP.d.ts} +36 -36
  175. package/dist/{types-Pme7sua0.d.cts → types-BFpFNM_m.d.cts} +57 -32
  176. package/dist/{types-Pme7sua0.d.ts → types-BFpFNM_m.d.ts} +57 -32
  177. package/dist/{types-8gUGeMgs.d.ts → types-Br7fm2mf.d.cts} +48 -26
  178. package/dist/{types-8gUGeMgs.d.cts → types-Br7fm2mf.d.ts} +48 -26
  179. package/dist/{types-BeAVNU-F.d.cts → types-C2qKTRR_.d.cts} +50 -45
  180. package/dist/{types-BeAVNU-F.d.ts → types-C2qKTRR_.d.ts} +50 -45
  181. package/dist/{types-DKpsfD3i.d.cts → types-DEaypVsD.d.cts} +115 -55
  182. package/dist/{types-DKpsfD3i.d.ts → types-DEaypVsD.d.ts} +115 -55
  183. package/dist/types-Dl4IaAHR.d.cts +282 -0
  184. package/dist/types-Dl4IaAHR.d.ts +282 -0
  185. package/dist/{types-CDa7F5ct.d.cts → types-DrQpTW1G.d.cts} +58 -50
  186. package/dist/{types-CDa7F5ct.d.ts → types-DrQpTW1G.d.ts} +58 -50
  187. package/dist/types-DuIO7cWK.d.cts +25 -0
  188. package/dist/types-DuIO7cWK.d.ts +25 -0
  189. package/dist/{types-B9A2g05r.d.cts → types-DuxfOYiO.d.cts} +47 -31
  190. package/dist/{types-B9A2g05r.d.ts → types-DuxfOYiO.d.ts} +47 -31
  191. package/dist/{types-D1dI_oTX.d.cts → types-jV1yDDBA.d.cts} +36 -36
  192. package/dist/{types-D1dI_oTX.d.ts → types-jV1yDDBA.d.ts} +36 -36
  193. package/package.json +192 -192
  194. package/src/core/buffer-reader.ts +130 -130
  195. package/src/core/buffer-writer.ts +100 -100
  196. package/src/core/errors.ts +1 -1
  197. package/src/core/hex.ts +21 -21
  198. package/src/core/session-types.ts +61 -59
  199. package/src/core/types.ts +18 -361
  200. package/src/drafts/draft07/codec.ts +1058 -938
  201. package/src/drafts/draft07/data-streams.ts +240 -240
  202. package/src/drafts/draft07/index.ts +124 -89
  203. package/src/drafts/draft07/messages.ts +76 -42
  204. package/src/drafts/draft07/rules.ts +107 -101
  205. package/src/drafts/draft07/session-fsm.ts +315 -287
  206. package/src/drafts/draft07/session.ts +8 -6
  207. package/src/drafts/draft07/types.ts +406 -72
  208. package/src/drafts/draft07/varint.ts +51 -51
  209. package/src/drafts/draft08/codec.ts +985 -953
  210. package/src/drafts/draft08/data-streams.ts +363 -359
  211. package/src/drafts/draft08/index.ts +10 -9
  212. package/src/drafts/draft08/messages.ts +59 -59
  213. package/src/drafts/draft08/rules.ts +73 -73
  214. package/src/drafts/draft08/session-fsm.ts +335 -303
  215. package/src/drafts/draft08/session.ts +6 -7
  216. package/src/drafts/draft08/types.ts +380 -384
  217. package/src/drafts/draft09/codec.ts +977 -945
  218. package/src/drafts/draft09/data-streams.ts +336 -332
  219. package/src/drafts/draft09/index.ts +10 -9
  220. package/src/drafts/draft09/messages.ts +59 -59
  221. package/src/drafts/draft09/rules.ts +73 -73
  222. package/src/drafts/draft09/session-fsm.ts +335 -303
  223. package/src/drafts/draft09/session.ts +6 -7
  224. package/src/drafts/draft09/types.ts +380 -384
  225. package/src/drafts/draft10/codec.ts +977 -945
  226. package/src/drafts/draft10/data-streams.ts +336 -332
  227. package/src/drafts/draft10/index.ts +10 -9
  228. package/src/drafts/draft10/messages.ts +59 -59
  229. package/src/drafts/draft10/rules.ts +73 -73
  230. package/src/drafts/draft10/session-fsm.ts +335 -303
  231. package/src/drafts/draft10/session.ts +6 -7
  232. package/src/drafts/draft10/types.ts +380 -384
  233. package/src/drafts/draft11/codec.ts +1054 -988
  234. package/src/drafts/draft11/data-streams.ts +316 -269
  235. package/src/drafts/draft11/index.ts +10 -9
  236. package/src/drafts/draft11/messages.ts +60 -59
  237. package/src/drafts/draft11/rules.ts +73 -73
  238. package/src/drafts/draft11/session-fsm.ts +359 -333
  239. package/src/drafts/draft11/session.ts +6 -7
  240. package/src/drafts/draft11/types.ts +385 -381
  241. package/src/drafts/draft12/codec.ts +1178 -1122
  242. package/src/drafts/draft12/data-streams.ts +324 -275
  243. package/src/drafts/draft12/index.ts +10 -9
  244. package/src/drafts/draft12/messages.ts +67 -66
  245. package/src/drafts/draft12/rules.ts +79 -79
  246. package/src/drafts/draft12/session-fsm.ts +384 -358
  247. package/src/drafts/draft12/session.ts +6 -7
  248. package/src/drafts/draft12/types.ts +424 -419
  249. package/src/drafts/draft13/codec.ts +1296 -1206
  250. package/src/drafts/draft13/data-streams.ts +326 -275
  251. package/src/drafts/draft13/index.ts +10 -9
  252. package/src/drafts/draft13/messages.ts +73 -68
  253. package/src/drafts/draft13/rules.ts +81 -81
  254. package/src/drafts/draft13/session-fsm.ts +392 -366
  255. package/src/drafts/draft13/session.ts +6 -7
  256. package/src/drafts/draft13/types.ts +447 -438
  257. package/src/drafts/draft14/codec.ts +1347 -1043
  258. package/src/drafts/draft14/data-streams.ts +831 -813
  259. package/src/drafts/draft14/index.ts +17 -9
  260. package/src/drafts/draft14/messages.ts +65 -65
  261. package/src/drafts/draft14/rules.ts +81 -81
  262. package/src/drafts/draft14/session-fsm.ts +415 -405
  263. package/src/drafts/draft14/session.ts +6 -7
  264. package/src/drafts/draft14/types.ts +451 -381
  265. package/src/drafts/draft15/codec.ts +1138 -978
  266. package/src/drafts/draft15/data-streams.ts +842 -794
  267. package/src/drafts/draft15/index.ts +10 -9
  268. package/src/drafts/draft15/messages.ts +54 -53
  269. package/src/drafts/draft15/rules.ts +67 -67
  270. package/src/drafts/draft15/session-fsm.ts +319 -299
  271. package/src/drafts/draft15/session.ts +6 -7
  272. package/src/drafts/draft15/types.ts +357 -339
  273. package/src/drafts/draft16/codec.ts +1242 -966
  274. package/src/drafts/draft16/data-streams.ts +835 -789
  275. package/src/drafts/draft16/index.ts +10 -9
  276. package/src/drafts/draft16/messages.ts +56 -55
  277. package/src/drafts/draft16/rules.ts +69 -69
  278. package/src/drafts/draft16/session-fsm.ts +319 -299
  279. package/src/drafts/draft16/session.ts +6 -7
  280. package/src/drafts/draft16/types.ts +386 -357
  281. package/src/drafts/draft17/codec.ts +1209 -971
  282. package/src/drafts/draft17/data-streams.ts +969 -758
  283. package/src/drafts/draft17/index.ts +9 -7
  284. package/src/drafts/draft17/messages.ts +43 -42
  285. package/src/drafts/draft17/rules.ts +58 -58
  286. package/src/drafts/draft17/session-fsm.ts +248 -216
  287. package/src/drafts/draft17/session.ts +5 -5
  288. package/src/drafts/draft17/types.ts +337 -313
  289. package/src/index.ts +85 -274
  290. package/src/session.ts +62 -23
  291. package/dist/chunk-FZDIEHQL.cjs +0 -1042
  292. package/dist/chunk-HDWJ2GDE.js +0 -24
  293. package/dist/chunk-KNDYS3DK.cjs +0 -24
  294. package/dist/chunk-N2KBF5Q2.js +0 -1042
  295. package/dist/types-QNXoxC9Y.d.cts +0 -236
  296. package/dist/types-QNXoxC9Y.d.ts +0 -236
  297. package/src/drafts/draft07/announce-fsm.ts +0 -2
  298. package/src/drafts/draft07/parameters.ts +0 -12
  299. package/src/drafts/draft07/subscription-fsm.ts +0 -3
@@ -7,84 +7,84 @@ import type {
7
7
  SubscriptionState,
8
8
  TransitionResult,
9
9
  ValidationResult,
10
- } from "../../core/session-types.js";
10
+ } from '../../core/session-types.js'
11
11
  import {
12
12
  CLIENT_ONLY_MESSAGES,
13
13
  getLegalIncoming,
14
14
  getLegalOutgoing,
15
15
  SERVER_ONLY_MESSAGES,
16
- } from "./rules.js";
17
- import type { Draft08Message, Draft08MessageType } from "./types.js";
16
+ } from './rules.js'
17
+ import type { Draft08Message, Draft08MessageType } from './types.js'
18
18
 
19
19
  function violation(
20
- code: ProtocolViolation<Draft08MessageType>["code"],
20
+ code: ProtocolViolation<Draft08MessageType>['code'],
21
21
  message: string,
22
22
  currentPhase: SessionPhase,
23
23
  offendingMessage: Draft08MessageType,
24
24
  ): ProtocolViolation<Draft08MessageType> {
25
- return { code, message, currentPhase, offendingMessage };
25
+ return { code, message, currentPhase, offendingMessage }
26
26
  }
27
27
 
28
28
  export class Draft08SessionFSM {
29
- private _phase: SessionPhase = "idle";
30
- private _role: "client" | "server";
31
- private _subscriptions = new Map<bigint, SubscriptionState>();
32
- private _announces = new Map<string, AnnounceState>();
33
- private _fetches = new Map<bigint, FetchState>();
34
- private _subscribeIds = new Set<bigint>();
29
+ private _phase: SessionPhase = 'idle'
30
+ private _role: 'client' | 'server'
31
+ private _subscriptions = new Map<bigint, SubscriptionState>()
32
+ private _announces = new Map<string, AnnounceState>()
33
+ private _fetches = new Map<bigint, FetchState>()
34
+ private _subscribeIds = new Set<bigint>()
35
35
 
36
- constructor(role: "client" | "server") {
37
- this._role = role;
36
+ constructor(role: 'client' | 'server') {
37
+ this._role = role
38
38
  }
39
39
 
40
40
  get phase(): SessionPhase {
41
- return this._phase;
41
+ return this._phase
42
42
  }
43
- get role(): "client" | "server" {
44
- return this._role;
43
+ get role(): 'client' | 'server' {
44
+ return this._role
45
45
  }
46
46
  get subscriptions(): ReadonlyMap<bigint, SubscriptionState> {
47
- return this._subscriptions;
47
+ return this._subscriptions
48
48
  }
49
49
  get announces(): ReadonlyMap<string, AnnounceState> {
50
- return this._announces;
50
+ return this._announces
51
51
  }
52
52
  get fetches(): ReadonlyMap<bigint, FetchState> {
53
- return this._fetches;
53
+ return this._fetches
54
54
  }
55
55
 
56
56
  get legalOutgoing(): ReadonlySet<Draft08MessageType> {
57
- return getLegalOutgoing(this._phase, this._role);
57
+ return getLegalOutgoing(this._phase, this._role)
58
58
  }
59
59
 
60
60
  get legalIncoming(): ReadonlySet<Draft08MessageType> {
61
- return getLegalIncoming(this._phase, this._role);
61
+ return getLegalIncoming(this._phase, this._role)
62
62
  }
63
63
 
64
64
  private checkRole(
65
65
  message: Draft08Message,
66
- direction: "inbound" | "outbound",
66
+ direction: 'inbound' | 'outbound',
67
67
  ): ProtocolViolation<Draft08MessageType> | null {
68
68
  const senderRole =
69
- direction === "outbound" ? this._role : this._role === "client" ? "server" : "client";
69
+ direction === 'outbound' ? this._role : this._role === 'client' ? 'server' : 'client'
70
70
 
71
- if (CLIENT_ONLY_MESSAGES.has(message.type) && senderRole !== "client") {
71
+ if (CLIENT_ONLY_MESSAGES.has(message.type) && senderRole !== 'client') {
72
72
  return violation(
73
- "ROLE_VIOLATION",
73
+ 'ROLE_VIOLATION',
74
74
  `${message.type} can only be sent by client`,
75
75
  this._phase,
76
76
  message.type,
77
- );
77
+ )
78
78
  }
79
- if (SERVER_ONLY_MESSAGES.has(message.type) && senderRole !== "server") {
79
+ if (SERVER_ONLY_MESSAGES.has(message.type) && senderRole !== 'server') {
80
80
  return violation(
81
- "ROLE_VIOLATION",
81
+ 'ROLE_VIOLATION',
82
82
  `${message.type} can only be sent by server`,
83
83
  this._phase,
84
84
  message.type,
85
- );
85
+ )
86
86
  }
87
- return null;
87
+ return null
88
88
  }
89
89
 
90
90
  private checkDuplicateSubscribeId(
@@ -93,13 +93,13 @@ export class Draft08SessionFSM {
93
93
  ): ProtocolViolation<Draft08MessageType> | null {
94
94
  if (this._subscribeIds.has(subscribeId)) {
95
95
  return violation(
96
- "DUPLICATE_REQUEST_ID",
96
+ 'DUPLICATE_REQUEST_ID',
97
97
  `Subscribe ID ${subscribeId} already in use`,
98
98
  this._phase,
99
99
  msgType,
100
- );
100
+ )
101
101
  }
102
- return null;
102
+ return null
103
103
  }
104
104
 
105
105
  private checkKnownSubscribeId(
@@ -108,192 +108,199 @@ export class Draft08SessionFSM {
108
108
  ): ProtocolViolation<Draft08MessageType> | null {
109
109
  if (!this._subscribeIds.has(subscribeId)) {
110
110
  return violation(
111
- "UNKNOWN_REQUEST_ID",
111
+ 'UNKNOWN_REQUEST_ID',
112
112
  `No request with subscribe ID ${subscribeId}`,
113
113
  this._phase,
114
114
  msgType,
115
- );
115
+ )
116
116
  }
117
- return null;
117
+ return null
118
118
  }
119
119
 
120
120
  validateOutgoing(message: Draft08Message): ValidationResult<Draft08MessageType> {
121
- const roleViolation = this.checkRole(message, "outbound");
122
- if (roleViolation) return { ok: false, violation: roleViolation };
121
+ const roleViolation = this.checkRole(message, 'outbound')
122
+ if (roleViolation) return { ok: false, violation: roleViolation }
123
123
 
124
124
  if (!this.legalOutgoing.has(message.type)) {
125
125
  return {
126
126
  ok: false,
127
127
  violation: violation(
128
- this._phase === "idle" || this._phase === "setup"
129
- ? "MESSAGE_BEFORE_SETUP"
130
- : "UNEXPECTED_MESSAGE",
128
+ this._phase === 'idle' || this._phase === 'setup'
129
+ ? 'MESSAGE_BEFORE_SETUP'
130
+ : 'UNEXPECTED_MESSAGE',
131
131
  `Cannot send ${message.type} in phase ${this._phase}`,
132
132
  this._phase,
133
133
  message.type,
134
134
  ),
135
- };
135
+ }
136
136
  }
137
- return { ok: true };
137
+ return { ok: true }
138
138
  }
139
139
 
140
140
  receive(message: Draft08Message): TransitionResult<Draft08MessageType> {
141
- const roleViolation = this.checkRole(message, "inbound");
142
- if (roleViolation) return { ok: false, violation: roleViolation };
143
- return this.applyTransition(message, "inbound");
141
+ const roleViolation = this.checkRole(message, 'inbound')
142
+ if (roleViolation) return { ok: false, violation: roleViolation }
143
+ return this.applyTransition(message, 'inbound')
144
144
  }
145
145
 
146
146
  send(message: Draft08Message): TransitionResult<Draft08MessageType> {
147
- const roleViolation = this.checkRole(message, "outbound");
148
- if (roleViolation) return { ok: false, violation: roleViolation };
149
- return this.applyTransition(message, "outbound");
147
+ const roleViolation = this.checkRole(message, 'outbound')
148
+ if (roleViolation) return { ok: false, violation: roleViolation }
149
+ return this.applyTransition(message, 'outbound')
150
150
  }
151
151
 
152
152
  private applyTransition(
153
153
  message: Draft08Message,
154
- direction: "inbound" | "outbound",
154
+ direction: 'inbound' | 'outbound',
155
155
  ): TransitionResult<Draft08MessageType> {
156
- const sideEffects: SideEffect[] = [];
156
+ const sideEffects: SideEffect[] = []
157
157
 
158
158
  switch (message.type) {
159
- case "client_setup":
160
- return this.handleClientSetup(direction);
161
- case "server_setup":
162
- return this.handleServerSetup(direction);
163
- case "goaway":
164
- return this.handleGoAway(message, sideEffects);
159
+ case 'client_setup':
160
+ return this.handleClientSetup(direction)
161
+ case 'server_setup':
162
+ return this.handleServerSetup(direction)
163
+ case 'goaway':
164
+ return this.handleGoAway(message, sideEffects)
165
165
 
166
166
  // Subscribe lifecycle
167
- case "subscribe":
168
- return this.handleSubscribe(message, sideEffects);
169
- case "subscribe_ok":
170
- return this.handleSubscribeOk(message, sideEffects);
171
- case "subscribe_error":
172
- return this.handleSubscribeError(message, sideEffects);
173
- case "subscribe_update":
174
- return this.handleSubscribeUpdate(message, sideEffects);
175
- case "subscribe_done":
176
- return this.handleSubscribeDone(message, sideEffects);
177
- case "unsubscribe":
178
- return this.handleUnsubscribe(message, sideEffects);
167
+ case 'subscribe':
168
+ return this.handleSubscribe(message, sideEffects)
169
+ case 'subscribe_ok':
170
+ return this.handleSubscribeOk(message, sideEffects)
171
+ case 'subscribe_error':
172
+ return this.handleSubscribeError(message, sideEffects)
173
+ case 'subscribe_update':
174
+ return this.handleSubscribeUpdate(message, sideEffects)
175
+ case 'subscribe_done':
176
+ return this.handleSubscribeDone(message, sideEffects)
177
+ case 'unsubscribe':
178
+ return this.handleUnsubscribe(message, sideEffects)
179
179
 
180
180
  // Announce lifecycle
181
- case "announce":
182
- return this.handleAnnounce(message, sideEffects);
183
- case "announce_ok":
184
- return this.handleAnnounceOk(message, sideEffects);
185
- case "announce_error":
186
- return this.handleAnnounceError(message, sideEffects);
187
- case "unannounce":
188
- return this.handleUnannounce(message, sideEffects);
189
- case "announce_cancel":
190
- return this.handleAnnounceCancel(message, sideEffects);
181
+ case 'announce':
182
+ return this.handleAnnounce(message, sideEffects)
183
+ case 'announce_ok':
184
+ return this.handleAnnounceOk(message, sideEffects)
185
+ case 'announce_error':
186
+ return this.handleAnnounceError(message, sideEffects)
187
+ case 'unannounce':
188
+ return this.handleUnannounce(message, sideEffects)
189
+ case 'announce_cancel':
190
+ return this.handleAnnounceCancel(message, sideEffects)
191
191
 
192
192
  // Fetch lifecycle
193
- case "fetch":
194
- return this.handleFetch(message, sideEffects);
195
- case "fetch_ok":
196
- return this.handleFetchOk(message, sideEffects);
197
- case "fetch_error":
198
- return this.handleFetchError(message, sideEffects);
199
- case "fetch_cancel":
200
- return this.handleFetchCancel(message, sideEffects);
193
+ case 'fetch':
194
+ return this.handleFetch(message, sideEffects)
195
+ case 'fetch_ok':
196
+ return this.handleFetchOk(message, sideEffects)
197
+ case 'fetch_error':
198
+ return this.handleFetchError(message, sideEffects)
199
+ case 'fetch_cancel':
200
+ return this.handleFetchCancel(message, sideEffects)
201
201
  default:
202
- return this.handleReadyPhaseMessage(message);
202
+ return this.handleReadyPhaseMessage(message)
203
203
  }
204
204
  }
205
205
 
206
206
  private handleClientSetup(
207
- direction: "inbound" | "outbound",
207
+ direction: 'inbound' | 'outbound',
208
208
  ): TransitionResult<Draft08MessageType> {
209
- if (this._phase !== "idle") {
209
+ if (this._phase !== 'idle') {
210
210
  return {
211
211
  ok: false,
212
212
  violation: violation(
213
- "SETUP_VIOLATION",
214
- "CLIENT_SETUP already sent/received",
213
+ 'SETUP_VIOLATION',
214
+ 'CLIENT_SETUP already sent/received',
215
215
  this._phase,
216
- "client_setup",
216
+ 'client_setup',
217
217
  ),
218
- };
218
+ }
219
219
  }
220
- if (direction === "outbound" && this._role !== "client") {
220
+ if (direction === 'outbound' && this._role !== 'client') {
221
221
  return {
222
222
  ok: false,
223
223
  violation: violation(
224
- "ROLE_VIOLATION",
225
- "Only client can send CLIENT_SETUP",
224
+ 'ROLE_VIOLATION',
225
+ 'Only client can send CLIENT_SETUP',
226
226
  this._phase,
227
- "client_setup",
227
+ 'client_setup',
228
228
  ),
229
- };
229
+ }
230
230
  }
231
- this._phase = "setup";
232
- return { ok: true, phase: this._phase, sideEffects: [] };
231
+ this._phase = 'setup'
232
+ return { ok: true, phase: this._phase, sideEffects: [] }
233
233
  }
234
234
 
235
235
  private handleServerSetup(
236
- direction: "inbound" | "outbound",
236
+ direction: 'inbound' | 'outbound',
237
237
  ): TransitionResult<Draft08MessageType> {
238
- if (this._phase !== "setup") {
238
+ if (this._phase !== 'setup') {
239
239
  return {
240
240
  ok: false,
241
241
  violation: violation(
242
- "SETUP_VIOLATION",
243
- "SERVER_SETUP before CLIENT_SETUP",
242
+ 'SETUP_VIOLATION',
243
+ 'SERVER_SETUP before CLIENT_SETUP',
244
244
  this._phase,
245
- "server_setup",
245
+ 'server_setup',
246
246
  ),
247
- };
247
+ }
248
248
  }
249
- if (direction === "outbound" && this._role !== "server") {
249
+ if (direction === 'outbound' && this._role !== 'server') {
250
250
  return {
251
251
  ok: false,
252
252
  violation: violation(
253
- "ROLE_VIOLATION",
254
- "Only server can send SERVER_SETUP",
253
+ 'ROLE_VIOLATION',
254
+ 'Only server can send SERVER_SETUP',
255
255
  this._phase,
256
- "server_setup",
256
+ 'server_setup',
257
257
  ),
258
- };
258
+ }
259
+ }
260
+ this._phase = 'ready'
261
+ return {
262
+ ok: true,
263
+ phase: this._phase,
264
+ sideEffects: [{ type: 'session-ready' }],
259
265
  }
260
- this._phase = "ready";
261
- return { ok: true, phase: this._phase, sideEffects: [{ type: "session-ready" }] };
262
266
  }
263
267
 
264
268
  private handleGoAway(
265
269
  message: Draft08Message,
266
270
  sideEffects: SideEffect[],
267
271
  ): TransitionResult<Draft08MessageType> {
268
- if (this._phase !== "ready" && this._phase !== "draining") {
272
+ if (this._phase !== 'ready' && this._phase !== 'draining') {
269
273
  return {
270
274
  ok: false,
271
275
  violation: violation(
272
- "UNEXPECTED_MESSAGE",
276
+ 'UNEXPECTED_MESSAGE',
273
277
  `GOAWAY not valid in phase ${this._phase}`,
274
278
  this._phase,
275
- "goaway",
279
+ 'goaway',
276
280
  ),
277
- };
281
+ }
278
282
  }
279
- this._phase = "draining";
280
- const goaway = message as import("./types.js").Draft08GoAway;
281
- sideEffects.push({ type: "session-draining", goAwayUri: goaway.new_session_uri });
282
- return { ok: true, phase: this._phase, sideEffects };
283
+ this._phase = 'draining'
284
+ const goaway = message as import('./types.js').Draft08GoAway
285
+ sideEffects.push({
286
+ type: 'session-draining',
287
+ goAwayUri: goaway.new_session_uri,
288
+ })
289
+ return { ok: true, phase: this._phase, sideEffects }
283
290
  }
284
291
 
285
292
  private requireReady(msgType: Draft08MessageType): ProtocolViolation<Draft08MessageType> | null {
286
- if (this._phase !== "ready" && this._phase !== "draining") {
293
+ if (this._phase !== 'ready' && this._phase !== 'draining') {
287
294
  return violation(
288
- this._phase === "idle" || this._phase === "setup"
289
- ? "MESSAGE_BEFORE_SETUP"
290
- : "UNEXPECTED_MESSAGE",
295
+ this._phase === 'idle' || this._phase === 'setup'
296
+ ? 'MESSAGE_BEFORE_SETUP'
297
+ : 'UNEXPECTED_MESSAGE',
291
298
  `${msgType} requires ready phase, current: ${this._phase}`,
292
299
  this._phase,
293
300
  msgType,
294
- );
301
+ )
295
302
  }
296
- return null;
303
+ return null
297
304
  }
298
305
 
299
306
  // ─── Subscribe lifecycle ───
@@ -302,184 +309,190 @@ export class Draft08SessionFSM {
302
309
  message: Draft08Message,
303
310
  sideEffects: SideEffect[],
304
311
  ): TransitionResult<Draft08MessageType> {
305
- const err = this.requireReady(message.type);
306
- if (err) return { ok: false, violation: err };
307
- const sub = message as import("./types.js").Draft08Subscribe;
308
- const dupErr = this.checkDuplicateSubscribeId(sub.subscribe_id, message.type);
309
- if (dupErr) return { ok: false, violation: dupErr };
310
- this._subscribeIds.add(sub.subscribe_id);
312
+ const err = this.requireReady(message.type)
313
+ if (err) return { ok: false, violation: err }
314
+ const sub = message as import('./types.js').Draft08Subscribe
315
+ const dupErr = this.checkDuplicateSubscribeId(sub.subscribe_id, message.type)
316
+ if (dupErr) return { ok: false, violation: dupErr }
317
+ this._subscribeIds.add(sub.subscribe_id)
311
318
  this._subscriptions.set(sub.subscribe_id, {
312
319
  subscribeId: sub.subscribe_id,
313
- phase: "pending",
320
+ phase: 'pending',
314
321
  trackNamespace: sub.track_namespace,
315
322
  trackName: sub.track_name,
316
- });
317
- return { ok: true, phase: this._phase, sideEffects };
323
+ })
324
+ return { ok: true, phase: this._phase, sideEffects }
318
325
  }
319
326
 
320
327
  private handleSubscribeOk(
321
328
  message: Draft08Message,
322
329
  sideEffects: SideEffect[],
323
330
  ): TransitionResult<Draft08MessageType> {
324
- const err = this.requireReady(message.type);
325
- if (err) return { ok: false, violation: err };
326
- const ok = message as import("./types.js").Draft08SubscribeOk;
327
- const idErr = this.checkKnownSubscribeId(ok.subscribe_id, message.type);
328
- if (idErr) return { ok: false, violation: idErr };
329
- const existing = this._subscriptions.get(ok.subscribe_id);
331
+ const err = this.requireReady(message.type)
332
+ if (err) return { ok: false, violation: err }
333
+ const ok = message as import('./types.js').Draft08SubscribeOk
334
+ const idErr = this.checkKnownSubscribeId(ok.subscribe_id, message.type)
335
+ if (idErr) return { ok: false, violation: idErr }
336
+ const existing = this._subscriptions.get(ok.subscribe_id)
330
337
  if (!existing)
331
338
  return {
332
339
  ok: false,
333
340
  violation: violation(
334
- "UNKNOWN_REQUEST_ID",
341
+ 'UNKNOWN_REQUEST_ID',
335
342
  `No subscription with subscribe ID ${ok.subscribe_id}`,
336
343
  this._phase,
337
344
  message.type,
338
345
  ),
339
- };
340
- if (existing.phase !== "pending")
346
+ }
347
+ if (existing.phase !== 'pending')
341
348
  return {
342
349
  ok: false,
343
350
  violation: violation(
344
- "STATE_VIOLATION",
351
+ 'STATE_VIOLATION',
345
352
  `Subscription ${ok.subscribe_id} is ${existing.phase}, not pending`,
346
353
  this._phase,
347
354
  message.type,
348
355
  ),
349
- };
350
- this._subscriptions.set(ok.subscribe_id, { ...existing, phase: "active" });
351
- sideEffects.push({ type: "subscription-activated", subscribeId: ok.subscribe_id });
352
- return { ok: true, phase: this._phase, sideEffects };
356
+ }
357
+ this._subscriptions.set(ok.subscribe_id, { ...existing, phase: 'active' })
358
+ sideEffects.push({
359
+ type: 'subscription-activated',
360
+ subscribeId: ok.subscribe_id,
361
+ })
362
+ return { ok: true, phase: this._phase, sideEffects }
353
363
  }
354
364
 
355
365
  private handleSubscribeError(
356
366
  message: Draft08Message,
357
367
  sideEffects: SideEffect[],
358
368
  ): TransitionResult<Draft08MessageType> {
359
- const err = this.requireReady(message.type);
360
- if (err) return { ok: false, violation: err };
361
- const subErr = message as import("./types.js").Draft08SubscribeError;
362
- const idErr = this.checkKnownSubscribeId(subErr.subscribe_id, message.type);
363
- if (idErr) return { ok: false, violation: idErr };
364
- const existing = this._subscriptions.get(subErr.subscribe_id);
369
+ const err = this.requireReady(message.type)
370
+ if (err) return { ok: false, violation: err }
371
+ const subErr = message as import('./types.js').Draft08SubscribeError
372
+ const idErr = this.checkKnownSubscribeId(subErr.subscribe_id, message.type)
373
+ if (idErr) return { ok: false, violation: idErr }
374
+ const existing = this._subscriptions.get(subErr.subscribe_id)
365
375
  if (!existing)
366
376
  return {
367
377
  ok: false,
368
378
  violation: violation(
369
- "UNKNOWN_REQUEST_ID",
379
+ 'UNKNOWN_REQUEST_ID',
370
380
  `No subscription with subscribe ID ${subErr.subscribe_id}`,
371
381
  this._phase,
372
382
  message.type,
373
383
  ),
374
- };
375
- if (existing.phase !== "pending")
384
+ }
385
+ if (existing.phase !== 'pending')
376
386
  return {
377
387
  ok: false,
378
388
  violation: violation(
379
- "STATE_VIOLATION",
389
+ 'STATE_VIOLATION',
380
390
  `Subscription ${subErr.subscribe_id} is ${existing.phase}, not pending`,
381
391
  this._phase,
382
392
  message.type,
383
393
  ),
384
- };
385
- this._subscriptions.set(subErr.subscribe_id, { ...existing, phase: "error" });
394
+ }
395
+ this._subscriptions.set(subErr.subscribe_id, {
396
+ ...existing,
397
+ phase: 'error',
398
+ })
386
399
  sideEffects.push({
387
- type: "subscription-ended",
400
+ type: 'subscription-ended',
388
401
  subscribeId: subErr.subscribe_id,
389
402
  reason: subErr.reason_phrase,
390
- });
391
- return { ok: true, phase: this._phase, sideEffects };
403
+ })
404
+ return { ok: true, phase: this._phase, sideEffects }
392
405
  }
393
406
 
394
407
  private handleSubscribeUpdate(
395
408
  message: Draft08Message,
396
409
  sideEffects: SideEffect[],
397
410
  ): TransitionResult<Draft08MessageType> {
398
- const err = this.requireReady(message.type);
399
- if (err) return { ok: false, violation: err };
400
- const update = message as import("./types.js").Draft08SubscribeUpdate;
401
- const idErr = this.checkKnownSubscribeId(update.subscribe_id, message.type);
402
- if (idErr) return { ok: false, violation: idErr };
403
- const existing = this._subscriptions.get(update.subscribe_id);
411
+ const err = this.requireReady(message.type)
412
+ if (err) return { ok: false, violation: err }
413
+ const update = message as import('./types.js').Draft08SubscribeUpdate
414
+ const idErr = this.checkKnownSubscribeId(update.subscribe_id, message.type)
415
+ if (idErr) return { ok: false, violation: idErr }
416
+ const existing = this._subscriptions.get(update.subscribe_id)
404
417
  if (!existing)
405
418
  return {
406
419
  ok: false,
407
420
  violation: violation(
408
- "UNKNOWN_REQUEST_ID",
421
+ 'UNKNOWN_REQUEST_ID',
409
422
  `No subscription with subscribe ID ${update.subscribe_id}`,
410
423
  this._phase,
411
424
  message.type,
412
425
  ),
413
- };
414
- if (existing.phase !== "active")
426
+ }
427
+ if (existing.phase !== 'active')
415
428
  return {
416
429
  ok: false,
417
430
  violation: violation(
418
- "STATE_VIOLATION",
431
+ 'STATE_VIOLATION',
419
432
  `Subscription ${update.subscribe_id} is ${existing.phase}, not active`,
420
433
  this._phase,
421
434
  message.type,
422
435
  ),
423
- };
424
- return { ok: true, phase: this._phase, sideEffects };
436
+ }
437
+ return { ok: true, phase: this._phase, sideEffects }
425
438
  }
426
439
 
427
440
  private handleSubscribeDone(
428
441
  message: Draft08Message,
429
442
  sideEffects: SideEffect[],
430
443
  ): TransitionResult<Draft08MessageType> {
431
- const err = this.requireReady(message.type);
432
- if (err) return { ok: false, violation: err };
433
- const done = message as import("./types.js").Draft08SubscribeDone;
434
- const idErr = this.checkKnownSubscribeId(done.subscribe_id, message.type);
435
- if (idErr) return { ok: false, violation: idErr };
436
- const existing = this._subscriptions.get(done.subscribe_id);
444
+ const err = this.requireReady(message.type)
445
+ if (err) return { ok: false, violation: err }
446
+ const done = message as import('./types.js').Draft08SubscribeDone
447
+ const idErr = this.checkKnownSubscribeId(done.subscribe_id, message.type)
448
+ if (idErr) return { ok: false, violation: idErr }
449
+ const existing = this._subscriptions.get(done.subscribe_id)
437
450
  if (!existing)
438
451
  return {
439
452
  ok: false,
440
453
  violation: violation(
441
- "UNKNOWN_REQUEST_ID",
454
+ 'UNKNOWN_REQUEST_ID',
442
455
  `No subscription with subscribe ID ${done.subscribe_id}`,
443
456
  this._phase,
444
457
  message.type,
445
458
  ),
446
- };
447
- this._subscriptions.set(done.subscribe_id, { ...existing, phase: "done" });
459
+ }
460
+ this._subscriptions.set(done.subscribe_id, { ...existing, phase: 'done' })
448
461
  sideEffects.push({
449
- type: "subscription-ended",
462
+ type: 'subscription-ended',
450
463
  subscribeId: done.subscribe_id,
451
464
  reason: done.reason_phrase,
452
- });
453
- return { ok: true, phase: this._phase, sideEffects };
465
+ })
466
+ return { ok: true, phase: this._phase, sideEffects }
454
467
  }
455
468
 
456
469
  private handleUnsubscribe(
457
470
  message: Draft08Message,
458
471
  sideEffects: SideEffect[],
459
472
  ): TransitionResult<Draft08MessageType> {
460
- const err = this.requireReady(message.type);
461
- if (err) return { ok: false, violation: err };
462
- const unsub = message as import("./types.js").Draft08Unsubscribe;
463
- const idErr = this.checkKnownSubscribeId(unsub.subscribe_id, message.type);
464
- if (idErr) return { ok: false, violation: idErr };
465
- const existing = this._subscriptions.get(unsub.subscribe_id);
473
+ const err = this.requireReady(message.type)
474
+ if (err) return { ok: false, violation: err }
475
+ const unsub = message as import('./types.js').Draft08Unsubscribe
476
+ const idErr = this.checkKnownSubscribeId(unsub.subscribe_id, message.type)
477
+ if (idErr) return { ok: false, violation: idErr }
478
+ const existing = this._subscriptions.get(unsub.subscribe_id)
466
479
  if (!existing)
467
480
  return {
468
481
  ok: false,
469
482
  violation: violation(
470
- "UNKNOWN_REQUEST_ID",
483
+ 'UNKNOWN_REQUEST_ID',
471
484
  `No subscription with subscribe ID ${unsub.subscribe_id}`,
472
485
  this._phase,
473
486
  message.type,
474
487
  ),
475
- };
476
- this._subscriptions.set(unsub.subscribe_id, { ...existing, phase: "done" });
488
+ }
489
+ this._subscriptions.set(unsub.subscribe_id, { ...existing, phase: 'done' })
477
490
  sideEffects.push({
478
- type: "subscription-ended",
491
+ type: 'subscription-ended',
479
492
  subscribeId: unsub.subscribe_id,
480
- reason: "unsubscribed",
481
- });
482
- return { ok: true, phase: this._phase, sideEffects };
493
+ reason: 'unsubscribed',
494
+ })
495
+ return { ok: true, phase: this._phase, sideEffects }
483
496
  }
484
497
 
485
498
  // ─── Announce lifecycle ───
@@ -488,111 +501,123 @@ export class Draft08SessionFSM {
488
501
  message: Draft08Message,
489
502
  sideEffects: SideEffect[],
490
503
  ): TransitionResult<Draft08MessageType> {
491
- const err = this.requireReady(message.type);
492
- if (err) return { ok: false, violation: err };
493
- const ann = message as import("./types.js").Draft08Announce;
494
- const nsKey = ann.track_namespace.join("/");
495
- this._announces.set(nsKey, { namespace: ann.track_namespace, phase: "pending" });
496
- return { ok: true, phase: this._phase, sideEffects };
504
+ const err = this.requireReady(message.type)
505
+ if (err) return { ok: false, violation: err }
506
+ const ann = message as import('./types.js').Draft08Announce
507
+ const nsKey = ann.track_namespace.join('/')
508
+ this._announces.set(nsKey, {
509
+ namespace: ann.track_namespace,
510
+ phase: 'pending',
511
+ })
512
+ return { ok: true, phase: this._phase, sideEffects }
497
513
  }
498
514
 
499
515
  private handleAnnounceOk(
500
516
  message: Draft08Message,
501
517
  sideEffects: SideEffect[],
502
518
  ): TransitionResult<Draft08MessageType> {
503
- const err = this.requireReady(message.type);
504
- if (err) return { ok: false, violation: err };
505
- const ok = message as import("./types.js").Draft08AnnounceOk;
506
- const nsKey = ok.track_namespace.join("/");
507
- const existing = this._announces.get(nsKey);
519
+ const err = this.requireReady(message.type)
520
+ if (err) return { ok: false, violation: err }
521
+ const ok = message as import('./types.js').Draft08AnnounceOk
522
+ const nsKey = ok.track_namespace.join('/')
523
+ const existing = this._announces.get(nsKey)
508
524
  if (!existing)
509
525
  return {
510
526
  ok: false,
511
527
  violation: violation(
512
- "UNKNOWN_REQUEST_ID",
528
+ 'UNKNOWN_REQUEST_ID',
513
529
  `No announce for namespace ${nsKey}`,
514
530
  this._phase,
515
531
  message.type,
516
532
  ),
517
- };
518
- if (existing.phase !== "pending")
533
+ }
534
+ if (existing.phase !== 'pending')
519
535
  return {
520
536
  ok: false,
521
537
  violation: violation(
522
- "STATE_VIOLATION",
538
+ 'STATE_VIOLATION',
523
539
  `Announce ${nsKey} is ${existing.phase}, not pending`,
524
540
  this._phase,
525
541
  message.type,
526
542
  ),
527
- };
528
- this._announces.set(nsKey, { ...existing, phase: "active" });
529
- return { ok: true, phase: this._phase, sideEffects };
543
+ }
544
+ this._announces.set(nsKey, { ...existing, phase: 'active' })
545
+ return { ok: true, phase: this._phase, sideEffects }
530
546
  }
531
547
 
532
548
  private handleAnnounceError(
533
549
  message: Draft08Message,
534
550
  sideEffects: SideEffect[],
535
551
  ): TransitionResult<Draft08MessageType> {
536
- const err = this.requireReady(message.type);
537
- if (err) return { ok: false, violation: err };
538
- const annErr = message as import("./types.js").Draft08AnnounceError;
539
- const nsKey = annErr.track_namespace.join("/");
540
- const existing = this._announces.get(nsKey);
552
+ const err = this.requireReady(message.type)
553
+ if (err) return { ok: false, violation: err }
554
+ const annErr = message as import('./types.js').Draft08AnnounceError
555
+ const nsKey = annErr.track_namespace.join('/')
556
+ const existing = this._announces.get(nsKey)
541
557
  if (!existing)
542
558
  return {
543
559
  ok: false,
544
560
  violation: violation(
545
- "UNKNOWN_REQUEST_ID",
561
+ 'UNKNOWN_REQUEST_ID',
546
562
  `No announce for namespace ${nsKey}`,
547
563
  this._phase,
548
564
  message.type,
549
565
  ),
550
- };
551
- if (existing.phase !== "pending")
566
+ }
567
+ if (existing.phase !== 'pending')
552
568
  return {
553
569
  ok: false,
554
570
  violation: violation(
555
- "STATE_VIOLATION",
571
+ 'STATE_VIOLATION',
556
572
  `Announce ${nsKey} is ${existing.phase}, not pending`,
557
573
  this._phase,
558
574
  message.type,
559
575
  ),
560
- };
561
- this._announces.set(nsKey, { ...existing, phase: "error" });
562
- sideEffects.push({ type: "announce-ended", namespace: annErr.track_namespace });
563
- return { ok: true, phase: this._phase, sideEffects };
576
+ }
577
+ this._announces.set(nsKey, { ...existing, phase: 'error' })
578
+ sideEffects.push({
579
+ type: 'announce-ended',
580
+ namespace: annErr.track_namespace,
581
+ })
582
+ return { ok: true, phase: this._phase, sideEffects }
564
583
  }
565
584
 
566
585
  private handleUnannounce(
567
586
  message: Draft08Message,
568
587
  sideEffects: SideEffect[],
569
588
  ): TransitionResult<Draft08MessageType> {
570
- const err = this.requireReady(message.type);
571
- if (err) return { ok: false, violation: err };
572
- const unann = message as import("./types.js").Draft08Unannounce;
573
- const nsKey = unann.track_namespace.join("/");
574
- const existing = this._announces.get(nsKey);
589
+ const err = this.requireReady(message.type)
590
+ if (err) return { ok: false, violation: err }
591
+ const unann = message as import('./types.js').Draft08Unannounce
592
+ const nsKey = unann.track_namespace.join('/')
593
+ const existing = this._announces.get(nsKey)
575
594
  if (existing) {
576
- this._announces.delete(nsKey);
577
- sideEffects.push({ type: "announce-ended", namespace: unann.track_namespace });
595
+ this._announces.delete(nsKey)
596
+ sideEffects.push({
597
+ type: 'announce-ended',
598
+ namespace: unann.track_namespace,
599
+ })
578
600
  }
579
- return { ok: true, phase: this._phase, sideEffects };
601
+ return { ok: true, phase: this._phase, sideEffects }
580
602
  }
581
603
 
582
604
  private handleAnnounceCancel(
583
605
  message: Draft08Message,
584
606
  sideEffects: SideEffect[],
585
607
  ): TransitionResult<Draft08MessageType> {
586
- const err = this.requireReady(message.type);
587
- if (err) return { ok: false, violation: err };
588
- const cancel = message as import("./types.js").Draft08AnnounceCancel;
589
- const nsKey = cancel.track_namespace.join("/");
590
- const existing = this._announces.get(nsKey);
608
+ const err = this.requireReady(message.type)
609
+ if (err) return { ok: false, violation: err }
610
+ const cancel = message as import('./types.js').Draft08AnnounceCancel
611
+ const nsKey = cancel.track_namespace.join('/')
612
+ const existing = this._announces.get(nsKey)
591
613
  if (existing) {
592
- this._announces.delete(nsKey);
593
- sideEffects.push({ type: "announce-ended", namespace: cancel.track_namespace });
614
+ this._announces.delete(nsKey)
615
+ sideEffects.push({
616
+ type: 'announce-ended',
617
+ namespace: cancel.track_namespace,
618
+ })
594
619
  }
595
- return { ok: true, phase: this._phase, sideEffects };
620
+ return { ok: true, phase: this._phase, sideEffects }
596
621
  }
597
622
 
598
623
  // ─── Fetch lifecycle ───
@@ -601,118 +626,125 @@ export class Draft08SessionFSM {
601
626
  message: Draft08Message,
602
627
  sideEffects: SideEffect[],
603
628
  ): TransitionResult<Draft08MessageType> {
604
- const err = this.requireReady(message.type);
605
- if (err) return { ok: false, violation: err };
606
- const fetch = message as import("./types.js").Draft08Fetch;
607
- const dupErr = this.checkDuplicateSubscribeId(fetch.subscribe_id, message.type);
608
- if (dupErr) return { ok: false, violation: dupErr };
609
- this._subscribeIds.add(fetch.subscribe_id);
610
- this._fetches.set(fetch.subscribe_id, { requestId: fetch.subscribe_id, phase: "pending" });
611
- return { ok: true, phase: this._phase, sideEffects };
629
+ const err = this.requireReady(message.type)
630
+ if (err) return { ok: false, violation: err }
631
+ const fetch = message as import('./types.js').Draft08Fetch
632
+ const dupErr = this.checkDuplicateSubscribeId(fetch.subscribe_id, message.type)
633
+ if (dupErr) return { ok: false, violation: dupErr }
634
+ this._subscribeIds.add(fetch.subscribe_id)
635
+ this._fetches.set(fetch.subscribe_id, {
636
+ requestId: fetch.subscribe_id,
637
+ phase: 'pending',
638
+ })
639
+ return { ok: true, phase: this._phase, sideEffects }
612
640
  }
613
641
 
614
642
  private handleFetchOk(
615
643
  message: Draft08Message,
616
644
  sideEffects: SideEffect[],
617
645
  ): TransitionResult<Draft08MessageType> {
618
- const err = this.requireReady(message.type);
619
- if (err) return { ok: false, violation: err };
620
- const ok = message as import("./types.js").Draft08FetchOk;
621
- const idErr = this.checkKnownSubscribeId(ok.subscribe_id, message.type);
622
- if (idErr) return { ok: false, violation: idErr };
623
- const existing = this._fetches.get(ok.subscribe_id);
646
+ const err = this.requireReady(message.type)
647
+ if (err) return { ok: false, violation: err }
648
+ const ok = message as import('./types.js').Draft08FetchOk
649
+ const idErr = this.checkKnownSubscribeId(ok.subscribe_id, message.type)
650
+ if (idErr) return { ok: false, violation: idErr }
651
+ const existing = this._fetches.get(ok.subscribe_id)
624
652
  if (!existing)
625
653
  return {
626
654
  ok: false,
627
655
  violation: violation(
628
- "UNKNOWN_REQUEST_ID",
656
+ 'UNKNOWN_REQUEST_ID',
629
657
  `No fetch with subscribe ID ${ok.subscribe_id}`,
630
658
  this._phase,
631
659
  message.type,
632
660
  ),
633
- };
634
- if (existing.phase !== "pending")
661
+ }
662
+ if (existing.phase !== 'pending')
635
663
  return {
636
664
  ok: false,
637
665
  violation: violation(
638
- "STATE_VIOLATION",
666
+ 'STATE_VIOLATION',
639
667
  `Fetch ${ok.subscribe_id} is ${existing.phase}, not pending`,
640
668
  this._phase,
641
669
  message.type,
642
670
  ),
643
- };
644
- this._fetches.set(ok.subscribe_id, { ...existing, phase: "active" });
645
- sideEffects.push({ type: "fetch-activated", requestId: ok.subscribe_id });
646
- return { ok: true, phase: this._phase, sideEffects };
671
+ }
672
+ this._fetches.set(ok.subscribe_id, { ...existing, phase: 'active' })
673
+ sideEffects.push({ type: 'fetch-activated', requestId: ok.subscribe_id })
674
+ return { ok: true, phase: this._phase, sideEffects }
647
675
  }
648
676
 
649
677
  private handleFetchError(
650
678
  message: Draft08Message,
651
679
  sideEffects: SideEffect[],
652
680
  ): TransitionResult<Draft08MessageType> {
653
- const err = this.requireReady(message.type);
654
- if (err) return { ok: false, violation: err };
655
- const fetchErr = message as import("./types.js").Draft08FetchError;
656
- const idErr = this.checkKnownSubscribeId(fetchErr.subscribe_id, message.type);
657
- if (idErr) return { ok: false, violation: idErr };
658
- const existing = this._fetches.get(fetchErr.subscribe_id);
681
+ const err = this.requireReady(message.type)
682
+ if (err) return { ok: false, violation: err }
683
+ const fetchErr = message as import('./types.js').Draft08FetchError
684
+ const idErr = this.checkKnownSubscribeId(fetchErr.subscribe_id, message.type)
685
+ if (idErr) return { ok: false, violation: idErr }
686
+ const existing = this._fetches.get(fetchErr.subscribe_id)
659
687
  if (!existing)
660
688
  return {
661
689
  ok: false,
662
690
  violation: violation(
663
- "UNKNOWN_REQUEST_ID",
691
+ 'UNKNOWN_REQUEST_ID',
664
692
  `No fetch with subscribe ID ${fetchErr.subscribe_id}`,
665
693
  this._phase,
666
694
  message.type,
667
695
  ),
668
- };
669
- this._fetches.set(fetchErr.subscribe_id, { ...existing, phase: "error" });
696
+ }
697
+ this._fetches.set(fetchErr.subscribe_id, { ...existing, phase: 'error' })
670
698
  sideEffects.push({
671
- type: "fetch-ended",
699
+ type: 'fetch-ended',
672
700
  requestId: fetchErr.subscribe_id,
673
701
  reason: fetchErr.reason_phrase,
674
- });
675
- return { ok: true, phase: this._phase, sideEffects };
702
+ })
703
+ return { ok: true, phase: this._phase, sideEffects }
676
704
  }
677
705
 
678
706
  private handleFetchCancel(
679
707
  message: Draft08Message,
680
708
  sideEffects: SideEffect[],
681
709
  ): TransitionResult<Draft08MessageType> {
682
- const err = this.requireReady(message.type);
683
- if (err) return { ok: false, violation: err };
684
- const cancel = message as import("./types.js").Draft08FetchCancel;
685
- const idErr = this.checkKnownSubscribeId(cancel.subscribe_id, message.type);
686
- if (idErr) return { ok: false, violation: idErr };
687
- const existing = this._fetches.get(cancel.subscribe_id);
710
+ const err = this.requireReady(message.type)
711
+ if (err) return { ok: false, violation: err }
712
+ const cancel = message as import('./types.js').Draft08FetchCancel
713
+ const idErr = this.checkKnownSubscribeId(cancel.subscribe_id, message.type)
714
+ if (idErr) return { ok: false, violation: idErr }
715
+ const existing = this._fetches.get(cancel.subscribe_id)
688
716
  if (!existing)
689
717
  return {
690
718
  ok: false,
691
719
  violation: violation(
692
- "UNKNOWN_REQUEST_ID",
720
+ 'UNKNOWN_REQUEST_ID',
693
721
  `No fetch with subscribe ID ${cancel.subscribe_id}`,
694
722
  this._phase,
695
723
  message.type,
696
724
  ),
697
- };
698
- this._fetches.set(cancel.subscribe_id, { ...existing, phase: "cancelled" });
699
- sideEffects.push({ type: "fetch-ended", requestId: cancel.subscribe_id, reason: "cancelled" });
700
- return { ok: true, phase: this._phase, sideEffects };
725
+ }
726
+ this._fetches.set(cancel.subscribe_id, { ...existing, phase: 'cancelled' })
727
+ sideEffects.push({
728
+ type: 'fetch-ended',
729
+ requestId: cancel.subscribe_id,
730
+ reason: 'cancelled',
731
+ })
732
+ return { ok: true, phase: this._phase, sideEffects }
701
733
  }
702
734
 
703
735
  // ─── Generic ready-phase handler ───
704
736
 
705
737
  private handleReadyPhaseMessage(message: Draft08Message): TransitionResult<Draft08MessageType> {
706
- const err = this.requireReady(message.type);
707
- if (err) return { ok: false, violation: err };
708
- return { ok: true, phase: this._phase, sideEffects: [] };
738
+ const err = this.requireReady(message.type)
739
+ if (err) return { ok: false, violation: err }
740
+ return { ok: true, phase: this._phase, sideEffects: [] }
709
741
  }
710
742
 
711
743
  reset(): void {
712
- this._phase = "idle";
713
- this._subscriptions.clear();
714
- this._announces.clear();
715
- this._fetches.clear();
716
- this._subscribeIds.clear();
744
+ this._phase = 'idle'
745
+ this._subscriptions.clear()
746
+ this._announces.clear()
747
+ this._fetches.clear()
748
+ this._subscribeIds.clear()
717
749
  }
718
750
  }