@norskvideo/moq-net 0.1.8 → 0.2.1

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":"publisher.js","sourceRoot":"","sources":["../../src/lite/publisher.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Dispose, Signal } from \"@moq/signals\";\nimport type * as broadcast from \"../broadcast.ts\";\nimport { error, reason } from \"../error.ts\";\nimport type * as group from \"../group.ts\";\nimport type { Origin } from \"../origin.ts\";\nimport * as Path from \"../path.ts\";\nimport { type Stream, Writer } from \"../stream.ts\";\nimport { Timescale } from \"../time.ts\";\nimport type * as track from \"../track.ts\";\nimport { AnnounceInit, AnnounceOk, type AnnounceRequest, encodeAnnounceBroadcast } from \"./announce.ts\";\nimport { Datagram as DatagramMessage } from \"./datagram.ts\";\nimport * as DatagramStream from \"./datagram_stream.ts\";\nimport type { Fetch } from \"./fetch.ts\";\nimport { Group as GroupMessage } from \"./group.ts\";\nimport { Priority, sendOrder } from \"./priority.ts\";\nimport { Probe } from \"./probe.ts\";\nimport {\n\tencodeSubscribeResponse,\n\ttype Subscribe,\n\tSubscribeEnd,\n\tSubscribeOk,\n\tSubscribeStart,\n\tSubscribeUpdate,\n} from \"./subscribe.ts\";\nimport { TrackInfo as TrackInfoMessage, type Track as TrackMessage } from \"./track.ts\";\nimport { hasAnnounceId, hasAnnounceOk, hasDatagrams, hasProbeRtt, Version } from \"./version.ts\";\n\nconst PROBE_INTERVAL = 100; // ms\nconst PROBE_MAX_AGE = 10_000; // ms\nconst PROBE_MAX_DELTA = 0.25;\nconst PROBE_RTT_DELTA = 0.25;\n\n/** Map a signed delta to an unsigned zigzag varint value (mirrors Rust `VarInt::from_zigzag`). */\nfunction zigzag(delta: bigint): bigint {\n\treturn delta >= 0n ? delta << 1n : (-delta << 1n) - 1n;\n}\n\n/** What {@link Publisher.runGroup} needs to serve one group. */\ninterface RunGroup {\n\t/** The subscription ID. */\n\tsub: bigint;\n\n\t/** The group to serve. */\n\tgroup: group.Consumer;\n\n\t/** The track's advertised timescale, applied to every frame timestamp. */\n\ttimescale: Timescale;\n\n\t/** The subscription's ranking, which this stream joins for as long as it runs. */\n\tpriority: Priority;\n\n\t/** Settles when the subscriber leaves, dropping a group still queued for a stream slot. */\n\tunsubscribed: Promise<void>;\n}\n\n// The TRACK stream, implicit SUBSCRIBE acceptance, and SUBSCRIBE_START/END are\n// all 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 * Handles publishing broadcasts and managing their lifecycle.\n *\n * @internal\n */\nexport class Publisher {\n\t// The version of the connection.\n\treadonly version: Version;\n\n\t// Per-connection origin appended to outbound Announce hops, so the peer\n\t// can detect loops and prefer shorter paths. Created by Connection and\n\t// shared with Subscriber, which can optionally use it to filter out its\n\t// own announcements.\n\treadonly origin: Origin;\n\n\t#quic: WebTransport;\n\n\t// The one writer for the outbound datagram stream (getWriter locks it), acquired once at\n\t// construction when this version + transport carry datagrams, released in close(). Its\n\t// presence is the gate: undefined means datagrams aren't served on this connection. All\n\t// subscriptions share it, since a second getWriter on the same stream would throw.\n\t#datagramWriter?: WritableStreamDefaultWriter<Uint8Array>;\n\n\t// Our published broadcasts.\n\t// It's a signal so we can live update any announce streams.\n\t#broadcasts = new Signal<Map<Path.Valid, broadcast.Producer> | undefined>(new Map());\n\n\t// TRACK_INFO is immutable per track, so resolve it from the application once\n\t// (via a throwaway subscribe whose info() resolves when the app calls accept)\n\t// and reuse it for every later TRACK request of the same track. Keyed by\n\t// `broadcast\\0track`. A rejected lookup is evicted so a retry can re-probe.\n\t#trackInfo = new Map<string, Promise<TrackInfoMessage>>();\n\n\t/**\n\t * Creates a new Publisher instance.\n\t * @param quic - The WebTransport session to use\n\t * @param version - Negotiated protocol version\n\t * @param origin - Origin id shared with the Subscriber\n\t *\n\t * @internal\n\t */\n\tconstructor(quic: WebTransport, version: Version, origin: Origin) {\n\t\tthis.#quic = quic;\n\t\tthis.version = version;\n\t\tthis.origin = origin;\n\n\t\t// Grab the datagram writer up front when the transport carries datagrams (no group\n\t\t// fallback, so it stays undefined otherwise). One writer for all subscriptions.\n\t\tif (hasDatagrams(version)) {\n\t\t\tthis.#datagramWriter = DatagramStream.datagramWriter(quic);\n\t\t}\n\t}\n\n\t/**\n\t * Publishes a broadcast with any associated tracks.\n\t * @param name - The broadcast to publish\n\t */\n\tpublish(path: Path.Valid, broadcast: broadcast.Producer) {\n\t\tthis.#broadcasts.mutate((broadcasts) => {\n\t\t\tif (!broadcasts) throw new Error(\"closed\");\n\t\t\tbroadcasts.set(path, broadcast);\n\t\t});\n\n\t\t// Remove the broadcast from the lookup when it's closed, unless the path was republished.\n\t\tvoid broadcast.closed.then(() => {\n\t\t\tthis.#broadcasts.mutate((broadcasts) => {\n\t\t\t\tif (broadcasts?.get(path) === broadcast) {\n\t\t\t\t\tbroadcasts.delete(path);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Handles an announce interest message.\n\t * @param msg - The announce interest message\n\t * @param stream - The stream to write announcements to\n\t *\n\t * @internal\n\t */\n\tasync runAnnounce(msg: AnnounceRequest, stream: Stream) {\n\t\tconsole.debug(`announce: prefix=${msg.prefix}`);\n\n\t\t// Send initial announcements\n\t\tlet active = new Set<Path.Valid>();\n\n\t\tconst broadcasts = this.#broadcasts.peek();\n\t\tif (!broadcasts) return; // closed\n\n\t\tfor (const name of broadcasts.keys()) {\n\t\t\tconst suffix = Path.stripPrefix(msg.prefix, name);\n\t\t\tif (suffix === null) continue;\n\t\t\tconsole.debug(`announce: broadcast=${name} active=true`);\n\t\t\tactive.add(suffix);\n\t\t}\n\n\t\t// Lite06+: announce ids. Every active we send implicitly assigns the next\n\t\t// per-stream ordinal; ended references the id instead of repeating the path.\n\t\tlet nextAnnounceId = 0n;\n\t\tconst announceIds = new Map<Path.Valid, bigint>();\n\n\t\tswitch (this.version) {\n\t\t\tcase Version.DRAFT_01:\n\t\t\tcase Version.DRAFT_02: {\n\t\t\t\tconst init = new AnnounceInit([...active]);\n\t\t\t\tawait init.encode(stream.writer, this.version);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tif (!hasAnnounceOk(this.version)) {\n\t\t\t\t\t// Draft03/04: send individual Announce messages, stamping our origin as a hop.\n\t\t\t\t\tfor (const suffix of active) {\n\t\t\t\t\t\tawait encodeAnnounceBroadcast(\n\t\t\t\t\t\t\tstream.writer,\n\t\t\t\t\t\t\t{ status: \"active\", suffix, hops: [this.origin] },\n\t\t\t\t\t\t\tthis.version,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// Report our origin id once via AnnounceOk and the count of initial announces\n\t\t\t\t// that follow; the subscriber stamps our origin onto each hop chain, so we omit it.\n\t\t\t\tconst ok = new AnnounceOk(this.origin, active.size);\n\t\t\t\tawait ok.encode(stream.writer, this.version);\n\t\t\t\tfor (const suffix of active) {\n\t\t\t\t\tif (hasAnnounceId(this.version)) {\n\t\t\t\t\t\tannounceIds.set(suffix, nextAnnounceId++);\n\t\t\t\t\t}\n\t\t\t\t\tawait encodeAnnounceBroadcast(stream.writer, { status: \"active\", suffix, hops: [] }, this.version);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// Wait for updates to the broadcasts.\n\t\tfor (;;) {\n\t\t\t// TODO Make a better helper within Signals.\n\t\t\tlet dispose!: Dispose;\n\t\t\tconst changed = new Promise<Map<Path.Valid, broadcast.Producer> | undefined>((resolve) => {\n\t\t\t\tdispose = this.#broadcasts.changed(resolve);\n\t\t\t});\n\n\t\t\t// Wait until the map of broadcasts changes.\n\t\t\tconst broadcasts = await Promise.race([changed, stream.reader.closed]);\n\t\t\tdispose();\n\t\t\tif (!broadcasts) break;\n\n\t\t\t// Create a new set of active broadcasts.\n\t\t\t// This is SLOW, but it's not worth optimizing because we often have just 1 broadcast anyway.\n\t\t\tconst newActive = new Set<Path.Valid>();\n\t\t\tfor (const name of broadcasts.keys()) {\n\t\t\t\tconst suffix = Path.stripPrefix(msg.prefix, name);\n\t\t\t\tif (suffix === null) continue; // Not our prefix.\n\t\t\t\tnewActive.add(suffix);\n\t\t\t}\n\n\t\t\t// Announce any new broadcasts. Lite05+ reports our origin once via AnnounceOk, so\n\t\t\t// the subscriber stamps it onto each hop chain; older versions stamp it here.\n\t\t\tfor (const added of newActive.difference(active)) {\n\t\t\t\tconsole.debug(`announce: broadcast=${added} active=true`);\n\t\t\t\tconst hops = hasAnnounceOk(this.version) ? [] : [this.origin];\n\t\t\t\tif (hasAnnounceId(this.version)) {\n\t\t\t\t\tannounceIds.set(added, nextAnnounceId++);\n\t\t\t\t}\n\t\t\t\tawait encodeAnnounceBroadcast(stream.writer, { status: \"active\", suffix: added, hops }, this.version);\n\t\t\t}\n\n\t\t\t// Announce any removed broadcasts. Lite06+ retracts by announce id;\n\t\t\t// older versions repeat the path (ended announces don't need hops).\n\t\t\tfor (const removed of active.difference(newActive)) {\n\t\t\t\tconsole.debug(`announce: broadcast=${removed} active=false`);\n\t\t\t\tif (hasAnnounceId(this.version)) {\n\t\t\t\t\tconst id = announceIds.get(removed);\n\t\t\t\t\tannounceIds.delete(removed);\n\t\t\t\t\tif (id === undefined) continue; // never announced\n\t\t\t\t\tawait encodeAnnounceBroadcast(stream.writer, { status: \"endedId\", id }, this.version);\n\t\t\t\t} else {\n\t\t\t\t\tawait encodeAnnounceBroadcast(stream.writer, { status: \"ended\", suffix: removed }, this.version);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// NOTE: This is kind of a hack that won't work with a rapid UNANNOUNCE/ANNOUNCE cycle.\n\t\t\t// However, our client doesn't do that anyway.\n\n\t\t\tactive = newActive;\n\t\t}\n\t}\n\n\t/**\n\t * Handles a subscribe message.\n\t * @param msg - The subscribe message\n\t * @param stream - The stream to write track data to\n\t *\n\t * @internal\n\t */\n\tasync runSubscribe(msg: Subscribe, stream: Stream) {\n\t\tconst broadcast = this.#broadcasts.peek()?.get(msg.broadcast);\n\t\tif (!broadcast) {\n\t\t\tconsole.debug(`publish unknown: broadcast=${msg.broadcast}`);\n\t\t\tstream.writer.reset(new Error(\"not found\"));\n\t\t\treturn;\n\t\t}\n\n\t\tconst track = broadcast.subscribe(msg.track, {\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\t\tconst startGroup = msg.startGroup ?? track.latest();\n\t\tif (startGroup !== undefined) track.startAt(startGroup);\n\t\ttrack.endAt(msg.endGroup);\n\n\t\t// The best-effort datagram loop, started once serving begins. It parks when the\n\t\t// track finishes (recvDatagram returns undefined), so #runTrack alone ends the\n\t\t// subscription; awaited during teardown so it doesn't outlive the subscription.\n\t\tlet datagrams = Promise.resolve();\n\n\t\ttry {\n\t\t\tlet timescale: Timescale = Timescale.MILLI;\n\n\t\t\tif (supportsTrackStream(this.version)) {\n\t\t\t\t// Lite-05+ accepts implicitly: no SUBSCRIBE_OK (the immutable\n\t\t\t\t// properties live in TRACK_INFO), and the resolved range arrives as\n\t\t\t\t// SUBSCRIBE_START / SUBSCRIBE_END emitted from #runTrack.\n\t\t\t\t//\n\t\t\t\t// The timescale is an immutable property, so serving MUST use exactly\n\t\t\t\t// what TRACK_INFO advertised. It comes from the producer's accept(), so\n\t\t\t\t// they always agree. Awaiting info() also surfaces a rejected track\n\t\t\t\t// (accept never called, track closed) as an error here, which resets the\n\t\t\t\t// stream.\n\t\t\t\tconst info = await track.info();\n\t\t\t\ttimescale = info.timescale;\n\t\t\t} else {\n\t\t\t\t// Older drafts acknowledge with SUBSCRIBE_OK and stream frames verbatim.\n\t\t\t\tconst ok = new SubscribeOk({\n\t\t\t\t\tpriority: msg.priority,\n\t\t\t\t\tordered: msg.ordered,\n\t\t\t\t\tmaxLatency: msg.maxLatency,\n\t\t\t\t\tstartGroup: msg.startGroup,\n\t\t\t\t\tendGroup: msg.endGroup,\n\t\t\t\t});\n\t\t\t\tawait encodeSubscribeResponse(stream.writer, { ok }, this.version);\n\t\t\t}\n\n\t\t\tconsole.debug(`publish ok: broadcast=${msg.broadcast} track=${track.name}`);\n\n\t\t\tconst serving = this.#runTrack(msg.id, msg.broadcast, track, stream.writer, timescale);\n\n\t\t\t// Serve datagrams concurrently with groups whenever the transport carries them\n\t\t\t// (the writer exists iff so). No group fallback: otherwise they simply aren't sent.\n\t\t\tif (this.#datagramWriter) {\n\t\t\t\tdatagrams = this.#runDatagrams(msg.id, track, timescale);\n\t\t\t}\n\n\t\t\tfor (;;) {\n\t\t\t\tconst decode = SubscribeUpdate.decodeMaybe(stream.reader, this.version);\n\n\t\t\t\tconst result = await Promise.any([serving, decode]);\n\t\t\t\tif (!result) break;\n\n\t\t\t\tif (result instanceof SubscribeUpdate) {\n\t\t\t\t\tconsole.debug(`subscribe update: broadcast=${msg.broadcast} track=${track.name}`);\n\t\t\t\t\ttrack.update({\n\t\t\t\t\t\tpriority: result.priority,\n\t\t\t\t\t\tordered: result.ordered,\n\t\t\t\t\t\tlatencyMax: result.maxLatency,\n\t\t\t\t\t\tstartGroup: result.startGroup,\n\t\t\t\t\t\tendGroup: result.endGroup,\n\t\t\t\t\t});\n\t\t\t\t\tif (result.startGroup !== undefined) track.startAt(result.startGroup);\n\t\t\t\t\ttrack.endAt(result.endGroup);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.debug(`publish done: broadcast=${msg.broadcast} track=${track.name}`);\n\t\t\tstream.close();\n\t\t\ttrack.close();\n\t\t\t// track.close ends the datagram loop; wait so it doesn't leak past teardown.\n\t\t\tawait datagrams;\n\t\t} catch (err: unknown) {\n\t\t\tconst e = error(err);\n\t\t\tconsole.warn(`publish error: broadcast=${msg.broadcast} track=${track.name} error=${reason(e)}`);\n\t\t\ttrack.close(e);\n\t\t\tstream.abort(e);\n\t\t\tawait datagrams;\n\t\t}\n\t}\n\n\t/**\n\t * Handles a FETCH stream by serving one group as bare frame records (lite-05+).\n\t *\n\t * @internal\n\t */\n\tasync runFetch(msg: Fetch, stream: Stream) {\n\t\tif (!supportsTrackStream(this.version)) {\n\t\t\tstream.writer.reset(new Error(\"fetch requires moq-lite-05 or newer\"));\n\t\t\treturn;\n\t\t}\n\n\t\tconst broadcast = this.#broadcasts.peek()?.get(msg.broadcast);\n\t\tif (!broadcast) {\n\t\t\tconsole.debug(`fetch unknown: broadcast=${msg.broadcast}`);\n\t\t\tstream.writer.reset(new Error(\"not found\"));\n\t\t\treturn;\n\t\t}\n\n\t\t// The subscriber opened this stream, so its send order only ranked the request. Rank the\n\t\t// response here, on the same scale as the group streams it competes with.\n\t\tstream.writer.setPriority(sendOrder({ priority: msg.priority }));\n\n\t\tlet group: group.Consumer | undefined;\n\t\ttry {\n\t\t\t// The timescale is immutable, so serve exactly what TRACK_INFO advertised.\n\t\t\tconst info = await this.#resolveTrackInfo(msg.broadcast, msg.track);\n\t\t\tgroup = await broadcast.track(msg.track).fetchGroup(msg.group, { priority: msg.priority });\n\t\t\tawait this.#runFetchGroup(group, stream.writer, Timescale(info.timescale));\n\t\t\tconsole.debug(`fetch done: broadcast=${msg.broadcast} track=${msg.track} group=${msg.group}`);\n\t\t\tstream.close();\n\t\t\tgroup.close();\n\t\t} catch (err: unknown) {\n\t\t\tconst e = error(err);\n\t\t\tconsole.warn(\n\t\t\t\t`fetch error: broadcast=${msg.broadcast} track=${msg.track} group=${msg.group} error=${reason(e)}`,\n\t\t\t);\n\t\t\tgroup?.close(e);\n\t\t\tstream.abort(e);\n\t\t}\n\t}\n\n\t/**\n\t * Runs a track and sends its data to the stream.\n\t * @param sub - The subscription ID\n\t * @param broadcast - The broadcast name\n\t * @param track - The track to run\n\t * @param stream - The stream to write to\n\t *\n\t * @internal\n\t */\n\tasync #runTrack(sub: bigint, broadcast: Path.Valid, track: track.Subscriber, stream: Writer, timescale: Timescale) {\n\t\t// Lite-05+ resolves the range on the subscribe stream: SUBSCRIBE_START once the\n\t\t// first group is known, SUBSCRIBE_END when the track finishes.\n\t\tconst emitRange = supportsTrackStream(this.version);\n\t\tlet startSent = false;\n\n\t\t// The exclusive end of the delivered range. recvGroup is arrival-ordered rather than\n\t\t// sequence-ordered, so this tracks the max and not the last group seen. 0 is already\n\t\t// the encoding for a track that produced no groups.\n\t\tlet end = 0;\n\n\t\t// One ranking for the whole subscription, shared by every group it serves.\n\t\tconst priority = new Priority(track);\n\n\t\t// Cancels groups still queued for a stream slot. Only the subscriber leaving counts:\n\t\t// a track that ran out of groups still has to flush the ones already queued, and we\n\t\t// FIN the subscribe stream ourselves below to say so.\n\t\tlet finished = false;\n\t\tlet unsubscribe!: () => void;\n\t\tconst unsubscribed = new Promise<void>((resolve) => {\n\t\t\tunsubscribe = resolve;\n\t\t});\n\t\tvoid stream.closed.then(\n\t\t\t() => {\n\t\t\t\tif (!finished) unsubscribe();\n\t\t\t},\n\t\t\t// A reset is always the peer.\n\t\t\t() => unsubscribe(),\n\t\t);\n\n\t\ttry {\n\t\t\tfor (;;) {\n\t\t\t\t// Exactly-once serving, not the sequence cursor: on a relay, a burst can be\n\t\t\t\t// ingested micro-reordered by the upstream leg, and a sequence cursor would\n\t\t\t\t// permanently skip the older group even though it is cached and in demand.\n\t\t\t\t// Staleness is the latency window's job (cache expiry), not arrival order's.\n\t\t\t\tconst next = track.recvGroup();\n\t\t\t\tconst group = await Promise.race([next, stream.closed]);\n\t\t\t\tif (!group) {\n\t\t\t\t\tnext.then((group) => group?.close()).catch(() => {});\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (emitRange && !startSent) {\n\t\t\t\t\tstartSent = true;\n\t\t\t\t\t// SUBSCRIBE_START promises nothing below this sequence will be delivered.\n\t\t\t\t\t// Arrival-order serving could later surface a straggler below the first\n\t\t\t\t\t// group, so pin the floor to what was announced.\n\t\t\t\t\ttrack.startAt(group.sequence);\n\t\t\t\t\tawait encodeSubscribeResponse(stream, { start: new SubscribeStart(group.sequence) }, this.version);\n\t\t\t\t}\n\t\t\t\tend = Math.max(end, group.sequence + 1);\n\n\t\t\t\tvoid this.#runGroup({ sub, group, timescale, priority, unsubscribed });\n\t\t\t}\n\n\t\t\tif (emitRange) {\n\t\t\t\tawait encodeSubscribeResponse(stream, { end: new SubscribeEnd(end) }, this.version);\n\t\t\t}\n\n\t\t\tconsole.debug(`publish close: broadcast=${broadcast} track=${track.name}`);\n\t\t\tfinished = true;\n\t\t\ttrack.close();\n\t\t\tstream.close();\n\t\t} catch (err: unknown) {\n\t\t\tconst e = error(err);\n\t\t\tconsole.warn(`publish error: broadcast=${broadcast} track=${track.name} error=${reason(e)}`);\n\t\t\tunsubscribe();\n\t\t\ttrack.close(e);\n\t\t\tstream.reset(e);\n\t\t} finally {\n\t\t\tpriority.close();\n\t\t}\n\t}\n\n\t/**\n\t * Answers a TRACK stream (0x6) with a single TRACK_INFO, then FINs.\n\t *\n\t * @internal\n\t */\n\tasync runTrackInfo(msg: TrackMessage, stream: Stream) {\n\t\ttry {\n\t\t\tconst info = await this.#resolveTrackInfo(msg.broadcast, msg.track);\n\t\t\tawait info.encode(stream.writer, this.version);\n\t\t\tconsole.debug(`track info: broadcast=${msg.broadcast} track=${msg.track}`);\n\t\t\tstream.close();\n\t\t} catch (err) {\n\t\t\tconsole.debug(`track unknown: broadcast=${msg.broadcast} track=${msg.track}`);\n\t\t\tstream.writer.reset(error(err));\n\t\t}\n\t}\n\n\t// Resolve (and cache) a track's immutable TRACK_INFO by asking the application.\n\t// `broadcast.track(name).info()` triggers a TrackRequest the app answers with\n\t// accept(TrackInfo); only the immutable properties are needed (not the groups).\n\t// Cached because they're fixed for the track's lifetime. Rejects if the broadcast\n\t// or track is unavailable.\n\t#resolveTrackInfo(broadcast: Path.Valid, track: string): Promise<TrackInfoMessage> {\n\t\tconst key = `${broadcast}\\0${track}`;\n\t\tconst cached = this.#trackInfo.get(key);\n\t\tif (cached) return cached;\n\n\t\tconst pending = (async () => {\n\t\t\tconst published = this.#broadcasts.peek()?.get(broadcast);\n\t\t\tif (!published) throw new Error(\"not found\");\n\n\t\t\tconst info = await published.track(track).info();\n\t\t\treturn new TrackInfoMessage({\n\t\t\t\tpriority: info.priority,\n\t\t\t\tordered: info.ordered,\n\t\t\t\t// Publisher Max Latency: the publisher's retention bound, advertised so\n\t\t\t\t// relays re-serve with the same window.\n\t\t\t\tlatencyMax: info.latencyMax,\n\t\t\t\t// Lite05 mandates per-frame timestamps. Advertise the track's timescale;\n\t\t\t\t// `#runGroup` emits each frame converted to it.\n\t\t\t\ttimescale: info.timescale,\n\t\t\t});\n\t\t})();\n\n\t\t// Don't poison the cache on failure: a later request may succeed.\n\t\tpending.catch(() => this.#trackInfo.delete(key));\n\t\tthis.#trackInfo.set(key, pending);\n\t\treturn pending;\n\t}\n\n\t/**\n\t * Forwards a track's datagrams best-effort over QUIC datagrams (lite-05 §6.4), parallel to\n\t * its groups. Each datagram is dropped (there is no group fallback) if the encoded body\n\t * doesn't fit the transport's datagram limit or the send fails. Returns once the track\n\t * finishes; a failure never tears down the subscription.\n\t *\n\t * @internal\n\t */\n\tasync #runDatagrams(sub: bigint, track: track.Subscriber, timescale: Timescale) {\n\t\tconst writer = this.#datagramWriter;\n\t\tif (!writer) return; // Only reached with a writer (see the #datagramWriter gate).\n\t\tconst maxSize = DatagramStream.maxDatagramSize(this.#quic);\n\n\t\ttry {\n\t\t\tfor (;;) {\n\t\t\t\tconst datagram = await track.recvDatagram();\n\t\t\t\tif (!datagram) return; // Track finished; #runTrack tears the subscription down.\n\n\t\t\t\t// Convert the timestamp to the track's advertised timescale, matching #runGroup.\n\t\t\t\tconst ts = Math.round(datagram.timestamp.as(timescale));\n\t\t\t\tconst body = new DatagramMessage(sub, datagram.sequence, ts, datagram.payload).encode();\n\n\t\t\t\t// No group fallback: drop anything that doesn't fit a single datagram.\n\t\t\t\tif (body.byteLength > maxSize) {\n\t\t\t\t\tconsole.debug(`dropping oversize datagram: sub=${sub} size=${body.byteLength} max=${maxSize}`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tawait writer.ready;\n\t\t\t\tawait writer.write(body);\n\t\t\t}\n\t\t} catch (err: unknown) {\n\t\t\t// Best-effort: a datagram send failure stops sending but never fails the subscription.\n\t\t\tconsole.debug(`datagram send stopped: sub=${sub} error=${reason(err)}`);\n\t\t}\n\t}\n\n\t// Serialize a fetched group's frames onto the FETCH stream as bare records: each a\n\t// zigzag-delta timestamp (at the track's advertised timescale) followed by size + bytes.\n\tasync #runFetchGroup(group: group.Consumer, stream: Writer, timescale: Timescale) {\n\t\tlet prevTs = 0n;\n\t\tfor (;;) {\n\t\t\tconst frame = await Promise.race([group.readFrame(), stream.closed]);\n\t\t\tif (!frame) break;\n\n\t\t\tconst ts = BigInt(Math.round(frame.timestamp.as(timescale)));\n\t\t\tawait stream.u62(zigzag(ts - prevTs));\n\t\t\tprevTs = ts;\n\n\t\t\tawait stream.u53(frame.payload.byteLength);\n\t\t\tawait stream.write(frame.payload);\n\t\t}\n\t}\n\n\t/**\n\t * Serves one group on its own unidirectional stream.\n\t *\n\t * @internal\n\t */\n\tasync #runGroup(options: RunGroup) {\n\t\tconst { sub, group, timescale, priority, unsubscribed } = options;\n\t\tconst msg = new GroupMessage(sub, group.sequence);\n\t\ttry {\n\t\t\t// The transport drains streams by send order, so this is what makes a high-priority\n\t\t\t// track (and a newer group within it) win the link when there isn't room for both.\n\t\t\t//\n\t\t\t// One stream per group is faster than a peer at its limit can retire them, so this\n\t\t\t// is the one path that doesn't wait for a slot: the transport would serve the opens\n\t\t\t// in the order we asked, which is oldest-first, exactly backwards for live media.\n\t\t\t// Failing here drops the group and lets the next one compete for the next slot.\n\t\t\tconst stream = await Writer.tryOpen(this.#quic, {\n\t\t\t\tsendOrder: priority.rank(group.sequence),\n\t\t\t\tcancel: unsubscribed,\n\t\t\t\twaitUntilAvailable: false,\n\t\t\t});\n\t\t\tif (!stream) {\n\t\t\t\tgroup.close(new Error(\"no stream slot\"));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Everything past this point runs inside the cleanup scope, so a failure never leaves\n\t\t\t// a finished group's stream being ranked.\n\t\t\ttry {\n\t\t\t\t// A SUBSCRIBE_UPDATE re-ranks the subscription, so a group already on the wire\n\t\t\t\t// follows it too rather than keeping a stale rank until it finishes.\n\t\t\t\tpriority.add(stream, group.sequence);\n\n\t\t\t\tawait stream.u53(0); // stream type\n\t\t\t\tawait msg.encode(stream);\n\n\t\t\t\t// Lite05+ prefixes every frame with a zigzag-delta timestamp at the track's\n\t\t\t\t// advertised timescale; older drafts omit it.\n\t\t\t\tconst timestamps = supportsTrackStream(this.version);\n\t\t\t\tlet prevTs = 0n;\n\n\t\t\t\tfor (;;) {\n\t\t\t\t\tconst frame = await Promise.race([group.readFrame(), stream.closed]);\n\t\t\t\t\tif (!frame) break;\n\n\t\t\t\t\tif (timestamps) {\n\t\t\t\t\t\t// Convert each frame to the track's advertised timescale.\n\t\t\t\t\t\tconst ts = BigInt(Math.round(frame.timestamp.as(timescale)));\n\t\t\t\t\t\tawait stream.u62(zigzag(ts - prevTs));\n\t\t\t\t\t\tprevTs = ts;\n\t\t\t\t\t}\n\n\t\t\t\t\tawait stream.u53(frame.payload.byteLength);\n\t\t\t\t\tawait stream.write(frame.payload);\n\t\t\t\t}\n\n\t\t\t\tstream.close();\n\t\t\t\tgroup.close();\n\t\t\t} catch (err: unknown) {\n\t\t\t\tconst e = error(err);\n\t\t\t\tstream.reset(e);\n\t\t\t\tgroup.close(e);\n\t\t\t} finally {\n\t\t\t\tpriority.remove(stream);\n\t\t\t}\n\t\t} catch (err: unknown) {\n\t\t\tconst e = error(err);\n\t\t\tgroup.close(e);\n\t\t}\n\t}\n\n\t/**\n\t * Handles a probe stream by periodically reporting estimated bitrate.\n\t * @param stream - The probe bidi stream\n\t *\n\t * @internal\n\t */\n\tasync runProbe(stream: Stream) {\n\t\t// getStats is not yet in the TypeScript WebTransport type definitions.\n\t\tconst quic = this.#quic as unknown as {\n\t\t\tgetStats?: () => Promise<{ estimatedSendRate: number | null; smoothedRtt?: number | null }>;\n\t\t};\n\t\tif (!quic.getStats) {\n\t\t\t// Best-effort: we can't supply bandwidth estimates, so close the\n\t\t\t// whole bidi (FIN + STOP_SENDING) to let the peer release its end.\n\t\t\tstream.close();\n\t\t\treturn;\n\t\t}\n\n\t\tlet lastSent: Probe | undefined;\n\t\tlet lastSentTime: number | undefined;\n\n\t\t// Whether a metric moved enough to be worth another report. Gaining or\n\t\t// losing a value always counts; both unknown never does.\n\t\tconst moved = (prev?: number, next?: number, threshold = 0): boolean => {\n\t\t\tif (prev === undefined && next === undefined) return false;\n\t\t\tif (prev === undefined || next === undefined) return true;\n\t\t\tif (prev === 0) return next !== 0;\n\t\t\treturn Math.abs(next - prev) / prev >= threshold;\n\t\t};\n\n\t\ttry {\n\t\t\tfor (;;) {\n\t\t\t\tconst timeout = new Promise<\"timeout\">((resolve) =>\n\t\t\t\t\tsetTimeout(() => resolve(\"timeout\"), PROBE_INTERVAL),\n\t\t\t\t);\n\t\t\t\tconst result = await Promise.race([timeout, stream.reader.closed]);\n\t\t\t\tif (result !== \"timeout\") break;\n\n\t\t\t\t// The two fields are independent on the wire, each using 0 for\n\t\t\t\t// unknown, so a transport exposing only one still has something to\n\t\t\t\t// report. Anything this version can't carry is dropped here rather\n\t\t\t\t// than by the encoder, so it reads as unknown to every check below.\n\t\t\t\tconst stats = await quic.getStats();\n\t\t\t\t// `smoothedRtt` is a DOMHighResTimeStamp, i.e. a double, but the wire\n\t\t\t\t// carries whole milliseconds and the varint encoder throws on a\n\t\t\t\t// fractional value. Round before it ever reaches `Probe`.\n\t\t\t\tconst rtt = stats.smoothedRtt != null ? Math.round(stats.smoothedRtt) : undefined;\n\t\t\t\tconst report = new Probe({\n\t\t\t\t\tbitrate: stats.estimatedSendRate ?? undefined,\n\t\t\t\t\trtt: hasProbeRtt(this.version) ? rtt : undefined,\n\t\t\t\t});\n\n\t\t\t\t// Nothing left to report. Say so once if it retracts a value the peer\n\t\t\t\t// is still holding, then stay quiet rather than repeating \"unknown\"\n\t\t\t\t// every time the max age comes around.\n\t\t\t\tif (report.bitrate === undefined && report.rtt === undefined) {\n\t\t\t\t\tconst retracts =\n\t\t\t\t\t\tlastSent !== undefined && (lastSent.bitrate !== undefined || lastSent.rtt !== undefined);\n\t\t\t\t\tif (!retracts) continue;\n\t\t\t\t}\n\n\t\t\t\tlet shouldSend: boolean;\n\t\t\t\tif (lastSent === undefined || lastSentTime === undefined) {\n\t\t\t\t\tshouldSend = true;\n\t\t\t\t} else {\n\t\t\t\t\tconst elapsed = performance.now() - lastSentTime;\n\t\t\t\t\t// The bitrate threshold decays to zero as the last report ages: a\n\t\t\t\t\t// stale estimate is worth refreshing for a smaller move.\n\t\t\t\t\tconst t = Math.max(PROBE_INTERVAL, Math.min(PROBE_MAX_AGE, elapsed));\n\t\t\t\t\tconst range = PROBE_MAX_AGE - PROBE_INTERVAL;\n\t\t\t\t\tconst threshold = (PROBE_MAX_DELTA * (PROBE_MAX_AGE - t)) / range;\n\t\t\t\t\tshouldSend =\n\t\t\t\t\t\telapsed >= PROBE_MAX_AGE ||\n\t\t\t\t\t\tmoved(lastSent.bitrate, report.bitrate, threshold) ||\n\t\t\t\t\t\tmoved(lastSent.rtt, report.rtt, PROBE_RTT_DELTA);\n\t\t\t\t}\n\n\t\t\t\tif (shouldSend) {\n\t\t\t\t\tawait report.encode(stream.writer, this.version);\n\t\t\t\t\tlastSent = report;\n\t\t\t\t\tlastSentTime = performance.now();\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (err: unknown) {\n\t\t\tconsole.warn(\"probe stream error\", err);\n\t\t\tstream.close();\n\t\t}\n\t}\n\n\tclose() {\n\t\tthis.#broadcasts.update((broadcasts) => {\n\t\t\tfor (const broadcast of broadcasts?.values() ?? []) {\n\t\t\t\tbroadcast.close();\n\t\t\t}\n\t\t\treturn undefined;\n\t\t});\n\n\t\t// Release the datagram writer's lock so the stream can be torn down.\n\t\tthis.#datagramWriter?.releaseLock();\n\t\tthis.#datagramWriter = undefined;\n\t}\n}\n"]}
1
+ {"version":3,"file":"publisher.js","sourceRoot":"","sources":["../../src/lite/publisher.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Dispose, type Getter, race, Signal } from \"@moq/signals\";\nimport type * as broadcast from \"../broadcast.ts\";\nimport { error, NotFound, reason, StreamCode, StreamError } from \"../error.ts\";\nimport type * as group from \"../group.ts\";\nimport { Cost, type Hop, type Route, routesEqual } from \"../hop.ts\";\nimport { hiddenBelow, hooks, presented } from \"../internal.ts\";\nimport type { Consumer as OriginConsumer } from \"../origin.ts\";\nimport type * as Path from \"../path.ts\";\nimport { type Reader, type Stream, Writer } from \"../stream.ts\";\nimport { Milli, Timescale } from \"../time.ts\";\nimport type * as track from \"../track.ts\";\nimport { type Advertised, type Advertisements, wireOf } from \"../wire.ts\";\nimport { AnnounceInit, AnnounceOk, type AnnounceRequest, encodeAnnounceBroadcast } from \"./announce.ts\";\nimport { Datagram as DatagramMessage } from \"./datagram.ts\";\nimport * as DatagramStream from \"./datagram_stream.ts\";\nimport type { Fetch } from \"./fetch.ts\";\nimport { Group as GroupMessage } from \"./group.ts\";\nimport { Priority, sendOrder } from \"./priority.ts\";\nimport { Probe } from \"./probe.ts\";\nimport {\n\tencodeSubscribeResponse,\n\texclusiveGroupEnd,\n\ttype Subscribe,\n\tSubscribeEnd,\n\tSubscribeOk,\n\tSubscribeStart,\n\tSubscribeUpdate,\n} from \"./subscribe.ts\";\nimport { TrackInfo as TrackInfoMessage, type Track as TrackMessage } from \"./track.ts\";\nimport {\n\thasAnnounceId,\n\thasAnnounceOk,\n\thasDatagrams,\n\thasProbeRtt,\n\thasRouteCost,\n\thasStreamCount,\n\tresolvesStart,\n\tVersion,\n} from \"./version.ts\";\n\nconst PROBE_INTERVAL = 100; // ms\nconst PROBE_MAX_AGE = 10_000; // ms\nconst PROBE_MAX_DELTA = 0.25;\nconst PROBE_RTT_DELTA = 0.25;\n\n/** Map a signed delta to an unsigned zigzag varint value (mirrors Rust `VarInt::from_zigzag`). */\nfunction zigzag(delta: bigint): bigint {\n\treturn delta >= 0n ? delta << 1n : (-delta << 1n) - 1n;\n}\n\n/** What {@link Publisher.openGroup} and {@link Publisher.serveGroup} need to serve one group. */\ninterface RunGroup {\n\t/** The subscription ID. */\n\tsub: bigint;\n\n\t/** The group to serve. */\n\tgroup: group.Consumer;\n\n\t/** The track's advertised timescale, applied to every frame timestamp. */\n\ttimescale: Timescale;\n\n\t/** The subscription's ranking, which this stream joins for as long as it runs. */\n\tpriority: Priority;\n\n\t/** Settles when the subscriber leaves, dropping a group still queued for a stream slot. */\n\tunsubscribed: Promise<void>;\n\n\t/** First frame to send; anything below it was excluded by the subscription. */\n\tstart: number;\n\n\t/** Last frame to send (inclusive), or undefined for the rest of the group. */\n\tend?: number;\n}\n\n// The TRACK stream, implicit SUBSCRIBE acceptance, and SUBSCRIBE_START/END are\n// all 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 * The frame bounds a subscription placed on its start and end group, as they stand\n * after any SUBSCRIBE_UPDATE.\n *\n * Only the two named groups are qualified; the group range itself lives on the\n * subscriber's read cursor (see {@link frameRange}).\n */\ntype FrameBounds = {\n\t/** The group {@link startFrame} qualifies, if the subscription named one. */\n\tstartGroup?: number;\n\t/** First frame to send within {@link startGroup}; every other group starts at 0. */\n\tstartFrame: number;\n\t/** The group {@link endFrame} qualifies, if the subscription named one. */\n\tendGroup?: number;\n\t/** Last frame (inclusive) to send within {@link endGroup}; every other group runs to its end. */\n\tendFrame?: number;\n};\n\n/**\n * The frames of `sequence` a subscription asked for, as a start index and an inclusive end.\n *\n * The frame bounds qualify the start and end group only; every other group is served whole.\n * Which groups are served at all is the subscriber's read cursor (`replaceGroups`),\n * applied when a group is popped rather than re-checked here.\n *\n * The serving loop calls this synchronously after the pop, before any SUBSCRIBE_UPDATE can\n * change `bounds`. Nothing downstream trims the frame range: it is a wire request,\n * deliberately decoupled from the receiver's local read cursor.\n */\nfunction frameRange(bounds: FrameBounds, sequence: number): { start: number; end?: number } {\n\treturn {\n\t\tstart: bounds.startGroup === sequence ? bounds.startFrame : 0,\n\t\tend: bounds.endGroup === sequence ? bounds.endFrame : undefined,\n\t};\n}\n\n/** What serving one group needs beyond the group itself. */\ntype ServeGroup = {\n\t/** The Subscribe ID the GROUP message references. */\n\tsub: bigint;\n\t/** The track's advertised timescale, which every frame timestamp is converted to. */\n\ttimescale: Timescale;\n\t/** First frame to send; anything below it was excluded by the subscription. */\n\tstart: number;\n\t/** Last frame to send (inclusive), or undefined for the rest of the group. */\n\tend?: number;\n};\n\n/** What serving fetched frames needs beyond the group and destination stream. */\ntype ServeFetch = Omit<ServeGroup, \"sub\">;\n\n/** What the serving loop takes from the subscribe stream instead of serving a group. */\ntype Control =\n\t/** The peer re-stated the subscription: priority, ordering, latency, and both ranges. */\n\t| { kind: \"update\"; update: SubscribeUpdate }\n\t/** The peer FIN'd, or our own half went away. Either way there is nobody left to serve. */\n\t| { kind: \"done\" }\n\t/** The stream failed; the subscription goes down with it. */\n\t| { kind: \"error\"; error: Error };\n\ntype SubscriptionControlOptions = {\n\treader: Reader;\n\twriter: Writer;\n\tversion: Version;\n\tapply: (update: SubscribeUpdate) => void;\n};\n\n/**\n * The subscribe stream's control half, decoded ahead of the serving loop.\n *\n * Decoding runs on its own and publishes each full subscription update immediately, so a\n * blocked response write cannot delay re-ranking streams already in flight. It separately\n * stores only the latest range state for the serving loop, which owns the local track cursor\n * and frame bounds. That keeps a group pop and its frame-range snapshot one indivisible step.\n *\n * Reading ahead makes control-first ordering hold for a burst. Coalescing bounds memory while\n * preserving the newest state decoded before the next group pop. The Rust publisher gets the\n * same ordering from `poll_decode_maybe`, which decodes straight out of the reader's buffer;\n * nothing here can decode synchronously, so it reads ahead instead.\n */\nclass SubscriptionControls {\n\t#writer: Writer;\n\t#update?: SubscribeUpdate;\n\t// Sticky, first one wins: null once the stream is over, an Error once it failed.\n\t#end?: Error | null;\n\t#ended: Promise<Error | null>;\n\t#resolveEnd!: (end: Error | null) => void;\n\t#changed = new Signal(0);\n\n\t/** Settles once decoding stops, so teardown can wait for it rather than leaving it running. */\n\treadonly decoding: Promise<void>;\n\n\tconstructor({ reader, writer, version, apply }: SubscriptionControlOptions) {\n\t\tthis.#writer = writer;\n\t\tthis.#ended = new Promise((resolve) => {\n\t\t\tthis.#resolveEnd = resolve;\n\t\t});\n\t\tthis.decoding = this.#decode(reader, version, apply);\n\t\t// Our own half going away ends the loop too, and has to reach it the same way: the\n\t\t// loop looks at nothing else.\n\t\tvoid writer.closed.then(\n\t\t\t() => this.#finish(null),\n\t\t\t(err: unknown) => this.#finish(error(err)),\n\t\t);\n\t}\n\n\t/** The next control to apply, or undefined while the peer is quiet. */\n\ttake(): Control | undefined {\n\t\tconst update = this.#update;\n\t\tthis.#update = undefined;\n\t\t// An update decoded before the stream ended still applies before the sticky end.\n\t\tif (update) return { kind: \"update\", update };\n\t\tif (this.#end === undefined) return undefined;\n\t\treturn this.#end === null ? { kind: \"done\" } : { kind: \"error\", error: this.#end };\n\t}\n\n\t/** Calls `fn` once {@link take} may answer differently. */\n\tchanged(fn: () => void): Dispose {\n\t\treturn this.#changed.changed(fn);\n\t}\n\n\t/** Returns false when peer departure supersedes a blocked response write. */\n\tasync response(pending: Promise<void>): Promise<boolean> {\n\t\t// `#ended` lives as long as the stream, so it is raced as-is rather than mapped per call.\n\t\tconst result = await race([\n\t\t\tpending.then(\n\t\t\t\t() => ({ kind: \"sent\" }) as const,\n\t\t\t\t(err: unknown) => ({ kind: \"error\", error: error(err) }) as const,\n\t\t\t),\n\t\t\tthis.#ended,\n\t\t]);\n\n\t\tif (result !== null && !(result instanceof Error)) {\n\t\t\tif (result.kind === \"sent\") return true;\n\t\t\tthrow result.error;\n\t\t}\n\n\t\t// The race leaves the blocked encode running, so reset the writable half too.\n\t\tthis.#writer.reset(result ?? new StreamError(StreamCode.Cancel, { message: \"cancel\" }));\n\t\tif (result) throw result;\n\t\treturn false;\n\t}\n\n\t/** Settles once the stream is over: `null` when it ended cleanly, or the failure. */\n\tget ended(): Promise<Error | null> {\n\t\treturn this.#ended;\n\t}\n\n\t#finish(end: Error | null) {\n\t\tif (this.#end !== undefined) return;\n\t\tthis.#end = end;\n\t\tthis.#resolveEnd(end);\n\t\tthis.#changed.update((value) => value + 1);\n\t}\n\n\tasync #decode(reader: Reader, version: Version, apply: (update: SubscribeUpdate) => void) {\n\t\ttry {\n\t\t\twhile (this.#end === undefined) {\n\t\t\t\tconst update = await SubscribeUpdate.decodeMaybe(reader, version);\n\t\t\t\tif (!update) break;\n\t\t\t\tapply(update);\n\t\t\t\tthis.#update = update;\n\t\t\t\tthis.#changed.update((value) => value + 1);\n\t\t\t}\n\t\t} catch (err: unknown) {\n\t\t\tthis.#finish(error(err));\n\t\t\treturn;\n\t\t}\n\t\tthis.#finish(null);\n\t}\n}\n\n// A microtask is too short: decoding one framed update crosses several awaits, each of which\n// can requeue behind the serving continuation. A task boundary lets the decoder finish whatever\n// the transport already delivered before the next group pop. Updates are rare, so groups do not\n// pay this scheduling cost on the normal path.\nconst yieldToControls = () => new Promise<void>((resolve) => setTimeout(resolve, 0));\n\n// Register both readiness sources in the same turn after the caller observed neither ready.\n// The winner disposes both registrations, so an idle subscription accumulates nothing no\n// matter how many times it wakes.\nfunction waitForSubscription(controls: SubscriptionControls, subscriber: track.Subscriber): Promise<void> {\n\treturn new Promise((resolve) => {\n\t\tlet settled = false;\n\t\tconst dispose: Dispose[] = [];\n\t\tconst wake = () => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tfor (const close of dispose) close();\n\t\t\tresolve();\n\t\t};\n\t\tdispose.push(controls.changed(wake), hooks.groupChanged(subscriber, wake));\n\t});\n}\n\n/**\n * The budget to serve a peer with, given what its wire could tell us.\n *\n * A version without the field decodes as `0`, which is indistinguishable from a peer\n * genuinely asking for the live edge. Serving that as real time would discard backlog\n * a legacy subscriber never declined, so fall back to a window wide enough not to drop\n * and leave enforcement to the receiver, as the IETF path does for the same reason.\n */\nfunction servingMaxAge(version: Version, requested: number | undefined): number {\n\treturn carriesMaxAge(version) ? (requested ?? 0) : Number.MAX_SAFE_INTEGER;\n}\n\n/** Whether this version's SUBSCRIBE carries Subscriber Max Age at all. */\nfunction carriesMaxAge(version: Version): boolean {\n\treturn version !== Version.DRAFT_01 && version !== Version.DRAFT_02;\n}\n\n/**\n * Position a subscription's read cursor for the wire serving it.\n *\n * On lite-06 there is nothing to do: the cursor is floored at the group the subscription\n * named (or 0), and its Max Age decides what above the floor is worth delivering.\n *\n * Pre-06 wires are the exception: their drafts define an absent `Group Start` as the\n * latest group, so say so explicitly rather than letting the budget reach back. Lite-03/04/05\n * carry a Max Age, but there it is a staleness tolerance only; lite-01/02 additionally get\n * an unbounded budget so nothing is dropped under them (see {@link servingMaxAge}), which\n * must not read as a request to replay the whole cache on join.\n */\nfunction positionCursor(track: track.Subscriber, version: Version, startGroup: number | undefined) {\n\tif (resolvesStart(version) || startGroup !== undefined) return;\n\n\tconst latest = track.latest();\n\tif (latest !== undefined) hooks.replaceGroups(track, { start: { included: latest } });\n}\n\n/**\n * Handles publishing broadcasts and managing their lifecycle.\n *\n * @internal\n */\nexport class Publisher {\n\t// The version of the connection.\n\treadonly version: Version;\n\n\t// Per-connection origin appended to outbound Announce hops, so the peer\n\t// can detect loops and prefer shorter paths. Created by Connection and\n\t// shared with Subscriber, which can optionally use it to filter out its\n\t// own announcements.\n\treadonly hop: Hop;\n\n\t#quic: WebTransport;\n\n\t// The one writer for the outbound datagram stream (getWriter locks it), acquired once at\n\t// construction when this version + transport carry datagrams, released in close(). Its\n\t// presence is the gate: undefined means datagrams aren't served on this connection. All\n\t// subscriptions share it, since a second getWriter on the same stream would throw.\n\t#datagramWriter?: WritableStreamDefaultWriter<Uint8Array>;\n\n\t// Originated advertisements this session forwards.\n\t#advertised: Getter<Advertisements | undefined>;\n\n\t#publish?: OriginConsumer;\n\n\t// TRACK_INFO is immutable per track, so resolve it from the application once\n\t// (via a throwaway subscribe whose info() resolves when the app calls accept)\n\t// and reuse it for every later TRACK request of the same track. Keyed by the\n\t// routing front rather than the path: immutability holds for one broadcast, and a\n\t// republish puts a different one on the path, so its entries must not be reused.\n\t// A rejected lookup is evicted so a retry can re-probe.\n\t#trackInfo = new WeakMap<broadcast.Consumer, Map<string, Promise<TrackInfoMessage>>>();\n\n\t/**\n\t * Creates a new Publisher instance.\n\t * @param quic - The WebTransport session to use\n\t * @param version - Negotiated protocol version\n\t * @param origin - Hop id shared with the Subscriber\n\t * @param publish - The origin whose broadcasts this session serves; omit to publish nothing\n\t *\n\t * @internal\n\t */\n\tconstructor(quic: WebTransport, version: Version, hop: Hop, publish?: OriginConsumer) {\n\t\tthis.#quic = quic;\n\t\tthis.version = version;\n\t\tthis.hop = hop;\n\t\tconst origin = publish && wireOf(publish);\n\t\tthis.#advertised = origin?.advertised ?? new Signal(new Map());\n\t\tthis.#publish = publish;\n\n\t\t// Grab the datagram writer up front when the transport carries datagrams (no group\n\t\t// fallback, so it stays undefined otherwise). One writer for all subscriptions.\n\t\tif (hasDatagrams(version)) {\n\t\t\tthis.#datagramWriter = DatagramStream.datagramWriter(quic);\n\t\t}\n\t}\n\n\t/**\n\t * Handles an announce interest message.\n\t * @param msg - The announce interest message\n\t * @param stream - The stream to write announcements to\n\t *\n\t * @internal\n\t */\n\tasync runAnnounce(msg: AnnounceRequest, stream: Stream) {\n\t\tconsole.debug(`announce: prefix=${msg.prefix}`);\n\n\t\t// Keyed by suffix, valued by identity plus route, so a republish diffs as\n\t\t// ended-then-active and a re-price as a restart.\n\t\tlet active = new Map<Path.Valid, Advertised>();\n\n\t\t// Lite06+: announce ids. Every active we send implicitly assigns the next\n\t\t// per-stream ordinal; ended/restart reference the id instead of repeating the path.\n\t\tlet nextAnnounceId = 0n;\n\t\tconst announceIds = new Map<Path.Valid, bigint>();\n\n\t\tconst wireHops = (route: Route): Hop[] => {\n\t\t\tif (hasAnnounceOk(this.version)) return route.hops;\n\t\t\treturn [...route.hops, this.hop];\n\t\t};\n\n\t\t// What the peer decodes for a route: pre-lite-06 wires carry no cost, so a re-price\n\t\t// there must not restart.\n\t\tconst onWire = (route: Route): Route => (hasRouteCost(this.version) ? route : { ...route, cost: Cost.zero });\n\n\t\tconst announce = async (suffix: Path.Valid, route: Route) => {\n\t\t\tconsole.debug(`announce: broadcast=${suffix} active=true`);\n\t\t\tif (hasAnnounceId(this.version)) announceIds.set(suffix, nextAnnounceId++);\n\t\t\tawait encodeAnnounceBroadcast(\n\t\t\t\tstream.writer,\n\t\t\t\t{ status: \"active\", suffix, hops: wireHops(route), cost: route.cost },\n\t\t\t\tthis.version,\n\t\t\t);\n\t\t};\n\n\t\tconst restart = async (suffix: Path.Valid, route: Route) => {\n\t\t\tif (!hasAnnounceId(this.version)) {\n\t\t\t\tawait retract(suffix);\n\t\t\t\tawait announce(suffix, route);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst id = announceIds.get(suffix);\n\t\t\tif (id === undefined) {\n\t\t\t\tawait announce(suffix, route);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconsole.debug(`announce: broadcast=${suffix} restart=true`);\n\t\t\tawait encodeAnnounceBroadcast(\n\t\t\t\tstream.writer,\n\t\t\t\t{ status: \"restart\", id, hops: wireHops(route), cost: route.cost },\n\t\t\t\tthis.version,\n\t\t\t);\n\t\t};\n\n\t\t// Lite06+ retracts by announce id; older versions repeat the path (ended announces\n\t\t// don't need hops).\n\t\tconst retract = async (suffix: Path.Valid) => {\n\t\t\tconsole.debug(`announce: broadcast=${suffix} active=false`);\n\t\t\tif (!hasAnnounceId(this.version)) {\n\t\t\t\tawait encodeAnnounceBroadcast(stream.writer, { status: \"ended\", suffix }, this.version);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst id = announceIds.get(suffix);\n\t\t\tannounceIds.delete(suffix);\n\t\t\tif (id === undefined) return; // never announced\n\t\t\tawait encodeAnnounceBroadcast(stream.writer, { status: \"endedId\", id }, this.version);\n\t\t};\n\n\t\t// Subscribe BEFORE writing anything: every encode below awaits the wire, and a publish\n\t\t// landing in that window only notifies the listeners already registered. One created\n\t\t// afterwards would sleep through it, leaving the change unannounced until something\n\t\t// unrelated moved.\n\t\t// TODO Make a better helper within Signals.\n\t\tlet dispose!: Dispose;\n\t\tlet changed = new Promise<Advertisements | undefined>((resolve) => {\n\t\t\tdispose = this.#advertised.changed(resolve);\n\t\t});\n\n\t\t// A hidden route stays off the wire unless the request opted in.\n\t\tconst carries = (covered: Path.Valid) => msg.hidden || !hiddenBelow(msg.prefix, covered);\n\n\t\ttry {\n\t\t\tconst initial = this.#advertised.peek();\n\t\t\tif (!initial) return; // closed\n\n\t\t\tfor (const [name, snap] of presented(msg.prefix, initial, carries)) {\n\t\t\t\tactive.set(name, snap);\n\t\t\t}\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\tfor (const suffix of active.keys()) {\n\t\t\t\t\t\tconsole.debug(`announce: broadcast=${suffix} active=true`);\n\t\t\t\t\t}\n\t\t\t\t\tconst init = new AnnounceInit([...active.keys()]);\n\t\t\t\t\tawait init.encode(stream.writer, this.version);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tif (!hasAnnounceOk(this.version)) {\n\t\t\t\t\t\tfor (const [suffix, snap] of active) {\n\t\t\t\t\t\t\tawait announce(suffix, snap.route);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst ok = new AnnounceOk(this.hop, active.size);\n\t\t\t\t\tawait ok.encode(stream.writer, this.version);\n\t\t\t\t\tfor (const [suffix, snap] of active) {\n\t\t\t\t\t\tawait announce(suffix, snap.route);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (;;) {\n\t\t\t\tconst advertised = await race([changed, stream.reader.closed]);\n\t\t\t\tdispose();\n\t\t\t\tif (!advertised) break;\n\n\t\t\t\t// Re-arm before reading, so an advertise that lands while we write is not lost.\n\t\t\t\tchanged = new Promise<Advertisements | undefined>((resolve) => {\n\t\t\t\t\tdispose = this.#advertised.changed(resolve);\n\t\t\t\t});\n\n\t\t\t\tconst latest = this.#advertised.peek();\n\t\t\t\tif (!latest) break;\n\n\t\t\t\tconst updated = new Map<Path.Valid, Advertised>();\n\t\t\t\tfor (const [name, snap] of presented(msg.prefix, latest, carries)) {\n\t\t\t\t\tupdated.set(name, snap);\n\t\t\t\t}\n\n\t\t\t\tfor (const [suffix, snap] of active) {\n\t\t\t\t\tconst cur = updated.get(suffix);\n\t\t\t\t\tif (!cur || cur.identity !== snap.identity) await retract(suffix);\n\t\t\t\t}\n\t\t\t\tfor (const [suffix, snap] of updated) {\n\t\t\t\t\tconst prev = active.get(suffix);\n\t\t\t\t\tif (!prev || prev.identity !== snap.identity) {\n\t\t\t\t\t\tawait announce(suffix, snap.route);\n\t\t\t\t\t} else if (!routesEqual(onWire(prev.route), onWire(snap.route))) {\n\t\t\t\t\t\tawait restart(suffix, snap.route);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tactive = updated;\n\t\t\t}\n\t\t} finally {\n\t\t\tdispose();\n\t\t}\n\t}\n\n\t/**\n\t * Handles a subscribe message.\n\t * @param msg - The subscribe message\n\t * @param stream - The stream to write track data to\n\t *\n\t * @internal\n\t */\n\tasync runSubscribe(msg: Subscribe, stream: Stream) {\n\t\tlet front: broadcast.Consumer | undefined;\n\t\ttry {\n\t\t\tfront =\n\t\t\t\tthis.#publish &&\n\t\t\t\t(wireOf(this.#publish).local(msg.broadcast) ?? (await wireOf(this.#publish).demand(msg.broadcast)));\n\t\t} catch (err: unknown) {\n\t\t\tstream.writer.reset(error(err));\n\t\t\treturn;\n\t\t}\n\t\tif (!front) {\n\t\t\tconsole.debug(`publish unknown: broadcast=${msg.broadcast}`);\n\t\t\tstream.writer.reset(new NotFound(`broadcast ${msg.broadcast}`));\n\t\t\treturn;\n\t\t}\n\n\t\tconst endGroup = exclusiveGroupEnd(msg.endGroup);\n\t\tconst track = wireOf(front).subscribe(msg.track, {\n\t\t\tpriority: msg.priority,\n\t\t\tmaxAge: Milli(servingMaxAge(this.version, msg.maxAge)),\n\t\t\tgroups: {\n\t\t\t\tstart: msg.startGroup === undefined ? undefined : { included: msg.startGroup },\n\t\t\t\tend: endGroup === undefined ? undefined : { excluded: endGroup },\n\t\t\t},\n\t\t});\n\t\tpositionCursor(track, this.version, msg.startGroup);\n\t\thooks.replaceGroups(track, { end: endGroup === undefined ? undefined : { excluded: endGroup } });\n\n\t\t// The best-effort datagram loop, started once serving begins. It parks when the\n\t\t// track finishes (recvDatagram returns undefined), so #runTrack alone ends the\n\t\t// subscription; awaited during teardown so it doesn't outlive the subscription.\n\t\tlet datagrams = Promise.resolve();\n\t\tlet controls: SubscriptionControls | undefined;\n\n\t\ttry {\n\t\t\tlet timescale: Timescale = Timescale.MILLI;\n\n\t\t\tif (supportsTrackStream(this.version)) {\n\t\t\t\t// Lite-05+ accepts implicitly: no SUBSCRIBE_OK (the immutable\n\t\t\t\t// properties live in TRACK_INFO), and the resolved range arrives as\n\t\t\t\t// SUBSCRIBE_START / SUBSCRIBE_END emitted from #runTrack.\n\t\t\t\t//\n\t\t\t\t// The timescale is an immutable property, so serving MUST use exactly\n\t\t\t\t// what TRACK_INFO advertised. It comes from the producer's accept(), so\n\t\t\t\t// they always agree. Awaiting info() also surfaces a rejected track\n\t\t\t\t// (accept never called, track closed) as an error here, which resets the\n\t\t\t\t// stream.\n\t\t\t\tconst info = await track.info();\n\t\t\t\ttimescale = info.timescale;\n\t\t\t} else {\n\t\t\t\t// Older drafts acknowledge with SUBSCRIBE_OK and stream frames verbatim.\n\t\t\t\tconst ok = new SubscribeOk({\n\t\t\t\t\tpriority: msg.priority,\n\t\t\t\t\tmaxAge: msg.maxAge,\n\t\t\t\t\tstartGroup: msg.startGroup,\n\t\t\t\t\tendGroup: msg.endGroup,\n\t\t\t\t});\n\t\t\t\tawait encodeSubscribeResponse(stream.writer, { ok }, this.version);\n\t\t\t}\n\n\t\t\tconsole.debug(`publish ok: broadcast=${msg.broadcast} track=${track.name}`);\n\n\t\t\t// Serve datagrams concurrently with groups whenever the transport carries them\n\t\t\t// (the writer exists iff so). No group fallback: otherwise they simply aren't sent.\n\t\t\tif (this.#datagramWriter) {\n\t\t\t\tdatagrams = this.#runDatagrams(msg.id, track, timescale);\n\t\t\t}\n\n\t\t\tcontrols = new SubscriptionControls({\n\t\t\t\treader: stream.reader,\n\t\t\t\twriter: stream.writer,\n\t\t\t\tversion: this.version,\n\t\t\t\tapply: (update) => {\n\t\t\t\t\tconst end = exclusiveGroupEnd(update.endGroup);\n\t\t\t\t\ttrack.update({\n\t\t\t\t\t\tpriority: update.priority,\n\t\t\t\t\t\tmaxAge: Milli(servingMaxAge(this.version, update.maxAge)),\n\t\t\t\t\t\tgroups: {\n\t\t\t\t\t\t\tstart: update.startGroup === undefined ? undefined : { included: update.startGroup },\n\t\t\t\t\t\t\tend: end === undefined ? undefined : { excluded: end },\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t});\n\t\t\tawait this.#runTrack(track, stream.writer, controls, {\n\t\t\t\tsub: msg.id,\n\t\t\t\tbroadcast: msg.broadcast,\n\t\t\t\ttimescale,\n\t\t\t\tbounds: {\n\t\t\t\t\tstartGroup: msg.startGroup,\n\t\t\t\t\tstartFrame: msg.startFrame,\n\t\t\t\t\tendGroup: msg.endGroup,\n\t\t\t\t\tendFrame: msg.endFrame,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tconsole.debug(`publish done: broadcast=${msg.broadcast} track=${track.name}`);\n\t\t\tstream.close();\n\t\t\ttrack.close();\n\t\t\t// Closing the stream ends the decoder and track.close ends the datagram loop.\n\t\t\tawait Promise.all([datagrams, controls.decoding]);\n\t\t} catch (err: unknown) {\n\t\t\tconst e = error(err);\n\t\t\tconsole.warn(`publish error: broadcast=${msg.broadcast} track=${track.name} error=${reason(e)}`);\n\t\t\ttrack.close(e);\n\t\t\tstream.abort(e);\n\t\t\tawait Promise.all([datagrams, controls?.decoding]);\n\t\t}\n\t}\n\n\t/**\n\t * Handles a FETCH stream by serving one group as bare frame records (lite-05+).\n\t *\n\t * @internal\n\t */\n\tasync runFetch(msg: Fetch, stream: Stream) {\n\t\tif (!supportsTrackStream(this.version)) {\n\t\t\tstream.writer.reset(new Error(\"fetch requires moq-lite-05 or newer\"));\n\t\t\treturn;\n\t\t}\n\n\t\tlet front: broadcast.Consumer | undefined;\n\t\ttry {\n\t\t\tfront =\n\t\t\t\tthis.#publish &&\n\t\t\t\t(wireOf(this.#publish).local(msg.broadcast) ?? (await wireOf(this.#publish).demand(msg.broadcast)));\n\t\t} catch (err: unknown) {\n\t\t\tstream.writer.reset(error(err));\n\t\t\treturn;\n\t\t}\n\t\tif (!front) {\n\t\t\tconsole.debug(`fetch unknown: broadcast=${msg.broadcast}`);\n\t\t\tstream.writer.reset(new NotFound(`broadcast ${msg.broadcast}`));\n\t\t\treturn;\n\t\t}\n\n\t\t// The subscriber opened this stream, so its send order only ranked the request. Rank the\n\t\t// response here, on the same scale as the group streams it competes with.\n\t\tstream.writer.setPriority(sendOrder({ priority: msg.priority }));\n\n\t\tlet group: group.Consumer | undefined;\n\t\ttry {\n\t\t\t// The timescale is immutable, so serve exactly what TRACK_INFO advertised. Both\n\t\t\t// come off the same front, so the metadata and the frames are one generation.\n\t\t\tconst info = await this.#resolveTrackInfo(front, msg.track);\n\t\t\tgroup = await wireOf(front).fetchGroup(msg.track, msg.group, { priority: msg.priority });\n\t\t\tawait this.#runFetchGroup(group, stream.writer, {\n\t\t\t\ttimescale: Timescale(info.timescale),\n\t\t\t\tstart: msg.startFrame,\n\t\t\t\tend: msg.endFrame,\n\t\t\t});\n\t\t\tconsole.debug(`fetch done: broadcast=${msg.broadcast} track=${msg.track} group=${msg.group}`);\n\t\t\tstream.close();\n\t\t\tgroup.close();\n\t\t} catch (err: unknown) {\n\t\t\tconst e = error(err);\n\t\t\tconsole.warn(\n\t\t\t\t`fetch error: broadcast=${msg.broadcast} track=${msg.track} group=${msg.group} error=${reason(e)}`,\n\t\t\t);\n\t\t\tgroup?.close(e);\n\t\t\tstream.abort(e);\n\t\t}\n\t}\n\n\t/**\n\t * Runs a track and sends its data to the stream.\n\t * @param sub - The subscription ID\n\t * @param broadcast - The broadcast name\n\t * @param track - The track to run\n\t * @param stream - The stream to write to\n\t *\n\t * @internal\n\t */\n\tasync #runTrack(\n\t\ttrack: track.Subscriber,\n\t\tstream: Writer,\n\t\tcontrols: SubscriptionControls,\n\t\tserving: { sub: bigint; broadcast: Path.Valid; timescale: Timescale; bounds: FrameBounds },\n\t) {\n\t\tconst { sub, broadcast, timescale, bounds } = serving;\n\t\t// Lite-05+ resolves the range on the subscribe stream: SUBSCRIBE_START once the\n\t\t// first group is known, SUBSCRIBE_END when the track finishes.\n\t\tconst emitRange = supportsTrackStream(this.version);\n\t\tlet startSent = false;\n\t\tlet endSent = false;\n\n\t\t// Lite-07+ counts the group streams in SUBSCRIBE_END, so it goes out only once every\n\t\t// served group has opened its stream or given up, and a cap holding groups back\n\t\t// delays it until they are released.\n\t\tconst countStreams = hasStreamCount(this.version);\n\t\tlet streams = 0;\n\t\tconst opening = new Set<Promise<unknown>>();\n\n\t\t// The track's exclusive final boundary. A Rust subscriber feeds SUBSCRIBE_END\n\t\t// straight into finish_at, so it must name the track's boundary (which counts\n\t\t// datagram sequences too), not the delivered range: a subscription cap can hold\n\t\t// produced groups back. The latest() fallback covers a subscription torn down\n\t\t// before the producer declared it.\n\t\tconst boundary = () => track.final() ?? (track.latest() ?? -1) + 1;\n\n\t\t// Before lite-07, SUBSCRIBE_END names that boundary, which a cap can hold groups back\n\t\t// from, so it goes out as soon as the producer finishes and the subscription keeps\n\t\t// serving whatever a later cap raise releases (see the Rust publisher's Recv::Boundary).\n\t\tconst sendEnd = async (): Promise<boolean> => {\n\t\t\tendSent = true;\n\t\t\tif (!emitRange) return true;\n\t\t\treturn controls.response(\n\t\t\t\t(async () => {\n\t\t\t\t\t// A group that gives up before its stream opens is never counted.\n\t\t\t\t\tif (countStreams) while (opening.size > 0) await Promise.all(opening);\n\t\t\t\t\tconst end = new SubscribeEnd(boundary(), streams);\n\t\t\t\t\tawait encodeSubscribeResponse(stream, { end }, this.version);\n\t\t\t\t})(),\n\t\t\t);\n\t\t};\n\n\t\t// One ranking for the whole subscription, shared by every group it serves.\n\t\tconst priority = new Priority(track);\n\n\t\t// Every group this subscription started serving, until its stream finishes or resets.\n\t\tconst groups = new Set<Promise<void>>();\n\n\t\t// Cancels groups still queued for a stream slot. Only the subscriber leaving counts:\n\t\t// a track that ran out of groups still has to flush the ones already queued, and the\n\t\t// caller FINs the subscribe stream to say so.\n\t\tlet finished = false;\n\t\tlet unsubscribe!: () => void;\n\t\tconst unsubscribed = new Promise<void>((resolve) => {\n\t\t\tunsubscribe = resolve;\n\t\t});\n\t\ttry {\n\t\t\tfor (;;) {\n\t\t\t\t// Control before data, matching the Rust publisher: every control decoded while\n\t\t\t\t// the loop was parked applies to the next pop, never to one already made. This\n\t\t\t\t// drain is synchronous, so nothing the decoder holds can land between the pop\n\t\t\t\t// below and its frame range.\n\t\t\t\tconst control = controls.take();\n\t\t\t\tif (control) {\n\t\t\t\t\tswitch (control.kind) {\n\t\t\t\t\t\tcase \"done\":\n\t\t\t\t\t\t\t// The subscriber left. Its queued groups are pointless now, which\n\t\t\t\t\t\t\t// the finally below acts on since `finished` stays false.\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\tcase \"error\":\n\t\t\t\t\t\t\tthrow control.error;\n\t\t\t\t\t\tcase \"update\": {\n\t\t\t\t\t\t\tconst update = control.update;\n\t\t\t\t\t\t\tconsole.debug(`subscribe update: broadcast=${broadcast} track=${track.name}`);\n\t\t\t\t\t\t\thooks.replaceGroups(track, {\n\t\t\t\t\t\t\t\tstart: update.startGroup === undefined ? undefined : { included: update.startGroup },\n\t\t\t\t\t\t\t\tend: update.endGroup === undefined ? undefined : { included: update.endGroup },\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tbounds.startGroup = update.startGroup;\n\t\t\t\t\t\t\tbounds.startFrame = update.startFrame;\n\t\t\t\t\t\t\tbounds.endGroup = update.endGroup;\n\t\t\t\t\t\t\tbounds.endFrame = update.endFrame;\n\t\t\t\t\t\t\tawait yieldToControls();\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Exactly-once arrival-order serving. This synchronous package-internal pop\n\t\t\t\t// and frameRange call are the operation's linearization point.\n\t\t\t\tconst recv = hooks.tryRecvGroup(track);\n\t\t\t\tswitch (recv.kind) {\n\t\t\t\t\tcase \"error\":\n\t\t\t\t\t\tthrow recv.error;\n\t\t\t\t\tcase \"idle\":\n\t\t\t\t\t\t// Before lite-07, an end declared ahead of the live edge goes out as\n\t\t\t\t\t\t// soon as it is known, while the remaining groups are still being\n\t\t\t\t\t\t// produced. The lite-07 count is not final until those groups open.\n\t\t\t\t\t\tif (!endSent && !countStreams && track.final() !== undefined) {\n\t\t\t\t\t\t\tif (!(await sendEnd())) return;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tawait waitForSubscription(controls, track);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tcase \"boundary\":\n\t\t\t\t\t\t// The producer finished but is still holding groups above the cap.\n\t\t\t\t\t\t// Declare the boundary, then wait for an update to release them.\n\t\t\t\t\t\tif (!endSent && !countStreams) {\n\t\t\t\t\t\t\tif (!(await sendEnd())) return;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tawait waitForSubscription(controls, track);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tcase \"done\": {\n\t\t\t\t\t\tif (!endSent) {\n\t\t\t\t\t\t\tif (!(await sendEnd())) return;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// The FIN tells the subscriber every group is accounted for, so it waits\n\t\t\t\t\t\t// until each group stream finished or reset. The subscriber leaving\n\t\t\t\t\t\t// instead cancels whatever is still queued.\n\t\t\t\t\t\tconst drained = Symbol(\"drained\");\n\t\t\t\t\t\tconst end = await Promise.race([Promise.all(groups).then(() => drained), controls.ended]);\n\t\t\t\t\t\tif (end instanceof Error) throw end;\n\t\t\t\t\t\tif (end !== drained) return;\n\t\t\t\t\t\tfinished = true;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst group = recv.group;\n\t\t\t\tconst range = frameRange(bounds, group.sequence);\n\n\t\t\t\tif (emitRange && !startSent) {\n\t\t\t\t\tstartSent = true;\n\t\t\t\t\t// SUBSCRIBE_START promises nothing below this sequence will be delivered.\n\t\t\t\t\t// Arrival-order serving could later surface a straggler below the first\n\t\t\t\t\t// group, so pin the floor to what was announced.\n\t\t\t\t\thooks.replaceGroups(track, {\n\t\t\t\t\t\tstart: { included: group.sequence },\n\t\t\t\t\t\tend: bounds.endGroup === undefined ? undefined : { included: bounds.endGroup },\n\t\t\t\t\t});\n\t\t\t\t\tif (\n\t\t\t\t\t\t!(await controls.response(\n\t\t\t\t\t\t\tencodeSubscribeResponse(\n\t\t\t\t\t\t\t\tstream,\n\t\t\t\t\t\t\t\t{ start: new SubscribeStart(group.sequence) },\n\t\t\t\t\t\t\t\tthis.version,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t))\n\t\t\t\t\t)\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst options: RunGroup = {\n\t\t\t\t\tsub,\n\t\t\t\t\tgroup,\n\t\t\t\t\ttimescale,\n\t\t\t\t\tpriority,\n\t\t\t\t\tunsubscribed,\n\t\t\t\t\tstart: range.start,\n\t\t\t\t\tend: range.end,\n\t\t\t\t};\n\t\t\t\t// `opening` settles when the stream opens so the lite-07 count can be sent.\n\t\t\t\t// `groups` covers the serve too, so the FIN still waits for every stream to\n\t\t\t\t// finish or reset, including one that has not opened yet.\n\t\t\t\tconst opened = this.#openGroup(options);\n\t\t\t\tconst task = opened.then(async (writer) => {\n\t\t\t\t\tif (!writer) return;\n\t\t\t\t\tstreams += 1;\n\t\t\t\t\tawait this.#serveGroup(writer, options);\n\t\t\t\t});\n\t\t\t\tgroups.add(task);\n\t\t\t\tvoid task.finally(() => groups.delete(task));\n\t\t\t\topening.add(opened);\n\t\t\t\tvoid opened.finally(() => opening.delete(opened));\n\t\t\t}\n\t\t} finally {\n\t\t\tif (!finished) unsubscribe();\n\t\t\tpriority.close();\n\t\t}\n\t}\n\n\t/**\n\t * Answers a TRACK stream (0x6) with a single TRACK_INFO, then FINs.\n\t *\n\t * @internal\n\t */\n\tasync runTrackInfo(msg: TrackMessage, stream: Stream) {\n\t\ttry {\n\t\t\tconst front =\n\t\t\t\tthis.#publish &&\n\t\t\t\t(wireOf(this.#publish).local(msg.broadcast) ?? (await wireOf(this.#publish).demand(msg.broadcast)));\n\t\t\tif (!front) throw new NotFound(`broadcast ${msg.broadcast}`);\n\n\t\t\tconst info = await this.#resolveTrackInfo(front, msg.track);\n\t\t\tawait info.encode(stream.writer, this.version);\n\t\t\tconsole.debug(`track info: broadcast=${msg.broadcast} track=${msg.track}`);\n\t\t\tstream.close();\n\t\t} catch (err) {\n\t\t\tconsole.debug(`track unknown: broadcast=${msg.broadcast} track=${msg.track}`);\n\t\t\tstream.writer.reset(error(err));\n\t\t}\n\t}\n\n\t// Resolve (and cache) a track's immutable TRACK_INFO by asking the application.\n\t// `resolveTrackInfo` triggers a TrackRequest the app answers with accept(TrackInfo);\n\t// only the immutable properties are needed (not the groups). Cached because they're\n\t// fixed for the track's lifetime. Rejects if the track is unavailable.\n\t#resolveTrackInfo(front: broadcast.Consumer, track: string): Promise<TrackInfoMessage> {\n\t\tlet tracks = this.#trackInfo.get(front);\n\t\tif (!tracks) {\n\t\t\ttracks = new Map();\n\t\t\tthis.#trackInfo.set(front, tracks);\n\t\t}\n\n\t\tconst cached = tracks.get(track);\n\t\tif (cached !== undefined) return cached;\n\n\t\tconst pending = (async () => {\n\t\t\tconst info = await wireOf(front).resolveTrackInfo(track);\n\t\t\treturn new TrackInfoMessage({\n\t\t\t\tpriority: info.priority,\n\t\t\t\t// Publisher Max Age: the publisher's retention bound, advertised so\n\t\t\t\t// relays re-serve with the same window.\n\t\t\t\tmaxAge: info.maxAge,\n\t\t\t\t// Lite05 mandates per-frame timestamps. Advertise the track's timescale;\n\t\t\t\t// `#serveGroup` emits each frame converted to it.\n\t\t\t\ttimescale: info.timescale,\n\t\t\t});\n\t\t})();\n\n\t\t// Don't poison the cache on failure: a later request may succeed.\n\t\tpending.catch(() => tracks.delete(track));\n\t\ttracks.set(track, pending);\n\t\treturn pending;\n\t}\n\n\t/**\n\t * Forwards a track's datagrams best-effort over QUIC datagrams (lite-05 §6.4), parallel to\n\t * its groups. Each datagram is dropped (there is no group fallback) if the encoded body\n\t * doesn't fit the transport's datagram limit or the send fails. Returns once the track\n\t * finishes; a failure never tears down the subscription.\n\t *\n\t * @internal\n\t */\n\tasync #runDatagrams(sub: bigint, track: track.Subscriber, timescale: Timescale) {\n\t\tconst writer = this.#datagramWriter;\n\t\tif (!writer) return; // Only reached with a writer (see the #datagramWriter gate).\n\t\tconst maxSize = DatagramStream.maxDatagramSize(this.#quic);\n\n\t\ttry {\n\t\t\tfor (;;) {\n\t\t\t\tconst datagram = await track.recvDatagram();\n\t\t\t\tif (!datagram) return; // Track finished; #runTrack tears the subscription down.\n\n\t\t\t\t// Convert the timestamp to the track's advertised timescale, matching #serveGroup.\n\t\t\t\tconst ts = Math.round(datagram.timestamp.as(timescale));\n\t\t\t\tconst body = new DatagramMessage(sub, datagram.sequence, ts, datagram.payload).encode(this.version);\n\n\t\t\t\t// No group fallback: drop anything that doesn't fit a single datagram.\n\t\t\t\tif (body.byteLength > maxSize) {\n\t\t\t\t\tconsole.debug(`dropping oversize datagram: sub=${sub} size=${body.byteLength} max=${maxSize}`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tawait writer.ready;\n\t\t\t\tawait writer.write(body);\n\t\t\t}\n\t\t} catch (err: unknown) {\n\t\t\t// Best-effort: a datagram send failure stops sending but never fails the subscription.\n\t\t\tconsole.debug(`datagram send stopped: sub=${sub} error=${reason(err)}`);\n\t\t}\n\t}\n\n\t// Serialize a fetched group's frames onto the FETCH stream as bare records: each a\n\t// zigzag-delta timestamp (at the track's advertised timescale) followed by size + bytes.\n\tasync #runFetchGroup(\n\t\tgroup: group.Consumer,\n\t\tstream: Writer,\n\t\t{ timescale, start: startFrame, end: endFrame }: ServeFetch,\n\t) {\n\t\t// The response carries no header, so the receiver numbers the first frame it gets\n\t\t// as `startFrame`. Skipping the head here is the only thing keeping those numbers\n\t\t// honest; a group that ends before we reach it can't be served at all.\n\t\tfor (let i = 0; i < startFrame; i++) {\n\t\t\tif (!(await race([group.readFrame(), stream.closed]))) {\n\t\t\t\tthrow new Error(`fetch group ended at frame ${i}, before the requested start ${startFrame}`);\n\t\t\t}\n\t\t}\n\n\t\tlet prevTs = 0n;\n\t\tfor (let index = startFrame; endFrame === undefined || index <= endFrame; index++) {\n\t\t\tconst frame = await race([group.readFrame(), stream.closed]);\n\t\t\tif (!frame) break;\n\n\t\t\tconst ts = BigInt(Math.round(frame.timestamp.as(timescale)));\n\t\t\tawait stream.u62(zigzag(ts - prevTs));\n\t\t\tprevTs = ts;\n\n\t\t\tawait stream.u53(frame.payload.byteLength);\n\t\t\tawait stream.write(frame.payload);\n\t\t}\n\t}\n\n\t/**\n\t * Opens the unidirectional stream for one group, or closes the group and resolves\n\t * `undefined` when it cannot get one.\n\t *\n\t * @internal\n\t */\n\tasync #openGroup(options: RunGroup): Promise<Writer | undefined> {\n\t\tconst { group, priority, unsubscribed } = options;\n\t\ttry {\n\t\t\t// The transport drains streams by send order, so this is what makes a high-priority\n\t\t\t// track (and a newer group within it) win the link when there isn't room for both.\n\t\t\t//\n\t\t\t// One stream per group is faster than a peer at its limit can retire them, so this\n\t\t\t// is the one path that doesn't wait for a slot: the transport would serve the opens\n\t\t\t// in the order we asked, which is oldest-first, exactly backwards for live media.\n\t\t\t// Failing here drops the group and lets the next one compete for the next slot.\n\t\t\tconst stream = await Writer.tryOpen(this.#quic, {\n\t\t\t\tversion: this.version,\n\t\t\t\tsendOrder: priority.rank(group.sequence),\n\t\t\t\tcancel: unsubscribed,\n\t\t\t\twaitUntilAvailable: false,\n\t\t\t});\n\t\t\tif (!stream) group.close(new Error(\"no stream slot\"));\n\t\t\treturn stream;\n\t\t} catch (err: unknown) {\n\t\t\tgroup.close(error(err));\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Serves one group on the stream {@link #openGroup} opened for it.\n\t *\n\t * @internal\n\t */\n\tasync #serveGroup(stream: Writer, options: RunGroup) {\n\t\tconst { sub, group, timescale, priority, start: startFrame, end: endFrame } = options;\n\t\t// This model holds whole groups, so frame `startFrame` is always reachable unless\n\t\t// the group ends first. Declaring it up front keeps the stream self-describing.\n\t\tconst msg = new GroupMessage({ subscribe: sub, sequence: group.sequence, frameStart: startFrame });\n\t\t// Everything past this point runs inside the cleanup scope, so a failure never leaves\n\t\t// a finished group's stream being ranked.\n\t\ttry {\n\t\t\t// A SUBSCRIBE_UPDATE re-ranks the subscription, so a group already on the wire\n\t\t\t// follows it too rather than keeping a stale rank until it finishes.\n\t\t\tpriority.add(stream, group.sequence);\n\n\t\t\tawait hooks.guardGroup(group, async () => {\n\t\t\t\tawait stream.u53(0); // stream type\n\t\t\t\tawait msg.encode(stream, this.version);\n\t\t\t});\n\n\t\t\t// Lite05+ prefixes every frame with a zigzag-delta timestamp at the track's\n\t\t\t// advertised timescale; older drafts omit it.\n\t\t\tconst timestamps = supportsTrackStream(this.version);\n\t\t\tlet prevTs = 0n;\n\t\t\t// Whether the cursor ever reached the requested start, which decides how the\n\t\t\t// end of the group is read below.\n\t\t\tlet reached = startFrame === 0;\n\n\t\t\tfor (;;) {\n\t\t\t\tconst read = await race([hooks.readGroupFrame(group), stream.closed]);\n\t\t\t\tif (!read) {\n\t\t\t\t\t// The group ended before the frame the subscriber asked to start\n\t\t\t\t\t// at, so this publisher can't serve the range at all. FINning here\n\t\t\t\t\t// would claim an empty group under that index; reset so it reads\n\t\t\t\t\t// as the gap it is.\n\t\t\t\t\tif (!reached) throw new Error(`group ended before frame ${startFrame}`);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\t// A group that ends exactly at the start is a valid, empty range.\n\t\t\t\t\tif (read.sequence + 1 >= startFrame) reached = true;\n\t\t\t\t\t// Frames below the requested start were excluded, and the receiver\n\t\t\t\t\t// numbers what it gets from `startFrame`.\n\t\t\t\t\tif (read.sequence < startFrame) continue;\n\t\t\t\t\tif (endFrame !== undefined && read.sequence > endFrame) break;\n\n\t\t\t\t\tif (timestamps) {\n\t\t\t\t\t\t// Convert each frame to the track's advertised timescale.\n\t\t\t\t\t\tconst ts = BigInt(Math.round(read.frame.timestamp.as(timescale)));\n\t\t\t\t\t\tawait hooks.guardGroup(group, () => stream.u62(zigzag(ts - prevTs)));\n\t\t\t\t\t\tprevTs = ts;\n\t\t\t\t\t}\n\n\t\t\t\t\tawait hooks.guardGroup(group, () => stream.u53(read.frame.payload.byteLength));\n\t\t\t\t\tawait hooks.guardGroup(group, () => stream.write(read.frame.payload));\n\t\t\t\t} finally {\n\t\t\t\t\tread.complete();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tstream.close();\n\t\t\tgroup.close();\n\t\t} catch (err: unknown) {\n\t\t\tconst e = error(err);\n\t\t\tstream.reset(e);\n\t\t\tgroup.close(e);\n\t\t} finally {\n\t\t\tpriority.remove(stream);\n\t\t}\n\t}\n\n\t/**\n\t * Handles a probe stream by periodically reporting estimated bitrate.\n\t * @param stream - The probe bidi stream\n\t *\n\t * @internal\n\t */\n\tasync runProbe(stream: Stream) {\n\t\t// getStats is not yet in the TypeScript WebTransport type definitions.\n\t\tconst quic = this.#quic as unknown as {\n\t\t\tgetStats?: () => Promise<{ estimatedSendRate: number | null; smoothedRtt?: number | null }>;\n\t\t};\n\t\tif (!quic.getStats) {\n\t\t\t// Best-effort: we can't supply bandwidth estimates, so close the\n\t\t\t// whole bidi (FIN + STOP_SENDING) to let the peer release its end.\n\t\t\tstream.close();\n\t\t\treturn;\n\t\t}\n\n\t\tlet lastSent: Probe | undefined;\n\t\tlet lastSentTime: number | undefined;\n\n\t\t// Whether a metric moved enough to be worth another report. Gaining or\n\t\t// losing a value always counts; both unknown never does.\n\t\tconst moved = (prev?: number, next?: number, threshold = 0): boolean => {\n\t\t\tif (prev === undefined && next === undefined) return false;\n\t\t\tif (prev === undefined || next === undefined) return true;\n\t\t\tif (prev === 0) return next !== 0;\n\t\t\treturn Math.abs(next - prev) / prev >= threshold;\n\t\t};\n\n\t\ttry {\n\t\t\tfor (;;) {\n\t\t\t\tconst timeout = new Promise<\"timeout\">((resolve) =>\n\t\t\t\t\tsetTimeout(() => resolve(\"timeout\"), PROBE_INTERVAL),\n\t\t\t\t);\n\t\t\t\tconst result = await race([timeout, stream.reader.closed]);\n\t\t\t\tif (result !== \"timeout\") break;\n\n\t\t\t\t// The two fields are independent on the wire, each using 0 for\n\t\t\t\t// unknown, so a transport exposing only one still has something to\n\t\t\t\t// report. Anything this version can't carry is dropped here rather\n\t\t\t\t// than by the encoder, so it reads as unknown to every check below.\n\t\t\t\tconst stats = await quic.getStats();\n\t\t\t\t// `smoothedRtt` is a DOMHighResTimeStamp, i.e. a double, but the wire\n\t\t\t\t// carries whole milliseconds and the varint encoder throws on a\n\t\t\t\t// fractional value. Round before it ever reaches `Probe`.\n\t\t\t\tconst rtt = stats.smoothedRtt != null ? Math.round(stats.smoothedRtt) : undefined;\n\t\t\t\tconst report = new Probe({\n\t\t\t\t\tbitrate: stats.estimatedSendRate ?? undefined,\n\t\t\t\t\trtt: hasProbeRtt(this.version) ? rtt : undefined,\n\t\t\t\t});\n\n\t\t\t\t// Nothing left to report. Say so once if it retracts a value the peer\n\t\t\t\t// is still holding, then stay quiet rather than repeating \"unknown\"\n\t\t\t\t// every time the max age comes around.\n\t\t\t\tif (report.bitrate === undefined && report.rtt === undefined) {\n\t\t\t\t\tconst retracts =\n\t\t\t\t\t\tlastSent !== undefined && (lastSent.bitrate !== undefined || lastSent.rtt !== undefined);\n\t\t\t\t\tif (!retracts) continue;\n\t\t\t\t}\n\n\t\t\t\tlet shouldSend: boolean;\n\t\t\t\tif (lastSent === undefined || lastSentTime === undefined) {\n\t\t\t\t\tshouldSend = true;\n\t\t\t\t} else {\n\t\t\t\t\tconst elapsed = performance.now() - lastSentTime;\n\t\t\t\t\t// The bitrate threshold decays to zero as the last report ages: a\n\t\t\t\t\t// stale estimate is worth refreshing for a smaller move.\n\t\t\t\t\tconst t = Math.max(PROBE_INTERVAL, Math.min(PROBE_MAX_AGE, elapsed));\n\t\t\t\t\tconst range = PROBE_MAX_AGE - PROBE_INTERVAL;\n\t\t\t\t\tconst threshold = (PROBE_MAX_DELTA * (PROBE_MAX_AGE - t)) / range;\n\t\t\t\t\tshouldSend =\n\t\t\t\t\t\telapsed >= PROBE_MAX_AGE ||\n\t\t\t\t\t\tmoved(lastSent.bitrate, report.bitrate, threshold) ||\n\t\t\t\t\t\tmoved(lastSent.rtt, report.rtt, PROBE_RTT_DELTA);\n\t\t\t\t}\n\n\t\t\t\tif (shouldSend) {\n\t\t\t\t\tawait report.encode(stream.writer, this.version);\n\t\t\t\t\tlastSent = report;\n\t\t\t\t\tlastSentTime = performance.now();\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (err: unknown) {\n\t\t\tconsole.warn(\"probe stream error\", err);\n\t\t\tstream.close();\n\t\t}\n\t}\n\n\tclose() {\n\t\t// The broadcasts belong to the origin, which outlives this session; closing here\n\t\t// only drops the borrow. The peer sees the unannounce when the streams die.\n\n\t\t// Release the datagram writer's lock so the stream can be torn down.\n\t\tthis.#datagramWriter?.releaseLock();\n\t\tthis.#datagramWriter = undefined;\n\t}\n}\n"]}
package/lite/setup.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
- * The lite-05 SETUP message: each endpoint advertises its capabilities once, as the
2
+ * The lite-05+ SETUP message: each endpoint advertises its capabilities once, as the
3
3
  * sole message on a unidirectional Setup Stream ({@link DataType.Setup}), then closes it.
4
4
  *
5
5
  * @module
6
6
  */
7
- import { type Origin } from "../origin";
8
- import type { Reader, Writer } from "../stream";
7
+ import { type Hop } from "../hop";
8
+ import { Reader, type Writer } from "../stream";
9
9
  import { type Version } from "./version";
10
10
  /**
11
11
  * The probe capability an endpoint advertises in SETUP.
@@ -51,8 +51,8 @@ export interface SetupProps {
51
51
  path?: string;
52
52
  /** See {@link Setup.role}. Defaults to {@link Role.Both}. */
53
53
  role?: Role;
54
- /** See {@link Setup.origin}. Omitted by default. */
55
- origin?: Origin;
54
+ /** See {@link Setup.hop}. Omitted by default. */
55
+ hop?: Hop;
56
56
  }
57
57
  /**
58
58
  * The SETUP message, sent once per endpoint on the unidirectional Setup Stream.
@@ -80,13 +80,13 @@ export declare class Setup {
80
80
  */
81
81
  role: Role;
82
82
  /**
83
- * This endpoint's origin (hop) id. The peer uses it to filter announcements and
83
+ * This endpoint's Hop ID. The peer uses it to filter announcements and
84
84
  * subscriptions whose route flows through this endpoint (lite-06 removed the
85
85
  * per-stream `exclude_hop` in its favor). `undefined` when the endpoint declares
86
86
  * no identity; a wire value of 0 decodes the same way.
87
87
  */
88
- origin?: Origin;
89
- constructor({ probe, path, role, origin }?: SetupProps);
88
+ hop?: Hop;
89
+ constructor({ probe, path, role, hop }?: SetupProps);
90
90
  /** Encode the SETUP message with its size prefix. Throws on pre-lite-05 versions. */
91
91
  encode(w: Writer, version: Version): Promise<void>;
92
92
  /** Decode a SETUP message with its size prefix. Throws on pre-lite-05 versions. */
@@ -1 +1 @@
1
- {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/lite/setup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,cAAc,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAInD,OAAO,EAAkB,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAc5D;;;;;;GAMG;AACH,eAAO,MAAM,UAAU;IACtB,wDAAwD;aACxD,IAAI,EAAE,CAAC;IACP,+EAA+E;aAC/E,MAAM,EAAE,CAAC;IACT,kFAAkF;aAClF,QAAQ,EAAE,CAAC;CACF,CAAC;AAEX,wDAAwD;AACxD,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC;AActE;;;;;;;;GAQG;AACH,eAAO,MAAM,IAAI;IAChB,0FAA0F;aAC1F,IAAI,EAAE,CAAC;IACP,wEAAwE;aACxE,SAAS,EAAE,CAAC;IACZ,6EAA6E;aAC7E,UAAU,EAAE,CAAC;CACJ,CAAC;AAEX,wCAAwC;AACxC,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,OAAO,IAAI,CAAC,CAAC;AAwFpD,6HAA6H;AAC7H,MAAM,WAAW,UAAU;IAC1B,oEAAoE;IACpE,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,qBAAa,KAAK;;IACjB,wFAAwF;IACxF,KAAK,EAAE,UAAU,CAAC;IAElB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;;OAIG;IACH,IAAI,EAAE,IAAI,CAAC;IAEX;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAE,UAAe,EAKzD;IAgDD,qFAAqF;IAC/E,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAGvD;IAED,mFAAmF;IACnF,OAAa,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAG/D;CACD"}
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/lite/setup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,GAAG,EAAa,MAAM,WAAW,CAAC;AAChD,OAAO,EAAgB,MAAM,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAGjE,OAAO,EAAkB,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAiB5D;;;;;;GAMG;AACH,eAAO,MAAM,UAAU;IACtB,wDAAwD;aACxD,IAAI,EAAE,CAAC;IACP,+EAA+E;aAC/E,MAAM,EAAE,CAAC;IACT,kFAAkF;aAClF,QAAQ,EAAE,CAAC;CACF,CAAC;AAEX,wDAAwD;AACxD,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC;AActE;;;;;;;;GAQG;AACH,eAAO,MAAM,IAAI;IAChB,0FAA0F;aAC1F,IAAI,EAAE,CAAC;IACP,wEAAwE;aACxE,SAAS,EAAE,CAAC;IACZ,6EAA6E;aAC7E,UAAU,EAAE,CAAC;CACJ,CAAC;AAEX,wCAAwC;AACxC,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,OAAO,IAAI,CAAC,CAAC;AAyFpD,6HAA6H;AAC7H,MAAM,WAAW,UAAU;IAC1B,oEAAoE;IACpE,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,iDAAiD;IACjD,GAAG,CAAC,EAAE,GAAG,CAAC;CACV;AAED;;;;;;GAMG;AACH,qBAAa,KAAK;;IACjB,wFAAwF;IACxF,KAAK,EAAE,UAAU,CAAC;IAElB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;;OAIG;IACH,IAAI,EAAE,IAAI,CAAC;IAEX;;;;;OAKG;IACH,GAAG,CAAC,EAAE,GAAG,CAAC;IAEV,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAE,UAAe,EAKtD;IAgDD,qFAAqF;IAC/E,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAGvD;IAED,mFAAmF;IACnF,OAAa,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAG/D;CACD"}
package/lite/setup.js CHANGED
@@ -1,13 +1,13 @@
1
1
  /* @ts-self-types="./setup.d.ts" */
2
2
  /**
3
- * The lite-05 SETUP message: each endpoint advertises its capabilities once, as the
3
+ * The lite-05+ SETUP message: each endpoint advertises its capabilities once, as the
4
4
  * sole message on a unidirectional Setup Stream ({@link DataType.Setup}), then closes it.
5
5
  *
6
6
  * @module
7
7
  */
8
- import { OriginSchema } from "../origin.js";
8
+ import { HopSchema } from "../hop.js";
9
+ import { encodeVarint, Reader } from "../stream.js";
9
10
  import { decodeUtf8 } from "../util/utf8.js";
10
- import * as Varint from "../varint.js";
11
11
  import * as Message from "./message.js";
12
12
  import { hasSetupStream } from "./version.js";
13
13
  /** Setup Parameter id for the Probe capability level. */
@@ -16,10 +16,12 @@ const PARAM_PROBE = 0x1n;
16
16
  const PARAM_PATH = 0x2n;
17
17
  /** Setup Parameter id for the client's intended {@link Role} (client-only). */
18
18
  const PARAM_ROLE = 0x3n;
19
- /** Setup Parameter id for the endpoint's origin (hop) id. */
20
- const PARAM_ORIGIN = 0x5n;
19
+ /** Setup Parameter id for the endpoint's Hop ID. */
20
+ const PARAM_HOP = 0x5n;
21
21
  /** Cap on the number of parameters in a bag, matching the Rust decoder. */
22
22
  const MAX_PARAMS = 64;
23
+ /** SETUP only carries negotiation parameters, so it gets a far smaller cap than other messages. */
24
+ const MAX_SETUP_SIZE = 64 * 1024;
23
25
  /**
24
26
  * The probe capability an endpoint advertises in SETUP.
25
27
  *
@@ -94,20 +96,21 @@ class Parameters {
94
96
  getBytes(id) {
95
97
  return this.#entries.get(id);
96
98
  }
97
- /** Set a parameter to a varint value, replacing any existing entry. */
98
- setVarint(id, value) {
99
- this.#entries.set(id, Varint.encode(Number(value)));
99
+ /** Set a parameter to a varint value in `version`'s encoding, replacing any existing entry. */
100
+ setVarint(id, value, version) {
101
+ this.#entries.set(id, encodeVarint(value, version));
100
102
  }
101
- /** Decode a parameter as a single varint, if present. Throws if trailing bytes remain. */
102
- getVarint(id) {
103
+ /** Decode a parameter as a single varint in `version`'s encoding, if present. Throws if trailing bytes remain. */
104
+ async getVarint(id, version) {
103
105
  const bytes = this.#entries.get(id);
104
106
  if (bytes === undefined)
105
107
  return undefined;
106
- const [value, remain] = Varint.decode(bytes);
107
- if (remain.byteLength !== 0) {
108
+ const r = new Reader(undefined, bytes, version);
109
+ const value = await r.u62();
110
+ if (!(await r.done())) {
108
111
  throw new Error("trailing bytes after varint parameter");
109
112
  }
110
- return BigInt(value);
113
+ return value;
111
114
  }
112
115
  async encode(w) {
113
116
  if (this.#entries.size > MAX_PARAMS) {
@@ -163,65 +166,65 @@ export class Setup {
163
166
  */
164
167
  role;
165
168
  /**
166
- * This endpoint's origin (hop) id. The peer uses it to filter announcements and
169
+ * This endpoint's Hop ID. The peer uses it to filter announcements and
167
170
  * subscriptions whose route flows through this endpoint (lite-06 removed the
168
171
  * per-stream `exclude_hop` in its favor). `undefined` when the endpoint declares
169
172
  * no identity; a wire value of 0 decodes the same way.
170
173
  */
171
- origin;
172
- constructor({ probe, path, role, origin } = {}) {
174
+ hop;
175
+ constructor({ probe, path, role, hop } = {}) {
173
176
  this.probe = probe ?? ProbeLevel.None;
174
177
  this.path = path;
175
178
  this.role = role ?? Role.Both;
176
- this.origin = origin;
179
+ this.hop = hop;
177
180
  }
178
181
  static #guard(version) {
179
182
  if (!hasSetupStream(version)) {
180
183
  throw new Error("setup stream not supported for this version");
181
184
  }
182
185
  }
183
- async #encode(w) {
186
+ async #encode(w, version) {
184
187
  const params = new Parameters();
185
188
  // None is the wire default, so omit it to keep the message empty when nothing is set.
186
189
  if (this.probe !== ProbeLevel.None) {
187
- params.setVarint(PARAM_PROBE, this.probe);
190
+ params.setVarint(PARAM_PROBE, this.probe, version);
188
191
  }
189
192
  if (this.path !== undefined) {
190
193
  params.setBytes(PARAM_PATH, new TextEncoder().encode(this.path));
191
194
  }
192
195
  // Both is the wire default, sent as the absence of the parameter.
193
196
  if (this.role !== Role.Both) {
194
- params.setVarint(PARAM_ROLE, this.role);
197
+ params.setVarint(PARAM_ROLE, this.role, version);
195
198
  }
196
- if (this.origin !== undefined && this.origin !== 0n) {
197
- params.setVarint(PARAM_ORIGIN, this.origin);
199
+ if (this.hop !== undefined && this.hop !== 0n) {
200
+ params.setVarint(PARAM_HOP, this.hop, version);
198
201
  }
199
202
  await params.encode(w);
200
203
  }
201
- static async #decode(r) {
204
+ static async #decode(r, version) {
202
205
  const params = await Parameters.decode(r);
203
- const probeCode = params.getVarint(PARAM_PROBE);
206
+ const probeCode = await params.getVarint(PARAM_PROBE, version);
204
207
  const probe = probeCode === undefined ? ProbeLevel.None : probeFromCode(probeCode);
205
208
  // An empty path is valid and means the same as omitting the parameter, so a
206
209
  // client that wants the root doesn't have to special-case it.
207
210
  const pathBytes = params.getBytes(PARAM_PATH);
208
211
  const path = pathBytes === undefined ? undefined : decodeUtf8(pathBytes);
209
- const roleCode = params.getVarint(PARAM_ROLE);
212
+ const roleCode = await params.getVarint(PARAM_ROLE, version);
210
213
  const role = roleCode === undefined ? Role.Both : roleFromCode(roleCode);
211
214
  // 0 carries no identity (it cannot be excluded), so it decodes as absent.
212
- const originRaw = params.getVarint(PARAM_ORIGIN);
213
- const origin = originRaw === undefined || originRaw === 0n ? undefined : OriginSchema.parse(originRaw);
214
- return new Setup({ probe, path, role, origin });
215
+ const hopRaw = await params.getVarint(PARAM_HOP, version);
216
+ const hop = hopRaw === undefined || hopRaw === 0n ? undefined : HopSchema.parse(hopRaw);
217
+ return new Setup({ probe, path, role, hop });
215
218
  }
216
219
  /** Encode the SETUP message with its size prefix. Throws on pre-lite-05 versions. */
217
220
  async encode(w, version) {
218
221
  Setup.#guard(version);
219
- return Message.encode(w, this.#encode.bind(this));
222
+ return Message.encode(w, (w) => this.#encode(w, version), MAX_SETUP_SIZE);
220
223
  }
221
224
  /** Decode a SETUP message with its size prefix. Throws on pre-lite-05 versions. */
222
225
  static async decode(r, version) {
223
226
  Setup.#guard(version);
224
- return Message.decode(r, Setup.#decode);
227
+ return Message.decode(r, (r) => Setup.#decode(r, version), MAX_SETUP_SIZE);
225
228
  }
226
229
  }
227
230
  //# sourceMappingURL=setup.js.map
package/lite/setup.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/lite/setup.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The lite-05 SETUP message: each endpoint advertises its capabilities once, as the\n * sole message on a unidirectional Setup Stream ({@link DataType.Setup}), then closes it.\n *\n * @module\n */\n\nimport { type Origin, OriginSchema } from \"../origin.ts\";\nimport type { Reader, Writer } from \"../stream.ts\";\nimport { decodeUtf8 } from \"../util/utf8.ts\";\nimport * as Varint from \"../varint.ts\";\nimport * as Message from \"./message.ts\";\nimport { hasSetupStream, type Version } from \"./version.ts\";\n\n/** Setup Parameter id for the Probe capability level. */\nconst PARAM_PROBE = 0x1n;\n/** Setup Parameter id for the request Path (client-only, URI-less transports). */\nconst PARAM_PATH = 0x2n;\n/** Setup Parameter id for the client's intended {@link Role} (client-only). */\nconst PARAM_ROLE = 0x3n;\n/** Setup Parameter id for the endpoint's origin (hop) id. */\nconst PARAM_ORIGIN = 0x5n;\n\n/** Cap on the number of parameters in a bag, matching the Rust decoder. */\nconst MAX_PARAMS = 64;\n\n/**\n * The probe capability an endpoint advertises in SETUP.\n *\n * Monotonic: a higher level implies every lower one. An unknown (future) value\n * decodes as the highest level we understand, so a peer that gains a new level is\n * treated as at least {@link ProbeLevel.Increase}.\n */\nexport const ProbeLevel = {\n\t/** No probing. Equivalent to omitting the parameter. */\n\tNone: 0,\n\t/** The publisher can measure and periodically report its estimated bitrate. */\n\tReport: 1,\n\t/** The publisher can additionally pad the connection (or send redundant data). */\n\tIncrease: 2,\n} as const;\n\n/** A probe capability level. See {@link ProbeLevel}. */\nexport type ProbeLevel = (typeof ProbeLevel)[keyof typeof ProbeLevel];\n\n/** Map a wire value to a level, saturating unknown values to {@link ProbeLevel.Increase}. */\nfunction probeFromCode(code: bigint): ProbeLevel {\n\tswitch (code) {\n\t\tcase 0n:\n\t\t\treturn ProbeLevel.None;\n\t\tcase 1n:\n\t\t\treturn ProbeLevel.Report;\n\t\tdefault:\n\t\t\treturn ProbeLevel.Increase;\n\t}\n}\n\n/**\n * The direction a client intends to use the session for.\n *\n * A client advertises this in its SETUP so the server can reject a token that lacks the\n * matching scope during the handshake, instead of accepting a session that then silently\n * carries no media (a subscribe-only token used to publish, or vice versa). It only ever\n * narrows what the server grants, so it is not a security boundary: the server still\n * enforces the token's scope regardless.\n */\nexport const Role = {\n\t/** The client may do either, or declined to say. Equivalent to omitting the parameter. */\n\tBoth: 0,\n\t/** The client will publish tracks (ingest); the server must consume. */\n\tPublisher: 1,\n\t/** The client will subscribe to tracks (egress); the server must publish. */\n\tSubscriber: 2,\n} as const;\n\n/** A session role. See {@link Role}. */\nexport type Role = (typeof Role)[keyof typeof Role];\n\n/**\n * Map a wire value to a role, falling back to {@link Role.Both}.\n *\n * The draft requires a receiver that does not recognize the value to treat it as `Both`,\n * so a newer client can't break an older server: it just loses the early reject and defers\n * to the token's scope.\n */\nfunction roleFromCode(code: bigint): Role {\n\tswitch (code) {\n\t\tcase 1n:\n\t\t\treturn Role.Publisher;\n\t\tcase 2n:\n\t\t\treturn Role.Subscriber;\n\t\tdefault:\n\t\t\treturn Role.Both;\n\t}\n}\n\n/**\n * A bag of `id -> raw bytes` parameters, the body shared by SETUP. Encoded as a varint\n * count followed by `id, length, value` triples; duplicate ids are rejected on decode.\n */\nclass Parameters {\n\t#entries = new Map<bigint, Uint8Array>();\n\n\t/** Set a parameter to a raw byte value, replacing any existing entry. */\n\tsetBytes(id: bigint, value: Uint8Array) {\n\t\tthis.#entries.set(id, value);\n\t}\n\n\t/** Return a parameter's raw byte value, if present. */\n\tgetBytes(id: bigint): Uint8Array | undefined {\n\t\treturn this.#entries.get(id);\n\t}\n\n\t/** Set a parameter to a varint value, replacing any existing entry. */\n\tsetVarint(id: bigint, value: number | bigint) {\n\t\tthis.#entries.set(id, Varint.encode(Number(value)));\n\t}\n\n\t/** Decode a parameter as a single varint, if present. Throws if trailing bytes remain. */\n\tgetVarint(id: bigint): bigint | undefined {\n\t\tconst bytes = this.#entries.get(id);\n\t\tif (bytes === undefined) return undefined;\n\t\tconst [value, remain] = Varint.decode(bytes);\n\t\tif (remain.byteLength !== 0) {\n\t\t\tthrow new Error(\"trailing bytes after varint parameter\");\n\t\t}\n\t\treturn BigInt(value);\n\t}\n\n\tasync encode(w: Writer) {\n\t\tif (this.#entries.size > MAX_PARAMS) {\n\t\t\tthrow new Error(\"too many parameters\");\n\t\t}\n\n\t\tawait w.u53(this.#entries.size);\n\t\tfor (const [id, value] of this.#entries) {\n\t\t\tawait w.u62(id);\n\t\t\tawait w.u53(value.byteLength);\n\t\t\tawait w.write(value);\n\t\t}\n\t}\n\n\tstatic async decode(r: Reader): Promise<Parameters> {\n\t\tconst params = new Parameters();\n\n\t\tconst count = await r.u53();\n\t\tif (count > MAX_PARAMS) {\n\t\t\tthrow new Error(\"too many parameters\");\n\t\t}\n\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tconst id = await r.u62();\n\t\t\tif (params.#entries.has(id)) {\n\t\t\t\tthrow new Error(`duplicate parameter id: ${id.toString()}`);\n\t\t\t}\n\t\t\tconst size = await r.u53();\n\t\t\tconst value = await r.read(size);\n\t\t\tparams.#entries.set(id, value);\n\t\t}\n\n\t\treturn params;\n\t}\n}\n\n/** The capabilities a {@link Setup} advertises. Each defaults to the wire default, which is the absence of the parameter. */\nexport interface SetupProps {\n\t/** See {@link Setup.probe}. Defaults to {@link ProbeLevel.None}. */\n\tprobe?: ProbeLevel;\n\t/** See {@link Setup.path}. Omitted by default. */\n\tpath?: string;\n\t/** See {@link Setup.role}. Defaults to {@link Role.Both}. */\n\trole?: Role;\n\t/** See {@link Setup.origin}. Omitted by default. */\n\torigin?: Origin;\n}\n\n/**\n * The SETUP message, sent once per endpoint on the unidirectional Setup Stream.\n *\n * lite-05+ only. The two endpoints' SETUP messages are independent: neither side\n * blocks on the peer's before opening other streams, but a stream whose encoding\n * depends on a negotiated capability (e.g. PROBE) must wait for it.\n */\nexport class Setup {\n\t/** The probe capability this endpoint supports. {@link ProbeLevel.None} when absent. */\n\tprobe: ProbeLevel;\n\n\t/**\n\t * The request path, for transports that carry no request URI (native QUIC, qmux over\n\t * TCP/TLS, unix sockets), with `?` and the URI query appended when there is one. Sent\n\t * only by the client; a server never sends one and a relay never forwards it.\n\t * `undefined` on URI-carrying bindings such as WebTransport, where sending one is a\n\t * protocol violation. An empty string means the same as `undefined`.\n\t */\n\tpath?: string;\n\n\t/**\n\t * The client's intended {@link Role}. `Both` is sent as the absence of the parameter, so\n\t * a client that never sets it decodes back to `Both`. Sent only by the client; a server\n\t * never sends one and a relay never forwards it.\n\t */\n\trole: Role;\n\n\t/**\n\t * This endpoint's origin (hop) id. The peer uses it to filter announcements and\n\t * subscriptions whose route flows through this endpoint (lite-06 removed the\n\t * per-stream `exclude_hop` in its favor). `undefined` when the endpoint declares\n\t * no identity; a wire value of 0 decodes the same way.\n\t */\n\torigin?: Origin;\n\n\tconstructor({ probe, path, role, origin }: SetupProps = {}) {\n\t\tthis.probe = probe ?? ProbeLevel.None;\n\t\tthis.path = path;\n\t\tthis.role = role ?? Role.Both;\n\t\tthis.origin = origin;\n\t}\n\n\tstatic #guard(version: Version) {\n\t\tif (!hasSetupStream(version)) {\n\t\t\tthrow new Error(\"setup stream not supported for this version\");\n\t\t}\n\t}\n\n\tasync #encode(w: Writer) {\n\t\tconst params = new Parameters();\n\t\t// None is the wire default, so omit it to keep the message empty when nothing is set.\n\t\tif (this.probe !== ProbeLevel.None) {\n\t\t\tparams.setVarint(PARAM_PROBE, this.probe);\n\t\t}\n\t\tif (this.path !== undefined) {\n\t\t\tparams.setBytes(PARAM_PATH, new TextEncoder().encode(this.path));\n\t\t}\n\t\t// Both is the wire default, sent as the absence of the parameter.\n\t\tif (this.role !== Role.Both) {\n\t\t\tparams.setVarint(PARAM_ROLE, this.role);\n\t\t}\n\t\tif (this.origin !== undefined && this.origin !== 0n) {\n\t\t\tparams.setVarint(PARAM_ORIGIN, this.origin);\n\t\t}\n\t\tawait params.encode(w);\n\t}\n\n\tstatic async #decode(r: Reader): Promise<Setup> {\n\t\tconst params = await Parameters.decode(r);\n\n\t\tconst probeCode = params.getVarint(PARAM_PROBE);\n\t\tconst probe = probeCode === undefined ? ProbeLevel.None : probeFromCode(probeCode);\n\n\t\t// An empty path is valid and means the same as omitting the parameter, so a\n\t\t// client that wants the root doesn't have to special-case it.\n\t\tconst pathBytes = params.getBytes(PARAM_PATH);\n\t\tconst path = pathBytes === undefined ? undefined : decodeUtf8(pathBytes);\n\n\t\tconst roleCode = params.getVarint(PARAM_ROLE);\n\t\tconst role = roleCode === undefined ? Role.Both : roleFromCode(roleCode);\n\n\t\t// 0 carries no identity (it cannot be excluded), so it decodes as absent.\n\t\tconst originRaw = params.getVarint(PARAM_ORIGIN);\n\t\tconst origin = originRaw === undefined || originRaw === 0n ? undefined : OriginSchema.parse(originRaw);\n\n\t\treturn new Setup({ probe, path, role, origin });\n\t}\n\n\t/** Encode the SETUP message with its size prefix. Throws on pre-lite-05 versions. */\n\tasync encode(w: Writer, version: Version): Promise<void> {\n\t\tSetup.#guard(version);\n\t\treturn Message.encode(w, this.#encode.bind(this));\n\t}\n\n\t/** Decode a SETUP message with its size prefix. Throws on pre-lite-05 versions. */\n\tstatic async decode(r: Reader, version: Version): Promise<Setup> {\n\t\tSetup.#guard(version);\n\t\treturn Message.decode(r, Setup.#decode);\n\t}\n}\n"]}
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/lite/setup.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The lite-05+ SETUP message: each endpoint advertises its capabilities once, as the\n * sole message on a unidirectional Setup Stream ({@link DataType.Setup}), then closes it.\n *\n * @module\n */\n\nimport { type Hop, HopSchema } from \"../hop.ts\";\nimport { encodeVarint, Reader, type Writer } from \"../stream.ts\";\nimport { decodeUtf8 } from \"../util/utf8.ts\";\nimport * as Message from \"./message.ts\";\nimport { hasSetupStream, type Version } from \"./version.ts\";\n\n/** Setup Parameter id for the Probe capability level. */\nconst PARAM_PROBE = 0x1n;\n/** Setup Parameter id for the request Path (client-only, URI-less transports). */\nconst PARAM_PATH = 0x2n;\n/** Setup Parameter id for the client's intended {@link Role} (client-only). */\nconst PARAM_ROLE = 0x3n;\n/** Setup Parameter id for the endpoint's Hop ID. */\nconst PARAM_HOP = 0x5n;\n\n/** Cap on the number of parameters in a bag, matching the Rust decoder. */\nconst MAX_PARAMS = 64;\n\n/** SETUP only carries negotiation parameters, so it gets a far smaller cap than other messages. */\nconst MAX_SETUP_SIZE = 64 * 1024;\n\n/**\n * The probe capability an endpoint advertises in SETUP.\n *\n * Monotonic: a higher level implies every lower one. An unknown (future) value\n * decodes as the highest level we understand, so a peer that gains a new level is\n * treated as at least {@link ProbeLevel.Increase}.\n */\nexport const ProbeLevel = {\n\t/** No probing. Equivalent to omitting the parameter. */\n\tNone: 0,\n\t/** The publisher can measure and periodically report its estimated bitrate. */\n\tReport: 1,\n\t/** The publisher can additionally pad the connection (or send redundant data). */\n\tIncrease: 2,\n} as const;\n\n/** A probe capability level. See {@link ProbeLevel}. */\nexport type ProbeLevel = (typeof ProbeLevel)[keyof typeof ProbeLevel];\n\n/** Map a wire value to a level, saturating unknown values to {@link ProbeLevel.Increase}. */\nfunction probeFromCode(code: bigint): ProbeLevel {\n\tswitch (code) {\n\t\tcase 0n:\n\t\t\treturn ProbeLevel.None;\n\t\tcase 1n:\n\t\t\treturn ProbeLevel.Report;\n\t\tdefault:\n\t\t\treturn ProbeLevel.Increase;\n\t}\n}\n\n/**\n * The direction a client intends to use the session for.\n *\n * A client advertises this in its SETUP so the server can reject a token that lacks the\n * matching scope during the handshake, instead of accepting a session that then silently\n * carries no media (a subscribe-only token used to publish, or vice versa). It only ever\n * narrows what the server grants, so it is not a security boundary: the server still\n * enforces the token's scope regardless.\n */\nexport const Role = {\n\t/** The client may do either, or declined to say. Equivalent to omitting the parameter. */\n\tBoth: 0,\n\t/** The client will publish tracks (ingest); the server must consume. */\n\tPublisher: 1,\n\t/** The client will subscribe to tracks (egress); the server must publish. */\n\tSubscriber: 2,\n} as const;\n\n/** A session role. See {@link Role}. */\nexport type Role = (typeof Role)[keyof typeof Role];\n\n/**\n * Map a wire value to a role, falling back to {@link Role.Both}.\n *\n * The draft requires a receiver that does not recognize the value to treat it as `Both`,\n * so a newer client can't break an older server: it just loses the early reject and defers\n * to the token's scope.\n */\nfunction roleFromCode(code: bigint): Role {\n\tswitch (code) {\n\t\tcase 1n:\n\t\t\treturn Role.Publisher;\n\t\tcase 2n:\n\t\t\treturn Role.Subscriber;\n\t\tdefault:\n\t\t\treturn Role.Both;\n\t}\n}\n\n/**\n * A bag of `id -> raw bytes` parameters, the body shared by SETUP. Encoded as a varint\n * count followed by `id, length, value` triples; duplicate ids are rejected on decode.\n */\nclass Parameters {\n\t#entries = new Map<bigint, Uint8Array>();\n\n\t/** Set a parameter to a raw byte value, replacing any existing entry. */\n\tsetBytes(id: bigint, value: Uint8Array) {\n\t\tthis.#entries.set(id, value);\n\t}\n\n\t/** Return a parameter's raw byte value, if present. */\n\tgetBytes(id: bigint): Uint8Array | undefined {\n\t\treturn this.#entries.get(id);\n\t}\n\n\t/** Set a parameter to a varint value in `version`'s encoding, replacing any existing entry. */\n\tsetVarint(id: bigint, value: number | bigint, version: Version) {\n\t\tthis.#entries.set(id, encodeVarint(value, version));\n\t}\n\n\t/** Decode a parameter as a single varint in `version`'s encoding, if present. Throws if trailing bytes remain. */\n\tasync getVarint(id: bigint, version: Version): Promise<bigint | undefined> {\n\t\tconst bytes = this.#entries.get(id);\n\t\tif (bytes === undefined) return undefined;\n\t\tconst r = new Reader(undefined, bytes, version);\n\t\tconst value = await r.u62();\n\t\tif (!(await r.done())) {\n\t\t\tthrow new Error(\"trailing bytes after varint parameter\");\n\t\t}\n\t\treturn value;\n\t}\n\n\tasync encode(w: Writer) {\n\t\tif (this.#entries.size > MAX_PARAMS) {\n\t\t\tthrow new Error(\"too many parameters\");\n\t\t}\n\n\t\tawait w.u53(this.#entries.size);\n\t\tfor (const [id, value] of this.#entries) {\n\t\t\tawait w.u62(id);\n\t\t\tawait w.u53(value.byteLength);\n\t\t\tawait w.write(value);\n\t\t}\n\t}\n\n\tstatic async decode(r: Reader): Promise<Parameters> {\n\t\tconst params = new Parameters();\n\n\t\tconst count = await r.u53();\n\t\tif (count > MAX_PARAMS) {\n\t\t\tthrow new Error(\"too many parameters\");\n\t\t}\n\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tconst id = await r.u62();\n\t\t\tif (params.#entries.has(id)) {\n\t\t\t\tthrow new Error(`duplicate parameter id: ${id.toString()}`);\n\t\t\t}\n\t\t\tconst size = await r.u53();\n\t\t\tconst value = await r.read(size);\n\t\t\tparams.#entries.set(id, value);\n\t\t}\n\n\t\treturn params;\n\t}\n}\n\n/** The capabilities a {@link Setup} advertises. Each defaults to the wire default, which is the absence of the parameter. */\nexport interface SetupProps {\n\t/** See {@link Setup.probe}. Defaults to {@link ProbeLevel.None}. */\n\tprobe?: ProbeLevel;\n\t/** See {@link Setup.path}. Omitted by default. */\n\tpath?: string;\n\t/** See {@link Setup.role}. Defaults to {@link Role.Both}. */\n\trole?: Role;\n\t/** See {@link Setup.hop}. Omitted by default. */\n\thop?: Hop;\n}\n\n/**\n * The SETUP message, sent once per endpoint on the unidirectional Setup Stream.\n *\n * lite-05+ only. The two endpoints' SETUP messages are independent: neither side\n * blocks on the peer's before opening other streams, but a stream whose encoding\n * depends on a negotiated capability (e.g. PROBE) must wait for it.\n */\nexport class Setup {\n\t/** The probe capability this endpoint supports. {@link ProbeLevel.None} when absent. */\n\tprobe: ProbeLevel;\n\n\t/**\n\t * The request path, for transports that carry no request URI (native QUIC, qmux over\n\t * TCP/TLS, unix sockets), with `?` and the URI query appended when there is one. Sent\n\t * only by the client; a server never sends one and a relay never forwards it.\n\t * `undefined` on URI-carrying bindings such as WebTransport, where sending one is a\n\t * protocol violation. An empty string means the same as `undefined`.\n\t */\n\tpath?: string;\n\n\t/**\n\t * The client's intended {@link Role}. `Both` is sent as the absence of the parameter, so\n\t * a client that never sets it decodes back to `Both`. Sent only by the client; a server\n\t * never sends one and a relay never forwards it.\n\t */\n\trole: Role;\n\n\t/**\n\t * This endpoint's Hop ID. The peer uses it to filter announcements and\n\t * subscriptions whose route flows through this endpoint (lite-06 removed the\n\t * per-stream `exclude_hop` in its favor). `undefined` when the endpoint declares\n\t * no identity; a wire value of 0 decodes the same way.\n\t */\n\thop?: Hop;\n\n\tconstructor({ probe, path, role, hop }: SetupProps = {}) {\n\t\tthis.probe = probe ?? ProbeLevel.None;\n\t\tthis.path = path;\n\t\tthis.role = role ?? Role.Both;\n\t\tthis.hop = hop;\n\t}\n\n\tstatic #guard(version: Version) {\n\t\tif (!hasSetupStream(version)) {\n\t\t\tthrow new Error(\"setup stream not supported for this version\");\n\t\t}\n\t}\n\n\tasync #encode(w: Writer, version: Version) {\n\t\tconst params = new Parameters();\n\t\t// None is the wire default, so omit it to keep the message empty when nothing is set.\n\t\tif (this.probe !== ProbeLevel.None) {\n\t\t\tparams.setVarint(PARAM_PROBE, this.probe, version);\n\t\t}\n\t\tif (this.path !== undefined) {\n\t\t\tparams.setBytes(PARAM_PATH, new TextEncoder().encode(this.path));\n\t\t}\n\t\t// Both is the wire default, sent as the absence of the parameter.\n\t\tif (this.role !== Role.Both) {\n\t\t\tparams.setVarint(PARAM_ROLE, this.role, version);\n\t\t}\n\t\tif (this.hop !== undefined && this.hop !== 0n) {\n\t\t\tparams.setVarint(PARAM_HOP, this.hop, version);\n\t\t}\n\t\tawait params.encode(w);\n\t}\n\n\tstatic async #decode(r: Reader, version: Version): Promise<Setup> {\n\t\tconst params = await Parameters.decode(r);\n\n\t\tconst probeCode = await params.getVarint(PARAM_PROBE, version);\n\t\tconst probe = probeCode === undefined ? ProbeLevel.None : probeFromCode(probeCode);\n\n\t\t// An empty path is valid and means the same as omitting the parameter, so a\n\t\t// client that wants the root doesn't have to special-case it.\n\t\tconst pathBytes = params.getBytes(PARAM_PATH);\n\t\tconst path = pathBytes === undefined ? undefined : decodeUtf8(pathBytes);\n\n\t\tconst roleCode = await params.getVarint(PARAM_ROLE, version);\n\t\tconst role = roleCode === undefined ? Role.Both : roleFromCode(roleCode);\n\n\t\t// 0 carries no identity (it cannot be excluded), so it decodes as absent.\n\t\tconst hopRaw = await params.getVarint(PARAM_HOP, version);\n\t\tconst hop = hopRaw === undefined || hopRaw === 0n ? undefined : HopSchema.parse(hopRaw);\n\n\t\treturn new Setup({ probe, path, role, hop });\n\t}\n\n\t/** Encode the SETUP message with its size prefix. Throws on pre-lite-05 versions. */\n\tasync encode(w: Writer, version: Version): Promise<void> {\n\t\tSetup.#guard(version);\n\t\treturn Message.encode(w, (w) => this.#encode(w, version), MAX_SETUP_SIZE);\n\t}\n\n\t/** Decode a SETUP message with its size prefix. Throws on pre-lite-05 versions. */\n\tstatic async decode(r: Reader, version: Version): Promise<Setup> {\n\t\tSetup.#guard(version);\n\t\treturn Message.decode(r, (r) => Setup.#decode(r, version), MAX_SETUP_SIZE);\n\t}\n}\n"]}