@moqtap/codec 0.2.3 → 0.4.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 (313) 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/{draft7-session.cjs → draft07-session.cjs} +2 -2
  72. package/dist/draft07-session.d.cts +8 -0
  73. package/dist/draft07-session.d.ts +8 -0
  74. package/dist/{draft7-session.js → draft07-session.js} +1 -1
  75. package/dist/draft07.cjs +129 -0
  76. package/dist/draft07.d.cts +67 -0
  77. package/dist/draft07.d.ts +67 -0
  78. package/dist/draft07.js +129 -0
  79. package/dist/draft08-session.cjs +6 -0
  80. package/dist/draft08-session.d.cts +8 -0
  81. package/dist/draft08-session.d.ts +8 -0
  82. package/dist/{draft8-session.js → draft08-session.js} +1 -1
  83. package/dist/draft08.cjs +119 -0
  84. package/dist/{draft8.d.cts → draft08.d.cts} +15 -13
  85. package/dist/{draft8.d.ts → draft08.d.ts} +15 -13
  86. package/dist/{draft8.js → draft08.js} +7 -4
  87. package/dist/draft09-session.cjs +6 -0
  88. package/dist/draft09-session.d.cts +8 -0
  89. package/dist/draft09-session.d.ts +8 -0
  90. package/dist/{draft9-session.js → draft09-session.js} +1 -1
  91. package/dist/draft09.cjs +119 -0
  92. package/dist/{draft9.d.cts → draft09.d.cts} +15 -13
  93. package/dist/{draft9.d.ts → draft09.d.ts} +15 -13
  94. package/dist/{draft9.js → draft09.js} +7 -4
  95. package/dist/draft10-session.cjs +2 -2
  96. package/dist/draft10-session.d.cts +6 -6
  97. package/dist/draft10-session.d.ts +6 -6
  98. package/dist/draft10-session.js +1 -1
  99. package/dist/draft10.cjs +8 -5
  100. package/dist/draft10.d.cts +14 -12
  101. package/dist/draft10.d.ts +14 -12
  102. package/dist/draft10.js +16 -13
  103. package/dist/draft11-session.cjs +2 -2
  104. package/dist/draft11-session.d.cts +6 -6
  105. package/dist/draft11-session.d.ts +6 -6
  106. package/dist/draft11-session.js +1 -1
  107. package/dist/draft11.cjs +8 -5
  108. package/dist/draft11.d.cts +14 -12
  109. package/dist/draft11.d.ts +14 -12
  110. package/dist/draft11.js +16 -13
  111. package/dist/draft12-session.cjs +2 -2
  112. package/dist/draft12-session.d.cts +6 -6
  113. package/dist/draft12-session.d.ts +6 -6
  114. package/dist/draft12-session.js +1 -1
  115. package/dist/draft12.cjs +8 -5
  116. package/dist/draft12.d.cts +16 -14
  117. package/dist/draft12.d.ts +16 -14
  118. package/dist/draft12.js +16 -13
  119. package/dist/draft13-session.cjs +2 -2
  120. package/dist/draft13-session.d.cts +6 -6
  121. package/dist/draft13-session.d.ts +6 -6
  122. package/dist/draft13-session.js +1 -1
  123. package/dist/draft13.cjs +8 -5
  124. package/dist/draft13.d.cts +16 -14
  125. package/dist/draft13.d.ts +16 -14
  126. package/dist/draft13.js +16 -13
  127. package/dist/draft14-session.cjs +2 -2
  128. package/dist/draft14-session.d.cts +6 -6
  129. package/dist/draft14-session.d.ts +6 -6
  130. package/dist/draft14-session.js +1 -1
  131. package/dist/draft14.cjs +14 -5
  132. package/dist/draft14.d.cts +14 -12
  133. package/dist/draft14.d.ts +14 -12
  134. package/dist/draft14.js +13 -4
  135. package/dist/draft15-session.cjs +2 -2
  136. package/dist/draft15-session.d.cts +6 -6
  137. package/dist/draft15-session.d.ts +6 -6
  138. package/dist/draft15-session.js +1 -1
  139. package/dist/draft15.cjs +8 -5
  140. package/dist/draft15.d.cts +14 -12
  141. package/dist/draft15.d.ts +14 -12
  142. package/dist/draft15.js +16 -13
  143. package/dist/draft16-session.cjs +2 -2
  144. package/dist/draft16-session.d.cts +6 -6
  145. package/dist/draft16-session.d.ts +6 -6
  146. package/dist/draft16-session.js +1 -1
  147. package/dist/draft16.cjs +8 -5
  148. package/dist/draft16.d.cts +14 -12
  149. package/dist/draft16.d.ts +14 -12
  150. package/dist/draft16.js +16 -13
  151. package/dist/draft17-session.cjs +2 -2
  152. package/dist/draft17-session.d.cts +7 -7
  153. package/dist/draft17-session.d.ts +7 -7
  154. package/dist/draft17-session.js +1 -1
  155. package/dist/draft17.cjs +8 -5
  156. package/dist/draft17.d.cts +11 -9
  157. package/dist/draft17.d.ts +11 -9
  158. package/dist/draft17.js +16 -13
  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 +29 -11
  167. package/dist/session.d.ts +29 -11
  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.cts → types-0IWbU9Z_.d.cts} +36 -36
  172. package/dist/{types-B0FT5Qs2.d.ts → 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.cts → types-Br7fm2mf.d.cts} +48 -26
  178. package/dist/{types-8gUGeMgs.d.ts → 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 +63 -25
  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/draft7-session.d.cts +0 -7
  296. package/dist/draft7-session.d.ts +0 -7
  297. package/dist/draft7.cjs +0 -72
  298. package/dist/draft7.d.cts +0 -148
  299. package/dist/draft7.d.ts +0 -148
  300. package/dist/draft7.js +0 -72
  301. package/dist/draft8-session.cjs +0 -6
  302. package/dist/draft8-session.d.cts +0 -8
  303. package/dist/draft8-session.d.ts +0 -8
  304. package/dist/draft8.cjs +0 -116
  305. package/dist/draft9-session.cjs +0 -6
  306. package/dist/draft9-session.d.cts +0 -8
  307. package/dist/draft9-session.d.ts +0 -8
  308. package/dist/draft9.cjs +0 -116
  309. package/dist/types-QNXoxC9Y.d.cts +0 -236
  310. package/dist/types-QNXoxC9Y.d.ts +0 -236
  311. package/src/drafts/draft07/announce-fsm.ts +0 -2
  312. package/src/drafts/draft07/parameters.ts +0 -12
  313. package/src/drafts/draft07/subscription-fsm.ts +0 -3
@@ -8,88 +8,88 @@ import type {
8
8
  SubscriptionState,
9
9
  TransitionResult,
10
10
  ValidationResult,
11
- } from "../../core/session-types.js";
11
+ } from '../../core/session-types.js'
12
12
  import {
13
13
  CLIENT_ONLY_MESSAGES,
14
14
  getLegalIncoming,
15
15
  getLegalOutgoing,
16
16
  SERVER_ONLY_MESSAGES,
17
- } from "./rules.js";
18
- import type { Draft14Message, Draft14MessageType } from "./types.js";
17
+ } from './rules.js'
18
+ import type { Draft14Message, Draft14MessageType } from './types.js'
19
19
 
20
20
  function violation(
21
- code: ProtocolViolation<Draft14MessageType>["code"],
21
+ code: ProtocolViolation<Draft14MessageType>['code'],
22
22
  message: string,
23
23
  currentPhase: SessionPhase,
24
24
  offendingMessage: Draft14MessageType,
25
25
  ): ProtocolViolation<Draft14MessageType> {
26
- return { code, message, currentPhase, offendingMessage };
26
+ return { code, message, currentPhase, offendingMessage }
27
27
  }
28
28
 
29
29
  export class Draft14SessionFSM {
30
- private _phase: SessionPhase = "idle";
31
- private _role: "client" | "server";
32
- private _subscriptions = new Map<bigint, SubscriptionState>();
33
- private _publishes = new Map<bigint, PublishState>();
34
- private _fetches = new Map<bigint, FetchState>();
35
- private _requestIds = new Set<bigint>();
30
+ private _phase: SessionPhase = 'idle'
31
+ private _role: 'client' | 'server'
32
+ private _subscriptions = new Map<bigint, SubscriptionState>()
33
+ private _publishes = new Map<bigint, PublishState>()
34
+ private _fetches = new Map<bigint, FetchState>()
35
+ private _requestIds = new Set<bigint>()
36
36
 
37
- constructor(role: "client" | "server") {
38
- this._role = role;
37
+ constructor(role: 'client' | 'server') {
38
+ this._role = role
39
39
  }
40
40
 
41
41
  get phase(): SessionPhase {
42
- return this._phase;
42
+ return this._phase
43
43
  }
44
- get role(): "client" | "server" {
45
- return this._role;
44
+ get role(): 'client' | 'server' {
45
+ return this._role
46
46
  }
47
47
  get subscriptions(): ReadonlyMap<bigint, SubscriptionState> {
48
- return this._subscriptions;
48
+ return this._subscriptions
49
49
  }
50
50
  get announces(): ReadonlyMap<string, AnnounceState> {
51
- return new Map();
51
+ return new Map()
52
52
  }
53
53
  get publishes(): ReadonlyMap<bigint, PublishState> {
54
- return this._publishes;
54
+ return this._publishes
55
55
  }
56
56
  get fetches(): ReadonlyMap<bigint, FetchState> {
57
- return this._fetches;
57
+ return this._fetches
58
58
  }
59
59
 
60
60
  get legalOutgoing(): ReadonlySet<Draft14MessageType> {
61
- return getLegalOutgoing(this._phase, this._role);
61
+ return getLegalOutgoing(this._phase, this._role)
62
62
  }
63
63
 
64
64
  get legalIncoming(): ReadonlySet<Draft14MessageType> {
65
- return getLegalIncoming(this._phase, this._role);
65
+ return getLegalIncoming(this._phase, this._role)
66
66
  }
67
67
 
68
68
  // Validate role constraints
69
69
  private checkRole(
70
70
  message: Draft14Message,
71
- direction: "inbound" | "outbound",
71
+ direction: 'inbound' | 'outbound',
72
72
  ): ProtocolViolation<Draft14MessageType> | null {
73
73
  const senderRole =
74
- direction === "outbound" ? this._role : this._role === "client" ? "server" : "client";
74
+ direction === 'outbound' ? this._role : this._role === 'client' ? 'server' : 'client'
75
75
 
76
- if (CLIENT_ONLY_MESSAGES.has(message.type) && senderRole !== "client") {
76
+ if (CLIENT_ONLY_MESSAGES.has(message.type) && senderRole !== 'client') {
77
77
  return violation(
78
- "ROLE_VIOLATION",
78
+ 'ROLE_VIOLATION',
79
79
  `${message.type} can only be sent by client`,
80
80
  this._phase,
81
81
  message.type,
82
- );
82
+ )
83
83
  }
84
- if (SERVER_ONLY_MESSAGES.has(message.type) && senderRole !== "server") {
84
+ if (SERVER_ONLY_MESSAGES.has(message.type) && senderRole !== 'server') {
85
85
  return violation(
86
- "ROLE_VIOLATION",
86
+ 'ROLE_VIOLATION',
87
87
  `${message.type} can only be sent by server`,
88
88
  this._phase,
89
89
  message.type,
90
- );
90
+ )
91
91
  }
92
- return null;
92
+ return null
93
93
  }
94
94
 
95
95
  private checkDuplicateRequestId(
@@ -98,13 +98,13 @@ export class Draft14SessionFSM {
98
98
  ): ProtocolViolation<Draft14MessageType> | null {
99
99
  if (this._requestIds.has(requestId)) {
100
100
  return violation(
101
- "DUPLICATE_REQUEST_ID",
101
+ 'DUPLICATE_REQUEST_ID',
102
102
  `Request ID ${requestId} already in use`,
103
103
  this._phase,
104
104
  msgType,
105
- );
105
+ )
106
106
  }
107
- return null;
107
+ return null
108
108
  }
109
109
 
110
110
  private checkKnownRequestId(
@@ -113,695 +113,709 @@ export class Draft14SessionFSM {
113
113
  ): ProtocolViolation<Draft14MessageType> | null {
114
114
  if (!this._requestIds.has(requestId)) {
115
115
  return violation(
116
- "UNKNOWN_REQUEST_ID",
116
+ 'UNKNOWN_REQUEST_ID',
117
117
  `No request with ID ${requestId}`,
118
118
  this._phase,
119
119
  msgType,
120
- );
120
+ )
121
121
  }
122
- return null;
122
+ return null
123
123
  }
124
124
 
125
125
  validateOutgoing(message: Draft14Message): ValidationResult<Draft14MessageType> {
126
- const roleViolation = this.checkRole(message, "outbound");
127
- if (roleViolation) return { ok: false, violation: roleViolation };
126
+ const roleViolation = this.checkRole(message, 'outbound')
127
+ if (roleViolation) return { ok: false, violation: roleViolation }
128
128
 
129
129
  if (!this.legalOutgoing.has(message.type)) {
130
130
  return {
131
131
  ok: false,
132
132
  violation: violation(
133
- this._phase === "idle" || this._phase === "setup"
134
- ? "MESSAGE_BEFORE_SETUP"
135
- : "UNEXPECTED_MESSAGE",
133
+ this._phase === 'idle' || this._phase === 'setup'
134
+ ? 'MESSAGE_BEFORE_SETUP'
135
+ : 'UNEXPECTED_MESSAGE',
136
136
  `Cannot send ${message.type} in phase ${this._phase}`,
137
137
  this._phase,
138
138
  message.type,
139
139
  ),
140
- };
140
+ }
141
141
  }
142
- return { ok: true };
142
+ return { ok: true }
143
143
  }
144
144
 
145
145
  receive(message: Draft14Message): TransitionResult<Draft14MessageType> {
146
- const roleViolation = this.checkRole(message, "inbound");
147
- if (roleViolation) return { ok: false, violation: roleViolation };
146
+ const roleViolation = this.checkRole(message, 'inbound')
147
+ if (roleViolation) return { ok: false, violation: roleViolation }
148
148
 
149
- return this.applyTransition(message, "inbound");
149
+ return this.applyTransition(message, 'inbound')
150
150
  }
151
151
 
152
152
  send(message: Draft14Message): TransitionResult<Draft14MessageType> {
153
- const roleViolation = this.checkRole(message, "outbound");
154
- if (roleViolation) return { ok: false, violation: roleViolation };
153
+ const roleViolation = this.checkRole(message, 'outbound')
154
+ if (roleViolation) return { ok: false, violation: roleViolation }
155
155
 
156
- return this.applyTransition(message, "outbound");
156
+ return this.applyTransition(message, 'outbound')
157
157
  }
158
158
 
159
159
  private applyTransition(
160
160
  message: Draft14Message,
161
- direction: "inbound" | "outbound",
161
+ direction: 'inbound' | 'outbound',
162
162
  ): TransitionResult<Draft14MessageType> {
163
- const sideEffects: SideEffect[] = [];
163
+ const sideEffects: SideEffect[] = []
164
164
 
165
165
  switch (message.type) {
166
- case "client_setup":
167
- return this.handleClientSetup(message, direction);
168
- case "server_setup":
169
- return this.handleServerSetup(message, direction);
170
- case "goaway":
171
- return this.handleGoAway(message, direction, sideEffects);
166
+ case 'client_setup':
167
+ return this.handleClientSetup(message, direction)
168
+ case 'server_setup':
169
+ return this.handleServerSetup(message, direction)
170
+ case 'goaway':
171
+ return this.handleGoAway(message, direction, sideEffects)
172
172
 
173
173
  // Subscribe lifecycle
174
- case "subscribe":
175
- return this.handleSubscribe(message, direction, sideEffects);
176
- case "subscribe_ok":
177
- return this.handleSubscribeOk(message, direction, sideEffects);
178
- case "subscribe_error":
179
- return this.handleSubscribeError(message, direction, sideEffects);
180
- case "subscribe_update":
181
- return this.handleSubscribeUpdate(message, direction, sideEffects);
182
- case "unsubscribe":
183
- return this.handleUnsubscribe(message, direction, sideEffects);
174
+ case 'subscribe':
175
+ return this.handleSubscribe(message, direction, sideEffects)
176
+ case 'subscribe_ok':
177
+ return this.handleSubscribeOk(message, direction, sideEffects)
178
+ case 'subscribe_error':
179
+ return this.handleSubscribeError(message, direction, sideEffects)
180
+ case 'subscribe_update':
181
+ return this.handleSubscribeUpdate(message, direction, sideEffects)
182
+ case 'unsubscribe':
183
+ return this.handleUnsubscribe(message, direction, sideEffects)
184
184
 
185
185
  // Publish lifecycle
186
- case "publish":
187
- return this.handlePublish(message, direction, sideEffects);
188
- case "publish_ok":
189
- return this.handlePublishOk(message, direction, sideEffects);
190
- case "publish_error":
191
- return this.handlePublishError(message, direction, sideEffects);
192
- case "publish_done":
193
- return this.handlePublishDone(message, direction, sideEffects);
186
+ case 'publish':
187
+ return this.handlePublish(message, direction, sideEffects)
188
+ case 'publish_ok':
189
+ return this.handlePublishOk(message, direction, sideEffects)
190
+ case 'publish_error':
191
+ return this.handlePublishError(message, direction, sideEffects)
192
+ case 'publish_done':
193
+ return this.handlePublishDone(message, direction, sideEffects)
194
194
 
195
195
  // Fetch lifecycle
196
- case "fetch":
197
- return this.handleFetch(message, direction, sideEffects);
198
- case "fetch_ok":
199
- return this.handleFetchOk(message, direction, sideEffects);
200
- case "fetch_error":
201
- return this.handleFetchError(message, direction, sideEffects);
202
- case "fetch_cancel":
203
- return this.handleFetchCancel(message, direction, sideEffects);
196
+ case 'fetch':
197
+ return this.handleFetch(message, direction, sideEffects)
198
+ case 'fetch_ok':
199
+ return this.handleFetchOk(message, direction, sideEffects)
200
+ case 'fetch_error':
201
+ return this.handleFetchError(message, direction, sideEffects)
202
+ case 'fetch_cancel':
203
+ return this.handleFetchCancel(message, direction, sideEffects)
204
204
 
205
205
  // Publish namespace lifecycle
206
- case "publish_namespace":
207
- return this.handlePublishNamespace(message, sideEffects);
208
- case "publish_namespace_ok":
209
- return this.handlePublishNamespaceOk(message, sideEffects);
210
- case "publish_namespace_error":
211
- return this.handlePublishNamespaceError(message, sideEffects);
212
- case "publish_namespace_done":
213
- return this.handlePublishNamespaceDone(message, sideEffects);
214
- case "publish_namespace_cancel":
215
- return this.handlePublishNamespaceCancel(message, sideEffects);
206
+ case 'publish_namespace':
207
+ return this.handlePublishNamespace(message, sideEffects)
208
+ case 'publish_namespace_ok':
209
+ return this.handlePublishNamespaceOk(message, sideEffects)
210
+ case 'publish_namespace_error':
211
+ return this.handlePublishNamespaceError(message, sideEffects)
212
+ case 'publish_namespace_done':
213
+ return this.handlePublishNamespaceDone(message, sideEffects)
214
+ case 'publish_namespace_cancel':
215
+ return this.handlePublishNamespaceCancel(message, sideEffects)
216
216
 
217
217
  // Subscribe namespace lifecycle
218
- case "subscribe_namespace":
219
- return this.handleSubscribeNamespace(message, sideEffects);
220
- case "subscribe_namespace_ok":
221
- return this.handleSubscribeNamespaceOk(message, sideEffects);
222
- case "subscribe_namespace_error":
223
- return this.handleSubscribeNamespaceError(message, sideEffects);
224
- case "unsubscribe_namespace":
225
- return this.handleUnsubscribeNamespace(message, sideEffects);
218
+ case 'subscribe_namespace':
219
+ return this.handleSubscribeNamespace(message, sideEffects)
220
+ case 'subscribe_namespace_ok':
221
+ return this.handleSubscribeNamespaceOk(message, sideEffects)
222
+ case 'subscribe_namespace_error':
223
+ return this.handleSubscribeNamespaceError(message, sideEffects)
224
+ case 'unsubscribe_namespace':
225
+ return this.handleUnsubscribeNamespace(message, sideEffects)
226
226
 
227
227
  // Track status lifecycle
228
- case "track_status":
229
- return this.handleTrackStatus(message, sideEffects);
230
- case "track_status_ok":
231
- return this.handleTrackStatusOk(message, sideEffects);
232
- case "track_status_error":
233
- return this.handleTrackStatusError(message, sideEffects);
228
+ case 'track_status':
229
+ return this.handleTrackStatus(message, sideEffects)
230
+ case 'track_status_ok':
231
+ return this.handleTrackStatusOk(message, sideEffects)
232
+ case 'track_status_error':
233
+ return this.handleTrackStatusError(message, sideEffects)
234
234
 
235
235
  // Other ready-phase messages
236
236
  default:
237
- return this.handleReadyPhaseMessage(message);
237
+ return this.handleReadyPhaseMessage(message)
238
238
  }
239
239
  }
240
240
 
241
241
  private handleClientSetup(
242
242
  _message: Draft14Message,
243
- direction: "inbound" | "outbound",
243
+ direction: 'inbound' | 'outbound',
244
244
  ): TransitionResult<Draft14MessageType> {
245
- if (this._phase !== "idle") {
245
+ if (this._phase !== 'idle') {
246
246
  return {
247
247
  ok: false,
248
248
  violation: violation(
249
- "SETUP_VIOLATION",
250
- "CLIENT_SETUP already sent/received",
249
+ 'SETUP_VIOLATION',
250
+ 'CLIENT_SETUP already sent/received',
251
251
  this._phase,
252
- "client_setup",
252
+ 'client_setup',
253
253
  ),
254
- };
254
+ }
255
255
  }
256
256
 
257
- if (direction === "outbound" && this._role !== "client") {
257
+ if (direction === 'outbound' && this._role !== 'client') {
258
258
  return {
259
259
  ok: false,
260
260
  violation: violation(
261
- "ROLE_VIOLATION",
262
- "Only client can send CLIENT_SETUP",
261
+ 'ROLE_VIOLATION',
262
+ 'Only client can send CLIENT_SETUP',
263
263
  this._phase,
264
- "client_setup",
264
+ 'client_setup',
265
265
  ),
266
- };
266
+ }
267
267
  }
268
268
 
269
- this._phase = "setup";
270
- return { ok: true, phase: this._phase, sideEffects: [] };
269
+ this._phase = 'setup'
270
+ return { ok: true, phase: this._phase, sideEffects: [] }
271
271
  }
272
272
 
273
273
  private handleServerSetup(
274
274
  _message: Draft14Message,
275
- direction: "inbound" | "outbound",
275
+ direction: 'inbound' | 'outbound',
276
276
  ): TransitionResult<Draft14MessageType> {
277
- if (this._phase !== "setup") {
277
+ if (this._phase !== 'setup') {
278
278
  return {
279
279
  ok: false,
280
280
  violation: violation(
281
- "SETUP_VIOLATION",
282
- "SERVER_SETUP before CLIENT_SETUP",
281
+ 'SETUP_VIOLATION',
282
+ 'SERVER_SETUP before CLIENT_SETUP',
283
283
  this._phase,
284
- "server_setup",
284
+ 'server_setup',
285
285
  ),
286
- };
286
+ }
287
287
  }
288
288
 
289
- if (direction === "outbound" && this._role !== "server") {
289
+ if (direction === 'outbound' && this._role !== 'server') {
290
290
  return {
291
291
  ok: false,
292
292
  violation: violation(
293
- "ROLE_VIOLATION",
294
- "Only server can send SERVER_SETUP",
293
+ 'ROLE_VIOLATION',
294
+ 'Only server can send SERVER_SETUP',
295
295
  this._phase,
296
- "server_setup",
296
+ 'server_setup',
297
297
  ),
298
- };
298
+ }
299
299
  }
300
300
 
301
- this._phase = "ready";
302
- return { ok: true, phase: this._phase, sideEffects: [{ type: "session-ready" }] };
301
+ this._phase = 'ready'
302
+ return {
303
+ ok: true,
304
+ phase: this._phase,
305
+ sideEffects: [{ type: 'session-ready' }],
306
+ }
303
307
  }
304
308
 
305
309
  private handleGoAway(
306
310
  message: Draft14Message,
307
- _direction: "inbound" | "outbound",
311
+ _direction: 'inbound' | 'outbound',
308
312
  sideEffects: SideEffect[],
309
313
  ): TransitionResult<Draft14MessageType> {
310
- if (this._phase !== "ready" && this._phase !== "draining") {
314
+ if (this._phase !== 'ready' && this._phase !== 'draining') {
311
315
  return {
312
316
  ok: false,
313
317
  violation: violation(
314
- "UNEXPECTED_MESSAGE",
318
+ 'UNEXPECTED_MESSAGE',
315
319
  `GOAWAY not valid in phase ${this._phase}`,
316
320
  this._phase,
317
- "goaway",
321
+ 'goaway',
318
322
  ),
319
- };
323
+ }
320
324
  }
321
- this._phase = "draining";
322
- const goaway = message as import("./types.js").Draft14GoAway;
323
- sideEffects.push({ type: "session-draining", goAwayUri: goaway.new_session_uri });
324
- return { ok: true, phase: this._phase, sideEffects };
325
+ this._phase = 'draining'
326
+ const goaway = message as import('./types.js').Draft14GoAway
327
+ sideEffects.push({
328
+ type: 'session-draining',
329
+ goAwayUri: goaway.new_session_uri,
330
+ })
331
+ return { ok: true, phase: this._phase, sideEffects }
325
332
  }
326
333
 
327
334
  private requireReady(msgType: Draft14MessageType): ProtocolViolation<Draft14MessageType> | null {
328
- if (this._phase !== "ready" && this._phase !== "draining") {
335
+ if (this._phase !== 'ready' && this._phase !== 'draining') {
329
336
  return violation(
330
- this._phase === "idle" || this._phase === "setup"
331
- ? "MESSAGE_BEFORE_SETUP"
332
- : "UNEXPECTED_MESSAGE",
337
+ this._phase === 'idle' || this._phase === 'setup'
338
+ ? 'MESSAGE_BEFORE_SETUP'
339
+ : 'UNEXPECTED_MESSAGE',
333
340
  `${msgType} requires ready phase, current: ${this._phase}`,
334
341
  this._phase,
335
342
  msgType,
336
- );
343
+ )
337
344
  }
338
- return null;
345
+ return null
339
346
  }
340
347
 
341
348
  // ─── Subscribe lifecycle ──────────────────────────────────────────────────────
342
349
 
343
350
  private handleSubscribe(
344
351
  message: Draft14Message,
345
- _direction: "inbound" | "outbound",
352
+ _direction: 'inbound' | 'outbound',
346
353
  sideEffects: SideEffect[],
347
354
  ): TransitionResult<Draft14MessageType> {
348
- const err = this.requireReady(message.type);
349
- if (err) return { ok: false, violation: err };
355
+ const err = this.requireReady(message.type)
356
+ if (err) return { ok: false, violation: err }
350
357
 
351
- const sub = message as import("./types.js").Draft14Subscribe;
352
- const dupErr = this.checkDuplicateRequestId(sub.request_id, message.type);
353
- if (dupErr) return { ok: false, violation: dupErr };
358
+ const sub = message as import('./types.js').Draft14Subscribe
359
+ const dupErr = this.checkDuplicateRequestId(sub.request_id, message.type)
360
+ if (dupErr) return { ok: false, violation: dupErr }
354
361
 
355
- this._requestIds.add(sub.request_id);
362
+ this._requestIds.add(sub.request_id)
356
363
  this._subscriptions.set(sub.request_id, {
357
364
  subscribeId: sub.request_id,
358
- phase: "pending",
365
+ phase: 'pending',
359
366
  trackNamespace: sub.track_namespace,
360
367
  trackName: sub.track_name,
361
- });
368
+ })
362
369
 
363
- return { ok: true, phase: this._phase, sideEffects };
370
+ return { ok: true, phase: this._phase, sideEffects }
364
371
  }
365
372
 
366
373
  private handleSubscribeOk(
367
374
  message: Draft14Message,
368
- _direction: "inbound" | "outbound",
375
+ _direction: 'inbound' | 'outbound',
369
376
  sideEffects: SideEffect[],
370
377
  ): TransitionResult<Draft14MessageType> {
371
- const err = this.requireReady(message.type);
372
- if (err) return { ok: false, violation: err };
378
+ const err = this.requireReady(message.type)
379
+ if (err) return { ok: false, violation: err }
373
380
 
374
- const ok = message as import("./types.js").Draft14SubscribeOk;
375
- const idErr = this.checkKnownRequestId(ok.request_id, message.type);
376
- if (idErr) return { ok: false, violation: idErr };
381
+ const ok = message as import('./types.js').Draft14SubscribeOk
382
+ const idErr = this.checkKnownRequestId(ok.request_id, message.type)
383
+ if (idErr) return { ok: false, violation: idErr }
377
384
 
378
- const existing = this._subscriptions.get(ok.request_id);
385
+ const existing = this._subscriptions.get(ok.request_id)
379
386
  if (!existing) {
380
387
  return {
381
388
  ok: false,
382
389
  violation: violation(
383
- "UNKNOWN_REQUEST_ID",
390
+ 'UNKNOWN_REQUEST_ID',
384
391
  `No subscription with request ID ${ok.request_id}`,
385
392
  this._phase,
386
393
  message.type,
387
394
  ),
388
- };
395
+ }
389
396
  }
390
- if (existing.phase !== "pending") {
397
+ if (existing.phase !== 'pending') {
391
398
  return {
392
399
  ok: false,
393
400
  violation: violation(
394
- "STATE_VIOLATION",
401
+ 'STATE_VIOLATION',
395
402
  `Subscription ${ok.request_id} is ${existing.phase}, not pending`,
396
403
  this._phase,
397
404
  message.type,
398
405
  ),
399
- };
406
+ }
400
407
  }
401
408
 
402
- this._subscriptions.set(ok.request_id, { ...existing, phase: "active" });
403
- sideEffects.push({ type: "subscription-activated", subscribeId: ok.request_id });
404
- return { ok: true, phase: this._phase, sideEffects };
409
+ this._subscriptions.set(ok.request_id, { ...existing, phase: 'active' })
410
+ sideEffects.push({
411
+ type: 'subscription-activated',
412
+ subscribeId: ok.request_id,
413
+ })
414
+ return { ok: true, phase: this._phase, sideEffects }
405
415
  }
406
416
 
407
417
  private handleSubscribeError(
408
418
  message: Draft14Message,
409
- _direction: "inbound" | "outbound",
419
+ _direction: 'inbound' | 'outbound',
410
420
  sideEffects: SideEffect[],
411
421
  ): TransitionResult<Draft14MessageType> {
412
- const err = this.requireReady(message.type);
413
- if (err) return { ok: false, violation: err };
422
+ const err = this.requireReady(message.type)
423
+ if (err) return { ok: false, violation: err }
414
424
 
415
- const subErr = message as import("./types.js").Draft14SubscribeError;
416
- const idErr = this.checkKnownRequestId(subErr.request_id, message.type);
417
- if (idErr) return { ok: false, violation: idErr };
425
+ const subErr = message as import('./types.js').Draft14SubscribeError
426
+ const idErr = this.checkKnownRequestId(subErr.request_id, message.type)
427
+ if (idErr) return { ok: false, violation: idErr }
418
428
 
419
- const existing = this._subscriptions.get(subErr.request_id);
429
+ const existing = this._subscriptions.get(subErr.request_id)
420
430
  if (!existing) {
421
431
  return {
422
432
  ok: false,
423
433
  violation: violation(
424
- "UNKNOWN_REQUEST_ID",
434
+ 'UNKNOWN_REQUEST_ID',
425
435
  `No subscription with request ID ${subErr.request_id}`,
426
436
  this._phase,
427
437
  message.type,
428
438
  ),
429
- };
439
+ }
430
440
  }
431
- if (existing.phase !== "pending") {
441
+ if (existing.phase !== 'pending') {
432
442
  return {
433
443
  ok: false,
434
444
  violation: violation(
435
- "STATE_VIOLATION",
445
+ 'STATE_VIOLATION',
436
446
  `Subscription ${subErr.request_id} is ${existing.phase}, not pending`,
437
447
  this._phase,
438
448
  message.type,
439
449
  ),
440
- };
450
+ }
441
451
  }
442
452
 
443
- this._subscriptions.set(subErr.request_id, { ...existing, phase: "error" });
453
+ this._subscriptions.set(subErr.request_id, { ...existing, phase: 'error' })
444
454
  sideEffects.push({
445
- type: "subscription-ended",
455
+ type: 'subscription-ended',
446
456
  subscribeId: subErr.request_id,
447
457
  reason: subErr.reason_phrase,
448
- });
449
- return { ok: true, phase: this._phase, sideEffects };
458
+ })
459
+ return { ok: true, phase: this._phase, sideEffects }
450
460
  }
451
461
 
452
462
  private handleSubscribeUpdate(
453
463
  message: Draft14Message,
454
- _direction: "inbound" | "outbound",
464
+ _direction: 'inbound' | 'outbound',
455
465
  sideEffects: SideEffect[],
456
466
  ): TransitionResult<Draft14MessageType> {
457
- const err = this.requireReady(message.type);
458
- if (err) return { ok: false, violation: err };
467
+ const err = this.requireReady(message.type)
468
+ if (err) return { ok: false, violation: err }
459
469
 
460
- const update = message as import("./types.js").Draft14SubscribeUpdate;
461
- const idErr = this.checkKnownRequestId(update.request_id, message.type);
462
- if (idErr) return { ok: false, violation: idErr };
470
+ const update = message as import('./types.js').Draft14SubscribeUpdate
471
+ const idErr = this.checkKnownRequestId(update.request_id, message.type)
472
+ if (idErr) return { ok: false, violation: idErr }
463
473
 
464
- const existing = this._subscriptions.get(update.request_id);
474
+ const existing = this._subscriptions.get(update.request_id)
465
475
  if (!existing) {
466
476
  return {
467
477
  ok: false,
468
478
  violation: violation(
469
- "UNKNOWN_REQUEST_ID",
479
+ 'UNKNOWN_REQUEST_ID',
470
480
  `No subscription with request ID ${update.request_id}`,
471
481
  this._phase,
472
482
  message.type,
473
483
  ),
474
- };
484
+ }
475
485
  }
476
- if (existing.phase !== "active") {
486
+ if (existing.phase !== 'active') {
477
487
  return {
478
488
  ok: false,
479
489
  violation: violation(
480
- "STATE_VIOLATION",
490
+ 'STATE_VIOLATION',
481
491
  `Subscription ${update.request_id} is ${existing.phase}, not active`,
482
492
  this._phase,
483
493
  message.type,
484
494
  ),
485
- };
495
+ }
486
496
  }
487
497
 
488
- return { ok: true, phase: this._phase, sideEffects };
498
+ return { ok: true, phase: this._phase, sideEffects }
489
499
  }
490
500
 
491
501
  private handleUnsubscribe(
492
502
  message: Draft14Message,
493
- _direction: "inbound" | "outbound",
503
+ _direction: 'inbound' | 'outbound',
494
504
  sideEffects: SideEffect[],
495
505
  ): TransitionResult<Draft14MessageType> {
496
- const err = this.requireReady(message.type);
497
- if (err) return { ok: false, violation: err };
506
+ const err = this.requireReady(message.type)
507
+ if (err) return { ok: false, violation: err }
498
508
 
499
- const unsub = message as import("./types.js").Draft14Unsubscribe;
500
- const idErr = this.checkKnownRequestId(unsub.request_id, message.type);
501
- if (idErr) return { ok: false, violation: idErr };
509
+ const unsub = message as import('./types.js').Draft14Unsubscribe
510
+ const idErr = this.checkKnownRequestId(unsub.request_id, message.type)
511
+ if (idErr) return { ok: false, violation: idErr }
502
512
 
503
- const existing = this._subscriptions.get(unsub.request_id);
513
+ const existing = this._subscriptions.get(unsub.request_id)
504
514
  if (!existing) {
505
515
  return {
506
516
  ok: false,
507
517
  violation: violation(
508
- "UNKNOWN_REQUEST_ID",
518
+ 'UNKNOWN_REQUEST_ID',
509
519
  `No subscription with request ID ${unsub.request_id}`,
510
520
  this._phase,
511
521
  message.type,
512
522
  ),
513
- };
523
+ }
514
524
  }
515
525
 
516
- this._subscriptions.set(unsub.request_id, { ...existing, phase: "done" });
526
+ this._subscriptions.set(unsub.request_id, { ...existing, phase: 'done' })
517
527
  sideEffects.push({
518
- type: "subscription-ended",
528
+ type: 'subscription-ended',
519
529
  subscribeId: unsub.request_id,
520
- reason: "unsubscribed",
521
- });
522
- return { ok: true, phase: this._phase, sideEffects };
530
+ reason: 'unsubscribed',
531
+ })
532
+ return { ok: true, phase: this._phase, sideEffects }
523
533
  }
524
534
 
525
535
  // ─── Publish lifecycle ────────────────────────────────────────────────────────
526
536
 
527
537
  private handlePublish(
528
538
  message: Draft14Message,
529
- _direction: "inbound" | "outbound",
539
+ _direction: 'inbound' | 'outbound',
530
540
  sideEffects: SideEffect[],
531
541
  ): TransitionResult<Draft14MessageType> {
532
- const err = this.requireReady(message.type);
533
- if (err) return { ok: false, violation: err };
542
+ const err = this.requireReady(message.type)
543
+ if (err) return { ok: false, violation: err }
534
544
 
535
- const pub = message as import("./types.js").Draft14Publish;
536
- const dupErr = this.checkDuplicateRequestId(pub.request_id, message.type);
537
- if (dupErr) return { ok: false, violation: dupErr };
545
+ const pub = message as import('./types.js').Draft14Publish
546
+ const dupErr = this.checkDuplicateRequestId(pub.request_id, message.type)
547
+ if (dupErr) return { ok: false, violation: dupErr }
538
548
 
539
- this._requestIds.add(pub.request_id);
549
+ this._requestIds.add(pub.request_id)
540
550
  this._publishes.set(pub.request_id, {
541
551
  requestId: pub.request_id,
542
- phase: "pending",
543
- });
552
+ phase: 'pending',
553
+ })
544
554
 
545
- return { ok: true, phase: this._phase, sideEffects };
555
+ return { ok: true, phase: this._phase, sideEffects }
546
556
  }
547
557
 
548
558
  private handlePublishOk(
549
559
  message: Draft14Message,
550
- _direction: "inbound" | "outbound",
560
+ _direction: 'inbound' | 'outbound',
551
561
  sideEffects: SideEffect[],
552
562
  ): TransitionResult<Draft14MessageType> {
553
- const err = this.requireReady(message.type);
554
- if (err) return { ok: false, violation: err };
563
+ const err = this.requireReady(message.type)
564
+ if (err) return { ok: false, violation: err }
555
565
 
556
- const ok = message as import("./types.js").Draft14PublishOk;
557
- const idErr = this.checkKnownRequestId(ok.request_id, message.type);
558
- if (idErr) return { ok: false, violation: idErr };
566
+ const ok = message as import('./types.js').Draft14PublishOk
567
+ const idErr = this.checkKnownRequestId(ok.request_id, message.type)
568
+ if (idErr) return { ok: false, violation: idErr }
559
569
 
560
- const existing = this._publishes.get(ok.request_id);
570
+ const existing = this._publishes.get(ok.request_id)
561
571
  if (!existing) {
562
572
  return {
563
573
  ok: false,
564
574
  violation: violation(
565
- "UNKNOWN_REQUEST_ID",
575
+ 'UNKNOWN_REQUEST_ID',
566
576
  `No publish with request ID ${ok.request_id}`,
567
577
  this._phase,
568
578
  message.type,
569
579
  ),
570
- };
580
+ }
571
581
  }
572
- if (existing.phase !== "pending") {
582
+ if (existing.phase !== 'pending') {
573
583
  return {
574
584
  ok: false,
575
585
  violation: violation(
576
- "STATE_VIOLATION",
586
+ 'STATE_VIOLATION',
577
587
  `Publish ${ok.request_id} is ${existing.phase}, not pending`,
578
588
  this._phase,
579
589
  message.type,
580
590
  ),
581
- };
591
+ }
582
592
  }
583
593
 
584
- this._publishes.set(ok.request_id, { ...existing, phase: "active" });
585
- sideEffects.push({ type: "publish-activated", requestId: ok.request_id });
586
- return { ok: true, phase: this._phase, sideEffects };
594
+ this._publishes.set(ok.request_id, { ...existing, phase: 'active' })
595
+ sideEffects.push({ type: 'publish-activated', requestId: ok.request_id })
596
+ return { ok: true, phase: this._phase, sideEffects }
587
597
  }
588
598
 
589
599
  private handlePublishError(
590
600
  message: Draft14Message,
591
- _direction: "inbound" | "outbound",
601
+ _direction: 'inbound' | 'outbound',
592
602
  sideEffects: SideEffect[],
593
603
  ): TransitionResult<Draft14MessageType> {
594
- const err = this.requireReady(message.type);
595
- if (err) return { ok: false, violation: err };
604
+ const err = this.requireReady(message.type)
605
+ if (err) return { ok: false, violation: err }
596
606
 
597
- const pubErr = message as import("./types.js").Draft14PublishError;
598
- const idErr = this.checkKnownRequestId(pubErr.request_id, message.type);
599
- if (idErr) return { ok: false, violation: idErr };
607
+ const pubErr = message as import('./types.js').Draft14PublishError
608
+ const idErr = this.checkKnownRequestId(pubErr.request_id, message.type)
609
+ if (idErr) return { ok: false, violation: idErr }
600
610
 
601
- const existing = this._publishes.get(pubErr.request_id);
611
+ const existing = this._publishes.get(pubErr.request_id)
602
612
  if (!existing) {
603
613
  return {
604
614
  ok: false,
605
615
  violation: violation(
606
- "UNKNOWN_REQUEST_ID",
616
+ 'UNKNOWN_REQUEST_ID',
607
617
  `No publish with request ID ${pubErr.request_id}`,
608
618
  this._phase,
609
619
  message.type,
610
620
  ),
611
- };
621
+ }
612
622
  }
613
- if (existing.phase !== "pending") {
623
+ if (existing.phase !== 'pending') {
614
624
  return {
615
625
  ok: false,
616
626
  violation: violation(
617
- "STATE_VIOLATION",
627
+ 'STATE_VIOLATION',
618
628
  `Publish ${pubErr.request_id} is ${existing.phase}, not pending`,
619
629
  this._phase,
620
630
  message.type,
621
631
  ),
622
- };
632
+ }
623
633
  }
624
634
 
625
- this._publishes.set(pubErr.request_id, { ...existing, phase: "error" });
635
+ this._publishes.set(pubErr.request_id, { ...existing, phase: 'error' })
626
636
  sideEffects.push({
627
- type: "publish-ended",
637
+ type: 'publish-ended',
628
638
  requestId: pubErr.request_id,
629
639
  reason: pubErr.reason_phrase,
630
- });
631
- return { ok: true, phase: this._phase, sideEffects };
640
+ })
641
+ return { ok: true, phase: this._phase, sideEffects }
632
642
  }
633
643
 
634
644
  private handlePublishDone(
635
645
  message: Draft14Message,
636
- _direction: "inbound" | "outbound",
646
+ _direction: 'inbound' | 'outbound',
637
647
  sideEffects: SideEffect[],
638
648
  ): TransitionResult<Draft14MessageType> {
639
- const err = this.requireReady(message.type);
640
- if (err) return { ok: false, violation: err };
649
+ const err = this.requireReady(message.type)
650
+ if (err) return { ok: false, violation: err }
641
651
 
642
- const done = message as import("./types.js").Draft14PublishDone;
643
- const idErr = this.checkKnownRequestId(done.request_id, message.type);
644
- if (idErr) return { ok: false, violation: idErr };
652
+ const done = message as import('./types.js').Draft14PublishDone
653
+ const idErr = this.checkKnownRequestId(done.request_id, message.type)
654
+ if (idErr) return { ok: false, violation: idErr }
645
655
 
646
- const existing = this._publishes.get(done.request_id);
656
+ const existing = this._publishes.get(done.request_id)
647
657
  if (!existing) {
648
658
  return {
649
659
  ok: false,
650
660
  violation: violation(
651
- "UNKNOWN_REQUEST_ID",
661
+ 'UNKNOWN_REQUEST_ID',
652
662
  `No publish with request ID ${done.request_id}`,
653
663
  this._phase,
654
664
  message.type,
655
665
  ),
656
- };
666
+ }
657
667
  }
658
668
 
659
- this._publishes.set(done.request_id, { ...existing, phase: "done" });
669
+ this._publishes.set(done.request_id, { ...existing, phase: 'done' })
660
670
  sideEffects.push({
661
- type: "publish-ended",
671
+ type: 'publish-ended',
662
672
  requestId: done.request_id,
663
673
  reason: done.reason_phrase,
664
- });
665
- return { ok: true, phase: this._phase, sideEffects };
674
+ })
675
+ return { ok: true, phase: this._phase, sideEffects }
666
676
  }
667
677
 
668
678
  // ─── Fetch lifecycle ──────────────────────────────────────────────────────────
669
679
 
670
680
  private handleFetch(
671
681
  message: Draft14Message,
672
- _direction: "inbound" | "outbound",
682
+ _direction: 'inbound' | 'outbound',
673
683
  sideEffects: SideEffect[],
674
684
  ): TransitionResult<Draft14MessageType> {
675
- const err = this.requireReady(message.type);
676
- if (err) return { ok: false, violation: err };
685
+ const err = this.requireReady(message.type)
686
+ if (err) return { ok: false, violation: err }
677
687
 
678
- const fetch = message as import("./types.js").Draft14Fetch;
679
- const dupErr = this.checkDuplicateRequestId(fetch.request_id, message.type);
680
- if (dupErr) return { ok: false, violation: dupErr };
688
+ const fetch = message as import('./types.js').Draft14Fetch
689
+ const dupErr = this.checkDuplicateRequestId(fetch.request_id, message.type)
690
+ if (dupErr) return { ok: false, violation: dupErr }
681
691
 
682
- this._requestIds.add(fetch.request_id);
692
+ this._requestIds.add(fetch.request_id)
683
693
  this._fetches.set(fetch.request_id, {
684
694
  requestId: fetch.request_id,
685
- phase: "pending",
686
- });
695
+ phase: 'pending',
696
+ })
687
697
 
688
- return { ok: true, phase: this._phase, sideEffects };
698
+ return { ok: true, phase: this._phase, sideEffects }
689
699
  }
690
700
 
691
701
  private handleFetchOk(
692
702
  message: Draft14Message,
693
- _direction: "inbound" | "outbound",
703
+ _direction: 'inbound' | 'outbound',
694
704
  sideEffects: SideEffect[],
695
705
  ): TransitionResult<Draft14MessageType> {
696
- const err = this.requireReady(message.type);
697
- if (err) return { ok: false, violation: err };
706
+ const err = this.requireReady(message.type)
707
+ if (err) return { ok: false, violation: err }
698
708
 
699
- const ok = message as import("./types.js").Draft14FetchOk;
700
- const idErr = this.checkKnownRequestId(ok.request_id, message.type);
701
- if (idErr) return { ok: false, violation: idErr };
709
+ const ok = message as import('./types.js').Draft14FetchOk
710
+ const idErr = this.checkKnownRequestId(ok.request_id, message.type)
711
+ if (idErr) return { ok: false, violation: idErr }
702
712
 
703
- const existing = this._fetches.get(ok.request_id);
713
+ const existing = this._fetches.get(ok.request_id)
704
714
  if (!existing) {
705
715
  return {
706
716
  ok: false,
707
717
  violation: violation(
708
- "UNKNOWN_REQUEST_ID",
718
+ 'UNKNOWN_REQUEST_ID',
709
719
  `No fetch with request ID ${ok.request_id}`,
710
720
  this._phase,
711
721
  message.type,
712
722
  ),
713
- };
723
+ }
714
724
  }
715
- if (existing.phase !== "pending") {
725
+ if (existing.phase !== 'pending') {
716
726
  return {
717
727
  ok: false,
718
728
  violation: violation(
719
- "STATE_VIOLATION",
729
+ 'STATE_VIOLATION',
720
730
  `Fetch ${ok.request_id} is ${existing.phase}, not pending`,
721
731
  this._phase,
722
732
  message.type,
723
733
  ),
724
- };
734
+ }
725
735
  }
726
736
 
727
- this._fetches.set(ok.request_id, { ...existing, phase: "active" });
728
- sideEffects.push({ type: "fetch-activated", requestId: ok.request_id });
729
- return { ok: true, phase: this._phase, sideEffects };
737
+ this._fetches.set(ok.request_id, { ...existing, phase: 'active' })
738
+ sideEffects.push({ type: 'fetch-activated', requestId: ok.request_id })
739
+ return { ok: true, phase: this._phase, sideEffects }
730
740
  }
731
741
 
732
742
  private handleFetchError(
733
743
  message: Draft14Message,
734
- _direction: "inbound" | "outbound",
744
+ _direction: 'inbound' | 'outbound',
735
745
  sideEffects: SideEffect[],
736
746
  ): TransitionResult<Draft14MessageType> {
737
- const err = this.requireReady(message.type);
738
- if (err) return { ok: false, violation: err };
747
+ const err = this.requireReady(message.type)
748
+ if (err) return { ok: false, violation: err }
739
749
 
740
- const fetchErr = message as import("./types.js").Draft14FetchError;
741
- const idErr = this.checkKnownRequestId(fetchErr.request_id, message.type);
742
- if (idErr) return { ok: false, violation: idErr };
750
+ const fetchErr = message as import('./types.js').Draft14FetchError
751
+ const idErr = this.checkKnownRequestId(fetchErr.request_id, message.type)
752
+ if (idErr) return { ok: false, violation: idErr }
743
753
 
744
- const existing = this._fetches.get(fetchErr.request_id);
754
+ const existing = this._fetches.get(fetchErr.request_id)
745
755
  if (!existing) {
746
756
  return {
747
757
  ok: false,
748
758
  violation: violation(
749
- "UNKNOWN_REQUEST_ID",
759
+ 'UNKNOWN_REQUEST_ID',
750
760
  `No fetch with request ID ${fetchErr.request_id}`,
751
761
  this._phase,
752
762
  message.type,
753
763
  ),
754
- };
764
+ }
755
765
  }
756
- if (existing.phase !== "pending") {
766
+ if (existing.phase !== 'pending') {
757
767
  return {
758
768
  ok: false,
759
769
  violation: violation(
760
- "STATE_VIOLATION",
770
+ 'STATE_VIOLATION',
761
771
  `Fetch ${fetchErr.request_id} is ${existing.phase}, not pending`,
762
772
  this._phase,
763
773
  message.type,
764
774
  ),
765
- };
775
+ }
766
776
  }
767
777
 
768
- this._fetches.set(fetchErr.request_id, { ...existing, phase: "error" });
778
+ this._fetches.set(fetchErr.request_id, { ...existing, phase: 'error' })
769
779
  sideEffects.push({
770
- type: "fetch-ended",
780
+ type: 'fetch-ended',
771
781
  requestId: fetchErr.request_id,
772
782
  reason: fetchErr.reason_phrase,
773
- });
774
- return { ok: true, phase: this._phase, sideEffects };
783
+ })
784
+ return { ok: true, phase: this._phase, sideEffects }
775
785
  }
776
786
 
777
787
  private handleFetchCancel(
778
788
  message: Draft14Message,
779
- _direction: "inbound" | "outbound",
789
+ _direction: 'inbound' | 'outbound',
780
790
  sideEffects: SideEffect[],
781
791
  ): TransitionResult<Draft14MessageType> {
782
- const err = this.requireReady(message.type);
783
- if (err) return { ok: false, violation: err };
792
+ const err = this.requireReady(message.type)
793
+ if (err) return { ok: false, violation: err }
784
794
 
785
- const cancel = message as import("./types.js").Draft14FetchCancel;
786
- const idErr = this.checkKnownRequestId(cancel.request_id, message.type);
787
- if (idErr) return { ok: false, violation: idErr };
795
+ const cancel = message as import('./types.js').Draft14FetchCancel
796
+ const idErr = this.checkKnownRequestId(cancel.request_id, message.type)
797
+ if (idErr) return { ok: false, violation: idErr }
788
798
 
789
- const existing = this._fetches.get(cancel.request_id);
799
+ const existing = this._fetches.get(cancel.request_id)
790
800
  if (!existing) {
791
801
  return {
792
802
  ok: false,
793
803
  violation: violation(
794
- "UNKNOWN_REQUEST_ID",
804
+ 'UNKNOWN_REQUEST_ID',
795
805
  `No fetch with request ID ${cancel.request_id}`,
796
806
  this._phase,
797
807
  message.type,
798
808
  ),
799
- };
809
+ }
800
810
  }
801
811
 
802
- this._fetches.set(cancel.request_id, { ...existing, phase: "cancelled" });
803
- sideEffects.push({ type: "fetch-ended", requestId: cancel.request_id, reason: "cancelled" });
804
- return { ok: true, phase: this._phase, sideEffects };
812
+ this._fetches.set(cancel.request_id, { ...existing, phase: 'cancelled' })
813
+ sideEffects.push({
814
+ type: 'fetch-ended',
815
+ requestId: cancel.request_id,
816
+ reason: 'cancelled',
817
+ })
818
+ return { ok: true, phase: this._phase, sideEffects }
805
819
  }
806
820
 
807
821
  // ─── Publish namespace lifecycle ──────────────────────────────────────────────
@@ -810,61 +824,57 @@ export class Draft14SessionFSM {
810
824
  message: Draft14Message,
811
825
  sideEffects: SideEffect[],
812
826
  ): TransitionResult<Draft14MessageType> {
813
- const err = this.requireReady(message.type);
814
- if (err) return { ok: false, violation: err };
815
- const pn = message as import("./types.js").Draft14PublishNamespace;
816
- const dupErr = this.checkDuplicateRequestId(pn.request_id, message.type);
817
- if (dupErr) return { ok: false, violation: dupErr };
818
- this._requestIds.add(pn.request_id);
819
- return { ok: true, phase: this._phase, sideEffects };
827
+ const err = this.requireReady(message.type)
828
+ if (err) return { ok: false, violation: err }
829
+ const pn = message as import('./types.js').Draft14PublishNamespace
830
+ const dupErr = this.checkDuplicateRequestId(pn.request_id, message.type)
831
+ if (dupErr) return { ok: false, violation: dupErr }
832
+ this._requestIds.add(pn.request_id)
833
+ return { ok: true, phase: this._phase, sideEffects }
820
834
  }
821
835
 
822
836
  private handlePublishNamespaceOk(
823
837
  message: Draft14Message,
824
838
  sideEffects: SideEffect[],
825
839
  ): TransitionResult<Draft14MessageType> {
826
- const err = this.requireReady(message.type);
827
- if (err) return { ok: false, violation: err };
828
- const ok = message as import("./types.js").Draft14PublishNamespaceOk;
829
- const idErr = this.checkKnownRequestId(ok.request_id, message.type);
830
- if (idErr) return { ok: false, violation: idErr };
831
- return { ok: true, phase: this._phase, sideEffects };
840
+ const err = this.requireReady(message.type)
841
+ if (err) return { ok: false, violation: err }
842
+ const ok = message as import('./types.js').Draft14PublishNamespaceOk
843
+ const idErr = this.checkKnownRequestId(ok.request_id, message.type)
844
+ if (idErr) return { ok: false, violation: idErr }
845
+ return { ok: true, phase: this._phase, sideEffects }
832
846
  }
833
847
 
834
848
  private handlePublishNamespaceError(
835
849
  message: Draft14Message,
836
850
  sideEffects: SideEffect[],
837
851
  ): TransitionResult<Draft14MessageType> {
838
- const err = this.requireReady(message.type);
839
- if (err) return { ok: false, violation: err };
840
- const pnErr = message as import("./types.js").Draft14PublishNamespaceError;
841
- const idErr = this.checkKnownRequestId(pnErr.request_id, message.type);
842
- if (idErr) return { ok: false, violation: idErr };
843
- return { ok: true, phase: this._phase, sideEffects };
852
+ const err = this.requireReady(message.type)
853
+ if (err) return { ok: false, violation: err }
854
+ const pnErr = message as import('./types.js').Draft14PublishNamespaceError
855
+ const idErr = this.checkKnownRequestId(pnErr.request_id, message.type)
856
+ if (idErr) return { ok: false, violation: idErr }
857
+ return { ok: true, phase: this._phase, sideEffects }
844
858
  }
845
859
 
846
860
  private handlePublishNamespaceDone(
847
861
  message: Draft14Message,
848
862
  sideEffects: SideEffect[],
849
863
  ): TransitionResult<Draft14MessageType> {
850
- const err = this.requireReady(message.type);
851
- if (err) return { ok: false, violation: err };
852
- const done = message as import("./types.js").Draft14PublishNamespaceDone;
853
- const idErr = this.checkKnownRequestId(done.request_id, message.type);
854
- if (idErr) return { ok: false, violation: idErr };
855
- return { ok: true, phase: this._phase, sideEffects };
864
+ const err = this.requireReady(message.type)
865
+ if (err) return { ok: false, violation: err }
866
+ // PublishNamespaceDone carries only track_namespace, no request_id
867
+ return { ok: true, phase: this._phase, sideEffects }
856
868
  }
857
869
 
858
870
  private handlePublishNamespaceCancel(
859
871
  message: Draft14Message,
860
872
  sideEffects: SideEffect[],
861
873
  ): TransitionResult<Draft14MessageType> {
862
- const err = this.requireReady(message.type);
863
- if (err) return { ok: false, violation: err };
864
- const cancel = message as import("./types.js").Draft14PublishNamespaceCancel;
865
- const idErr = this.checkKnownRequestId(cancel.request_id, message.type);
866
- if (idErr) return { ok: false, violation: idErr };
867
- return { ok: true, phase: this._phase, sideEffects };
874
+ const err = this.requireReady(message.type)
875
+ if (err) return { ok: false, violation: err }
876
+ // PublishNamespaceCancel carries track_namespace + error_code, no request_id
877
+ return { ok: true, phase: this._phase, sideEffects }
868
878
  }
869
879
 
870
880
  // ─── Subscribe namespace lifecycle ──────────────────────────────────────────────
@@ -873,47 +883,47 @@ export class Draft14SessionFSM {
873
883
  message: Draft14Message,
874
884
  sideEffects: SideEffect[],
875
885
  ): TransitionResult<Draft14MessageType> {
876
- const err = this.requireReady(message.type);
877
- if (err) return { ok: false, violation: err };
878
- const sn = message as import("./types.js").Draft14SubscribeNamespace;
879
- const dupErr = this.checkDuplicateRequestId(sn.request_id, message.type);
880
- if (dupErr) return { ok: false, violation: dupErr };
881
- this._requestIds.add(sn.request_id);
882
- return { ok: true, phase: this._phase, sideEffects };
886
+ const err = this.requireReady(message.type)
887
+ if (err) return { ok: false, violation: err }
888
+ const sn = message as import('./types.js').Draft14SubscribeNamespace
889
+ const dupErr = this.checkDuplicateRequestId(sn.request_id, message.type)
890
+ if (dupErr) return { ok: false, violation: dupErr }
891
+ this._requestIds.add(sn.request_id)
892
+ return { ok: true, phase: this._phase, sideEffects }
883
893
  }
884
894
 
885
895
  private handleSubscribeNamespaceOk(
886
896
  message: Draft14Message,
887
897
  sideEffects: SideEffect[],
888
898
  ): TransitionResult<Draft14MessageType> {
889
- const err = this.requireReady(message.type);
890
- if (err) return { ok: false, violation: err };
891
- const ok = message as import("./types.js").Draft14SubscribeNamespaceOk;
892
- const idErr = this.checkKnownRequestId(ok.request_id, message.type);
893
- if (idErr) return { ok: false, violation: idErr };
894
- return { ok: true, phase: this._phase, sideEffects };
899
+ const err = this.requireReady(message.type)
900
+ if (err) return { ok: false, violation: err }
901
+ const ok = message as import('./types.js').Draft14SubscribeNamespaceOk
902
+ const idErr = this.checkKnownRequestId(ok.request_id, message.type)
903
+ if (idErr) return { ok: false, violation: idErr }
904
+ return { ok: true, phase: this._phase, sideEffects }
895
905
  }
896
906
 
897
907
  private handleSubscribeNamespaceError(
898
908
  message: Draft14Message,
899
909
  sideEffects: SideEffect[],
900
910
  ): TransitionResult<Draft14MessageType> {
901
- const err = this.requireReady(message.type);
902
- if (err) return { ok: false, violation: err };
903
- const snErr = message as import("./types.js").Draft14SubscribeNamespaceError;
904
- const idErr = this.checkKnownRequestId(snErr.request_id, message.type);
905
- if (idErr) return { ok: false, violation: idErr };
906
- return { ok: true, phase: this._phase, sideEffects };
911
+ const err = this.requireReady(message.type)
912
+ if (err) return { ok: false, violation: err }
913
+ const snErr = message as import('./types.js').Draft14SubscribeNamespaceError
914
+ const idErr = this.checkKnownRequestId(snErr.request_id, message.type)
915
+ if (idErr) return { ok: false, violation: idErr }
916
+ return { ok: true, phase: this._phase, sideEffects }
907
917
  }
908
918
 
909
919
  private handleUnsubscribeNamespace(
910
920
  message: Draft14Message,
911
921
  sideEffects: SideEffect[],
912
922
  ): TransitionResult<Draft14MessageType> {
913
- const err = this.requireReady(message.type);
914
- if (err) return { ok: false, violation: err };
923
+ const err = this.requireReady(message.type)
924
+ if (err) return { ok: false, violation: err }
915
925
  // unsubscribe_namespace has no request_id — namespace-based
916
- return { ok: true, phase: this._phase, sideEffects };
926
+ return { ok: true, phase: this._phase, sideEffects }
917
927
  }
918
928
 
919
929
  // ─── Track status lifecycle ──────────────────────────────────────────────────
@@ -922,52 +932,52 @@ export class Draft14SessionFSM {
922
932
  message: Draft14Message,
923
933
  sideEffects: SideEffect[],
924
934
  ): TransitionResult<Draft14MessageType> {
925
- const err = this.requireReady(message.type);
926
- if (err) return { ok: false, violation: err };
927
- const ts = message as import("./types.js").Draft14TrackStatus;
928
- const dupErr = this.checkDuplicateRequestId(ts.request_id, message.type);
929
- if (dupErr) return { ok: false, violation: dupErr };
930
- this._requestIds.add(ts.request_id);
931
- return { ok: true, phase: this._phase, sideEffects };
935
+ const err = this.requireReady(message.type)
936
+ if (err) return { ok: false, violation: err }
937
+ const ts = message as import('./types.js').Draft14TrackStatus
938
+ const dupErr = this.checkDuplicateRequestId(ts.request_id, message.type)
939
+ if (dupErr) return { ok: false, violation: dupErr }
940
+ this._requestIds.add(ts.request_id)
941
+ return { ok: true, phase: this._phase, sideEffects }
932
942
  }
933
943
 
934
944
  private handleTrackStatusOk(
935
945
  message: Draft14Message,
936
946
  sideEffects: SideEffect[],
937
947
  ): TransitionResult<Draft14MessageType> {
938
- const err = this.requireReady(message.type);
939
- if (err) return { ok: false, violation: err };
940
- const ok = message as import("./types.js").Draft14TrackStatusOk;
941
- const idErr = this.checkKnownRequestId(ok.request_id, message.type);
942
- if (idErr) return { ok: false, violation: idErr };
943
- return { ok: true, phase: this._phase, sideEffects };
948
+ const err = this.requireReady(message.type)
949
+ if (err) return { ok: false, violation: err }
950
+ const ok = message as import('./types.js').Draft14TrackStatusOk
951
+ const idErr = this.checkKnownRequestId(ok.request_id, message.type)
952
+ if (idErr) return { ok: false, violation: idErr }
953
+ return { ok: true, phase: this._phase, sideEffects }
944
954
  }
945
955
 
946
956
  private handleTrackStatusError(
947
957
  message: Draft14Message,
948
958
  sideEffects: SideEffect[],
949
959
  ): TransitionResult<Draft14MessageType> {
950
- const err = this.requireReady(message.type);
951
- if (err) return { ok: false, violation: err };
952
- const tsErr = message as import("./types.js").Draft14TrackStatusError;
953
- const idErr = this.checkKnownRequestId(tsErr.request_id, message.type);
954
- if (idErr) return { ok: false, violation: idErr };
955
- return { ok: true, phase: this._phase, sideEffects };
960
+ const err = this.requireReady(message.type)
961
+ if (err) return { ok: false, violation: err }
962
+ const tsErr = message as import('./types.js').Draft14TrackStatusError
963
+ const idErr = this.checkKnownRequestId(tsErr.request_id, message.type)
964
+ if (idErr) return { ok: false, violation: idErr }
965
+ return { ok: true, phase: this._phase, sideEffects }
956
966
  }
957
967
 
958
968
  // ─── Generic ready-phase handler ──────────────────────────────────────────────
959
969
 
960
970
  private handleReadyPhaseMessage(message: Draft14Message): TransitionResult<Draft14MessageType> {
961
- const err = this.requireReady(message.type);
962
- if (err) return { ok: false, violation: err };
963
- return { ok: true, phase: this._phase, sideEffects: [] };
971
+ const err = this.requireReady(message.type)
972
+ if (err) return { ok: false, violation: err }
973
+ return { ok: true, phase: this._phase, sideEffects: [] }
964
974
  }
965
975
 
966
976
  reset(): void {
967
- this._phase = "idle";
968
- this._subscriptions.clear();
969
- this._publishes.clear();
970
- this._fetches.clear();
971
- this._requestIds.clear();
977
+ this._phase = 'idle'
978
+ this._subscriptions.clear()
979
+ this._publishes.clear()
980
+ this._fetches.clear()
981
+ this._requestIds.clear()
972
982
  }
973
983
  }