@norskvideo/moq-net 0.1.8 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (286) hide show
  1. package/README.md +2 -2
  2. package/announce.d.ts +7 -0
  3. package/announce.d.ts.map +1 -0
  4. package/announce.js +8 -0
  5. package/announce.js.map +1 -0
  6. package/announced.d.ts +49 -91
  7. package/announced.d.ts.map +1 -1
  8. package/announced.js +21 -156
  9. package/announced.js.map +1 -1
  10. package/bandwidth.d.ts +163 -0
  11. package/bandwidth.d.ts.map +1 -0
  12. package/bandwidth.js +304 -0
  13. package/bandwidth.js.map +1 -0
  14. package/bandwidth_api.d.ts +7 -0
  15. package/bandwidth_api.d.ts.map +1 -0
  16. package/bandwidth_api.js +8 -0
  17. package/bandwidth_api.js.map +1 -0
  18. package/broadcast.d.ts +44 -35
  19. package/broadcast.d.ts.map +1 -1
  20. package/broadcast.js +104 -60
  21. package/broadcast.js.map +1 -1
  22. package/connection/accept.d.ts +16 -1
  23. package/connection/accept.d.ts.map +1 -1
  24. package/connection/accept.js +52 -28
  25. package/connection/accept.js.map +1 -1
  26. package/connection/browser.d.ts.map +1 -1
  27. package/connection/browser.js +9 -7
  28. package/connection/browser.js.map +1 -1
  29. package/connection/connect.d.ts +30 -6
  30. package/connection/connect.d.ts.map +1 -1
  31. package/connection/connect.js +110 -54
  32. package/connection/connect.js.map +1 -1
  33. package/connection/established.d.ts +17 -21
  34. package/connection/established.d.ts.map +1 -1
  35. package/connection/established.js.map +1 -1
  36. package/connection/forward.d.ts +2 -0
  37. package/connection/forward.d.ts.map +1 -0
  38. package/connection/forward.js +173 -0
  39. package/connection/forward.js.map +1 -0
  40. package/connection/handshake.d.ts +1 -0
  41. package/connection/handshake.d.ts.map +1 -1
  42. package/connection/handshake.js +5 -2
  43. package/connection/handshake.js.map +1 -1
  44. package/connection/index.d.ts +5 -5
  45. package/connection/index.d.ts.map +1 -1
  46. package/connection/index.js +4 -5
  47. package/connection/index.js.map +1 -1
  48. package/connection/pool.d.ts +186 -0
  49. package/connection/pool.d.ts.map +1 -0
  50. package/connection/pool.js +361 -0
  51. package/connection/pool.js.map +1 -0
  52. package/connection/reload.d.ts +14 -93
  53. package/connection/reload.d.ts.map +1 -1
  54. package/connection/reload.js +217 -81
  55. package/connection/reload.js.map +1 -1
  56. package/connection/stats.d.ts +3 -26
  57. package/connection/stats.d.ts.map +1 -1
  58. package/connection/stats.js.map +1 -1
  59. package/connection/transport.d.ts +0 -7
  60. package/connection/transport.d.ts.map +1 -1
  61. package/consume.d.ts +1 -43
  62. package/consume.d.ts.map +1 -1
  63. package/consume.js +1 -1
  64. package/consume.js.map +1 -1
  65. package/error.d.ts +180 -29
  66. package/error.d.ts.map +1 -1
  67. package/error.js +331 -16
  68. package/error.js.map +1 -1
  69. package/errors.d.ts +7 -0
  70. package/errors.d.ts.map +1 -0
  71. package/errors.js +8 -0
  72. package/errors.js.map +1 -0
  73. package/group.d.ts +9 -43
  74. package/group.d.ts.map +1 -1
  75. package/group.js +284 -69
  76. package/group.js.map +1 -1
  77. package/hop.d.ts +115 -0
  78. package/hop.d.ts.map +1 -0
  79. package/hop.js +119 -0
  80. package/hop.js.map +1 -0
  81. package/ietf/adapter.d.ts +5 -1
  82. package/ietf/adapter.d.ts.map +1 -1
  83. package/ietf/adapter.js +105 -60
  84. package/ietf/adapter.js.map +1 -1
  85. package/ietf/aliases.d.ts +1 -78
  86. package/ietf/aliases.d.ts.map +1 -1
  87. package/ietf/cluster.d.ts +9 -123
  88. package/ietf/cluster.d.ts.map +1 -1
  89. package/ietf/cluster.js +84 -44
  90. package/ietf/cluster.js.map +1 -1
  91. package/ietf/connection.d.ts +6 -72
  92. package/ietf/connection.d.ts.map +1 -1
  93. package/ietf/connection.js +62 -56
  94. package/ietf/connection.js.map +1 -1
  95. package/ietf/error.d.ts +11 -0
  96. package/ietf/error.d.ts.map +1 -0
  97. package/ietf/error.js +193 -0
  98. package/ietf/error.js.map +1 -0
  99. package/ietf/fetch.d.ts +7 -20
  100. package/ietf/fetch.d.ts.map +1 -1
  101. package/ietf/fetch.js +52 -22
  102. package/ietf/fetch.js.map +1 -1
  103. package/ietf/filter.d.ts +2 -0
  104. package/ietf/filter.d.ts.map +1 -1
  105. package/ietf/filter.js +10 -1
  106. package/ietf/filter.js.map +1 -1
  107. package/ietf/goaway.d.ts.map +1 -1
  108. package/ietf/goaway.js +22 -5
  109. package/ietf/goaway.js.map +1 -1
  110. package/ietf/hidden.d.ts +2 -0
  111. package/ietf/hidden.d.ts.map +1 -0
  112. package/ietf/hidden.js +30 -0
  113. package/ietf/hidden.js.map +1 -0
  114. package/ietf/index.d.ts +2 -0
  115. package/ietf/index.d.ts.map +1 -1
  116. package/ietf/index.js +2 -0
  117. package/ietf/index.js.map +1 -1
  118. package/ietf/object.d.ts +15 -8
  119. package/ietf/object.d.ts.map +1 -1
  120. package/ietf/object.js +51 -36
  121. package/ietf/object.js.map +1 -1
  122. package/ietf/parameters.d.ts +14 -2
  123. package/ietf/parameters.d.ts.map +1 -1
  124. package/ietf/parameters.js +97 -29
  125. package/ietf/parameters.js.map +1 -1
  126. package/ietf/properties.d.ts +1 -0
  127. package/ietf/properties.d.ts.map +1 -1
  128. package/ietf/properties.js +14 -0
  129. package/ietf/properties.js.map +1 -1
  130. package/ietf/publish.d.ts +19 -2
  131. package/ietf/publish.d.ts.map +1 -1
  132. package/ietf/publish.js +40 -6
  133. package/ietf/publish.js.map +1 -1
  134. package/ietf/publish_namespace.d.ts +25 -0
  135. package/ietf/publish_namespace.d.ts.map +1 -1
  136. package/ietf/publish_namespace.js +63 -0
  137. package/ietf/publish_namespace.js.map +1 -1
  138. package/ietf/publisher.d.ts +1 -82
  139. package/ietf/publisher.d.ts.map +1 -1
  140. package/ietf/publisher.js +483 -235
  141. package/ietf/publisher.js.map +1 -1
  142. package/ietf/solicit.d.ts +1 -40
  143. package/ietf/solicit.d.ts.map +1 -1
  144. package/ietf/subscribe.d.ts +8 -6
  145. package/ietf/subscribe.d.ts.map +1 -1
  146. package/ietf/subscribe.js +33 -27
  147. package/ietf/subscribe.js.map +1 -1
  148. package/ietf/subscribe_namespace.d.ts +8 -2
  149. package/ietf/subscribe_namespace.d.ts.map +1 -1
  150. package/ietf/subscribe_namespace.js +18 -8
  151. package/ietf/subscribe_namespace.js.map +1 -1
  152. package/ietf/subscriber.d.ts +1 -65
  153. package/ietf/subscriber.d.ts.map +1 -1
  154. package/ietf/subscriber.js +337 -123
  155. package/ietf/subscriber.js.map +1 -1
  156. package/ietf/token.d.ts +2 -0
  157. package/ietf/token.d.ts.map +1 -0
  158. package/ietf/token.js +99 -0
  159. package/ietf/token.js.map +1 -0
  160. package/ietf/track.d.ts +4 -0
  161. package/ietf/track.d.ts.map +1 -1
  162. package/ietf/track.js +6 -20
  163. package/ietf/track.js.map +1 -1
  164. package/ietf/version.d.ts +12 -1
  165. package/ietf/version.d.ts.map +1 -1
  166. package/ietf/version.js +13 -0
  167. package/ietf/version.js.map +1 -1
  168. package/index.d.ts +12 -7
  169. package/index.d.ts.map +1 -1
  170. package/index.js +10 -5
  171. package/index.js.map +1 -1
  172. package/internal.d.ts +115 -1
  173. package/internal.d.ts.map +1 -1
  174. package/internal.js +108 -0
  175. package/internal.js.map +1 -1
  176. package/lite/announce.d.ts +60 -10
  177. package/lite/announce.d.ts.map +1 -1
  178. package/lite/announce.js +176 -31
  179. package/lite/announce.js.map +1 -1
  180. package/lite/connection.d.ts +9 -59
  181. package/lite/connection.d.ts.map +1 -1
  182. package/lite/connection.js +34 -35
  183. package/lite/connection.js.map +1 -1
  184. package/lite/datagram.d.ts +3 -2
  185. package/lite/datagram.d.ts.map +1 -1
  186. package/lite/datagram.js +7 -8
  187. package/lite/datagram.js.map +1 -1
  188. package/lite/fetch.d.ts +15 -1
  189. package/lite/fetch.d.ts.map +1 -1
  190. package/lite/fetch.js +39 -7
  191. package/lite/fetch.js.map +1 -1
  192. package/lite/goaway.d.ts.map +1 -1
  193. package/lite/goaway.js +7 -1
  194. package/lite/goaway.js.map +1 -1
  195. package/lite/group.d.ts +30 -12
  196. package/lite/group.d.ts.map +1 -1
  197. package/lite/group.js +68 -26
  198. package/lite/group.js.map +1 -1
  199. package/lite/message.d.ts +2 -2
  200. package/lite/message.d.ts.map +1 -1
  201. package/lite/message.js +14 -5
  202. package/lite/message.js.map +1 -1
  203. package/lite/priority.d.ts +1 -61
  204. package/lite/priority.d.ts.map +1 -1
  205. package/lite/priority.js +4 -5
  206. package/lite/priority.js.map +1 -1
  207. package/lite/publisher.d.ts +1 -69
  208. package/lite/publisher.d.ts.map +1 -1
  209. package/lite/publisher.js +630 -262
  210. package/lite/publisher.js.map +1 -1
  211. package/lite/setup.d.ts +8 -8
  212. package/lite/setup.d.ts.map +1 -1
  213. package/lite/setup.js +33 -30
  214. package/lite/setup.js.map +1 -1
  215. package/lite/subscribe.d.ts +71 -17
  216. package/lite/subscribe.d.ts.map +1 -1
  217. package/lite/subscribe.js +205 -53
  218. package/lite/subscribe.js.map +1 -1
  219. package/lite/subscriber.d.ts +15 -56
  220. package/lite/subscriber.d.ts.map +1 -1
  221. package/lite/subscriber.js +451 -247
  222. package/lite/subscriber.js.map +1 -1
  223. package/lite/track.d.ts +4 -10
  224. package/lite/track.d.ts.map +1 -1
  225. package/lite/track.js +34 -29
  226. package/lite/track.js.map +1 -1
  227. package/lite/version.d.ts +42 -6
  228. package/lite/version.d.ts.map +1 -1
  229. package/lite/version.js +126 -10
  230. package/lite/version.js.map +1 -1
  231. package/origin.d.ts +256 -29
  232. package/origin.d.ts.map +1 -1
  233. package/origin.js +1427 -37
  234. package/origin.js.map +1 -1
  235. package/package.json +8 -3
  236. package/path.d.ts +25 -7
  237. package/path.d.ts.map +1 -1
  238. package/path.js +5 -3
  239. package/path.js.map +1 -1
  240. package/stream.d.ts +73 -14
  241. package/stream.d.ts.map +1 -1
  242. package/stream.js +372 -141
  243. package/stream.js.map +1 -1
  244. package/tail.d.ts +18 -0
  245. package/tail.d.ts.map +1 -0
  246. package/tail.js +167 -0
  247. package/tail.js.map +1 -0
  248. package/time.d.ts +15 -2
  249. package/time.d.ts.map +1 -1
  250. package/time.js +28 -9
  251. package/time.js.map +1 -1
  252. package/track.d.ts +211 -83
  253. package/track.d.ts.map +1 -1
  254. package/track.js +816 -205
  255. package/track.js.map +1 -1
  256. package/util/abort.d.ts +2 -0
  257. package/util/abort.d.ts.map +1 -0
  258. package/util/abort.js +20 -0
  259. package/util/abort.js.map +1 -0
  260. package/util/log.d.ts +5 -0
  261. package/util/log.d.ts.map +1 -0
  262. package/util/log.js +17 -0
  263. package/util/log.js.map +1 -0
  264. package/util/u64.d.ts +39 -0
  265. package/util/u64.d.ts.map +1 -0
  266. package/util/u64.js +83 -0
  267. package/util/u64.js.map +1 -0
  268. package/util/varint.d.ts +29 -0
  269. package/util/varint.d.ts.map +1 -0
  270. package/util/varint.js +198 -0
  271. package/util/varint.js.map +1 -0
  272. package/varint.d.ts +10 -6
  273. package/varint.d.ts.map +1 -1
  274. package/varint.js +40 -237
  275. package/varint.js.map +1 -1
  276. package/wire.d.ts +80 -0
  277. package/wire.d.ts.map +1 -0
  278. package/wire.js +32 -0
  279. package/wire.js.map +1 -0
  280. package/zod.d.ts +1 -1
  281. package/zod.d.ts.map +1 -1
  282. package/zod.js.map +1 -1
  283. package/mock.d.ts +0 -66
  284. package/mock.d.ts.map +0 -1
  285. package/mock.js +0 -243
  286. package/mock.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 { 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"]}
1
+ {"version":3,"file":"subscriber.js","sourceRoot":"","sources":["../../src/lite/subscriber.ts"],"names":[],"mappings":"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","sourcesContent":["import { race, 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 { controlTimeout, error, ProtocolViolation, reason, StreamCode, StreamError, sessionCause } from \"../error.ts\";\nimport * as netGroup from \"../group.ts\";\nimport { Cost, type Hop, MAX_HOPS, type Route, randomHop, routesEqual, stampHops, UNKNOWN_HOP } from \"../hop.ts\";\nimport { groupBounds, hiddenBelow, scopeCaptures, scopeHead, scopeOverlaps } from \"../internal.ts\";\nimport * as Path from \"../path.ts\";\nimport { type OpenOptions, type Reader, Stream } from \"../stream.ts\";\nimport { TAIL_GRACE_MS, Tail } from \"../tail.ts\";\nimport * as Time from \"../time.ts\";\nimport type * as track from \"../track.ts\";\nimport { untilAborted } from \"../util/abort.ts\";\nimport { TimeoutError, withTimeout } from \"../util/timeout.ts\";\nimport { overrideBroadcastWire, wireOf } from \"../wire.ts\";\nimport {\n\tAnnounceHistory,\n\tAnnounceInit,\n\tAnnounceOk,\n\tAnnounceRequest,\n\tdecodeAnnounceBroadcastMaybe,\n} 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 { frameDecoder, type Group as GroupMessage, readFrames } 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 {\n\tdecodeSubscribeResponse,\n\tdecodeSubscribeResponseMaybe,\n\tEMPTY_RANGE,\n\temptyRange,\n\texclusiveGroupEnd,\n\tinclusiveGroupEnd,\n\tSubscribe,\n\tSubscribeUpdate,\n} from \"./subscribe.ts\";\nimport { TrackInfo, Track as TrackMessage } from \"./track.ts\";\nimport {\n\thasAnnounceId,\n\thasAnnounceOk,\n\thasDatagrams,\n\thasProbeRtt,\n\thasStreamCount,\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// 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\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\t// The group streams received, so the subscription can wait for the ones still owed\n\t// after the publisher ends it.\n\ttail: Tail;\n\t// The first group the SUBSCRIBE asked for, if any.\n\trequested?: number;\n\t// The first group the publisher serves (SUBSCRIBE_START) and the track's exclusive end\n\t// (SUBSCRIBE_END), once it declares them.\n\tstart?: number;\n\tend?: number;\n\t// Group streams opened by the publisher, when SUBSCRIBE_END carries the count.\n\tstreams?: number;\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 reflected announces can be dropped on receipt.\n\treadonly hop: Hop;\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// A random Hop ID of this connection's own, written as the first hop of any chain that\n\t// names no publisher, so a publisher that reconnects reads as a new one.\n\t#stamp: Hop;\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, { group: netGroup.Producer; accepted: Promise<void> }>();\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 - Hop 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\thop: Hop,\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.hop = hop;\n\t\tthis.#stamp = randomHop();\n\t\tthis.#probe = probe;\n\t\tthis.#peerSetup = peerSetup;\n\t}\n\n\t/**\n\t * Subscribe to broadcast announcements matching `scope`. Paths are relative\n\t * to the session, not the scope.\n\t *\n\t * Reflected announces (those whose hop chain already includes this\n\t * connection) are always dropped: moq-lite-06 has none to keep, and older\n\t * versions stay consistent with that.\n\t *\n\t * Hidden routes (a `.`-prefixed segment below the scope's head) are left out unless\n\t * `options.hidden` opts in. The opt-in rides the request on lite-07+; an older peer\n\t * never hides anything, so the rule is also applied here.\n\t */\n\tannounced(scope: Path.Pattern = Path.Pattern.all(), options?: announce.Options): announce.Consumer {\n\t\tconst announced = new announce.Producer();\n\t\t// The wire speaks announce interest by prefix, and echoes suffixes beneath it.\n\t\tvoid this.#runAnnounced(announced, scopeHead(scope), scope, options?.hidden ?? false);\n\t\treturn announced.consume();\n\t}\n\n\tasync #runAnnounced(\n\t\tannounced: announce.Producer,\n\t\tprefix: Path.Valid,\n\t\tscope: Path.Pattern,\n\t\thidden: boolean,\n\t): Promise<void> {\n\t\tconsole.debug(`announced: prefix=${prefix}`);\n\t\t// Lite04/05: send our own session-level Hop 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.hop, hidden);\n\t\tconst visible = (path: Path.Valid) => scopeOverlaps(scope, path) && (hidden || !hiddenBelow(prefix, path));\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, { version: this.version });\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 Hop 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 reflected-announce loop check seeing the full chain.\n\t\t\tlet responderOrigin: Hop | 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// Keep a withheld 0: it names nobody for loop detection, but it is the\n\t\t\t\t// anonymous mark and must travel the reconstructed chain. Assigned identities\n\t\t\t\t// stay off this hop and are never forwarded.\n\t\t\t\tresponderOrigin = ok.hop;\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) from a\n\t\t\t// new publisher on the route, whose content the next consume must not share\n\t\t\t// with the old one's.\n\t\t\ttype Advertisement = {\n\t\t\t\tpublisher: Hop | undefined;\n\t\t\t\tlive: boolean;\n\t\t\t\troute: Route;\n\t\t\t\tcaptures: Path.Pattern[] | undefined;\n\t\t\t};\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 this connection's stamp 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(path)) {\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\tconst route = { hops: [this.#stamp, UNKNOWN_HOP], cost: Cost.zero };\n\t\t\t\t\t\tconst live = visible(path);\n\t\t\t\t\t\tconst captures = scopeCaptures(scope, path);\n\t\t\t\t\t\tadvertised.set(path, { publisher: this.#stamp, live, route, captures });\n\t\t\t\t\t\tif (!live) continue;\n\t\t\t\t\t\tconsole.debug(`announced: broadcast=${path} active=true`);\n\t\t\t\t\t\tannounced.append({ prefix: path, captures, kind: \"announced\", route });\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, and lite-07 bases copy\n\t\t\t// from it. Tracked even for announces we skip as reflected, since the sender\n\t\t\t// doesn't know we skipped.\n\t\t\tconst history = new AnnounceHistory();\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 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 path: 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: Hop[] | undefined;\n\t\t\t\tlet cost: Cost | undefined;\n\n\t\t\t\tswitch (announce.status) {\n\t\t\t\t\tcase \"active\": {\n\t\t\t\t\t\tconst resolved = hasAnnounceId(this.version) ? history.start(announce) : announce;\n\t\t\t\t\t\t// The wire names the suffix beneath the interest prefix; the consumer\n\t\t\t\t\t\t// sees the covered path from the session root.\n\t\t\t\t\t\tpath = Path.join(prefix, resolved.suffix);\n\t\t\t\t\t\tactive = true;\n\t\t\t\t\t\thops = resolved.hops;\n\t\t\t\t\t\tcost = announce.cost;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"ended\":\n\t\t\t\t\t\tpath = Path.join(prefix, 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\tpath = Path.join(prefix, history.end(announce.id));\n\t\t\t\t\t\tactive = false;\n\t\t\t\t\t\tbreak;\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 resolved = history.update(announce);\n\t\t\t\t\t\tpath = Path.join(prefix, resolved.suffix);\n\t\t\t\t\t\tactive = true;\n\t\t\t\t\t\thops = resolved.hops;\n\t\t\t\t\t\tcost = announce.cost;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"skipped\":\n\t\t\t\t\t\tcontinue;\n\t\t\t\t}\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(path)) {\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(path);\n\t\t\t\t\tadvertised.delete(path);\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({\n\t\t\t\t\t\tprefix: path,\n\t\t\t\t\t\tcaptures: previous.captures,\n\t\t\t\t\t\tkind: \"retracted\",\n\t\t\t\t\t\troute: previous.route,\n\t\t\t\t\t});\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) {\n\t\t\t\t\tconst full = responderOrigin !== undefined ? [...hops, responderOrigin] : hops;\n\t\t\t\t\tif (full.includes(this.hop)) {\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(path, {\n\t\t\t\t\t\t\tpublisher: undefined,\n\t\t\t\t\t\t\tlive: false,\n\t\t\t\t\t\t\troute: { hops: full, cost: Cost.zero },\n\t\t\t\t\t\t\tcaptures: undefined,\n\t\t\t\t\t\t});\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\tretract();\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// The first hop identifies the original publisher; an empty chain means the\n\t\t\t\t// peer itself originated it. One that names nobody (lite-01..03, or a peer\n\t\t\t\t// reporting 0) gets this connection's stamp in front of its 0.\n\t\t\t\tconst fullHops = stampHops(\n\t\t\t\t\thops !== undefined && responderOrigin !== undefined\n\t\t\t\t\t\t? [...hops, responderOrigin]\n\t\t\t\t\t\t: [...(hops ?? [])],\n\t\t\t\t\tthis.#stamp,\n\t\t\t\t);\n\t\t\t\t// Appending a withheld AnnounceOk(0) onto a 32-entry list is the same\n\t\t\t\t// drop Rust's Hops::push makes: do not expose an overlong chain.\n\t\t\t\tif (fullHops === undefined || fullHops.length > MAX_HOPS) {\n\t\t\t\t\tconsole.debug(`announced: broadcast=${path} dropped (hop chain at MAX_HOPS)`);\n\t\t\t\t\tadvertised.set(path, {\n\t\t\t\t\t\tpublisher: undefined,\n\t\t\t\t\t\tlive: false,\n\t\t\t\t\t\troute: { hops: [], cost: Cost.zero },\n\t\t\t\t\t\tcaptures: undefined,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst publisher = fullHops[0];\n\t\t\t\tconst route: Route = { hops: fullHops, cost: cost ?? Cost.zero };\n\t\t\t\tconst captures = scopeCaptures(scope, path);\n\t\t\t\tif (!visible(path)) {\n\t\t\t\t\tadvertised.set(path, { publisher, live: false, route, captures });\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// A second advertisement for a path we already carry is a restart: either an\n\t\t\t\t// explicit ANNOUNCE_UPDATE, or (lite-05) a duplicate ANNOUNCE. It updates the\n\t\t\t\t// route in place, so a forwarder re-prices without retracting.\n\t\t\t\tconst previous = advertised.get(path);\n\t\t\t\tif (previous?.live) {\n\t\t\t\t\t// A different publisher took the path. Subscriptions already open drain\n\t\t\t\t\t// the old copy, but the next consume starts fresh rather than reusing the\n\t\t\t\t\t// old publisher's cached track info.\n\t\t\t\t\tif (previous.publisher !== publisher) this.#consumes.evict(path);\n\t\t\t\t\tadvertised.set(path, { publisher, live: true, route, captures });\n\t\t\t\t\tconsole.debug(`announced: broadcast=${path} rerouted`);\n\t\t\t\t\tif (!routesEqual(previous.route, route)) {\n\t\t\t\t\t\tannounced.append({ prefix: path, captures, kind: \"updated\", route });\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tadvertised.set(path, { publisher, live: true, route, captures });\n\n\t\t\t\tconsole.debug(`announced: broadcast=${path} active=true`);\n\t\t\t\tannounced.append({ prefix: path, captures, kind: \"announced\", route });\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 wireOf(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\t\tconst initialBounds = groupBounds(subscription.groups);\n\t\tif (emptyRange({ startGroup: initialBounds.start, endGroup: initialBounds.end })) {\n\t\t\trequest.reject(new Error(EMPTY_RANGE));\n\t\t\treturn;\n\t\t}\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\t\tconst bounds = groupBounds(subscription.groups);\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\tmaxAge: subscription.maxAge,\n\t\t\tstartGroup: subscription.groups?.start === undefined ? undefined : bounds.start,\n\t\t\tendGroup: inclusiveGroupEnd(bounds.end),\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; entry: SubscribeEntry };\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\t// The setup outlived its deadline waiting for the first response: a control\n\t\t\t// timeout, not content that arrived late.\n\t\t\tconst e = err instanceof TimeoutError ? controlTimeout(err) : await sessionCause(this.#quic, 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, entry } = opened;\n\t\tconst producer = entry.track;\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 until\n\t\t\t// its FIN; older drafts just close it. Either way group streams can still be in\n\t\t\t// flight, so the track ends only once the tail is accounted for. A reset rejects\n\t\t\t// instead, so the track ends with that error rather than a clean tail.\n\t\t\tconst responses = supportsTrackStream(this.version)\n\t\t\t\t? this.#runResponses(stream, entry)\n\t\t\t\t: stream.reader.closed;\n\t\t\tconst closed = responses.then(() => this.#settleTail(entry));\n\t\t\t// A reset that lands after the race below settled is moot; the race observes one before.\n\t\t\tclosed.catch(() => {});\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, entry, 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\t// Updates stop quietly at the FIN, which can land before the responses ahead of it are\n\t\t\t// decoded, so only their failure is terminal on its own.\n\t\t\tconst terminal: PromiseLike<unknown>[] = [closed, producer.closed];\n\t\t\tif (subscriptionUpdates !== undefined) terminal.push(subscriptionUpdates.then(() => closed));\n\t\t\tconst done = 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 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 = await sessionCause(this.#quic, 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; entry: SubscribeEntry }> {\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\tconst entry: SubscribeEntry = {\n\t\t\ttrack: producer,\n\t\t\ttimescale,\n\t\t\t// The effective max age is the stopgap grace: the wrong clock (it bounds\n\t\t\t// presentation-time drift), but it is how long the subscriber was willing to wait\n\t\t\t// for a late group anyway. Already the smaller of the subscriber's and the track's.\n\t\t\ttail: new Tail({\n\t\t\t\tgrace: () => {\n\t\t\t\t\tconst maxAge = producer.subscription.peek()?.maxAge ?? Time.Milli.zero;\n\t\t\t\t\treturn maxAge > 0 ? maxAge : TAIL_GRACE_MS;\n\t\t\t\t},\n\t\t\t}),\n\t\t\trequested: msg.startGroup,\n\t\t};\n\t\tthis.#subscribes.set(id, entry);\n\n\t\tstate.stream = await Stream.open(this.#quic, { version: this.version });\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, entry };\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\treturn this.#exchange({ version: this.version }, async (stream) => {\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});\n\t}\n\n\t// Opens a stream and runs a request/response exchange on it, resetting the stream if `run`\n\t// fails. Subscriber.close() also resets it while `run` is pending, so a peer that never\n\t// answers cannot hold it open, and a stream that opens after the close is reset at once.\n\tasync #exchange<T>(options: OpenOptions, run: (stream: Stream) => Promise<T>): Promise<T> {\n\t\tconst closed = this.#closed.signal;\n\t\tclosed.throwIfAborted();\n\t\tconst stream = await Stream.open(this.#quic, options);\n\t\tconst abort = () => stream.abort(error(closed.reason));\n\t\tclosed.addEventListener(\"abort\", abort);\n\t\ttry {\n\t\t\tclosed.throwIfAborted();\n\t\t\treturn await run(stream);\n\t\t} catch (err) {\n\t\t\tstream.abort(error(err));\n\t\t\tthrow err;\n\t\t} finally {\n\t\t\tclosed.removeEventListener(\"abort\", abort);\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 Age 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\tmaxAge: Time.Milli(info.maxAge),\n\t\t\tpriority: info.priority,\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.query(). 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\tasync fetchGroup(\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\toptions.signal?.throwIfAborted();\n\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\t//\n\t\t// Reserve each caller's mirror before the fetch starts or is awaited: the fetch watches\n\t\t// demand from the start, and a fast FIN cannot discard frames before these callers\n\t\t// receive their handles. An abort closes only this caller's mirror, so the stream is\n\t\t// cancelled once the last one leaves.\n\t\tconst key = JSON.stringify([broadcast, track, sequence]);\n\t\tlet entry = this.#fetches.get(key);\n\t\tlet consumer: netGroup.Consumer;\n\t\tif (entry && !entry.group.isClosed) {\n\t\t\tconsumer = entry.group.mirror();\n\t\t} else {\n\t\t\tconst group = new netGroup.Producer(sequence);\n\t\t\tconsumer = group.mirror();\n\t\t\tentry = { group, accepted: this.#runFetch(broadcast, track, sequence, options.priority ?? 0, group) };\n\t\t\tthis.#fetches.set(key, entry);\n\t\t\tvoid group.closed.then(() => {\n\t\t\t\tif (this.#fetches.get(key)?.group === group) this.#fetches.delete(key);\n\t\t\t});\n\t\t}\n\n\t\ttry {\n\t\t\tawait untilAborted(entry.accepted, options.signal);\n\t\t\treturn consumer;\n\t\t} catch (err) {\n\t\t\tconsumer.close();\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t// Open the FETCH stream and pump the response into the shared group. Setup errors close the\n\t// group, evict the entry, and reject every caller waiting for acceptance. A setup every caller\n\t// has abandoned is cancelled the same way.\n\tasync #runFetch(\n\t\tbroadcast: Path.Valid,\n\t\ttrack: string,\n\t\tsequence: number,\n\t\tpriority: number,\n\t\tgroup: netGroup.Producer,\n\t): Promise<void> {\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\t// Lite has no FETCH_OK, so a publisher that never answers would hold the setup forever.\n\t\t\t// Subscriber.close() closing the group releases every caller at any stage, and resets\n\t\t\t// the streams the setup opened.\n\t\t\tconst setup = this.#fetchSetup(broadcast, track, sequence, priority, group);\n\t\t\tlet accepted: { stream: Stream; info: TrackInfo };\n\t\t\ttry {\n\t\t\t\taccepted = await untilAbandoned(group, setup);\n\t\t\t} catch (err: unknown) {\n\t\t\t\t// A setup that finishes just after the close hands back a stream nobody will read.\n\t\t\t\tvoid setup.then(\n\t\t\t\t\t({ stream }) => stream.abort(error(err)),\n\t\t\t\t\t() => void 0,\n\t\t\t\t);\n\t\t\t\tthrow err;\n\t\t\t}\n\n\t\t\tvoid this.#runFetchResponse(accepted.stream, group, Time.Timescale(accepted.info.timescale));\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// Resolve the track's timescale, then open the FETCH stream and wait for it to be accepted.\n\t// Closing the group during that wait resets the stream.\n\tasync #fetchSetup(\n\t\tbroadcast: Path.Valid,\n\t\ttrack: string,\n\t\tsequence: number,\n\t\tpriority: number,\n\t\tgroup: netGroup.Producer,\n\t): Promise<{ stream: Stream; info: TrackInfo }> {\n\t\tconst info = await untilClosed(group, this.#trackInfo(broadcast, track));\n\t\treturn this.#exchange({ sendOrder: sendOrder({ priority }), version: this.version }, async (stream) => {\n\t\t\tawait stream.writer.u53(StreamId.Fetch);\n\t\t\tawait new FetchMessage({ broadcast, track, priority, group: sequence }).encode(stream.writer, this.version);\n\t\t\t// A byte or an empty-group FIN accepts the fetch; a reset rejects it.\n\t\t\t// done() buffers that byte so the response pump can decode it normally.\n\t\t\tawait untilClosed(group, stream.reader.done());\n\t\t\treturn { stream, info };\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\tconst decode = frameDecoder(timescale);\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. `unused` is watched across frames as one stable\n\t\t\t// promise; the check is level-triggered, so a coalesced fetch that arrives before we\n\t\t\t// cancel re-arms and resumes.\n\t\t\tconst idle: unique symbol = Symbol(\"idle\");\n\t\t\tlet unused = group.unused().then((): typeof idle => idle);\n\t\t\t// A decode consumes its frame whenever it lands, so one outstanding across a re-arm is\n\t\t\t// kept and awaited again rather than abandoned with its frame.\n\t\t\tlet pending: Promise<netGroup.Frame | undefined> | undefined;\n\t\t\tfor (;;) {\n\t\t\t\t// Buffered frames are written without an await, as in a group stream.\n\t\t\t\tlet frame = pending === undefined ? stream.reader.tryDecode(decode) : undefined;\n\t\t\t\tif (!frame) {\n\t\t\t\t\tpending ??= stream.reader.decodeMaybe(decode);\n\t\t\t\t\tconst next = await race([pending, group.closed, unused]);\n\t\t\t\t\tif (next === idle) {\n\t\t\t\t\t\tif (!group.isClosed && group.used.peek()) {\n\t\t\t\t\t\t\tunused = group.unused().then((): typeof idle => idle);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tpending = undefined;\n\t\t\t\t\tif (!next || next instanceof Error) break;\n\t\t\t\t\tframe = next;\n\t\t\t\t}\n\t\t\t\tgroup.writeFrame(frame);\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// Reads SUBSCRIBE_START/END/DROP on the subscribe stream until FIN (lite-05+), recording\n\t// the range the tail is accounted against. SUBSCRIBE_END declares the track's end right\n\t// away, so a consumer learns it before the last groups arrive. The publisher must declare\n\t// the end before FIN; resets and malformed responses reject with their failure.\n\tasync #runResponses(stream: Stream, entry: SubscribeEntry): Promise<void> {\n\t\tfor (;;) {\n\t\t\tconst resp = await decodeSubscribeResponseMaybe(stream.reader, this.version);\n\t\t\tif (!resp) {\n\t\t\t\tif (entry.end === undefined)\n\t\t\t\t\tthrow new ProtocolViolation(\"subscribe stream ended without SUBSCRIBE_END\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (\"start\" in resp) {\n\t\t\t\tentry.start = resp.start.group;\n\t\t\t\t// The groups the SUBSCRIBE asked for below it are unavailable, whatever the\n\t\t\t\t// demand asks later.\n\t\t\t\tif (entry.requested !== undefined) entry.tail.account(entry.requested, entry.start);\n\t\t\t} else if (\"end\" in resp) {\n\t\t\t\tif (entry.end !== undefined) throw new ProtocolViolation(\"duplicate SUBSCRIBE_END\");\n\t\t\t\tentry.end = resp.end.group;\n\t\t\t\tif (hasStreamCount(this.version)) entry.streams = resp.end.streams;\n\t\t\t\t// A local close can win the race with the response; there is nothing left to end.\n\t\t\t\tif (entry.track.closed.peek() !== undefined) continue;\n\t\t\t\ttry {\n\t\t\t\t\tentry.track.finishAt(entry.end);\n\t\t\t\t} catch (err) {\n\t\t\t\t\t// lite-05 specified an inclusive end, and @moq/net 0.1.3 to 0.1.9 sent one, so\n\t\t\t\t\t// there an end below a received group only costs the early boundary: the FIN\n\t\t\t\t\t// still finishes the track. Later drafts made it exclusive.\n\t\t\t\t\tif (this.version !== Version.DRAFT_05) {\n\t\t\t\t\t\tthrow new ProtocolViolation(`invalid SUBSCRIBE_END: ${reason(error(err))}`);\n\t\t\t\t\t}\n\t\t\t\t\tconsole.warn(`invalid SUBSCRIBE_END: ${reason(error(err))}`);\n\t\t\t\t}\n\t\t\t} else if (\"drop\" in resp) {\n\t\t\t\tentry.tail.account(resp.drop.start, resp.drop.end + 1);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Wait for the group streams the publisher still owes once it has ended the subscription.\n\t//\n\t// lite-07 counts streams, so skipped sequences owe nothing. Older drafts account for\n\t// the range using received headers and SUBSCRIBE_DROP. A counted stream reset before\n\t// its header leaves no trace, so the grace still bounds that wait. Streams whose\n\t// headers arrived keep reading until their own FIN or reset.\n\t#settleTail(entry: SubscribeEntry): Promise<void> {\n\t\tconst { tail, track } = entry;\n\n\t\tconst complete = () => {\n\t\t\tif (entry.streams !== undefined) return tail.streams >= entry.streams;\n\t\t\t// Without SUBSCRIBE_END (older drafts) nothing says which groups are owed.\n\t\t\tif (entry.end === undefined) return false;\n\t\t\t// Without SUBSCRIBE_START the publisher served no group at all.\n\t\t\tif (entry.start === undefined) return true;\n\t\t\t// Owed from the floor the demand last asked for, which an update can move either\n\t\t\t// way, or where SUBSCRIBE_START resolved a live-edge one. The groups the SUBSCRIBE\n\t\t\t// asked for below its SUBSCRIBE_START were accounted for when it arrived.\n\t\t\tconst groups = track.subscription.peek()?.groups;\n\t\t\tconst bounds = groupBounds(groups ?? {});\n\t\t\tconst start = groups?.start === undefined ? entry.start : bounds.start;\n\t\t\tconst end = bounds.end === undefined ? entry.end : Math.min(entry.end, bounds.end);\n\t\t\treturn tail.covers(start, end);\n\t\t};\n\n\t\treturn tail.settle(complete, track.closed);\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 a 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\tentry: SubscribeEntry,\n\t\tmsg: Subscribe,\n\t\tstream: Stream,\n\t): Promise<void> {\n\t\tconst track = entry.track;\n\t\tconst stopped: Promise<null> = race([track.closed, stream.reader.closed]).then(() => null);\n\t\tlet lastSent: track.Subscription = {\n\t\t\tpriority: msg.priority,\n\t\t\tmaxAge: Time.Milli(msg.maxAge),\n\t\t\tgroups: {\n\t\t\t\tstart: msg.startGroup === undefined ? undefined : { included: msg.startGroup },\n\t\t\t\tend: msg.endGroup === undefined ? undefined : { excluded: exclusiveGroupEnd(msg.endGroup) ?? 0 },\n\t\t\t},\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 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\t// Demand collapsing to nothing is refused the same way an initial empty\n\t\t\t// request is: the error closes the track, so every local subscriber sees it.\n\t\t\tconst bounds = groupBounds(current.groups);\n\t\t\tif (emptyRange({ startGroup: bounds.start, endGroup: bounds.end })) throw new Error(EMPTY_RANGE);\n\n\t\t\t// A lowered floor owes groups nobody asked for until now.\n\t\t\tif (current.groups?.start !== undefined) {\n\t\t\t\tconst floor = lastSent.groups?.start === undefined ? entry.start : groupBounds(lastSent.groups).start;\n\t\t\t\tentry.tail.demand(bounds.start, floor ?? Number.POSITIVE_INFINITY);\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/maxAge/etc.\n\t\t\tconst update = new SubscribeUpdate({\n\t\t\t\tpriority: current.priority ?? 0,\n\t\t\t\tmaxAge: current.maxAge,\n\t\t\t\tstartGroup: current.groups?.start === undefined ? undefined : bounds.start,\n\t\t\t\tendGroup: inclusiveGroupEnd(bounds.end),\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\tconst ag = groupBounds(a.groups);\n\t\tconst bg = groupBounds(b.groups);\n\t\treturn (\n\t\t\t(a.priority ?? 0) === (b.priority ?? 0) &&\n\t\t\t(a.maxAge ?? 0) === (b.maxAge ?? 0) &&\n\t\t\tag.start === bg.start &&\n\t\t\tag.end === bg.end\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, tail } = entry;\n\t\tconst producer = new netGroup.Producer(group.sequence);\n\t\tconst read = tail.open(group.sequence);\n\n\t\ttry {\n\t\t\t// The publisher contradicted its own end, which no later group can repair. lite-05\n\t\t\t// specified an inclusive end, so its last group lands on it: the write below drops\n\t\t\t// only that group there.\n\t\t\tif (entry.end !== undefined && group.sequence >= entry.end && this.version !== Version.DRAFT_05) {\n\t\t\t\tconst violation = new ProtocolViolation(\n\t\t\t\t\t`group ${group.sequence} is at or past the declared end ${entry.end}`,\n\t\t\t\t);\n\t\t\t\ttrack.close(violation);\n\t\t\t\tthrow violation;\n\t\t\t}\n\t\t\ttrack.writeGroup(producer);\n\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 StreamError(StreamCode.Cancel, { message: \"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\tawait readFrames(stream, producer, scale);\n\n\t\t\tproducer.close();\n\t\t\tstream.stop(new StreamError(StreamCode.Cancel, { message: \"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} finally {\n\t\t\tread();\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, this.version);\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\t// A datagram's sequence is never owed a stream, so it never holds the tail open.\n\t\tentry.tail.account(dg.sequence, dg.sequence + 1);\n\t\tentry.track.insertDatagram(dg.sequence, timestamp, 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, { version: this.version });\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\t/**\n\t * Ends every subscribed track: cleanly for a deliberate close, or with `err` when the\n\t * session died, since those tracks were cut off rather than ended.\n\t */\n\tclose(err?: Error) {\n\t\t// A fetch or setup exchange cut off by the session is incomplete even on a deliberate\n\t\t// close, so it always ends with an error.\n\t\tconst cut = err ?? new StreamError(StreamCode.SessionClosed, { message: \"session closed\" });\n\t\tthis.#closed.abort(cut);\n\n\t\tfor (const { track } of this.#subscribes.values()) {\n\t\t\ttrack.close(err);\n\t\t}\n\n\t\tthis.#subscribes.clear();\n\n\t\t// This also releases callers still awaiting acceptance.\n\t\tfor (const { group } of this.#fetches.values()) {\n\t\t\tgroup.close(cut);\n\t\t}\n\t}\n}\n\n// Settles with `step`, or rejects with the group's error once it closes first. A publisher\n// may never answer a FETCH, so Subscriber.close() closing the group is what releases it.\nasync function untilClosed<T>(group: netGroup.Producer, step: Promise<T>): Promise<T> {\n\tconst value = await race([step, group.closed]);\n\tconst closed = group.closed.peek();\n\tif (closed !== undefined) throw closed ?? new Error(\"fetch closed before it was accepted\");\n\treturn value as T;\n}\n\n// Like untilClosed, but also cancels once every reader has left. Demand is level-triggered, so a\n// caller that coalesces onto the group before the check re-arms it.\nasync function untilAbandoned<T>(group: netGroup.Producer, step: Promise<T>): Promise<T> {\n\tconst idle: unique symbol = Symbol(\"idle\");\n\tfor (;;) {\n\t\tconst value = await untilClosed(group, race([step, group.unused().then((): typeof idle => idle)]));\n\t\tif (value !== idle) return value as T;\n\t\tif (!group.used.peek()) throw new StreamError(StreamCode.Cancel, { message: \"cancel\" });\n\t}\n}\n\n/**\n * A broadcast consumed from a lite session. It resolves `track.Consumer.query()` 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\toverrideBroadcastWire(this, {\n\t\t\tresolveTrackInfo: (name) => subscriber.resolveTrackInfo(path, name),\n\t\t\tfetchGroup: (name, sequence, options) => subscriber.fetchGroup(path, name, sequence, options),\n\t\t});\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"]}
package/lite/track.d.ts CHANGED
@@ -23,25 +23,19 @@ export declare class TrackInfo {
23
23
  /** The publisher's tie-break priority for this track. */
24
24
  priority: number;
25
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
- */
29
- ordered: boolean;
30
- /**
31
- * Publisher Max Latency: an upper bound (milliseconds) on how long the publisher
26
+ * Publisher Max Age: an upper bound (milliseconds) on how long the publisher
32
27
  * caches a non-latest group past the arrival of a newer one.
33
28
  */
34
- latencyMax: number;
29
+ maxAge: number;
35
30
  /**
36
31
  * Per-frame timestamp scale (units per second). Mandatory on Lite05: a real
37
32
  * (non-zero) scale, and every frame on the wire is prefixed with a zigzag-delta
38
33
  * timestamp at this scale.
39
34
  */
40
35
  timescale: number;
41
- constructor({ priority, ordered, latencyMax, timescale, }: {
36
+ constructor({ priority, maxAge, timescale, }: {
42
37
  priority?: number;
43
- ordered?: boolean;
44
- latencyMax?: number;
38
+ maxAge?: number;
45
39
  timescale?: number;
46
40
  });
47
41
  encode(w: Writer, version: Version): Promise<void>;
@@ -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,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"}
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;AAGnD,OAAO,EAAiB,OAAO,EAAE,MAAM,cAAc,CAAC;AAetD;;;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,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB,YAAY,EACX,QAAY,EACZ,MAAU,EACV,SAA2B,GAC3B,EAAE;QACF,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;KACnB,EAUA;IAkBK,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAYvD;IAED,OAAa,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAGnE;CACD"}
package/lite/track.js CHANGED
@@ -1,7 +1,8 @@
1
1
  /* @ts-self-types="./track.d.ts" */
2
2
  import * as Path from "../path.js";
3
+ import { Timescale } from "../time.js";
3
4
  import * as Message from "./message.js";
4
- import { Version } from "./version.js";
5
+ import { hasGroupOrder, Version } from "./version.js";
5
6
  // The Track Stream (0x6) is draft-05+ only.
6
7
  function guardTrack(version) {
7
8
  switch (version) {
@@ -52,55 +53,59 @@ export class TrackInfo {
52
53
  /** The publisher's tie-break priority for this track. */
53
54
  priority;
54
55
  /**
55
- * Whether groups are prioritized in sequence order. Groups may always arrive
56
- * out-of-order (or not at all) over the network.
57
- */
58
- ordered;
59
- /**
60
- * Publisher Max Latency: an upper bound (milliseconds) on how long the publisher
56
+ * Publisher Max Age: an upper bound (milliseconds) on how long the publisher
61
57
  * caches a non-latest group past the arrival of a newer one.
62
58
  */
63
- latencyMax;
59
+ maxAge;
64
60
  /**
65
61
  * Per-frame timestamp scale (units per second). Mandatory on Lite05: a real
66
62
  * (non-zero) scale, and every frame on the wire is prefixed with a zigzag-delta
67
63
  * timestamp at this scale.
68
64
  */
69
65
  timescale;
70
- constructor({ priority = 0, ordered = false, latencyMax = 0, timescale = 0, }) {
66
+ constructor({ priority = 0, maxAge = 0, timescale = Timescale.MILLI, }) {
67
+ if (!Number.isInteger(priority) || priority < 0 || priority > 255) {
68
+ throw new RangeError(`priority must be an integer in 0..=255: ${priority}`);
69
+ }
70
+ if (!Number.isSafeInteger(maxAge) || maxAge < 0) {
71
+ throw new RangeError(`maxAge must be a safe non-negative integer: ${maxAge}`);
72
+ }
71
73
  this.priority = priority;
72
- this.ordered = ordered;
73
- this.latencyMax = latencyMax;
74
- this.timescale = timescale;
74
+ this.maxAge = maxAge;
75
+ this.timescale = Timescale(timescale);
75
76
  }
76
- async #encode(w) {
77
+ async #encode(w, version) {
77
78
  await w.u8(this.priority);
78
- await w.bool(this.ordered);
79
- await w.u53(this.latencyMax);
79
+ // The retired `Ordered` byte: lite-05 keeps it in its layout, written as 0.
80
+ if (hasGroupOrder(version))
81
+ await w.bool(false);
82
+ await w.u53(this.maxAge);
80
83
  await w.u53(this.timescale);
81
84
  }
82
- static async #decode(r) {
85
+ static async #decode(r, version) {
83
86
  const priority = await r.u8();
84
- const ordered = await r.bool();
85
- const latencyMax = await r.u53();
87
+ if (hasGroupOrder(version))
88
+ await r.bool();
89
+ const maxAge = await r.u53();
86
90
  const timescale = await r.u53();
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().
89
- if (timescale === 0)
90
- throw new Error("track timescale must be non-zero");
91
- return new TrackInfo({ priority, ordered, latencyMax, timescale });
91
+ return new TrackInfo({ priority, maxAge, timescale });
92
92
  }
93
93
  async encode(w, version) {
94
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));
95
+ // Re-check after construction: fields are public, and a mutated value must not
96
+ // reach the length-prefixed writer.
97
+ if (!Number.isInteger(this.priority) || this.priority < 0 || this.priority > 255) {
98
+ throw new RangeError(`priority must be an integer in 0..=255: ${this.priority}`);
99
+ }
100
+ if (!Number.isSafeInteger(this.maxAge) || this.maxAge < 0) {
101
+ throw new RangeError(`maxAge must be a safe non-negative integer: ${this.maxAge}`);
102
+ }
103
+ Timescale(this.timescale);
104
+ return Message.encode(w, (w) => this.#encode(w, version));
100
105
  }
101
106
  static async decode(r, version) {
102
107
  guardTrack(version);
103
- return Message.decode(r, (r) => TrackInfo.#decode(r));
108
+ return Message.decode(r, (r) => TrackInfo.#decode(r, version));
104
109
  }
105
110
  }
106
111
  //# 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 { 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"]}
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 { Timescale } from \"../time.ts\";\nimport * as Message from \"./message.ts\";\nimport { hasGroupOrder, 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 * Publisher Max Age: 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\tmaxAge: 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\tmaxAge = 0,\n\t\ttimescale = Timescale.MILLI,\n\t}: {\n\t\tpriority?: number;\n\t\tmaxAge?: number;\n\t\ttimescale?: number;\n\t}) {\n\t\tif (!Number.isInteger(priority) || priority < 0 || priority > 255) {\n\t\t\tthrow new RangeError(`priority must be an integer in 0..=255: ${priority}`);\n\t\t}\n\t\tif (!Number.isSafeInteger(maxAge) || maxAge < 0) {\n\t\t\tthrow new RangeError(`maxAge must be a safe non-negative integer: ${maxAge}`);\n\t\t}\n\t\tthis.priority = priority;\n\t\tthis.maxAge = maxAge;\n\t\tthis.timescale = Timescale(timescale);\n\t}\n\n\tasync #encode(w: Writer, version: Version) {\n\t\tawait w.u8(this.priority);\n\t\t// The retired `Ordered` byte: lite-05 keeps it in its layout, written as 0.\n\t\tif (hasGroupOrder(version)) await w.bool(false);\n\t\tawait w.u53(this.maxAge);\n\t\tawait w.u53(this.timescale);\n\t}\n\n\tstatic async #decode(r: Reader, version: Version): Promise<TrackInfo> {\n\t\tconst priority = await r.u8();\n\t\tif (hasGroupOrder(version)) await r.bool();\n\t\tconst maxAge = await r.u53();\n\t\tconst timescale = await r.u53();\n\t\treturn new TrackInfo({ priority, maxAge, timescale });\n\t}\n\n\tasync encode(w: Writer, version: Version): Promise<void> {\n\t\tguardTrack(version);\n\t\t// Re-check after construction: fields are public, and a mutated value must not\n\t\t// reach the length-prefixed writer.\n\t\tif (!Number.isInteger(this.priority) || this.priority < 0 || this.priority > 255) {\n\t\t\tthrow new RangeError(`priority must be an integer in 0..=255: ${this.priority}`);\n\t\t}\n\t\tif (!Number.isSafeInteger(this.maxAge) || this.maxAge < 0) {\n\t\t\tthrow new RangeError(`maxAge must be a safe non-negative integer: ${this.maxAge}`);\n\t\t}\n\t\tTimescale(this.timescale);\n\t\treturn Message.encode(w, (w) => this.#encode(w, version));\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, version));\n\t}\n}\n"]}