@norskvideo/moq-net 0.1.2 → 0.1.4

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 (310) hide show
  1. package/README.md +1 -0
  2. package/announced.d.ts +111 -21
  3. package/announced.d.ts.map +1 -1
  4. package/announced.js +213 -40
  5. package/announced.js.map +1 -1
  6. package/broadcast.d.ts +80 -25
  7. package/broadcast.d.ts.map +1 -1
  8. package/broadcast.js +270 -49
  9. package/broadcast.js.map +1 -1
  10. package/connection/accept.d.ts +6 -0
  11. package/connection/accept.d.ts.map +1 -1
  12. package/connection/accept.js +42 -13
  13. package/connection/accept.js.map +1 -1
  14. package/connection/browser.d.ts +5 -0
  15. package/connection/browser.d.ts.map +1 -0
  16. package/connection/browser.js +31 -0
  17. package/connection/browser.js.map +1 -0
  18. package/connection/connect.d.ts +43 -1
  19. package/connection/connect.d.ts.map +1 -1
  20. package/connection/connect.js +118 -123
  21. package/connection/connect.js.map +1 -1
  22. package/connection/established.d.ts +43 -16
  23. package/connection/established.d.ts.map +1 -1
  24. package/connection/established.js.map +1 -1
  25. package/connection/handshake.d.ts +12 -1
  26. package/connection/handshake.d.ts.map +1 -1
  27. package/connection/handshake.js +30 -14
  28. package/connection/handshake.js.map +1 -1
  29. package/connection/index.d.ts +8 -0
  30. package/connection/index.d.ts.map +1 -1
  31. package/connection/index.js +6 -0
  32. package/connection/index.js.map +1 -1
  33. package/connection/reload.d.ts +66 -9
  34. package/connection/reload.d.ts.map +1 -1
  35. package/connection/reload.js +192 -66
  36. package/connection/reload.js.map +1 -1
  37. package/connection/stats.d.ts +92 -0
  38. package/connection/stats.d.ts.map +1 -0
  39. package/connection/stats.js +35 -0
  40. package/connection/stats.js.map +1 -0
  41. package/connection/transport.d.ts +10 -0
  42. package/connection/transport.d.ts.map +1 -0
  43. package/connection/transport.js +12 -0
  44. package/connection/transport.js.map +1 -0
  45. package/consume.d.ts +44 -0
  46. package/consume.d.ts.map +1 -0
  47. package/consume.js +60 -0
  48. package/consume.js.map +1 -0
  49. package/datagram.d.ts +23 -0
  50. package/datagram.d.ts.map +1 -0
  51. package/datagram.js +3 -0
  52. package/datagram.js.map +1 -0
  53. package/error.d.ts +76 -0
  54. package/error.d.ts.map +1 -0
  55. package/error.js +107 -0
  56. package/error.js.map +1 -0
  57. package/group.d.ts +143 -38
  58. package/group.d.ts.map +1 -1
  59. package/group.js +270 -68
  60. package/group.js.map +1 -1
  61. package/ietf/adapter.d.ts +2 -2
  62. package/ietf/adapter.d.ts.map +1 -1
  63. package/ietf/adapter.js +20 -10
  64. package/ietf/adapter.js.map +1 -1
  65. package/ietf/aliases.d.ts +73 -5
  66. package/ietf/aliases.d.ts.map +1 -1
  67. package/ietf/aliases.js +121 -14
  68. package/ietf/aliases.js.map +1 -1
  69. package/ietf/cluster.d.ts +141 -0
  70. package/ietf/cluster.d.ts.map +1 -0
  71. package/ietf/cluster.js +204 -0
  72. package/ietf/cluster.js.map +1 -0
  73. package/ietf/connection.d.ts +39 -6
  74. package/ietf/connection.d.ts.map +1 -1
  75. package/ietf/connection.js +73 -12
  76. package/ietf/connection.js.map +1 -1
  77. package/ietf/fetch.d.ts +17 -0
  78. package/ietf/fetch.d.ts.map +1 -1
  79. package/ietf/fetch.js +21 -0
  80. package/ietf/fetch.js.map +1 -1
  81. package/ietf/filter.d.ts +87 -0
  82. package/ietf/filter.d.ts.map +1 -0
  83. package/ietf/filter.js +292 -0
  84. package/ietf/filter.js.map +1 -0
  85. package/ietf/index.d.ts +2 -0
  86. package/ietf/index.d.ts.map +1 -1
  87. package/ietf/index.js +3 -0
  88. package/ietf/index.js.map +1 -1
  89. package/ietf/namespace.d.ts +6 -0
  90. package/ietf/namespace.d.ts.map +1 -1
  91. package/ietf/namespace.js +27 -2
  92. package/ietf/namespace.js.map +1 -1
  93. package/ietf/object.d.ts +54 -6
  94. package/ietf/object.d.ts.map +1 -1
  95. package/ietf/object.js +178 -25
  96. package/ietf/object.js.map +1 -1
  97. package/ietf/parameters.d.ts +35 -10
  98. package/ietf/parameters.d.ts.map +1 -1
  99. package/ietf/parameters.js +236 -45
  100. package/ietf/parameters.js.map +1 -1
  101. package/ietf/priority.d.ts +5 -0
  102. package/ietf/priority.d.ts.map +1 -0
  103. package/ietf/priority.js +10 -0
  104. package/ietf/priority.js.map +1 -0
  105. package/ietf/properties.d.ts +13 -2
  106. package/ietf/properties.d.ts.map +1 -1
  107. package/ietf/properties.js +65 -8
  108. package/ietf/properties.js.map +1 -1
  109. package/ietf/publish.d.ts.map +1 -1
  110. package/ietf/publish.js +13 -3
  111. package/ietf/publish.js.map +1 -1
  112. package/ietf/publish_namespace.d.ts +16 -2
  113. package/ietf/publish_namespace.d.ts.map +1 -1
  114. package/ietf/publish_namespace.js +25 -6
  115. package/ietf/publish_namespace.js.map +1 -1
  116. package/ietf/publisher.d.ts +40 -7
  117. package/ietf/publisher.d.ts.map +1 -1
  118. package/ietf/publisher.js +751 -134
  119. package/ietf/publisher.js.map +1 -1
  120. package/ietf/request.js +1 -1
  121. package/ietf/request.js.map +1 -1
  122. package/ietf/solicit.d.ts +41 -0
  123. package/ietf/solicit.d.ts.map +1 -0
  124. package/ietf/solicit.js +47 -0
  125. package/ietf/solicit.js.map +1 -0
  126. package/ietf/subscribe.d.ts +41 -2
  127. package/ietf/subscribe.d.ts.map +1 -1
  128. package/ietf/subscribe.js +103 -22
  129. package/ietf/subscribe.js.map +1 -1
  130. package/ietf/subscribe_namespace.d.ts +21 -7
  131. package/ietf/subscribe_namespace.d.ts.map +1 -1
  132. package/ietf/subscribe_namespace.js +31 -14
  133. package/ietf/subscribe_namespace.js.map +1 -1
  134. package/ietf/subscriber.d.ts +20 -7
  135. package/ietf/subscriber.d.ts.map +1 -1
  136. package/ietf/subscriber.js +512 -142
  137. package/ietf/subscriber.js.map +1 -1
  138. package/ietf/version.d.ts +7 -1
  139. package/ietf/version.d.ts.map +1 -1
  140. package/ietf/version.js +7 -0
  141. package/ietf/version.js.map +1 -1
  142. package/index.d.ts +10 -5
  143. package/index.d.ts.map +1 -1
  144. package/index.js +10 -5
  145. package/index.js.map +1 -1
  146. package/internal.d.ts +29 -0
  147. package/internal.d.ts.map +1 -0
  148. package/internal.js +8 -0
  149. package/internal.js.map +1 -0
  150. package/lite/announce.d.ts +62 -15
  151. package/lite/announce.d.ts.map +1 -1
  152. package/lite/announce.js +230 -94
  153. package/lite/announce.js.map +1 -1
  154. package/lite/connection.d.ts +69 -20
  155. package/lite/connection.d.ts.map +1 -1
  156. package/lite/connection.js +128 -81
  157. package/lite/connection.js.map +1 -1
  158. package/lite/datagram.d.ts +23 -0
  159. package/lite/datagram.d.ts.map +1 -0
  160. package/lite/datagram.js +57 -0
  161. package/lite/datagram.js.map +1 -0
  162. package/lite/datagram_stream.d.ts +8 -0
  163. package/lite/datagram_stream.d.ts.map +1 -0
  164. package/lite/datagram_stream.js +44 -0
  165. package/lite/datagram_stream.js.map +1 -0
  166. package/lite/fetch.d.ts.map +1 -1
  167. package/lite/fetch.js +2 -2
  168. package/lite/fetch.js.map +1 -1
  169. package/lite/index.d.ts +3 -0
  170. package/lite/index.d.ts.map +1 -1
  171. package/lite/index.js +3 -0
  172. package/lite/index.js.map +1 -1
  173. package/lite/priority.d.ts +67 -0
  174. package/lite/priority.d.ts.map +1 -0
  175. package/lite/priority.js +114 -0
  176. package/lite/priority.js.map +1 -0
  177. package/lite/probe.d.ts +18 -2
  178. package/lite/probe.d.ts.map +1 -1
  179. package/lite/probe.js +24 -22
  180. package/lite/probe.js.map +1 -1
  181. package/lite/publisher.d.ts +14 -7
  182. package/lite/publisher.d.ts.map +1 -1
  183. package/lite/publisher.js +406 -84
  184. package/lite/publisher.js.map +1 -1
  185. package/lite/setup.d.ts +83 -6
  186. package/lite/setup.d.ts.map +1 -1
  187. package/lite/setup.js +203 -31
  188. package/lite/setup.js.map +1 -1
  189. package/lite/stream.d.ts +12 -3
  190. package/lite/stream.d.ts.map +1 -1
  191. package/lite/stream.js +7 -4
  192. package/lite/stream.js.map +1 -1
  193. package/lite/subscribe.d.ts +37 -23
  194. package/lite/subscribe.d.ts.map +1 -1
  195. package/lite/subscribe.js +70 -55
  196. package/lite/subscribe.js.map +1 -1
  197. package/lite/subscriber.d.ts +29 -23
  198. package/lite/subscriber.d.ts.map +1 -1
  199. package/lite/subscriber.js +689 -112
  200. package/lite/subscriber.js.map +1 -1
  201. package/lite/track.d.ts +25 -13
  202. package/lite/track.d.ts.map +1 -1
  203. package/lite/track.js +60 -35
  204. package/lite/track.js.map +1 -1
  205. package/lite/version.d.ts +39 -4
  206. package/lite/version.d.ts.map +1 -1
  207. package/lite/version.js +139 -17
  208. package/lite/version.js.map +1 -1
  209. package/mock.d.ts +53 -3
  210. package/mock.d.ts.map +1 -1
  211. package/mock.js +110 -21
  212. package/mock.js.map +1 -1
  213. package/{lite/origin.d.ts → origin.d.ts} +25 -1
  214. package/origin.d.ts.map +1 -0
  215. package/{lite/origin.js → origin.js} +25 -1
  216. package/origin.js.map +1 -0
  217. package/package.json +6 -4
  218. package/path.d.ts +67 -0
  219. package/path.d.ts.map +1 -1
  220. package/path.js +128 -0
  221. package/path.js.map +1 -1
  222. package/stream.d.ts +94 -4
  223. package/stream.d.ts.map +1 -1
  224. package/stream.js +128 -17
  225. package/stream.js.map +1 -1
  226. package/time.d.ts +109 -86
  227. package/time.d.ts.map +1 -1
  228. package/time.js +80 -30
  229. package/time.js.map +1 -1
  230. package/track.d.ts +298 -47
  231. package/track.d.ts.map +1 -1
  232. package/track.js +721 -109
  233. package/track.js.map +1 -1
  234. package/util/timeout.d.ts +5 -0
  235. package/util/timeout.d.ts.map +1 -0
  236. package/util/timeout.js +18 -0
  237. package/util/timeout.js.map +1 -0
  238. package/util/utf8.d.ts +3 -0
  239. package/util/utf8.d.ts.map +1 -0
  240. package/util/utf8.js +7 -0
  241. package/util/utf8.js.map +1 -0
  242. package/varint.d.ts +14 -3
  243. package/varint.d.ts.map +1 -1
  244. package/varint.js +23 -12
  245. package/varint.js.map +1 -1
  246. package/zod.d.ts +5 -5
  247. package/zod.d.ts.map +1 -1
  248. package/zod.js.map +1 -1
  249. package/bandwidth.d.ts +0 -11
  250. package/bandwidth.d.ts.map +0 -1
  251. package/bandwidth.js +0 -7
  252. package/bandwidth.js.map +0 -1
  253. package/connection/cert.test.d.ts +0 -2
  254. package/connection/cert.test.d.ts.map +0 -1
  255. package/connection/cert.test.js +0 -26
  256. package/connection/cert.test.js.map +0 -1
  257. package/connection/reload.test.d.ts +0 -2
  258. package/connection/reload.test.d.ts.map +0 -1
  259. package/connection/reload.test.js +0 -39
  260. package/connection/reload.test.js.map +0 -1
  261. package/group.test.d.ts +0 -2
  262. package/group.test.d.ts.map +0 -1
  263. package/group.test.js +0 -66
  264. package/group.test.js.map +0 -1
  265. package/ietf/aliases.test.d.ts +0 -2
  266. package/ietf/aliases.test.d.ts.map +0 -1
  267. package/ietf/aliases.test.js +0 -30
  268. package/ietf/aliases.test.js.map +0 -1
  269. package/ietf/ietf.test.d.ts +0 -2
  270. package/ietf/ietf.test.d.ts.map +0 -1
  271. package/ietf/ietf.test.js +0 -873
  272. package/ietf/ietf.test.js.map +0 -1
  273. package/integration.test.d.ts +0 -2
  274. package/integration.test.d.ts.map +0 -1
  275. package/integration.test.js +0 -90
  276. package/integration.test.js.map +0 -1
  277. package/lite/origin.d.ts.map +0 -1
  278. package/lite/origin.js.map +0 -1
  279. package/lite/subscriber.test.d.ts +0 -2
  280. package/lite/subscriber.test.d.ts.map +0 -1
  281. package/lite/subscriber.test.js +0 -30
  282. package/lite/subscriber.test.js.map +0 -1
  283. package/lite/track.test.d.ts +0 -2
  284. package/lite/track.test.d.ts.map +0 -1
  285. package/lite/track.test.js +0 -53
  286. package/lite/track.test.js.map +0 -1
  287. package/path.test.d.ts +0 -2
  288. package/path.test.d.ts.map +0 -1
  289. package/path.test.js +0 -169
  290. package/path.test.js.map +0 -1
  291. package/stream.test.d.ts +0 -2
  292. package/stream.test.d.ts.map +0 -1
  293. package/stream.test.js +0 -210
  294. package/stream.test.js.map +0 -1
  295. package/track.test.d.ts +0 -2
  296. package/track.test.d.ts.map +0 -1
  297. package/track.test.js +0 -56
  298. package/track.test.js.map +0 -1
  299. package/util/error.d.ts +0 -3
  300. package/util/error.d.ts.map +0 -1
  301. package/util/error.js +0 -9
  302. package/util/error.js.map +0 -1
  303. package/util/index.d.ts +0 -2
  304. package/util/index.d.ts.map +0 -1
  305. package/util/index.js +0 -3
  306. package/util/index.js.map +0 -1
  307. package/varint.test.d.ts +0 -2
  308. package/varint.test.d.ts.map +0 -1
  309. package/varint.test.js +0 -106
  310. package/varint.test.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"subscriber.js","sourceRoot":"","sources":["../../src/lite/subscriber.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Signal } from \"@moq/signals\";\nimport { Announced } from \"../announced.ts\";\nimport type { Bandwidth } from \"../bandwidth.ts\";\nimport { Broadcast, type TrackRequest } from \"../broadcast.ts\";\nimport { Group } from \"../group.ts\";\nimport * as Path from \"../path.ts\";\nimport { type Reader, Stream } from \"../stream.ts\";\nimport type * as Time from \"../time.ts\";\nimport type { Track } from \"../track.ts\";\nimport { error } from \"../util/error.ts\";\nimport { Announce, AnnounceInit, AnnounceInterest } from \"./announce.ts\";\nimport type { Group as GroupMessage } from \"./group.ts\";\nimport type { Origin } from \"./origin.ts\";\nimport { Probe } from \"./probe.ts\";\nimport { StreamId } from \"./stream.ts\";\nimport { decodeSubscribeResponse, decodeSubscribeResponseMaybe, Subscribe, SubscribeUpdate } from \"./subscribe.ts\";\nimport { hasTrackStream, Version } from \"./version.ts\";\n\n/**\n * Options accepted by {@link Subscriber.announced}.\n */\nexport interface AnnouncedOptions {\n\t/**\n\t * If true, skip announcements whose hop chain contains this connection's\n\t * own origin id — useful for meshes that reflect announces back. Defaults\n\t * to false for backwards compatibility: existing code (notably hang.live)\n\t * relies on seeing its own publishes as the signal that a namespace\n\t * published successfully.\n\t */\n\tignoreSelf?: boolean;\n}\n\n/**\n * Handles subscribing to broadcasts and managing their lifecycle.\n *\n * @internal\n */\nexport class Subscriber {\n\t#quic: WebTransport;\n\n\t// The version of the connection.\n\treadonly version: Version;\n\n\t// Shared with the Publisher so callers can optionally filter out their\n\t// own announcements on a per-call basis (see {@link AnnouncedOptions}).\n\treadonly origin: Origin;\n\n\t// Our subscribed tracks.\n\t#subscribes = new Map<bigint, Track>();\n\t#subscribeNext = 0n;\n\n\t// Recv bandwidth producer (Lite03+ only).\n\t#recvBandwidth?: Bandwidth;\n\n\t// RTT producer (Lite04+ only).\n\t#rtt?: Signal<Time.Milli | undefined>;\n\n\t// Distinguishes failures from streams torn down by Subscriber.close().\n\t#closed = new AbortController();\n\n\t/**\n\t * Creates a new Subscriber instance.\n\t * @param quic - The WebTransport session to use\n\t * @param version - The protocol version\n\t * @param origin - Origin id shared with the Publisher\n\t * @param recvBandwidth - Optional bandwidth producer for PROBE\n\t * @param rtt - Optional RTT signal for PROBE\n\t *\n\t * @internal\n\t */\n\tconstructor(\n\t\tquic: WebTransport,\n\t\tversion: Version,\n\t\torigin: Origin,\n\t\trecvBandwidth?: Bandwidth,\n\t\trtt?: Signal<Time.Milli | undefined>,\n\t) {\n\t\tthis.#quic = quic;\n\t\tthis.version = version;\n\t\tthis.origin = origin;\n\t\tthis.#recvBandwidth = recvBandwidth;\n\t\tthis.#rtt = rtt;\n\t}\n\n\t/**\n\t * Subscribe to broadcast announcements under `prefix`.\n\t *\n\t * Pass `{ ignoreSelf: true }` to skip announces that have already traversed\n\t * this connection's {@link origin}.\n\t */\n\tannounced(prefix = Path.empty(), options: AnnouncedOptions = {}): Announced {\n\t\tconst announced = new Announced();\n\t\tvoid this.#runAnnounced(announced, prefix, options);\n\t\treturn announced;\n\t}\n\n\tasync #runAnnounced(announced: Announced, prefix: Path.Valid, options: AnnouncedOptions): Promise<void> {\n\t\tconsole.debug(`announced: prefix=${prefix}`);\n\t\t// Send our own session-level origin id so the peer can skip announces\n\t\t// whose hop chain already passed through us. Matches the Rust subscriber's\n\t\t// `exclude_hop: self.self_origin.id` in `run_announce_prefix`.\n\t\tconst msg = new AnnounceInterest(prefix, this.origin);\n\n\t\ttry {\n\t\t\t// Open a stream and send the announce interest.\n\t\t\tconst stream = await Stream.open(this.#quic);\n\t\t\tawait stream.writer.u53(StreamId.Announce);\n\t\t\tawait msg.encode(stream.writer, this.version);\n\n\t\t\tswitch (this.version) {\n\t\t\t\tcase Version.DRAFT_01:\n\t\t\t\tcase Version.DRAFT_02: {\n\t\t\t\t\t// Receive ANNOUNCE_INIT first\n\t\t\t\t\tconst init = await AnnounceInit.decode(stream.reader, this.version);\n\n\t\t\t\t\t// Process initial announcements\n\t\t\t\t\tfor (const suffix of init.suffixes) {\n\t\t\t\t\t\tconst path = Path.join(prefix, suffix);\n\t\t\t\t\t\tconsole.debug(`announced: broadcast=${path} active=true`);\n\t\t\t\t\t\tannounced.append({ path, active: true });\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\t// Draft03+: no AnnounceInit, initial state comes via Announce messages.\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Receive announce updates (for Draft03, this includes initial state)\n\t\t\tfor (;;) {\n\t\t\t\tconst announce = await Promise.race([\n\t\t\t\t\tAnnounce.decodeMaybe(stream.reader, this.version),\n\t\t\t\t\tannounced.closed,\n\t\t\t\t]);\n\t\t\t\tif (!announce) break;\n\t\t\t\tif (announce instanceof Error) throw announce;\n\n\t\t\t\t// Optionally drop reflected announces so callers asking for\n\t\t\t\t// \"someone else's broadcasts\" don't re-see their own publishes.\n\t\t\t\tif (options.ignoreSelf && announce.hops.includes(this.origin)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst path = Path.join(prefix, announce.suffix);\n\n\t\t\t\tconsole.debug(`announced: broadcast=${path} active=${announce.active}`);\n\t\t\t\tannounced.append({ path, active: announce.active });\n\t\t\t}\n\n\t\t\tannounced.close();\n\t\t} catch (err: unknown) {\n\t\t\tannounced.close(error(err));\n\t\t}\n\t}\n\n\t/**\n\t * Consumes a broadcast from the connection.\n\t *\n\t * @param name - The name of the broadcast to consume\n\t * @returns A Broadcast instance\n\t */\n\tconsume(path: Path.Valid): Broadcast {\n\t\tconst broadcast = new Broadcast();\n\n\t\tvoid (async () => {\n\t\t\tfor (;;) {\n\t\t\t\tconst request = await broadcast.requested();\n\t\t\t\tif (!request) break;\n\t\t\t\tvoid this.#runSubscribe(path, request);\n\t\t\t}\n\t\t})();\n\n\t\treturn broadcast;\n\t}\n\n\tasync #runSubscribe(broadcast: Path.Valid, request: TrackRequest) {\n\t\tconst id = this.#subscribeNext++;\n\n\t\t// Save the writer so we can append groups to it.\n\t\tthis.#subscribes.set(id, request.track);\n\n\t\tconsole.debug(`subscribe start: id=${id} broadcast=${broadcast} track=${request.track.name}`);\n\n\t\tconst msg = new Subscribe({ id, broadcast, track: request.track.name, priority: request.priority });\n\n\t\tconst stream = await Stream.open(this.#quic);\n\t\tawait stream.writer.u53(StreamId.Subscribe);\n\t\tawait msg.encode(stream.writer, this.version);\n\n\t\ttry {\n\t\t\t// The first response MUST be a SUBSCRIBE_OK.\n\t\t\tconst resp = await decodeSubscribeResponse(stream.reader, this.version);\n\t\t\tif (!(\"ok\" in resp)) {\n\t\t\t\tthrow new Error(\"first subscribe response must be SUBSCRIBE_OK\");\n\t\t\t}\n\t\t\tconsole.debug(`subscribe ok: id=${id} broadcast=${broadcast} track=${request.track.name}`);\n\n\t\t\t// Watch for priority changes and send SUBSCRIBE_UPDATE. Lite01/Lite02\n\t\t\t// don't carry SUBSCRIBE_UPDATE on the wire, so skip the watcher there\n\t\t\t// and just wait on the stream/track like before.\n\t\t\t// Draining responses also consumes any SUBSCRIBE_END / SUBSCRIBE_DROP and\n\t\t\t// resolves when the publisher FINs.\n\t\t\tconst waits: Promise<unknown>[] = [this.#drainResponses(stream), request.track.closed];\n\t\t\tswitch (this.version) {\n\t\t\t\tcase Version.DRAFT_01:\n\t\t\t\tcase Version.DRAFT_02:\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\twaits.push(this.#runPriorityUpdates(id, broadcast, request.track, msg, stream));\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tawait Promise.race(waits);\n\n\t\t\trequest.track.close();\n\t\t\tstream.close();\n\t\t\tconsole.debug(`subscribe close: id=${id} broadcast=${broadcast} track=${request.track.name}`);\n\t\t} catch (err) {\n\t\t\tconst e = error(err);\n\t\t\trequest.track.close(e);\n\t\t\tconsole.warn(\n\t\t\t\t`subscribe error: id=${id} broadcast=${broadcast} track=${request.track.name} error=${e.message}`,\n\t\t\t);\n\t\t\tstream.abort(e);\n\t\t} finally {\n\t\t\tthis.#subscribes.delete(id);\n\t\t}\n\t}\n\n\t/**\n\t * Drain responses on the subscribe stream until the publisher FINs.\n\t *\n\t * The first SUBSCRIBE_OK is consumed by the caller; this reads any further\n\t * SUBSCRIBE_END / SUBSCRIBE_DROP. They aren't acted on yet (groups arrive on\n\t * their own streams regardless), but consuming them keeps the stream aligned.\n\t */\n\tasync #drainResponses(stream: Stream): Promise<void> {\n\t\tfor (;;) {\n\t\t\tconst resp = await decodeSubscribeResponseMaybe(stream.reader, this.version);\n\t\t\tif (!resp) break;\n\t\t}\n\t}\n\n\t/**\n\t * Send SUBSCRIBE_UPDATE messages whenever the track's priority signal changes.\n\t *\n\t * Resolves cleanly when the stream or track closes, so the caller can include\n\t * this in Promise.race without leaving a dangling pending write that would\n\t * become an unhandled rejection if the user calls updatePriority after close.\n\t *\n\t * Peeks the signal at the top of every iteration so that updates which landed\n\t * before SubscribeOk arrived (or between iterations, before .next() registered\n\t * its listener) aren't lost.\n\t */\n\tasync #runPriorityUpdates(\n\t\tid: bigint,\n\t\tbroadcast: Path.Valid,\n\t\ttrack: Track,\n\t\tmsg: Subscribe,\n\t\tstream: Stream,\n\t): Promise<void> {\n\t\tconst stopped: Promise<null> = Promise.race([track.closed, stream.reader.closed]).then(() => null);\n\t\tlet lastSent: number | undefined;\n\n\t\tfor (;;) {\n\t\t\tconst current = track.state.priority.peek();\n\t\t\tif (current === undefined || current === lastSent) {\n\t\t\t\t// Nothing new to send; wait for a change or termination.\n\t\t\t\tconst next = await Promise.race([track.state.priority.next(), stopped]);\n\t\t\t\tif (next === null) return;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Round-trip the other Subscribe parameters so the publisher doesn't\n\t\t\t// interpret SUBSCRIBE_UPDATE as a reset of ordered/maxLatency/etc.\n\t\t\tconst update = new SubscribeUpdate({\n\t\t\t\tpriority: current,\n\t\t\t\tordered: msg.ordered,\n\t\t\t\tmaxLatency: msg.maxLatency,\n\t\t\t\tstartGroup: msg.startGroup,\n\t\t\t\tendGroup: msg.endGroup,\n\t\t\t});\n\t\t\tawait update.encode(stream.writer, this.version);\n\t\t\tlastSent = current;\n\t\t\tconsole.debug(`subscribe update: id=${id} broadcast=${broadcast} track=${track.name} priority=${current}`);\n\t\t}\n\t}\n\n\t/**\n\t * Handles a group message.\n\t * @param group - The group message\n\t * @param stream - The stream to read frames from\n\t *\n\t * @internal\n\t */\n\tasync runGroup(group: GroupMessage, stream: Reader) {\n\t\tconst subscribe = this.#subscribes.get(group.subscribe);\n\t\tif (!subscribe) {\n\t\t\tif (group.subscribe >= this.#subscribeNext) {\n\t\t\t\tthrow new Error(`unknown subscription: id=${group.subscribe}`);\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst producer = new Group(group.sequence);\n\t\tsubscribe.writeGroup(producer);\n\n\t\ttry {\n\t\t\tfor (;;) {\n\t\t\t\tconst done = await Promise.race([stream.done(), subscribe.closed, producer.closed]);\n\t\t\t\tif (done !== false) break;\n\n\t\t\t\tif (hasTrackStream(this.version)) {\n\t\t\t\t\t// moq-lite-05+ prefixes each frame with a zigzag timestamp delta. Decode it\n\t\t\t\t\t// to stay aligned with the wire, but don't surface it yet.\n\t\t\t\t\tawait stream.u62();\n\t\t\t\t}\n\n\t\t\t\tconst size = await stream.u53();\n\t\t\t\tconst payload = await stream.read(size);\n\t\t\t\tif (!payload) break;\n\n\t\t\t\tproducer.writeFrame(payload);\n\t\t\t}\n\n\t\t\tproducer.close();\n\t\t\tstream.stop(new Error(\"cancel\"));\n\t\t} catch (err: unknown) {\n\t\t\tconst e = error(err);\n\t\t\tproducer.close(e);\n\t\t\tstream.stop(e);\n\t\t}\n\t}\n\n\t/**\n\t * Opens a PROBE bidi stream to receive bandwidth estimates from the publisher.\n\t * Returns immediately if recv bandwidth is not supported.\n\t *\n\t * Probe is best-effort telemetry: a stream-level failure (peer reset, FIN,\n\t * missing peer support, transport hiccup) is caught and logged, never\n\t * propagated to the connection. On exit the bandwidth/RTT signals are\n\t * cleared so consumers see them as stale.\n\t *\n\t * @internal\n\t */\n\tasync runProbe(): Promise<void> {\n\t\tif (!this.#recvBandwidth) return;\n\t\tif (this.version === Version.DRAFT_01 || this.version === Version.DRAFT_02) return;\n\n\t\t// Probe is best-effort: any failure (stream reset by peer, missing peer support,\n\t\t// transport hiccup) MUST NOT tear down the connection. On error, drop the\n\t\t// bandwidth/RTT estimates so consumers know they're stale.\n\t\ttry {\n\t\t\tconst stream = await Stream.open(this.#quic);\n\t\t\tawait stream.writer.u53(StreamId.Probe);\n\n\t\t\tfor (;;) {\n\t\t\t\tconst probe = await Probe.decodeMaybe(stream.reader, this.version);\n\t\t\t\tif (!probe) break;\n\t\t\t\tthis.#recvBandwidth.set(probe.bitrate ?? undefined);\n\t\t\t\tif (this.#rtt && probe.rtt !== undefined) {\n\t\t\t\t\tthis.#rtt.set(probe.rtt as Time.Milli);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (err: unknown) {\n\t\t\tif (!this.#closed.signal.aborted) {\n\t\t\t\tconsole.warn(\"probe stream error\", err);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.#recvBandwidth.set(undefined);\n\t\t\tthis.#rtt?.set(undefined);\n\t\t}\n\t}\n\n\tclose() {\n\t\tthis.#closed.abort();\n\n\t\tfor (const track of this.#subscribes.values()) {\n\t\t\ttrack.close();\n\t\t}\n\n\t\tthis.#subscribes.clear();\n\t}\n}\n"]}
1
+ {"version":3,"file":"subscriber.js","sourceRoot":"","sources":["../../src/lite/subscriber.ts"],"names":[],"mappings":"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","sourcesContent":["import { Signal } from \"@moq/signals\";\nimport * as announce from \"../announced.ts\";\nimport * as broadcast from \"../broadcast.ts\";\nimport type { Probe as ProbeStats } from \"../connection/stats.ts\";\nimport { BroadcastCache } from \"../consume.ts\";\nimport { error, ProtocolViolation, reason } from \"../error.ts\";\nimport * as netGroup from \"../group.ts\";\nimport { type Origin, UNKNOWN_ORIGIN } from \"../origin.ts\";\nimport * as Path from \"../path.ts\";\nimport { type Reader, Stream } from \"../stream.ts\";\nimport * as Time from \"../time.ts\";\nimport type * as track from \"../track.ts\";\nimport { withTimeout } from \"../util/timeout.ts\";\nimport { AnnounceInit, AnnounceOk, AnnounceRequest, decodeAnnounceBroadcastMaybe } from \"./announce.ts\";\nimport { Datagram as DatagramMessage } from \"./datagram.ts\";\nimport * as DatagramStream from \"./datagram_stream.ts\";\nimport { Fetch as FetchMessage } from \"./fetch.ts\";\nimport type { Group as GroupMessage } from \"./group.ts\";\nimport { sendOrder } from \"./priority.ts\";\nimport { Probe } from \"./probe.ts\";\nimport { ProbeLevel, type Setup } from \"./setup.ts\";\nimport { StreamId } from \"./stream.ts\";\nimport { decodeSubscribeResponse, decodeSubscribeResponseMaybe, Subscribe, SubscribeUpdate } from \"./subscribe.ts\";\nimport { TrackInfo, Track as TrackMessage } from \"./track.ts\";\nimport {\n\thasAnnounceId,\n\thasAnnounceOk,\n\thasDatagrams,\n\thasExcludeHop,\n\thasProbeRtt,\n\trestartSupported,\n\tVersion,\n} from \"./version.ts\";\n\n// Bound on how long stream-open plus the first response (SUBSCRIBE_OK on older\n// drafts, or TRACK_INFO on lite-05+) may take. Browsers cap concurrent QUIC streams\n// (Chrome ~100) and we open with waitUntilAvailable, so past the cap the open blocks\n// until the peer frees a slot. The timeout turns a stall into a clear error.\nconst SUBSCRIBE_SETUP_TIMEOUT_MS = 10_000;\n\n/** Decode an unsigned zigzag varint back to a signed delta (mirrors Rust `VarInt::to_zigzag`). */\nfunction unzigzag(v: bigint): bigint {\n\treturn (v >> 1n) ^ -(v & 1n);\n}\n\n// The TRACK stream and implicit SUBSCRIBE acceptance are lite-05+.\nfunction supportsTrackStream(version: Version): boolean {\n\tswitch (version) {\n\t\tcase Version.DRAFT_01:\n\t\tcase Version.DRAFT_02:\n\t\tcase Version.DRAFT_03:\n\t\tcase Version.DRAFT_04:\n\t\t\treturn false;\n\t\tdefault:\n\t\t\treturn true;\n\t}\n}\n\n/**\n * Options accepted by {@link Subscriber.announced}.\n */\nexport interface AnnouncedOptions {\n\t/**\n\t * If true, skip announcements whose hop chain contains this connection's\n\t * own origin id. Useful for meshes that reflect announces back. Defaults\n\t * to false for backwards compatibility: existing code (notably hang.live)\n\t * relies on seeing its own publishes as the signal that a namespace\n\t * published successfully.\n\t *\n\t * Only meaningful on lite-04/05, where the peer filters reflected announces\n\t * on request (ANNOUNCE_REQUEST's `Exclude Hop`). Later versions dropped that\n\t * field, so reflected announces are always skipped.\n\t */\n\tignoreSelf?: boolean;\n}\n\ninterface SubscribeEntry {\n\t// The write side: incoming GROUP streams are routed here. The application reads\n\t// the matching track.Subscriber it got from broadcast.Consumer.subscribe.\n\ttrack: track.Producer;\n\t// Per-frame timestamp scale (0 = none). undefined until it's known (from TRACK_INFO\n\t// on lite-05+, or implicit defaults on older drafts). A non-zero value means each\n\t// frame on the group stream is prefixed with a zigzag-delta timestamp varint that\n\t// runGroup must consume to stay in sync; group streams block on it before decoding,\n\t// since a group's QUIC stream can race ahead of the subscribe stream.\n\ttimescale: Signal<number | undefined>;\n}\n\n/**\n * Handles subscribing to broadcasts and managing their lifecycle.\n *\n * @internal\n */\n// What we close a session with on a protocol violation.\n//\n// The draft names the condition but assigns no numbers, so this is the Rust\n// implementation's code for `Error::ProtocolViolation`: matching it is what makes the\n// two report the same thing, where the default 0 would tell the peer it closed cleanly.\nconst PROTOCOL_VIOLATION_CODE = 15;\n\n// WebTransport rejects a close reason over 1024 bytes of UTF-8 by throwing, so a reason\n// built from peer-supplied data has to be bounded before it gets there. A broadcast path\n// is peer-supplied and long enough to reach this on its own.\nconst MAX_CLOSE_REASON = 1024;\n\n// The longest prefix of `text` that fits a close reason. `encodeInto` stops on a whole\n// code point, so `read` never lands mid-character the way slicing bytes would.\nfunction closeReason(text: string): string {\n\tconst encoder = new TextEncoder();\n\tconst buf = new Uint8Array(MAX_CLOSE_REASON);\n\tconst { read } = encoder.encodeInto(text, buf);\n\treturn text.slice(0, read);\n}\n\nexport class Subscriber {\n\t#quic: WebTransport;\n\n\t// The version of the connection.\n\treadonly version: Version;\n\n\t// Shared with the Publisher so callers can optionally filter out their\n\t// own announcements on a per-call basis (see {@link AnnouncedOptions}).\n\treadonly origin: Origin;\n\n\t// Our subscribed tracks. `timescale` resolves once known (from TRACK_INFO on\n\t// lite-05+, or implicit defaults on older drafts); group streams block on it\n\t// before decoding any frame, since a group's QUIC stream can race ahead.\n\t#subscribes = new Map<bigint, SubscribeEntry>();\n\t#subscribeNext = 0n;\n\n\t// Dedup consumed broadcasts per path: repeat consume() calls share one subscription.\n\t#consumes = new BroadcastCache();\n\n\t// Dedup in-flight one-shot fetches, keyed by [broadcast, track, sequence]. Concurrent (or\n\t// repeat, while still open) fetchGroup() calls for the same group share one FETCH stream and\n\t// each get an independent mirror; the entry is evicted once the group closes.\n\t#fetches = new Map<string, netGroup.Producer>();\n\n\t// The peer's PROBE estimates, written as they arrive (Lite03+ only).\n\t#probe?: Signal<ProbeStats>;\n\n\t// The peer's SETUP (lite-05+), undefined until it arrives. Gates opening the PROBE\n\t// stream on the peer having advertised Probe >= Report.\n\t#peerSetup?: Signal<Setup | undefined>;\n\n\t// Distinguishes failures from streams torn down by Subscriber.close().\n\t#closed = new AbortController();\n\t/**\n\t * Creates a new Subscriber instance.\n\t * @param quic - The WebTransport session to use\n\t * @param version - The protocol version\n\t * @param origin - Origin id shared with the Publisher\n\t * @param probe - Optional sink for the peer's PROBE estimates\n\t * @param peerSetup - Optional peer SETUP slot for capability gating (lite-05+)\n\t *\n\t * @internal\n\t */\n\tconstructor(\n\t\tquic: WebTransport,\n\t\tversion: Version,\n\t\torigin: Origin,\n\t\tprobe?: Signal<ProbeStats>,\n\t\tpeerSetup?: Signal<Setup | undefined>,\n\t) {\n\t\tthis.#quic = quic;\n\t\tthis.version = version;\n\t\tthis.origin = origin;\n\t\tthis.#probe = probe;\n\t\tthis.#peerSetup = peerSetup;\n\t}\n\n\t/**\n\t * Subscribe to broadcast announcements under `prefix`.\n\t *\n\t * Pass `{ ignoreSelf: true }` to skip announces that have already traversed\n\t * this connection's {@link origin}.\n\t */\n\tannounced(prefix = Path.empty(), options: AnnouncedOptions = {}): announce.Consumer {\n\t\tconst announced = new announce.Producer(prefix);\n\t\tvoid this.#runAnnounced(announced, prefix, options);\n\t\treturn announced.consume();\n\t}\n\n\tasync #runAnnounced(announced: announce.Producer, prefix: Path.Valid, options: AnnouncedOptions): Promise<void> {\n\t\tconsole.debug(`announced: prefix=${prefix}`);\n\t\t// Lite04/05: send our own session-level origin id so the peer can skip announces\n\t\t// whose hop chain already passed through us. Encoding drops it on every other\n\t\t// version, where we drop the reflected announce on receipt instead. Matches the\n\t\t// Rust subscriber's `exclude_hop: self.self_origin.id` in `run_announce_prefix`.\n\t\tconst msg = new AnnounceRequest(prefix, this.origin);\n\n\t\t// Drop reflected announces so callers asking for \"someone else's broadcasts\"\n\t\t// don't re-see their own publishes. A caller can always ask for this, and it is\n\t\t// required on versions that don't carry excludeHop above: there the peer isn't\n\t\t// filtering them out for us, so filtering here keeps what the app sees the same\n\t\t// as lite-05. Lite01-03 carry no real hop ids, so the check never matches there.\n\t\tconst dropReflected = options.ignoreSelf || !hasExcludeHop(this.version);\n\n\t\t// Opened outside the try so the catch can reach it: a protocol violation below has\n\t\t// to reset the stream, not just close our side of it.\n\t\tlet stream: Stream;\n\t\ttry {\n\t\t\tstream = await Stream.open(this.#quic);\n\t\t} catch (err: unknown) {\n\t\t\tannounced.close(error(err));\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\t// Send the announce interest.\n\t\t\tawait stream.writer.u53(StreamId.Announce);\n\t\t\tawait msg.encode(stream.writer, this.version);\n\n\t\t\t// Lite05+: the publisher reports its own origin id before any announces.\n\t\t\t// It no longer stamps itself onto each hop chain, so we append it here to\n\t\t\t// keep the ignoreSelf loop check seeing the full chain.\n\t\t\tlet responderOrigin: Origin | undefined;\n\t\t\tif (hasAnnounceOk(this.version)) {\n\t\t\t\tconst ok = await AnnounceOk.decode(stream.reader, this.version);\n\t\t\t\t// A responder that withholds its identity sends the reserved 0. It names\n\t\t\t\t// nobody, so folding it into a chain would stamp a placeholder that cannot\n\t\t\t\t// close a loop or tell two publishers apart. Treat it as absent instead,\n\t\t\t\t// which is the loop-blind route the draft describes.\n\t\t\t\tresponderOrigin = ok.origin === UNKNOWN_ORIGIN ? undefined : ok.origin;\n\t\t\t}\n\n\t\t\t// Every advertisement the peer currently has live, keyed by suffix (at most one\n\t\t\t// per path is current, and every announce on this stream shares `prefix`).\n\t\t\t//\n\t\t\t// An advertisement skipped locally as a reflected loop is recorded with\n\t\t\t// `publisher: undefined` and `live: false`: the peer numbered it and will retract\n\t\t\t// it regardless of what we made of it, so its path is not free. Dropping it from\n\t\t\t// the map instead would let a later announce take the path, and the skipped one's\n\t\t\t// `endedId` would then retract that one's state.\n\t\t\t//\n\t\t\t// `publisher` is what lets a restart tell a route change (same publisher,\n\t\t\t// subscriptions resume) from a replacement (a new generation took the path,\n\t\t\t// nothing carries over).\n\t\t\ttype Advertisement = { publisher: Origin | undefined; live: boolean };\n\t\t\tconst advertised = new Map<Path.Valid, Advertisement>();\n\n\t\t\tswitch (this.version) {\n\t\t\t\tcase Version.DRAFT_01:\n\t\t\t\tcase Version.DRAFT_02: {\n\t\t\t\t\t// Receive ANNOUNCE_INIT first\n\t\t\t\t\tconst init = await AnnounceInit.decode(stream.reader, this.version);\n\n\t\t\t\t\t// Process initial announcements. These are advertisements like any other, so\n\t\t\t\t\t// they go on record and obey the same one-per-path rule: the initial set\n\t\t\t\t\t// naming a path twice is the same violation as two ANNOUNCE_STARTs for it,\n\t\t\t\t\t// and the record is what catches either. Draft01/02 carry no hop ids and no\n\t\t\t\t\t// ANNOUNCE_OK, so nothing names the publisher.\n\t\t\t\t\tfor (const suffix of init.suffixes) {\n\t\t\t\t\t\tconst path = Path.join(prefix, suffix);\n\t\t\t\t\t\tif (advertised.has(suffix)) {\n\t\t\t\t\t\t\tthrow new ProtocolViolation(`duplicate announce for ${path}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tadvertised.set(suffix, { publisher: undefined, live: true });\n\t\t\t\t\t\tconsole.debug(`announced: broadcast=${path} active=true`);\n\t\t\t\t\t\tannounced.append({ path: suffix, active: true });\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\t// Draft03+: no AnnounceInit, initial state comes via Announce messages.\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Lite06+: announce ids. Each received `active` implicitly assigns the next\n\t\t\t// per-stream ordinal; `endedId`/`restart` reference it. Tracked even for\n\t\t\t// announces we skip via ignoreSelf, since the sender doesn't know we skipped.\n\t\t\tlet nextAnnounceId = 0n;\n\t\t\tconst announcedById = new Map<bigint, Path.Valid>();\n\n\t\t\t// Receive announce updates (for Draft03, this includes initial state)\n\t\t\tfor (;;) {\n\t\t\t\tconst announce = await Promise.race([\n\t\t\t\t\tdecodeAnnounceBroadcastMaybe(stream.reader, this.version),\n\t\t\t\t\tannounced.closed,\n\t\t\t\t]);\n\t\t\t\t// undefined: the stream ended. null: the consumer closed cleanly.\n\t\t\t\tif (!announce) break;\n\t\t\t\tif (announce instanceof Error) throw announce;\n\n\t\t\t\tlet suffix: Path.Valid;\n\t\t\t\tlet active: boolean;\n\t\t\t\t// Present on active/restart; ended messages never carry hops worth checking.\n\t\t\t\tlet hops: Origin[] | undefined;\n\n\t\t\t\tswitch (announce.status) {\n\t\t\t\t\tcase \"active\":\n\t\t\t\t\t\tsuffix = announce.suffix;\n\t\t\t\t\t\tactive = true;\n\t\t\t\t\t\thops = announce.hops;\n\t\t\t\t\t\tif (hasAnnounceId(this.version)) {\n\t\t\t\t\t\t\tannouncedById.set(nextAnnounceId++, announce.suffix);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"ended\":\n\t\t\t\t\t\tsuffix = announce.suffix;\n\t\t\t\t\t\tactive = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"endedId\": {\n\t\t\t\t\t\t// Resolve and retire the id; an unknown or retired id is a protocol violation.\n\t\t\t\t\t\tconst path = announcedById.get(announce.id);\n\t\t\t\t\t\tif (path === undefined) throw new ProtocolViolation(`unknown announce id: ${announce.id}`);\n\t\t\t\t\t\tannouncedById.delete(announce.id);\n\t\t\t\t\t\tsuffix = path;\n\t\t\t\t\t\tactive = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"restart\": {\n\t\t\t\t\t\t// Resolve the id; it stays live (the replacement reuses it).\n\t\t\t\t\t\tconst path = announcedById.get(announce.id);\n\t\t\t\t\t\tif (path === undefined) throw new ProtocolViolation(`unknown announce id: ${announce.id}`);\n\t\t\t\t\t\tsuffix = path;\n\t\t\t\t\t\tactive = true;\n\t\t\t\t\t\thops = announce.hops;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst path = Path.join(prefix, suffix);\n\n\t\t\t\t// One current advertisement per path per stream, decided before anything below\n\t\t\t\t// can skip this announcement. A second ANNOUNCE_START for a path the peer\n\t\t\t\t// already advertised is a violation whether or not its route would be usable\n\t\t\t\t// here, and whether or not we kept the first; letting a skip pre-empt it would\n\t\t\t\t// retract the live route and leave the stream open on a peer already out of\n\t\t\t\t// spec.\n\t\t\t\t//\n\t\t\t\t// lite-05 alone is exempt, where a duplicate ANNOUNCE *is* the replacement\n\t\t\t\t// idiom. lite-06 gave that its own message and older versions never had one, so\n\t\t\t\t// a duplicate means the same thing on both sides of it. Mirrors the branch the\n\t\t\t\t// Rust announce loop takes before `start_announce`.\n\t\t\t\tconst duplicateIsRestart = restartSupported(this.version) && !hasAnnounceId(this.version);\n\t\t\t\tif (announce.status === \"active\" && !duplicateIsRestart && advertised.has(suffix)) {\n\t\t\t\t\tthrow new ProtocolViolation(`duplicate announce for ${path}`);\n\t\t\t\t}\n\n\t\t\t\t// Retract the path: forget the advertisement, drop the shared consume entry so a\n\t\t\t\t// later announce subscribes fresh rather than cloning the dead generation's tracks,\n\t\t\t\t// and tell the consumer. A no-op for an advertisement never surfaced, which is\n\t\t\t\t// what an id retiring a skipped announce resolves to.\n\t\t\t\tconst retract = () => {\n\t\t\t\t\tconst previous = advertised.get(suffix);\n\t\t\t\t\tadvertised.delete(suffix);\n\t\t\t\t\tif (!previous?.live) return;\n\t\t\t\t\tthis.#consumes.evict(path);\n\t\t\t\t\tconsole.debug(`announced: broadcast=${path} active=false`);\n\t\t\t\t\tannounced.append({ path: suffix, active: false });\n\t\t\t\t};\n\n\t\t\t\t// In Lite05+ the sender's origin arrives via AnnounceOk, not in each hop\n\t\t\t\t// list, so fold it back in before checking.\n\t\t\t\tif (hops !== undefined && dropReflected) {\n\t\t\t\t\tconst full = responderOrigin !== undefined ? [...hops, responderOrigin] : hops;\n\t\t\t\t\tif (full.includes(this.origin)) {\n\t\t\t\t\t\t// A reflected restart means the peer's remaining route loops back through\n\t\t\t\t\t\t// us, so the route is gone even though the message says active. The\n\t\t\t\t\t\t// advertisement stays live: the peer still holds the path and its id still\n\t\t\t\t\t\t// resolves here.\n\t\t\t\t\t\tretract();\n\t\t\t\t\t\tadvertised.set(suffix, { publisher: undefined, live: false });\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (active) {\n\t\t\t\t\t// The first hop identifies the original publisher; an empty chain means the\n\t\t\t\t\t// peer itself originated it. See `restart_announce` in the Rust subscriber.\n\t\t\t\t\tconst publisher = hops?.[0] ?? responderOrigin;\n\n\t\t\t\t\t// A publisher with no identity (an empty chain from a peer that withheld its\n\t\t\t\t\t// own id, or a lite-03 UNKNOWN placeholder) never proves continuity: two such\n\t\t\t\t\t// advertisements can be unrelated publishers. Mirrors the\n\t\t\t\t\t// `publisher == Origin::UNKNOWN` arm of the Rust `restart_announce`.\n\t\t\t\t\tconst identified = publisher !== undefined && publisher !== UNKNOWN_ORIGIN;\n\n\t\t\t\t\t// A second advertisement for a path we already carry is a restart: either an\n\t\t\t\t\t// explicit ANNOUNCE_UPDATE, or (lite-05) a duplicate ANNOUNCE.\n\t\t\t\t\tconst previous = advertised.get(suffix);\n\t\t\t\t\tif (previous?.live) {\n\t\t\t\t\t\tif (identified && previous.publisher === publisher) {\n\t\t\t\t\t\t\t// Same publisher, new route. In-flight subscriptions resume across it,\n\t\t\t\t\t\t\t// so there is nothing for a consumer to react to. An unidentified\n\t\t\t\t\t\t\t// publisher falls through to the replacement path below instead.\n\t\t\t\t\t\t\tconsole.debug(`announced: broadcast=${path} rerouted`);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// A different publisher took the path, so cached track info and existing\n\t\t\t\t\t\t// subscriptions must not carry over. Surface a real end before the start.\n\t\t\t\t\t\tretract();\n\t\t\t\t\t}\n\n\t\t\t\t\t// After `retract()`, which clears the entry: the path is advertised again, by\n\t\t\t\t\t// whoever just took it over. Recording it before would leave nothing behind, so\n\t\t\t\t\t// the *next* takeover would read as a first announcement and skip its own end.\n\t\t\t\t\tadvertised.set(suffix, { publisher, live: true });\n\t\t\t\t} else {\n\t\t\t\t\tretract();\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconsole.debug(`announced: broadcast=${path} active=true`);\n\t\t\t\tannounced.append({ path: suffix, active: true });\n\t\t\t}\n\n\t\t\tannounced.close();\n\t\t} catch (err: unknown) {\n\t\t\tconst e = error(err);\n\t\t\t// Reaches here on a protocol violation the peer committed (a second\n\t\t\t// advertisement for a live path, an unknown announce id) as well as on a\n\t\t\t// transport failure. Either way the peer has to be told: closing only our side\n\t\t\t// would leave it announcing into a stream nobody reads.\n\t\t\tstream.abort(e);\n\t\t\tannounced.close(e);\n\t\t\t// A violation ends the session, not just this stream, so a nonconforming peer\n\t\t\t// cannot repeat it on the next one. Matches `ietf::Subscriber` and the Rust\n\t\t\t// lite subscriber, where the announce half only ever ends the session on error.\n\t\t\tif (e instanceof ProtocolViolation) {\n\t\t\t\tthis.#quic.close({ closeCode: PROTOCOL_VIOLATION_CODE, reason: closeReason(reason(e)) });\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Consumes a broadcast from the connection.\n\t *\n\t * Deduplicated per path: repeat calls for the same still-live path share one reference-counted\n\t * broadcast (and one upstream subscription). The shared broadcast closes once every caller has\n\t * closed its handle, so callers close normally.\n\t *\n\t * @param name - The name of the broadcast to consume\n\t * @returns A Broadcast instance\n\t */\n\tconsume(path: Path.Valid): broadcast.Consumer {\n\t\treturn this.#consumes.get(path) ?? this.#consumes.insert(path, this.#createConsume(path));\n\t}\n\n\t#createConsume(path: Path.Valid): broadcast.Consumer {\n\t\t// A consumed broadcast resolves info() and fetchGroup() over the wire by reaching\n\t\t// back into this Subscriber (see ConsumeBroadcast below), rather than the wire\n\t\t// installing callbacks on the broadcast.\n\t\tconst consumer = new ConsumeBroadcast(this, path);\n\n\t\tvoid (async () => {\n\t\t\tfor (;;) {\n\t\t\t\tconst request = await consumer.requested();\n\t\t\t\tif (!request) break;\n\t\t\t\tvoid this.#runSubscribe(path, request);\n\t\t\t}\n\t\t})();\n\n\t\treturn consumer;\n\t}\n\n\tasync #runSubscribe(broadcast: Path.Valid, request: track.Request) {\n\t\tconst id = this.#subscribeNext++;\n\t\tconst subscription = request.subscription;\n\n\t\t// `timescale` stays undefined until TRACK_INFO (or, on older drafts,\n\t\t// implicit defaults) resolves it; runGroup blocks on it before decoding.\n\t\tconst timescale = new Signal<number | undefined>(undefined);\n\n\t\tconsole.debug(`subscribe start: id=${id} broadcast=${broadcast} track=${request.name}`);\n\n\t\tconst msg = new Subscribe({\n\t\t\tid,\n\t\t\tbroadcast,\n\t\t\ttrack: request.name,\n\t\t\tpriority: subscription.priority ?? 0,\n\t\t\tordered: subscription.ordered,\n\t\t\tmaxLatency: subscription.latencyMax,\n\t\t\tstartGroup: subscription.startGroup,\n\t\t\tendGroup: subscription.endGroup,\n\t\t});\n\n\t\t// Open the stream under a timeout. The stream handle flows back via `state`\n\t\t// so the timeout path can abort it if it finishes opening after the deadline.\n\t\tconst state: { stream?: Stream } = {};\n\t\tconst setup = this.#openSubscribe(state, msg, request, id, timescale);\n\n\t\tlet opened: { stream: Stream; producer: track.Producer };\n\t\ttry {\n\t\t\topened = await withTimeout(\n\t\t\t\tsetup,\n\t\t\t\tSUBSCRIBE_SETUP_TIMEOUT_MS,\n\t\t\t\t`subscribe timed out after ${SUBSCRIBE_SETUP_TIMEOUT_MS}ms waiting for the first response (browser stream limit reached?)`,\n\t\t\t);\n\t\t\tconsole.debug(`subscribe ok: id=${id} broadcast=${broadcast} track=${request.name}`);\n\t\t} catch (err) {\n\t\t\tconst e = error(err);\n\t\t\trequest.reject(e);\n\t\t\tthis.#subscribes.delete(id);\n\t\t\tconsole.warn(`subscribe error: id=${id} broadcast=${broadcast} track=${request.name} error=${reason(e)}`);\n\t\t\t// If the stream eventually opens after the timeout, abort it so we\n\t\t\t// don't leak it. Cover both branches: setup may resolve late, or it\n\t\t\t// may reject (e.g. encode/decode failure) after the stream is open.\n\t\t\tsetup.then(\n\t\t\t\t() => state.stream?.abort(e),\n\t\t\t\t() => state.stream?.abort(e),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst { stream, producer } = opened;\n\t\ttry {\n\t\t\t// Watch for subscription changes and send SUBSCRIBE_UPDATE. Lite01/Lite02\n\t\t\t// don't carry SUBSCRIBE_UPDATE on the wire, so skip the watcher there\n\t\t\t// and just wait on the stream/track like before.\n\t\t\t//\n\t\t\t// On lite-05+ the publisher sends SUBSCRIBE_START/END/DROP on this stream;\n\t\t\t// drain them (we don't drive delivery off the resolved range) so the FIN is\n\t\t\t// observed. Older drafts just wait for the stream to close.\n\t\t\tconst closed = supportsTrackStream(this.version) ? this.#drainResponses(stream) : stream.reader.closed;\n\t\t\tconst subscriptionUpdates =\n\t\t\t\tthis.version === Version.DRAFT_01 || this.version === Version.DRAFT_02\n\t\t\t\t\t? undefined\n\t\t\t\t\t: this.#runSubscriptionUpdates(id, broadcast, producer, msg, stream);\n\n\t\t\t// Terminal conditions (stream end, track close, a failed subscription update) settle at most\n\t\t\t// once; race them into one stable promise so the demand loop doesn't re-subscribe each pass.\n\t\t\tconst terminal: PromiseLike<unknown>[] = [closed, producer.closed];\n\t\t\tif (subscriptionUpdates !== undefined) terminal.push(subscriptionUpdates);\n\t\t\tconst done = Promise.race(terminal);\n\n\t\t\t// Serve until a terminal condition fires or the last local subscriber leaves. The unused\n\t\t\t// wake is level-triggered: re-check demand so a subscriber that returns before we tear\n\t\t\t// down (e.g. a quickly unmuted tile) resumes on the same subscription.\n\t\t\tconst idle = Symbol(\"idle\");\n\t\t\tfor (;;) {\n\t\t\t\tconst reason = await Promise.race([done, producer.unused().then(() => idle)]);\n\t\t\t\tif (reason === idle && producer.closed.peek() === undefined && producer.used.peek()) continue;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tproducer.close();\n\t\t\tstream.close();\n\t\t\tconsole.debug(`subscribe close: id=${id} broadcast=${broadcast} track=${request.name}`);\n\t\t} catch (err) {\n\t\t\tconst e = error(err);\n\t\t\tproducer.close(e);\n\t\t\tconsole.warn(`subscribe error: id=${id} broadcast=${broadcast} track=${request.name} error=${reason(e)}`);\n\t\t\tstream.abort(e);\n\t\t} finally {\n\t\t\tthis.#subscribes.delete(id);\n\t\t}\n\t}\n\n\t// Determine the track's immutable properties, accept the request (so the\n\t// application's track.Subscriber resolves and incoming groups have a producer to\n\t// write into), register it, then open the subscribe stream. `state.stream` is\n\t// populated as soon as the subscribe stream opens so the caller can clean it up\n\t// on timeout even before this promise settles.\n\t//\n\t// On lite-05+ the properties come from a TRACK stream opened first, and the\n\t// SUBSCRIBE is accepted implicitly (no SUBSCRIBE_OK). Older drafts carry no\n\t// per-track properties, so they resolve to defaults and just drain SUBSCRIBE_OK.\n\tasync #openSubscribe(\n\t\tstate: { stream?: Stream },\n\t\tmsg: Subscribe,\n\t\trequest: track.Request,\n\t\tid: bigint,\n\t\ttimescale: Signal<number | undefined>,\n\t): Promise<{ stream: Stream; producer: track.Producer }> {\n\t\tlet producer: track.Producer;\n\t\tlet drainOk = false;\n\n\t\tif (supportsTrackStream(this.version)) {\n\t\t\t// Fetch the immutable properties once via the TRACK stream.\n\t\t\tconst info = await this.#trackInfo(msg.broadcast, msg.track);\n\t\t\tproducer = request.accept(this.#toModelInfo(info));\n\t\t\ttimescale.set(info.timescale);\n\t\t} else {\n\t\t\t// Older drafts negotiate nothing per-track: verbatim frames, no timescale.\n\t\t\tproducer = request.accept();\n\t\t\ttimescale.set(0);\n\t\t\tdrainOk = true;\n\t\t}\n\n\t\t// Register before opening SUBSCRIBE so a racing GROUP stream finds the entry.\n\t\tthis.#subscribes.set(id, { track: producer, timescale });\n\n\t\tstate.stream = await Stream.open(this.#quic);\n\t\tawait state.stream.writer.u53(StreamId.Subscribe);\n\t\tawait msg.encode(state.stream.writer, this.version);\n\n\t\tif (drainOk) {\n\t\t\t// The first response MUST be a SUBSCRIBE_OK (older drafts only).\n\t\t\tconst resp = await decodeSubscribeResponse(state.stream.reader, this.version);\n\t\t\tif (!(\"ok\" in resp)) {\n\t\t\t\tthrow new Error(\"first subscribe response must be SUBSCRIBE_OK\");\n\t\t\t}\n\t\t}\n\n\t\treturn { stream: state.stream, producer };\n\t}\n\n\t// Opens a TRACK stream, reads the single TRACK_INFO, and FINs. Lite-05+ only.\n\tasync #trackInfo(broadcast: Path.Valid, track: string): Promise<TrackInfo> {\n\t\tconst stream = await Stream.open(this.#quic);\n\t\ttry {\n\t\t\tawait stream.writer.u53(StreamId.Track);\n\t\t\tawait new TrackMessage(broadcast, track).encode(stream.writer, this.version);\n\t\t\tconst info = await TrackInfo.decode(stream.reader, this.version);\n\t\t\t// The publisher FINs after TRACK_INFO; FIN our side too.\n\t\t\tstream.close();\n\t\t\treturn info;\n\t\t} catch (err) {\n\t\t\tstream.abort(error(err));\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t// Map the wire TRACK_INFO onto the model track.Info a producer/consumer holds.\n\t#toModelInfo(info: TrackInfo): track.Info {\n\t\treturn {\n\t\t\ttimescale: Time.Timescale(info.timescale),\n\t\t\t// Publisher Max Latency rides on the wire, so the local retention window\n\t\t\t// matches what the upstream advertises (relays re-serve with the same bound).\n\t\t\tlatencyMax: info.latencyMax,\n\t\t\tpriority: info.priority,\n\t\t\tordered: info.ordered,\n\t\t};\n\t}\n\n\t// Resolve a track's immutable model info via a TRACK stream (lite-05+), for the\n\t// ConsumeBroadcast backing track.Consumer.info(). On older drafts there's no TRACK\n\t// stream, so this rejects rather than fabricating defaults.\n\tasync resolveTrackInfo(broadcast: Path.Valid, track: string): Promise<track.Info> {\n\t\tif (!supportsTrackStream(this.version)) {\n\t\t\tthrow new Error(\"track info requires moq-lite-05 or newer\");\n\t\t}\n\t\treturn this.#toModelInfo(await this.#trackInfo(broadcast, track));\n\t}\n\n\t// Open a FETCH stream for one group and stream its bare frames into a group, for the\n\t// ConsumeBroadcast backing track.Consumer.fetchGroup() (lite-05+).\n\tfetchGroup(\n\t\tbroadcast: Path.Valid,\n\t\ttrack: string,\n\t\tsequence: number,\n\t\toptions: track.FetchGroupOptions = {},\n\t): Promise<netGroup.Consumer> {\n\t\t// Coalesce onto a still-open fetch of the same group so we don't open a second FETCH\n\t\t// stream (and re-download it); each caller reads an independent mirror.\n\t\tconst key = JSON.stringify([broadcast, track, sequence]);\n\t\tconst existing = this.#fetches.get(key);\n\t\tif (existing && !existing.isClosed) return Promise.resolve(existing.mirror());\n\n\t\t// Create and cache the group synchronously (before any await) so a concurrent fetch for\n\t\t// the same group finds it and coalesces rather than racing to open its own stream.\n\t\tconst group = new netGroup.Producer(sequence);\n\t\tthis.#fetches.set(key, group);\n\t\tvoid group.closed.then(() => {\n\t\t\tif (this.#fetches.get(key) === group) this.#fetches.delete(key);\n\t\t});\n\n\t\treturn this.#runFetch(broadcast, track, sequence, options, group);\n\t}\n\n\t// Open the FETCH stream and pump the response into the shared group. Setup errors close the\n\t// group (so coalesced mirrors observe them and the entry evicts) and reject this caller.\n\tasync #runFetch(\n\t\tbroadcast: Path.Valid,\n\t\ttrack: string,\n\t\tsequence: number,\n\t\toptions: track.FetchGroupOptions,\n\t\tgroup: netGroup.Producer,\n\t): Promise<netGroup.Consumer> {\n\t\ttry {\n\t\t\tif (!supportsTrackStream(this.version)) {\n\t\t\t\tthrow new Error(\"fetch group requires moq-lite-05 or newer\");\n\t\t\t}\n\n\t\t\tconst info = await this.#trackInfo(broadcast, track);\n\t\t\tconst priority = options.priority ?? 0;\n\t\t\tconst stream = await Stream.open(this.#quic, { sendOrder: sendOrder({ priority }) });\n\n\t\t\ttry {\n\t\t\t\tawait stream.writer.u53(StreamId.Fetch);\n\t\t\t\tawait new FetchMessage(broadcast, track, priority, sequence).encode(stream.writer, this.version);\n\t\t\t} catch (err: unknown) {\n\t\t\t\tstream.abort(error(err));\n\t\t\t\tthrow err;\n\t\t\t}\n\n\t\t\t// Mint this caller's reader before starting the pump, so the group has demand when the\n\t\t\t// pump begins watching it (an abandoned fetch cancels once every reader has left).\n\t\t\tconst consumer = group.mirror();\n\t\t\tvoid this.#runFetchResponse(stream, group, Time.Timescale(info.timescale));\n\t\t\treturn consumer;\n\t\t} catch (err: unknown) {\n\t\t\tgroup.close(error(err));\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t// Read the FETCH response (bare zigzag-delta-timestamped frames) into the group, then\n\t// FIN. A stream-level failure aborts the group so its reader observes the gap.\n\tasync #runFetchResponse(stream: Stream, group: netGroup.Producer, timescale: Time.Timescale): Promise<void> {\n\t\ttry {\n\t\t\tlet prevTs = 0n;\n\n\t\t\t// Serve until the stream FINs, the group closes, or every reader leaves. A group can\n\t\t\t// stay open indefinitely (a catalog or JSON stream), so an abandoned fetch is stopped by\n\t\t\t// demand, not by the stream ending. `closed` and `unused` are watched across frames as\n\t\t\t// stable promises (not re-subscribed to the signals each frame); the unused check is\n\t\t\t// level-triggered, so a coalesced fetch that arrives before we cancel re-arms and resumes.\n\t\t\tconst idle = Symbol(\"idle\");\n\t\t\tconst closed = Promise.resolve<Error | null>(group.closed);\n\t\t\tlet unused = group.unused().then(() => idle);\n\t\t\tfor (;;) {\n\t\t\t\tconst done = await Promise.race([stream.reader.done(), closed, unused]);\n\t\t\t\tif (done === idle) {\n\t\t\t\t\tif (!group.isClosed && group.used.peek()) {\n\t\t\t\t\t\tunused = group.unused().then(() => idle);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (done !== false) break;\n\n\t\t\t\tprevTs += unzigzag(await stream.reader.u62());\n\t\t\t\tconst timestamp = new Time.Timestamp(Number(prevTs), timescale);\n\t\t\t\tconst size = await stream.reader.u53();\n\t\t\t\tconst payload = await stream.reader.read(size);\n\t\t\t\tif (!payload) break;\n\t\t\t\tgroup.writeFrame({ payload, timestamp });\n\t\t\t}\n\n\t\t\tgroup.close();\n\t\t\tstream.close();\n\t\t} catch (err: unknown) {\n\t\t\tconst e = error(err);\n\t\t\tgroup.close(e);\n\t\t\tstream.abort(e);\n\t\t}\n\t}\n\n\t// Drains SUBSCRIBE_START/END/DROP on the subscribe stream until FIN (lite-05+).\n\t// The resolved range is informational here; the producer already orders groups.\n\t// Resolves (never rejects) on FIN or on the stream being reset out from under it,\n\t// so it's safe to drop from a Promise.race without an unhandled rejection.\n\tasync #drainResponses(stream: Stream): Promise<void> {\n\t\ttry {\n\t\t\tfor (;;) {\n\t\t\t\tconst resp = await decodeSubscribeResponseMaybe(stream.reader, this.version);\n\t\t\t\tif (!resp) return;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Stream closed or reset; nothing more to drain.\n\t\t}\n\t}\n\n\t/**\n\t * Send SUBSCRIBE_UPDATE messages whenever the track's aggregate subscription changes.\n\t *\n\t * Resolves cleanly when the stream or track closes, so the caller can include\n\t * this in Promise.race without leaving a dangling pending write that would\n\t * become an unhandled rejection if the user calls update after close.\n\t *\n\t * Peeks the signal at the top of every iteration so that updates which landed\n\t * before SubscribeOk arrived (or between iterations, before .next() registered\n\t * its listener) aren't lost.\n\t */\n\tasync #runSubscriptionUpdates(\n\t\tid: bigint,\n\t\tbroadcast: Path.Valid,\n\t\ttrack: track.Producer,\n\t\tmsg: Subscribe,\n\t\tstream: Stream,\n\t): Promise<void> {\n\t\tconst stopped: Promise<null> = Promise.race([track.closed, stream.reader.closed]).then(() => null);\n\t\tlet lastSent: track.Subscription = {\n\t\t\tpriority: msg.priority,\n\t\t\tordered: msg.ordered,\n\t\t\tlatencyMax: msg.maxLatency,\n\t\t\tstartGroup: msg.startGroup,\n\t\t\tendGroup: msg.endGroup,\n\t\t};\n\n\t\tfor (;;) {\n\t\t\tconst current = track.subscription.peek();\n\t\t\tif (current === undefined || this.#sameSubscription(current, lastSent)) {\n\t\t\t\t// Nothing new to send; wait for a change or termination.\n\t\t\t\tconst next = await Promise.race([track.subscription.changed(), stopped]);\n\t\t\t\tif (next === null) return;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst update = new SubscribeUpdate({\n\t\t\t\tpriority: current.priority ?? 0,\n\t\t\t\tordered: current.ordered,\n\t\t\t\tmaxLatency: current.latencyMax,\n\t\t\t\tstartGroup: current.startGroup,\n\t\t\t\tendGroup: current.endGroup,\n\t\t\t});\n\t\t\tawait update.encode(stream.writer, this.version);\n\t\t\tlastSent = { ...current };\n\t\t\tconsole.debug(`subscribe update: id=${id} broadcast=${broadcast} track=${track.name}`);\n\t\t}\n\t}\n\n\t#sameSubscription(a: track.Subscription, b: track.Subscription): boolean {\n\t\treturn (\n\t\t\t(a.priority ?? 0) === (b.priority ?? 0) &&\n\t\t\t(a.ordered ?? false) === (b.ordered ?? false) &&\n\t\t\t(a.latencyMax ?? 0) === (b.latencyMax ?? 0) &&\n\t\t\ta.startGroup === b.startGroup &&\n\t\t\ta.endGroup === b.endGroup\n\t\t);\n\t}\n\n\t/**\n\t * Handles a group message.\n\t * @param group - The group message\n\t * @param stream - The stream to read frames from\n\t *\n\t * @internal\n\t */\n\tasync runGroup(group: GroupMessage, stream: Reader) {\n\t\tconst entry = this.#subscribes.get(group.subscribe);\n\t\tif (!entry) {\n\t\t\tif (group.subscribe >= this.#subscribeNext) {\n\t\t\t\tthrow new Error(`unknown subscription: id=${group.subscribe}`);\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst { track, timescale } = entry;\n\t\tconst producer = new netGroup.Producer(group.sequence);\n\t\ttrack.writeGroup(producer);\n\n\t\ttry {\n\t\t\t// Block until the timescale is known; the group's stream can arrive before\n\t\t\t// TRACK_INFO (or implicit defaults) resolves it on the subscribe stream.\n\t\t\tlet scale = timescale.peek();\n\t\t\twhile (scale === undefined) {\n\t\t\t\tif (track.closed.peek() !== undefined) {\n\t\t\t\t\t// Subscription ended before the scale resolved; nothing to decode.\n\t\t\t\t\tproducer.close();\n\t\t\t\t\tstream.stop(new Error(\"cancel\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tawait Signal.race(timescale, track.closed);\n\t\t\t\tscale = timescale.peek();\n\t\t\t}\n\n\t\t\t// A non-zero scale means every frame is prefixed with a zigzag-delta timestamp\n\t\t\t// (the lite-05 FRAME format), which we decode into a Timestamp at that scale.\n\t\t\t// Scale 0 (pre-lite-05) carries no timestamp, so we wall-clock-stamp.\n\t\t\tlet prevTs = 0n;\n\n\t\t\tfor (;;) {\n\t\t\t\tconst done = await Promise.race([stream.done(), track.closed, producer.closed]);\n\t\t\t\tif (done !== false) break;\n\n\t\t\t\tlet timestamp: Time.Timestamp;\n\t\t\t\tif (scale !== 0) {\n\t\t\t\t\tprevTs += unzigzag(await stream.u62());\n\t\t\t\t\ttimestamp = new Time.Timestamp(Number(prevTs), Time.Timescale(scale));\n\t\t\t\t} else {\n\t\t\t\t\ttimestamp = Time.Timestamp.now();\n\t\t\t\t}\n\n\t\t\t\tconst size = await stream.u53();\n\t\t\t\tconst payload = await stream.read(size);\n\t\t\t\tif (!payload) break;\n\n\t\t\t\tproducer.writeFrame({ payload, timestamp });\n\t\t\t}\n\n\t\t\tproducer.close();\n\t\t\tstream.stop(new Error(\"cancel\"));\n\t\t} catch (err: unknown) {\n\t\t\tconst e = error(err);\n\t\t\tproducer.close(e);\n\t\t\tstream.stop(e);\n\t\t}\n\t}\n\n\t/**\n\t * Receives QUIC datagrams and routes each to its subscription's track producer (lite-05 §6.4).\n\t *\n\t * Returns immediately on a non-datagram transport or pre-lite-05 version. A decode error or an\n\t * unknown subscribe id drops that datagram without tearing down the session (best-effort); the\n\t * loop ends only when the datagram stream closes.\n\t *\n\t * @internal\n\t */\n\tasync runDatagrams(): Promise<void> {\n\t\tif (!hasDatagrams(this.version) || DatagramStream.maxDatagramSize(this.#quic) === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Never reject: this loop is awaited alongside the connection's other tasks, so a\n\t\t// datagram-stream failure must not tear the whole session down (it's best-effort).\n\t\tconst reader = DatagramStream.datagramReader(this.#quic);\n\t\tif (!reader) return;\n\n\t\ttry {\n\t\t\ttry {\n\t\t\t\tfor (;;) {\n\t\t\t\t\tconst { value, done } = await reader.read();\n\t\t\t\t\tif (done) break;\n\t\t\t\t\tif (!value) continue;\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait this.#routeDatagram(value);\n\t\t\t\t\t} catch (err: unknown) {\n\t\t\t\t\t\tconsole.debug(`dropping datagram: ${reason(err)}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\treader.releaseLock();\n\t\t\t}\n\t\t} catch (err: unknown) {\n\t\t\tconst e = error(err);\n\t\t\tif (e.message === \"The session is closed.\") {\n\t\t\t\tconsole.debug(`datagram receive stopped: ${e.message}`);\n\t\t\t} else {\n\t\t\t\tconsole.warn(\"datagram stream error\", err);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Decode one datagram body and hand it to the matching subscription's producer. Drops the\n\t// datagram (best-effort) if the subscription is unknown/closed or its timescale isn't resolved.\n\tasync #routeDatagram(payload: Uint8Array): Promise<void> {\n\t\tconst dg = await DatagramMessage.decode(payload);\n\n\t\tconst entry = this.#subscribes.get(dg.subscribe);\n\t\tif (!entry) return; // Unknown or already-closed subscription.\n\n\t\t// Datagrams are lite-05+, which always negotiates a timescale; if it hasn't resolved\n\t\t// yet (the datagram raced ahead of TRACK_INFO), drop rather than guess.\n\t\tconst scale = entry.timescale.peek();\n\t\tif (!scale) return;\n\n\t\tconst timestamp = new Time.Timestamp(dg.timestamp, Time.Timescale(scale));\n\t\tentry.track.writeDatagram({ sequence: dg.sequence, timestamp, payload: dg.payload });\n\t}\n\n\t/**\n\t * Opens a PROBE bidi stream to receive bandwidth estimates from the publisher.\n\t * Returns immediately if recv bandwidth is not supported.\n\t *\n\t * Probe is best-effort telemetry: a stream-level failure (peer reset, FIN,\n\t * missing peer support, transport hiccup) is caught and logged, never\n\t * propagated to the connection. On exit the bandwidth/RTT signals are\n\t * cleared so consumers see them as stale.\n\t *\n\t * @internal\n\t */\n\t// Await the peer's advertised probe level, blocking until its SETUP arrives. The peer\n\t// MUST send exactly one SETUP, so this resolves once that stream is read.\n\tasync #peerProbeLevel(peerSetup: Signal<Setup | undefined>): Promise<ProbeLevel> {\n\t\tlet setup = peerSetup.peek();\n\t\twhile (setup === undefined) {\n\t\t\tsetup = await peerSetup.changed();\n\t\t}\n\t\treturn setup.probe;\n\t}\n\n\tasync runProbe(): Promise<void> {\n\t\tif (!this.#probe) return;\n\t\tif (this.version === Version.DRAFT_01 || this.version === Version.DRAFT_02) return;\n\n\t\t// Lite-05+ gates the PROBE stream on the peer advertising Probe >= Report in its\n\t\t// SETUP. Wait for the SETUP, then bail if the peer can't report bitrate. Older\n\t\t// drafts have no SETUP, so they keep probing unconditionally.\n\t\tif (this.#peerSetup) {\n\t\t\tconst probe = await this.#peerProbeLevel(this.#peerSetup);\n\t\t\tif (probe < ProbeLevel.Report) return;\n\t\t}\n\n\t\t// Probe is best-effort: any failure (stream reset by peer, missing peer support,\n\t\t// transport hiccup) MUST NOT tear down the connection. On error, drop the\n\t\t// estimates so consumers know they're stale.\n\t\ttry {\n\t\t\tconst stream = await Stream.open(this.#quic);\n\t\t\tawait stream.writer.u53(StreamId.Probe);\n\n\t\t\tfor (;;) {\n\t\t\t\tconst probe = await Probe.decodeMaybe(stream.reader, this.version);\n\t\t\t\tif (!probe) break;\n\t\t\t\t// lite-03 carries no RTT field, so an absent value there means \"not\n\t\t\t\t// carried\" and the last reading stands. From lite-04 the field is\n\t\t\t\t// always present and 0 explicitly means unknown, so undefined is the\n\t\t\t\t// peer retracting a value we would otherwise hold forever.\n\t\t\t\tconst prev = this.#probe.peek();\n\t\t\t\tconst rtt = probe.rtt !== undefined ? Time.Milli(probe.rtt) : undefined;\n\t\t\t\tthis.#probe.set({\n\t\t\t\t\t// `undefined` is the peer reporting \"unknown\", not an estimate of\n\t\t\t\t\t// zero; letting it through would become a real 0 bps ABR target.\n\t\t\t\t\testimatedRecvRate: probe.bitrate,\n\t\t\t\t\trtt: hasProbeRtt(this.version) ? rtt : (rtt ?? prev.rtt),\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (err: unknown) {\n\t\t\tif (!this.#closed.signal.aborted) {\n\t\t\t\tconsole.warn(\"probe stream error\", err);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.#probe.set({});\n\t\t}\n\t}\n\n\tclose() {\n\t\tthis.#closed.abort();\n\n\t\tfor (const { track } of this.#subscribes.values()) {\n\t\t\ttrack.close();\n\t\t}\n\n\t\tthis.#subscribes.clear();\n\t}\n}\n\n/**\n * A broadcast consumed from a lite session. It resolves `track.Consumer.info()` and\n * `.fetchGroup()` over the wire (lite-05+ TRACK / FETCH streams) by reaching into the\n * {@link Subscriber} it was opened from, the way the Rust `BroadcastConsumer` holds its\n * session. Live subscribes still flow through the inherited requested() queue.\n */\nclass ConsumeBroadcast extends broadcast.Consumer {\n\t#subscriber: Subscriber;\n\t#path: Path.Valid;\n\n\tconstructor(subscriber: Subscriber, path: Path.Valid, state?: never) {\n\t\tsuper(state);\n\t\tthis.#subscriber = subscriber;\n\t\tthis.#path = path;\n\t}\n\n\t// Preserve the subclass (and its wire-backed info/fetchGroup) when the consume cache shares\n\t// this broadcast across callers.\n\toverride clone(): ConsumeBroadcast {\n\t\treturn new ConsumeBroadcast(this.#subscriber, this.#path, this.shareState());\n\t}\n\n\toverride resolveTrackInfo(name: string): Promise<track.Info> {\n\t\treturn this.#subscriber.resolveTrackInfo(this.#path, name);\n\t}\n\n\toverride fetchGroup(name: string, sequence: number, options?: track.FetchGroupOptions): Promise<netGroup.Consumer> {\n\t\treturn this.#subscriber.fetchGroup(this.#path, name, sequence, options);\n\t}\n}\n"]}
package/lite/track.d.ts CHANGED
@@ -1,36 +1,48 @@
1
1
  import * as Path from "../path";
2
2
  import type { Reader, Writer } from "../stream";
3
- import { type Version } from "./version";
3
+ import { Version } from "./version";
4
4
  /**
5
- * Sent by a subscriber on a Track stream (moq-lite-05+) to request a track's
6
- * immutable publisher properties without subscribing or fetching.
5
+ * TRACK request: the first (and only) subscriber message on a Track Stream (0x6).
6
+ * Asks for a track's immutable publisher properties without subscribing or fetching.
7
7
  */
8
8
  export declare class Track {
9
9
  #private;
10
10
  broadcast: Path.Valid;
11
11
  track: string;
12
- constructor(props: {
13
- broadcast: Path.Valid;
14
- track: string;
15
- });
12
+ constructor(broadcast: Path.Valid, track: string);
16
13
  encode(w: Writer, version: Version): Promise<void>;
17
14
  static decode(r: Reader, version: Version): Promise<Track>;
18
15
  }
19
16
  /**
20
- * The publisher's reply on a Track stream (moq-lite-05+): the track's immutable
21
- * properties. Sent once, then the publisher FINs the stream.
17
+ * TRACK_INFO reply: the publisher's sole message on a Track Stream, carrying the
18
+ * track's immutable properties. Fetched once and reused across every SUBSCRIBE and
19
+ * FETCH for the track.
22
20
  */
23
21
  export declare class TrackInfo {
24
22
  #private;
23
+ /** The publisher's tie-break priority for this track. */
25
24
  priority: number;
25
+ /**
26
+ * Whether groups are prioritized in sequence order. Groups may always arrive
27
+ * out-of-order (or not at all) over the network.
28
+ */
26
29
  ordered: boolean;
27
- maxLatency: number;
30
+ /**
31
+ * Publisher Max Latency: an upper bound (milliseconds) on how long the publisher
32
+ * caches a non-latest group past the arrival of a newer one.
33
+ */
34
+ latencyMax: number;
35
+ /**
36
+ * Per-frame timestamp scale (units per second). Mandatory on Lite05: a real
37
+ * (non-zero) scale, and every frame on the wire is prefixed with a zigzag-delta
38
+ * timestamp at this scale.
39
+ */
28
40
  timescale: number;
29
- constructor(props: {
41
+ constructor({ priority, ordered, latencyMax, timescale, }: {
30
42
  priority?: number;
31
43
  ordered?: boolean;
32
- maxLatency?: number;
33
- timescale: number;
44
+ latencyMax?: number;
45
+ timescale?: number;
34
46
  });
35
47
  encode(w: Writer, version: Version): Promise<void>;
36
48
  static decode(r: Reader, version: Version): Promise<TrackInfo>;
@@ -1 +1 @@
1
- {"version":3,"file":"track.d.ts","sourceRoot":"","sources":["../../src/lite/track.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAkB,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5D;;;GAGG;AACH,qBAAa,KAAK;;IACjB,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IAEd,YAAY,KAAK,EAAE;QAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAG1D;IAaK,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAGvD;IAED,OAAa,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAG/D;CACD;AAED;;;GAGG;AACH,qBAAa,SAAS;;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAElB,YAAY,KAAK,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAQlG;IAmBK,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAGvD;IAED,OAAa,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAGnE;CACD"}
1
+ {"version":3,"file":"track.d.ts","sourceRoot":"","sources":["../../src/lite/track.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAevC;;;GAGG;AACH,qBAAa,KAAK;;IACjB,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IAEd,YAAY,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAG/C;IAaK,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAGvD;IAED,OAAa,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAG/D;CACD;AAED;;;;GAIG;AACH,qBAAa,SAAS;;IACrB,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB,YAAY,EACX,QAAY,EACZ,OAAe,EACf,UAAc,EACd,SAAa,GACb,EAAE;QACF,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;KACnB,EAKA;IAoBK,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAMvD;IAED,OAAa,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAGnE;CACD"}
package/lite/track.js CHANGED
@@ -1,17 +1,29 @@
1
1
  /* @ts-self-types="./track.d.ts" */
2
2
  import * as Path from "../path.js";
3
3
  import * as Message from "./message.js";
4
- import { hasTrackStream } from "./version.js";
4
+ import { Version } from "./version.js";
5
+ // The Track Stream (0x6) is draft-05+ only.
6
+ function guardTrack(version) {
7
+ switch (version) {
8
+ case Version.DRAFT_01:
9
+ case Version.DRAFT_02:
10
+ case Version.DRAFT_03:
11
+ case Version.DRAFT_04:
12
+ throw new Error("track stream not supported for this version");
13
+ default:
14
+ break;
15
+ }
16
+ }
5
17
  /**
6
- * Sent by a subscriber on a Track stream (moq-lite-05+) to request a track's
7
- * immutable publisher properties without subscribing or fetching.
18
+ * TRACK request: the first (and only) subscriber message on a Track Stream (0x6).
19
+ * Asks for a track's immutable publisher properties without subscribing or fetching.
8
20
  */
9
21
  export class Track {
10
22
  broadcast;
11
23
  track;
12
- constructor(props) {
13
- this.broadcast = props.broadcast;
14
- this.track = props.track;
24
+ constructor(broadcast, track) {
25
+ this.broadcast = broadcast;
26
+ this.track = track;
15
27
  }
16
28
  async #encode(w) {
17
29
  await w.string(Path.encode(this.broadcast));
@@ -20,62 +32,75 @@ export class Track {
20
32
  static async #decode(r) {
21
33
  const broadcast = Path.decode(await r.string());
22
34
  const track = await r.string();
23
- return new Track({ broadcast, track });
35
+ return new Track(broadcast, track);
24
36
  }
25
37
  async encode(w, version) {
26
- if (!hasTrackStream(version))
27
- throw new Error("TRACK requires moq-lite-05+");
28
- return Message.encode(w, this.#encode.bind(this));
38
+ guardTrack(version);
39
+ return Message.encode(w, (w) => this.#encode(w));
29
40
  }
30
41
  static async decode(r, version) {
31
- if (!hasTrackStream(version))
32
- throw new Error("TRACK requires moq-lite-05+");
33
- return Message.decode(r, Track.#decode);
42
+ guardTrack(version);
43
+ return Message.decode(r, (r) => Track.#decode(r));
34
44
  }
35
45
  }
36
46
  /**
37
- * The publisher's reply on a Track stream (moq-lite-05+): the track's immutable
38
- * properties. Sent once, then the publisher FINs the stream.
47
+ * TRACK_INFO reply: the publisher's sole message on a Track Stream, carrying the
48
+ * track's immutable properties. Fetched once and reused across every SUBSCRIBE and
49
+ * FETCH for the track.
39
50
  */
40
51
  export class TrackInfo {
52
+ /** The publisher's tie-break priority for this track. */
41
53
  priority;
54
+ /**
55
+ * Whether groups are prioritized in sequence order. Groups may always arrive
56
+ * out-of-order (or not at all) over the network.
57
+ */
42
58
  ordered;
43
- maxLatency;
59
+ /**
60
+ * Publisher Max Latency: an upper bound (milliseconds) on how long the publisher
61
+ * caches a non-latest group past the arrival of a newer one.
62
+ */
63
+ latencyMax;
64
+ /**
65
+ * Per-frame timestamp scale (units per second). Mandatory on Lite05: a real
66
+ * (non-zero) scale, and every frame on the wire is prefixed with a zigzag-delta
67
+ * timestamp at this scale.
68
+ */
44
69
  timescale;
45
- constructor(props) {
46
- if (!Number.isInteger(props.timescale) || props.timescale <= 0) {
47
- throw new Error("TRACK_INFO timescale must be a positive integer");
48
- }
49
- this.priority = props.priority ?? 0;
50
- this.ordered = props.ordered ?? false;
51
- this.maxLatency = props.maxLatency ?? 0;
52
- this.timescale = props.timescale;
70
+ constructor({ priority = 0, ordered = false, latencyMax = 0, timescale = 0, }) {
71
+ this.priority = priority;
72
+ this.ordered = ordered;
73
+ this.latencyMax = latencyMax;
74
+ this.timescale = timescale;
53
75
  }
54
76
  async #encode(w) {
55
77
  await w.u8(this.priority);
56
78
  await w.bool(this.ordered);
57
- await w.u53(this.maxLatency);
79
+ await w.u53(this.latencyMax);
58
80
  await w.u53(this.timescale);
59
81
  }
60
82
  static async #decode(r) {
61
83
  const priority = await r.u8();
62
84
  const ordered = await r.bool();
63
- const maxLatency = await r.u53();
85
+ const latencyMax = await r.u53();
64
86
  const timescale = await r.u53();
65
- // A zero timescale is a protocol violation: every track has a media timeline.
87
+ // Mandatory on Lite05: a zero scale is invalid (mirrors Rust's Timescale::new rejection),
88
+ // and would otherwise throw later when wrapped in Timescale().
66
89
  if (timescale === 0)
67
- throw new Error("TRACK_INFO timescale must be a positive integer");
68
- return new TrackInfo({ priority, ordered, maxLatency, timescale });
90
+ throw new Error("track timescale must be non-zero");
91
+ return new TrackInfo({ priority, ordered, latencyMax, timescale });
69
92
  }
70
93
  async encode(w, version) {
71
- if (!hasTrackStream(version))
72
- throw new Error("TRACK_INFO requires moq-lite-05+");
73
- return Message.encode(w, this.#encode.bind(this));
94
+ guardTrack(version);
95
+ // Reject a zero timescale on encode too, so an invalid TrackInfo fails fast on
96
+ // the sender rather than only at the peer's decoder.
97
+ if (this.timescale === 0)
98
+ throw new Error("track timescale must be non-zero");
99
+ return Message.encode(w, (w) => this.#encode(w));
74
100
  }
75
101
  static async decode(r, version) {
76
- if (!hasTrackStream(version))
77
- throw new Error("TRACK_INFO requires moq-lite-05+");
78
- return Message.decode(r, TrackInfo.#decode);
102
+ guardTrack(version);
103
+ return Message.decode(r, (r) => TrackInfo.#decode(r));
79
104
  }
80
105
  }
81
106
  //# sourceMappingURL=track.js.map
package/lite/track.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"track.js","sourceRoot":"","sources":["../../src/lite/track.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Path from \"../path.ts\";\nimport type { Reader, Writer } from \"../stream.ts\";\nimport * as Message from \"./message.ts\";\nimport { hasTrackStream, type Version } from \"./version.ts\";\n\n/**\n * Sent by a subscriber on a Track stream (moq-lite-05+) to request a track's\n * immutable publisher properties without subscribing or fetching.\n */\nexport class Track {\n\tbroadcast: Path.Valid;\n\ttrack: string;\n\n\tconstructor(props: { broadcast: Path.Valid; track: string }) {\n\t\tthis.broadcast = props.broadcast;\n\t\tthis.track = props.track;\n\t}\n\n\tasync #encode(w: Writer) {\n\t\tawait w.string(Path.encode(this.broadcast));\n\t\tawait w.string(this.track);\n\t}\n\n\tstatic async #decode(r: Reader): Promise<Track> {\n\t\tconst broadcast = Path.decode(await r.string());\n\t\tconst track = await r.string();\n\t\treturn new Track({ broadcast, track });\n\t}\n\n\tasync encode(w: Writer, version: Version): Promise<void> {\n\t\tif (!hasTrackStream(version)) throw new Error(\"TRACK requires moq-lite-05+\");\n\t\treturn Message.encode(w, this.#encode.bind(this));\n\t}\n\n\tstatic async decode(r: Reader, version: Version): Promise<Track> {\n\t\tif (!hasTrackStream(version)) throw new Error(\"TRACK requires moq-lite-05+\");\n\t\treturn Message.decode(r, Track.#decode);\n\t}\n}\n\n/**\n * The publisher's reply on a Track stream (moq-lite-05+): the track's immutable\n * properties. Sent once, then the publisher FINs the stream.\n */\nexport class TrackInfo {\n\tpriority: number;\n\tordered: boolean;\n\tmaxLatency: number;\n\ttimescale: number;\n\n\tconstructor(props: { priority?: number; ordered?: boolean; maxLatency?: number; timescale: number }) {\n\t\tif (!Number.isInteger(props.timescale) || props.timescale <= 0) {\n\t\t\tthrow new Error(\"TRACK_INFO timescale must be a positive integer\");\n\t\t}\n\t\tthis.priority = props.priority ?? 0;\n\t\tthis.ordered = props.ordered ?? false;\n\t\tthis.maxLatency = props.maxLatency ?? 0;\n\t\tthis.timescale = props.timescale;\n\t}\n\n\tasync #encode(w: Writer) {\n\t\tawait w.u8(this.priority);\n\t\tawait w.bool(this.ordered);\n\t\tawait w.u53(this.maxLatency);\n\t\tawait w.u53(this.timescale);\n\t}\n\n\tstatic async #decode(r: Reader): Promise<TrackInfo> {\n\t\tconst priority = await r.u8();\n\t\tconst ordered = await r.bool();\n\t\tconst maxLatency = await r.u53();\n\t\tconst timescale = await r.u53();\n\t\t// A zero timescale is a protocol violation: every track has a media timeline.\n\t\tif (timescale === 0) throw new Error(\"TRACK_INFO timescale must be a positive integer\");\n\t\treturn new TrackInfo({ priority, ordered, maxLatency, timescale });\n\t}\n\n\tasync encode(w: Writer, version: Version): Promise<void> {\n\t\tif (!hasTrackStream(version)) throw new Error(\"TRACK_INFO requires moq-lite-05+\");\n\t\treturn Message.encode(w, this.#encode.bind(this));\n\t}\n\n\tstatic async decode(r: Reader, version: Version): Promise<TrackInfo> {\n\t\tif (!hasTrackStream(version)) throw new Error(\"TRACK_INFO requires moq-lite-05+\");\n\t\treturn Message.decode(r, TrackInfo.#decode);\n\t}\n}\n"]}
1
+ {"version":3,"file":"track.js","sourceRoot":"","sources":["../../src/lite/track.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Path from \"../path.ts\";\nimport type { Reader, Writer } from \"../stream.ts\";\nimport * as Message from \"./message.ts\";\nimport { Version } from \"./version.ts\";\n\n// The Track Stream (0x6) is draft-05+ only.\nfunction guardTrack(version: Version) {\n\tswitch (version) {\n\t\tcase Version.DRAFT_01:\n\t\tcase Version.DRAFT_02:\n\t\tcase Version.DRAFT_03:\n\t\tcase Version.DRAFT_04:\n\t\t\tthrow new Error(\"track stream not supported for this version\");\n\t\tdefault:\n\t\t\tbreak;\n\t}\n}\n\n/**\n * TRACK request: the first (and only) subscriber message on a Track Stream (0x6).\n * Asks for a track's immutable publisher properties without subscribing or fetching.\n */\nexport class Track {\n\tbroadcast: Path.Valid;\n\ttrack: string;\n\n\tconstructor(broadcast: Path.Valid, track: string) {\n\t\tthis.broadcast = broadcast;\n\t\tthis.track = track;\n\t}\n\n\tasync #encode(w: Writer) {\n\t\tawait w.string(Path.encode(this.broadcast));\n\t\tawait w.string(this.track);\n\t}\n\n\tstatic async #decode(r: Reader): Promise<Track> {\n\t\tconst broadcast = Path.decode(await r.string());\n\t\tconst track = await r.string();\n\t\treturn new Track(broadcast, track);\n\t}\n\n\tasync encode(w: Writer, version: Version): Promise<void> {\n\t\tguardTrack(version);\n\t\treturn Message.encode(w, (w) => this.#encode(w));\n\t}\n\n\tstatic async decode(r: Reader, version: Version): Promise<Track> {\n\t\tguardTrack(version);\n\t\treturn Message.decode(r, (r) => Track.#decode(r));\n\t}\n}\n\n/**\n * TRACK_INFO reply: the publisher's sole message on a Track Stream, carrying the\n * track's immutable properties. Fetched once and reused across every SUBSCRIBE and\n * FETCH for the track.\n */\nexport class TrackInfo {\n\t/** The publisher's tie-break priority for this track. */\n\tpriority: number;\n\t/**\n\t * Whether groups are prioritized in sequence order. Groups may always arrive\n\t * out-of-order (or not at all) over the network.\n\t */\n\tordered: boolean;\n\t/**\n\t * Publisher Max Latency: an upper bound (milliseconds) on how long the publisher\n\t * caches a non-latest group past the arrival of a newer one.\n\t */\n\tlatencyMax: number;\n\t/**\n\t * Per-frame timestamp scale (units per second). Mandatory on Lite05: a real\n\t * (non-zero) scale, and every frame on the wire is prefixed with a zigzag-delta\n\t * timestamp at this scale.\n\t */\n\ttimescale: number;\n\n\tconstructor({\n\t\tpriority = 0,\n\t\tordered = false,\n\t\tlatencyMax = 0,\n\t\ttimescale = 0,\n\t}: {\n\t\tpriority?: number;\n\t\tordered?: boolean;\n\t\tlatencyMax?: number;\n\t\ttimescale?: number;\n\t}) {\n\t\tthis.priority = priority;\n\t\tthis.ordered = ordered;\n\t\tthis.latencyMax = latencyMax;\n\t\tthis.timescale = timescale;\n\t}\n\n\tasync #encode(w: Writer) {\n\t\tawait w.u8(this.priority);\n\t\tawait w.bool(this.ordered);\n\t\tawait w.u53(this.latencyMax);\n\t\tawait w.u53(this.timescale);\n\t}\n\n\tstatic async #decode(r: Reader): Promise<TrackInfo> {\n\t\tconst priority = await r.u8();\n\t\tconst ordered = await r.bool();\n\t\tconst latencyMax = await r.u53();\n\t\tconst timescale = await r.u53();\n\t\t// Mandatory on Lite05: a zero scale is invalid (mirrors Rust's Timescale::new rejection),\n\t\t// and would otherwise throw later when wrapped in Timescale().\n\t\tif (timescale === 0) throw new Error(\"track timescale must be non-zero\");\n\t\treturn new TrackInfo({ priority, ordered, latencyMax, timescale });\n\t}\n\n\tasync encode(w: Writer, version: Version): Promise<void> {\n\t\tguardTrack(version);\n\t\t// Reject a zero timescale on encode too, so an invalid TrackInfo fails fast on\n\t\t// the sender rather than only at the peer's decoder.\n\t\tif (this.timescale === 0) throw new Error(\"track timescale must be non-zero\");\n\t\treturn Message.encode(w, (w) => this.#encode(w));\n\t}\n\n\tstatic async decode(r: Reader, version: Version): Promise<TrackInfo> {\n\t\tguardTrack(version);\n\t\treturn Message.decode(r, (r) => TrackInfo.#decode(r));\n\t}\n}\n"]}
package/lite/version.d.ts CHANGED
@@ -3,14 +3,49 @@ export declare const Version: {
3
3
  readonly DRAFT_02: 4279086338;
4
4
  readonly DRAFT_03: 4279086339;
5
5
  readonly DRAFT_04: 4279086340;
6
- readonly DRAFT_05_WIP: 4279086341;
6
+ readonly DRAFT_05: 4279086341;
7
+ readonly DRAFT_06: 4279086342;
7
8
  };
8
9
  export type Version = (typeof Version)[keyof typeof Version];
10
+ /**
11
+ * Whether the PROBE message carries the RTT field.
12
+ *
13
+ * Added in lite-04. Lite-03 carries the bitrate alone, so a report with only an RTT to
14
+ * give says nothing there and must not be sent.
15
+ */
16
+ export declare function hasProbeRtt(version: Version): boolean;
17
+ export declare function hasSetupStream(version: Version): boolean;
18
+ export declare function hasDatagrams(version: Version): boolean;
19
+ /** Whether announce streams begin with ANNOUNCE_OK and omit the sender's origin from each hop chain. */
20
+ export declare function hasAnnounceOk(version: Version): boolean;
21
+ /** Whether the version can replace an advertisement in place rather than retracting and
22
+ * re-announcing it. Added in lite-05 as a duplicate ANNOUNCE; lite-06 gave it a message of
23
+ * its own (ANNOUNCE_UPDATE) and made the duplicate a violation. */
24
+ export declare function restartSupported(version: Version): boolean;
25
+ /** Whether announcements carry implicit announce ids: each `active` assigns the next
26
+ * per-stream ordinal, and `ended`/`restart` reference that id instead of repeating the
27
+ * path. Added in lite-06. */
28
+ export declare function hasAnnounceId(version: Version): boolean;
29
+ /** Whether ANNOUNCE_REQUEST carries the Exclude Hop field: the subscriber's own
30
+ * origin id, which the publisher uses to skip announces whose hop chain already
31
+ * passed through the subscriber. Present in lite-04 and lite-05 only.
32
+ *
33
+ * The receiver's own reflected-announce check drops those announces anyway (and
34
+ * catches loops of any length, not just the two-hop case), so lite-06 drops the
35
+ * field and keeps the check.
36
+ *
37
+ * Unlike the gates above, this lists the versions that *have* the field: it was
38
+ * removed rather than added, so future versions default to not carrying it. */
39
+ export declare function hasExcludeHop(version: Version): boolean;
40
+ /** Whether announcements carry a route cost varint alongside the hop chain: the
41
+ * marginal cost of pulling the broadcast via this route, accumulated per link.
42
+ * Added in lite-06. Older versions carry nothing, so a received route stays at
43
+ * zero and routing falls back to the hop-count tie-break. */
44
+ export declare function hasRouteCost(version: Version): boolean;
9
45
  export declare const ALPN = "moql";
10
46
  export declare const ALPN_03 = "moq-lite-03";
11
47
  export declare const ALPN_04 = "moq-lite-04";
12
- export declare const ALPN_05_WIP = "moq-lite-05-wip";
48
+ export declare const ALPN_05 = "moq-lite-05";
49
+ export declare const ALPN_06_WIP = "moq-lite-06-wip";
13
50
  export declare function versionName(v: Version): string;
14
- export declare function hasSetupStream(v: Version): boolean;
15
- export declare function hasTrackStream(v: Version): boolean;
16
51
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/lite/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO;aACnB,QAAQ,EAAE,UAAU;aACpB,QAAQ,EAAE,UAAU;aACpB,QAAQ,EAAE,UAAU;aACpB,QAAQ,EAAE,UAAU;aAGpB,YAAY,EAAE,UAAU;CACf,CAAC;AAEX,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,OAAO,OAAO,CAAC,CAAC;AAI7D,eAAO,MAAM,IAAI,SAAS,CAAC;AAG3B,eAAO,MAAM,OAAO,gBAAgB,CAAC;AAGrC,eAAO,MAAM,OAAO,gBAAgB,CAAC;AAIrC,eAAO,MAAM,WAAW,oBAAoB,CAAC;AAU7C,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAE9C;AAGD,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAElD;AAKD,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAElD"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/lite/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO;aACnB,QAAQ,EAAE,UAAU;aACpB,QAAQ,EAAE,UAAU;aACpB,QAAQ,EAAE,UAAU;aACpB,QAAQ,EAAE,UAAU;aACpB,QAAQ,EAAE,UAAU;aAIpB,QAAQ,EAAE,UAAU;CACX,CAAC;AAEX,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,OAAO,OAAO,CAAC,CAAC;AAE7D;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAUrD;AAID,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAWxD;AAKD,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAWtD;AAED,wGAAwG;AACxG,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAWvD;AAED;;mEAEmE;AACnE,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAW1D;AAED;;6BAE6B;AAC7B,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAYvD;AAED;;;;;;;;;+EAS+E;AAC/E,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAQvD;AAED;;;6DAG6D;AAC7D,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAYtD;AAID,eAAO,MAAM,IAAI,SAAS,CAAC;AAG3B,eAAO,MAAM,OAAO,gBAAgB,CAAC;AAGrC,eAAO,MAAM,OAAO,gBAAgB,CAAC;AAGrC,eAAO,MAAM,OAAO,gBAAgB,CAAC;AAKrC,eAAO,MAAM,WAAW,oBAAoB,CAAC;AAW7C,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAE9C"}