@norskvideo/moq-net 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. package/README.md +1 -0
  2. package/announced.d.ts +111 -21
  3. package/announced.d.ts.map +1 -1
  4. package/announced.js +213 -40
  5. package/announced.js.map +1 -1
  6. package/broadcast.d.ts +80 -25
  7. package/broadcast.d.ts.map +1 -1
  8. package/broadcast.js +270 -49
  9. package/broadcast.js.map +1 -1
  10. package/connection/accept.d.ts +6 -0
  11. package/connection/accept.d.ts.map +1 -1
  12. package/connection/accept.js +42 -13
  13. package/connection/accept.js.map +1 -1
  14. package/connection/browser.d.ts +5 -0
  15. package/connection/browser.d.ts.map +1 -0
  16. package/connection/browser.js +31 -0
  17. package/connection/browser.js.map +1 -0
  18. package/connection/connect.d.ts +43 -1
  19. package/connection/connect.d.ts.map +1 -1
  20. package/connection/connect.js +118 -123
  21. package/connection/connect.js.map +1 -1
  22. package/connection/established.d.ts +43 -16
  23. package/connection/established.d.ts.map +1 -1
  24. package/connection/established.js.map +1 -1
  25. package/connection/handshake.d.ts +12 -1
  26. package/connection/handshake.d.ts.map +1 -1
  27. package/connection/handshake.js +30 -14
  28. package/connection/handshake.js.map +1 -1
  29. package/connection/index.d.ts +8 -0
  30. package/connection/index.d.ts.map +1 -1
  31. package/connection/index.js +6 -0
  32. package/connection/index.js.map +1 -1
  33. package/connection/reload.d.ts +66 -9
  34. package/connection/reload.d.ts.map +1 -1
  35. package/connection/reload.js +192 -66
  36. package/connection/reload.js.map +1 -1
  37. package/connection/stats.d.ts +92 -0
  38. package/connection/stats.d.ts.map +1 -0
  39. package/connection/stats.js +35 -0
  40. package/connection/stats.js.map +1 -0
  41. package/connection/transport.d.ts +10 -0
  42. package/connection/transport.d.ts.map +1 -0
  43. package/connection/transport.js +12 -0
  44. package/connection/transport.js.map +1 -0
  45. package/consume.d.ts +44 -0
  46. package/consume.d.ts.map +1 -0
  47. package/consume.js +60 -0
  48. package/consume.js.map +1 -0
  49. package/datagram.d.ts +23 -0
  50. package/datagram.d.ts.map +1 -0
  51. package/datagram.js +3 -0
  52. package/datagram.js.map +1 -0
  53. package/error.d.ts +76 -0
  54. package/error.d.ts.map +1 -0
  55. package/error.js +107 -0
  56. package/error.js.map +1 -0
  57. package/group.d.ts +143 -38
  58. package/group.d.ts.map +1 -1
  59. package/group.js +270 -68
  60. package/group.js.map +1 -1
  61. package/ietf/adapter.d.ts +2 -2
  62. package/ietf/adapter.d.ts.map +1 -1
  63. package/ietf/adapter.js +20 -10
  64. package/ietf/adapter.js.map +1 -1
  65. package/ietf/aliases.d.ts +73 -5
  66. package/ietf/aliases.d.ts.map +1 -1
  67. package/ietf/aliases.js +121 -14
  68. package/ietf/aliases.js.map +1 -1
  69. package/ietf/cluster.d.ts +141 -0
  70. package/ietf/cluster.d.ts.map +1 -0
  71. package/ietf/cluster.js +204 -0
  72. package/ietf/cluster.js.map +1 -0
  73. package/ietf/connection.d.ts +39 -6
  74. package/ietf/connection.d.ts.map +1 -1
  75. package/ietf/connection.js +73 -12
  76. package/ietf/connection.js.map +1 -1
  77. package/ietf/fetch.d.ts +17 -0
  78. package/ietf/fetch.d.ts.map +1 -1
  79. package/ietf/fetch.js +21 -0
  80. package/ietf/fetch.js.map +1 -1
  81. package/ietf/filter.d.ts +87 -0
  82. package/ietf/filter.d.ts.map +1 -0
  83. package/ietf/filter.js +292 -0
  84. package/ietf/filter.js.map +1 -0
  85. package/ietf/index.d.ts +2 -0
  86. package/ietf/index.d.ts.map +1 -1
  87. package/ietf/index.js +3 -0
  88. package/ietf/index.js.map +1 -1
  89. package/ietf/namespace.d.ts +6 -0
  90. package/ietf/namespace.d.ts.map +1 -1
  91. package/ietf/namespace.js +27 -2
  92. package/ietf/namespace.js.map +1 -1
  93. package/ietf/object.d.ts +54 -6
  94. package/ietf/object.d.ts.map +1 -1
  95. package/ietf/object.js +178 -25
  96. package/ietf/object.js.map +1 -1
  97. package/ietf/parameters.d.ts +35 -10
  98. package/ietf/parameters.d.ts.map +1 -1
  99. package/ietf/parameters.js +236 -45
  100. package/ietf/parameters.js.map +1 -1
  101. package/ietf/priority.d.ts +5 -0
  102. package/ietf/priority.d.ts.map +1 -0
  103. package/ietf/priority.js +10 -0
  104. package/ietf/priority.js.map +1 -0
  105. package/ietf/properties.d.ts +13 -2
  106. package/ietf/properties.d.ts.map +1 -1
  107. package/ietf/properties.js +65 -8
  108. package/ietf/properties.js.map +1 -1
  109. package/ietf/publish.d.ts.map +1 -1
  110. package/ietf/publish.js +13 -3
  111. package/ietf/publish.js.map +1 -1
  112. package/ietf/publish_namespace.d.ts +16 -2
  113. package/ietf/publish_namespace.d.ts.map +1 -1
  114. package/ietf/publish_namespace.js +25 -6
  115. package/ietf/publish_namespace.js.map +1 -1
  116. package/ietf/publisher.d.ts +40 -7
  117. package/ietf/publisher.d.ts.map +1 -1
  118. package/ietf/publisher.js +751 -134
  119. package/ietf/publisher.js.map +1 -1
  120. package/ietf/request.js +1 -1
  121. package/ietf/request.js.map +1 -1
  122. package/ietf/solicit.d.ts +41 -0
  123. package/ietf/solicit.d.ts.map +1 -0
  124. package/ietf/solicit.js +47 -0
  125. package/ietf/solicit.js.map +1 -0
  126. package/ietf/subscribe.d.ts +41 -2
  127. package/ietf/subscribe.d.ts.map +1 -1
  128. package/ietf/subscribe.js +103 -22
  129. package/ietf/subscribe.js.map +1 -1
  130. package/ietf/subscribe_namespace.d.ts +21 -7
  131. package/ietf/subscribe_namespace.d.ts.map +1 -1
  132. package/ietf/subscribe_namespace.js +31 -14
  133. package/ietf/subscribe_namespace.js.map +1 -1
  134. package/ietf/subscriber.d.ts +20 -7
  135. package/ietf/subscriber.d.ts.map +1 -1
  136. package/ietf/subscriber.js +512 -142
  137. package/ietf/subscriber.js.map +1 -1
  138. package/ietf/version.d.ts +7 -1
  139. package/ietf/version.d.ts.map +1 -1
  140. package/ietf/version.js +7 -0
  141. package/ietf/version.js.map +1 -1
  142. package/index.d.ts +10 -5
  143. package/index.d.ts.map +1 -1
  144. package/index.js +10 -5
  145. package/index.js.map +1 -1
  146. package/internal.d.ts +29 -0
  147. package/internal.d.ts.map +1 -0
  148. package/internal.js +8 -0
  149. package/internal.js.map +1 -0
  150. package/lite/announce.d.ts +62 -15
  151. package/lite/announce.d.ts.map +1 -1
  152. package/lite/announce.js +230 -94
  153. package/lite/announce.js.map +1 -1
  154. package/lite/connection.d.ts +69 -20
  155. package/lite/connection.d.ts.map +1 -1
  156. package/lite/connection.js +128 -81
  157. package/lite/connection.js.map +1 -1
  158. package/lite/datagram.d.ts +23 -0
  159. package/lite/datagram.d.ts.map +1 -0
  160. package/lite/datagram.js +57 -0
  161. package/lite/datagram.js.map +1 -0
  162. package/lite/datagram_stream.d.ts +8 -0
  163. package/lite/datagram_stream.d.ts.map +1 -0
  164. package/lite/datagram_stream.js +44 -0
  165. package/lite/datagram_stream.js.map +1 -0
  166. package/lite/fetch.d.ts.map +1 -1
  167. package/lite/fetch.js +2 -2
  168. package/lite/fetch.js.map +1 -1
  169. package/lite/index.d.ts +3 -0
  170. package/lite/index.d.ts.map +1 -1
  171. package/lite/index.js +3 -0
  172. package/lite/index.js.map +1 -1
  173. package/lite/priority.d.ts +67 -0
  174. package/lite/priority.d.ts.map +1 -0
  175. package/lite/priority.js +114 -0
  176. package/lite/priority.js.map +1 -0
  177. package/lite/probe.d.ts +18 -2
  178. package/lite/probe.d.ts.map +1 -1
  179. package/lite/probe.js +24 -22
  180. package/lite/probe.js.map +1 -1
  181. package/lite/publisher.d.ts +14 -7
  182. package/lite/publisher.d.ts.map +1 -1
  183. package/lite/publisher.js +406 -84
  184. package/lite/publisher.js.map +1 -1
  185. package/lite/setup.d.ts +83 -6
  186. package/lite/setup.d.ts.map +1 -1
  187. package/lite/setup.js +203 -31
  188. package/lite/setup.js.map +1 -1
  189. package/lite/stream.d.ts +12 -3
  190. package/lite/stream.d.ts.map +1 -1
  191. package/lite/stream.js +7 -4
  192. package/lite/stream.js.map +1 -1
  193. package/lite/subscribe.d.ts +37 -23
  194. package/lite/subscribe.d.ts.map +1 -1
  195. package/lite/subscribe.js +70 -55
  196. package/lite/subscribe.js.map +1 -1
  197. package/lite/subscriber.d.ts +29 -23
  198. package/lite/subscriber.d.ts.map +1 -1
  199. package/lite/subscriber.js +689 -112
  200. package/lite/subscriber.js.map +1 -1
  201. package/lite/track.d.ts +25 -13
  202. package/lite/track.d.ts.map +1 -1
  203. package/lite/track.js +60 -35
  204. package/lite/track.js.map +1 -1
  205. package/lite/version.d.ts +39 -4
  206. package/lite/version.d.ts.map +1 -1
  207. package/lite/version.js +139 -17
  208. package/lite/version.js.map +1 -1
  209. package/mock.d.ts +53 -3
  210. package/mock.d.ts.map +1 -1
  211. package/mock.js +110 -21
  212. package/mock.js.map +1 -1
  213. package/{lite/origin.d.ts → origin.d.ts} +25 -1
  214. package/origin.d.ts.map +1 -0
  215. package/{lite/origin.js → origin.js} +25 -1
  216. package/origin.js.map +1 -0
  217. package/package.json +6 -4
  218. package/path.d.ts +67 -0
  219. package/path.d.ts.map +1 -1
  220. package/path.js +128 -0
  221. package/path.js.map +1 -1
  222. package/stream.d.ts +94 -4
  223. package/stream.d.ts.map +1 -1
  224. package/stream.js +128 -17
  225. package/stream.js.map +1 -1
  226. package/time.d.ts +109 -86
  227. package/time.d.ts.map +1 -1
  228. package/time.js +80 -30
  229. package/time.js.map +1 -1
  230. package/track.d.ts +298 -47
  231. package/track.d.ts.map +1 -1
  232. package/track.js +721 -109
  233. package/track.js.map +1 -1
  234. package/util/timeout.d.ts +5 -0
  235. package/util/timeout.d.ts.map +1 -0
  236. package/util/timeout.js +18 -0
  237. package/util/timeout.js.map +1 -0
  238. package/util/utf8.d.ts +3 -0
  239. package/util/utf8.d.ts.map +1 -0
  240. package/util/utf8.js +7 -0
  241. package/util/utf8.js.map +1 -0
  242. package/varint.d.ts +14 -3
  243. package/varint.d.ts.map +1 -1
  244. package/varint.js +23 -12
  245. package/varint.js.map +1 -1
  246. package/zod.d.ts +5 -5
  247. package/zod.d.ts.map +1 -1
  248. package/zod.js.map +1 -1
  249. package/bandwidth.d.ts +0 -11
  250. package/bandwidth.d.ts.map +0 -1
  251. package/bandwidth.js +0 -7
  252. package/bandwidth.js.map +0 -1
  253. package/connection/cert.test.d.ts +0 -2
  254. package/connection/cert.test.d.ts.map +0 -1
  255. package/connection/cert.test.js +0 -26
  256. package/connection/cert.test.js.map +0 -1
  257. package/connection/reload.test.d.ts +0 -2
  258. package/connection/reload.test.d.ts.map +0 -1
  259. package/connection/reload.test.js +0 -39
  260. package/connection/reload.test.js.map +0 -1
  261. package/group.test.d.ts +0 -2
  262. package/group.test.d.ts.map +0 -1
  263. package/group.test.js +0 -66
  264. package/group.test.js.map +0 -1
  265. package/ietf/aliases.test.d.ts +0 -2
  266. package/ietf/aliases.test.d.ts.map +0 -1
  267. package/ietf/aliases.test.js +0 -30
  268. package/ietf/aliases.test.js.map +0 -1
  269. package/ietf/ietf.test.d.ts +0 -2
  270. package/ietf/ietf.test.d.ts.map +0 -1
  271. package/ietf/ietf.test.js +0 -873
  272. package/ietf/ietf.test.js.map +0 -1
  273. package/integration.test.d.ts +0 -2
  274. package/integration.test.d.ts.map +0 -1
  275. package/integration.test.js +0 -90
  276. package/integration.test.js.map +0 -1
  277. package/lite/origin.d.ts.map +0 -1
  278. package/lite/origin.js.map +0 -1
  279. package/lite/subscriber.test.d.ts +0 -2
  280. package/lite/subscriber.test.d.ts.map +0 -1
  281. package/lite/subscriber.test.js +0 -30
  282. package/lite/subscriber.test.js.map +0 -1
  283. package/lite/track.test.d.ts +0 -2
  284. package/lite/track.test.d.ts.map +0 -1
  285. package/lite/track.test.js +0 -53
  286. package/lite/track.test.js.map +0 -1
  287. package/path.test.d.ts +0 -2
  288. package/path.test.d.ts.map +0 -1
  289. package/path.test.js +0 -169
  290. package/path.test.js.map +0 -1
  291. package/stream.test.d.ts +0 -2
  292. package/stream.test.d.ts.map +0 -1
  293. package/stream.test.js +0 -210
  294. package/stream.test.js.map +0 -1
  295. package/track.test.d.ts +0 -2
  296. package/track.test.d.ts.map +0 -1
  297. package/track.test.js +0 -56
  298. package/track.test.js.map +0 -1
  299. package/util/error.d.ts +0 -3
  300. package/util/error.d.ts.map +0 -1
  301. package/util/error.js +0 -9
  302. package/util/error.js.map +0 -1
  303. package/util/index.d.ts +0 -2
  304. package/util/index.d.ts.map +0 -1
  305. package/util/index.js +0 -3
  306. package/util/index.js.map +0 -1
  307. package/varint.test.d.ts +0 -2
  308. package/varint.test.d.ts.map +0 -1
  309. package/varint.test.js +0 -106
  310. package/varint.test.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"publisher.js","sourceRoot":"","sources":["../../src/lite/publisher.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Dispose, Signal } from \"@moq/signals\";\nimport type { Broadcast } from \"../broadcast.ts\";\nimport type { Group } from \"../group.ts\";\nimport * as Path from \"../path.ts\";\nimport { type Stream, Writer } from \"../stream.ts\";\nimport type { Track } from \"../track.ts\";\nimport { error } from \"../util/error.ts\";\nimport { Announce, AnnounceInit, type AnnounceInterest } from \"./announce.ts\";\nimport { Group as GroupMessage } from \"./group.ts\";\nimport type { Origin } from \"./origin.ts\";\nimport { Probe } from \"./probe.ts\";\nimport { encodeSubscribeResponse, type Subscribe, SubscribeEnd, SubscribeOk, SubscribeUpdate } from \"./subscribe.ts\";\nimport type { Track as TrackMessage } from \"./track.ts\";\nimport { TrackInfo } from \"./track.ts\";\nimport { hasTrackStream, Version } from \"./version.ts\";\n\nconst PROBE_INTERVAL = 100; // ms\nconst PROBE_MAX_AGE = 10_000; // ms\nconst PROBE_MAX_DELTA = 0.25;\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// 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> | undefined>(new Map());\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\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) {\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.\n\t\tvoid broadcast.closed.finally(() => {\n\t\t\tthis.#broadcasts.mutate((broadcasts) => {\n\t\t\t\tbroadcasts?.delete(path);\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: AnnounceInterest, 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\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\t// Draft03+: send individual Announce messages for initial state.\n\t\t\t\tfor (const suffix of active) {\n\t\t\t\t\tconst wire = new Announce({ suffix, active: true, hops: [this.origin] });\n\t\t\t\t\tawait wire.encode(stream.writer, this.version);\n\t\t\t\t}\n\t\t\t\tbreak;\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> | 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.\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 wire = new Announce({ suffix: added, active: true, hops: [this.origin] });\n\t\t\t\tawait wire.encode(stream.writer, this.version);\n\t\t\t}\n\n\t\t\t// Announce any removed broadcasts.\n\t\t\t// Ended announces don't need hops — the peer matches on path only.\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\tconst wire = new Announce({ suffix: removed, active: false });\n\t\t\t\tawait wire.encode(stream.writer, this.version);\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, msg.priority);\n\n\t\ttry {\n\t\t\t// moq-lite-05+ trims SUBSCRIBE_OK to the resolved start group; the publisher\n\t\t\t// properties move to TRACK_INFO. Earlier versions echo the priority inline.\n\t\t\tconst info = hasTrackStream(this.version)\n\t\t\t\t? new SubscribeOk({ startGroup: msg.startGroup ?? 0 })\n\t\t\t\t: new SubscribeOk({ priority: msg.priority });\n\t\t\tawait encodeSubscribeResponse(stream.writer, { ok: info }, this.version);\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);\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(\n\t\t\t\t\t\t`subscribe update: broadcast=${msg.broadcast} track=${track.name} priority=${result.priority}`,\n\t\t\t\t\t);\n\t\t\t\t\ttrack.updatePriority(result.priority);\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} catch (err: unknown) {\n\t\t\tconst e = error(err);\n\t\t\tconsole.warn(`publish error: broadcast=${msg.broadcast} track=${track.name} error=${e.message}`);\n\t\t\ttrack.close(e);\n\t\t\tstream.abort(e);\n\t\t}\n\t}\n\n\t/**\n\t * Serves a Track stream (moq-lite-05+): replies with the track's immutable TRACK_INFO.\n\t *\n\t * @internal\n\t */\n\tasync runTrackInfo(msg: TrackMessage, stream: Stream) {\n\t\tconst broadcast = this.#broadcasts.peek()?.get(msg.broadcast);\n\t\tif (!broadcast) {\n\t\t\tthrow new Error(\"not found\");\n\t\t}\n\n\t\t// The publisher properties aren't tracked in the browser model yet; report\n\t\t// defaults with a millisecond timescale matching the wall-clock frame timestamps.\n\t\tconst info = new TrackInfo({ timescale: 1000 });\n\t\tawait info.encode(stream.writer, this.version);\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, stream: Writer) {\n\t\ttry {\n\t\t\tlet lastSequence: number | undefined;\n\t\t\tlet trackEnded = false;\n\n\t\t\tfor (;;) {\n\t\t\t\tconst next = track.recvGroup();\n\t\t\t\tconst res = await Promise.race([\n\t\t\t\t\tnext.then((group) => ({ group })),\n\t\t\t\t\tstream.closed.then(() => \"closed\" as const),\n\t\t\t\t]);\n\t\t\t\tif (res === \"closed\") {\n\t\t\t\t\tnext.then((group) => group?.close()).catch(() => {});\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (!res.group) {\n\t\t\t\t\ttrackEnded = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tlastSequence = res.group.sequence;\n\t\t\t\tvoid this.#runGroup(sub, res.group);\n\t\t\t}\n\n\t\t\t// moq-lite-05+: signal end-of-track before the subscribe stream FINs.\n\t\t\tif (trackEnded && hasTrackStream(this.version)) {\n\t\t\t\tconst end = new SubscribeEnd({ group: lastSequence ?? 0 });\n\t\t\t\tawait encodeSubscribeResponse(stream, { end }, this.version);\n\t\t\t}\n\n\t\t\tconsole.debug(`publish close: broadcast=${broadcast} track=${track.name}`);\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=${e.message}`);\n\t\t\ttrack.close(e);\n\t\t\tstream.reset(e);\n\t\t}\n\t}\n\n\t/**\n\t * Runs a group and sends its frames to the stream.\n\t * @param sub - The subscription ID\n\t * @param group - The group to run\n\t *\n\t * @internal\n\t */\n\tasync #runGroup(sub: bigint, group: Group) {\n\t\tconst msg = new GroupMessage(sub, group.sequence);\n\t\ttry {\n\t\t\tconst stream = await Writer.open(this.#quic);\n\t\t\tawait stream.u8(0); // stream type\n\t\t\tawait msg.encode(stream);\n\n\t\t\ttry {\n\t\t\t\t// moq-lite-05+ stamps each frame with a wall-clock millisecond timestamp, sent\n\t\t\t\t// as a zigzag delta from the previous frame (the first frame is a delta from 0).\n\t\t\t\tlet prevTimestamp = 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 (hasTrackStream(this.version)) {\n\t\t\t\t\t\tconst now = BigInt(Date.now());\n\t\t\t\t\t\tconst delta = now - prevTimestamp;\n\t\t\t\t\t\tprevTimestamp = now;\n\t\t\t\t\t\tawait stream.u62((delta << 1n) ^ (delta >> 63n));\n\t\t\t\t\t}\n\n\t\t\t\t\tawait stream.u53(frame.byteLength);\n\t\t\t\t\tawait stream.write(frame);\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}\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 }>;\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 lastSentBitrate: number | undefined;\n\t\tlet lastSentTime: number | undefined;\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\tconst stats = await quic.getStats();\n\t\t\t\tconst bitrate = stats.estimatedSendRate;\n\t\t\t\tif (bitrate == null) continue;\n\n\t\t\t\tlet shouldSend: boolean;\n\t\t\t\tif (lastSentBitrate === undefined || lastSentTime === undefined) {\n\t\t\t\t\tshouldSend = true;\n\t\t\t\t} else if (lastSentBitrate === 0) {\n\t\t\t\t\tshouldSend = bitrate > 0;\n\t\t\t\t} else {\n\t\t\t\t\tconst elapsed = performance.now() - lastSentTime;\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\tconst change = Math.abs(bitrate - lastSentBitrate) / lastSentBitrate;\n\t\t\t\t\tshouldSend = change >= threshold;\n\t\t\t\t}\n\n\t\t\t\tif (shouldSend) {\n\t\t\t\t\tawait new Probe(bitrate).encode(stream.writer, this.version);\n\t\t\t\t\tlastSentBitrate = bitrate;\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\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, 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"]}
package/lite/setup.d.ts CHANGED
@@ -1,18 +1,95 @@
1
+ /**
2
+ * The lite-05 SETUP message: each endpoint advertises its capabilities once, as the
3
+ * sole message on a unidirectional Setup Stream ({@link DataType.Setup}), then closes it.
4
+ *
5
+ * @module
6
+ */
7
+ import { type Origin } from "../origin";
1
8
  import type { Reader, Writer } from "../stream";
2
9
  import { type Version } from "./version";
3
10
  /**
4
- * The moq-lite-05 SETUP message, sent once per endpoint on a unidirectional Setup stream.
11
+ * The probe capability an endpoint advertises in SETUP.
12
+ *
13
+ * Monotonic: a higher level implies every lower one. An unknown (future) value
14
+ * decodes as the highest level we understand, so a peer that gains a new level is
15
+ * treated as at least {@link ProbeLevel.Increase}.
16
+ */
17
+ export declare const ProbeLevel: {
18
+ /** No probing. Equivalent to omitting the parameter. */
19
+ readonly None: 0;
20
+ /** The publisher can measure and periodically report its estimated bitrate. */
21
+ readonly Report: 1;
22
+ /** The publisher can additionally pad the connection (or send redundant data). */
23
+ readonly Increase: 2;
24
+ };
25
+ /** A probe capability level. See {@link ProbeLevel}. */
26
+ export type ProbeLevel = (typeof ProbeLevel)[keyof typeof ProbeLevel];
27
+ /**
28
+ * The direction a client intends to use the session for.
29
+ *
30
+ * A client advertises this in its SETUP so the server can reject a token that lacks the
31
+ * matching scope during the handshake, instead of accepting a session that then silently
32
+ * carries no media (a subscribe-only token used to publish, or vice versa). It only ever
33
+ * narrows what the server grants, so it is not a security boundary: the server still
34
+ * enforces the token's scope regardless.
35
+ */
36
+ export declare const Role: {
37
+ /** The client may do either, or declined to say. Equivalent to omitting the parameter. */
38
+ readonly Both: 0;
39
+ /** The client will publish tracks (ingest); the server must consume. */
40
+ readonly Publisher: 1;
41
+ /** The client will subscribe to tracks (egress); the server must publish. */
42
+ readonly Subscriber: 2;
43
+ };
44
+ /** A session role. See {@link Role}. */
45
+ export type Role = (typeof Role)[keyof typeof Role];
46
+ /** The capabilities a {@link Setup} advertises. Each defaults to the wire default, which is the absence of the parameter. */
47
+ export interface SetupProps {
48
+ /** See {@link Setup.probe}. Defaults to {@link ProbeLevel.None}. */
49
+ probe?: ProbeLevel;
50
+ /** See {@link Setup.path}. Omitted by default. */
51
+ path?: string;
52
+ /** See {@link Setup.role}. Defaults to {@link Role.Both}. */
53
+ role?: Role;
54
+ /** See {@link Setup.origin}. Omitted by default. */
55
+ origin?: Origin;
56
+ }
57
+ /**
58
+ * The SETUP message, sent once per endpoint on the unidirectional Setup Stream.
5
59
  *
6
- * The browser conveys its path via the WebTransport URL, so it never sends a Path
7
- * parameter; this class still parses one for completeness when reading a peer's SETUP.
60
+ * lite-05+ only. The two endpoints' SETUP messages are independent: neither side
61
+ * blocks on the peer's before opening other streams, but a stream whose encoding
62
+ * depends on a negotiated capability (e.g. PROBE) must wait for it.
8
63
  */
9
64
  export declare class Setup {
10
65
  #private;
66
+ /** The probe capability this endpoint supports. {@link ProbeLevel.None} when absent. */
67
+ probe: ProbeLevel;
68
+ /**
69
+ * The request path, for transports that carry no request URI (native QUIC, qmux over
70
+ * TCP/TLS, unix sockets), with `?` and the URI query appended when there is one. Sent
71
+ * only by the client; a server never sends one and a relay never forwards it.
72
+ * `undefined` on URI-carrying bindings such as WebTransport, where sending one is a
73
+ * protocol violation. An empty string means the same as `undefined`.
74
+ */
11
75
  path?: string;
12
- constructor(props?: {
13
- path?: string;
14
- });
76
+ /**
77
+ * The client's intended {@link Role}. `Both` is sent as the absence of the parameter, so
78
+ * a client that never sets it decodes back to `Both`. Sent only by the client; a server
79
+ * never sends one and a relay never forwards it.
80
+ */
81
+ role: Role;
82
+ /**
83
+ * This endpoint's origin (hop) id. The peer uses it to filter announcements and
84
+ * subscriptions whose route flows through this endpoint (lite-06 removed the
85
+ * per-stream `exclude_hop` in its favor). `undefined` when the endpoint declares
86
+ * no identity; a wire value of 0 decodes the same way.
87
+ */
88
+ origin?: Origin;
89
+ constructor({ probe, path, role, origin }?: SetupProps);
90
+ /** Encode the SETUP message with its size prefix. Throws on pre-lite-05 versions. */
15
91
  encode(w: Writer, version: Version): Promise<void>;
92
+ /** Decode a SETUP message with its size prefix. Throws on pre-lite-05 versions. */
16
93
  static decode(r: Reader, version: Version): Promise<Setup>;
17
94
  }
18
95
  //# sourceMappingURL=setup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/lite/setup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAkB,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAK5D;;;;;GAKG;AACH,qBAAa,KAAK;;IAEjB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,YAAY,KAAK,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAO,EAExC;IA6BK,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAGvD;IAED,OAAa,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAG/D;CACD"}
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"}
package/lite/setup.js CHANGED
@@ -1,54 +1,226 @@
1
1
  /* @ts-self-types="./setup.d.ts" */
2
+ /**
3
+ * The lite-05 SETUP message: each endpoint advertises its capabilities once, as the
4
+ * sole message on a unidirectional Setup Stream ({@link DataType.Setup}), then closes it.
5
+ *
6
+ * @module
7
+ */
8
+ import { OriginSchema } from "../origin.js";
9
+ import { decodeUtf8 } from "../util/utf8.js";
10
+ import * as Varint from "../varint.js";
2
11
  import * as Message from "./message.js";
3
12
  import { hasSetupStream } from "./version.js";
4
- /// Setup parameter ID for the request Path (client-only, on URI-less transports).
5
- const PARAM_PATH = 0x2;
13
+ /** Setup Parameter id for the Probe capability level. */
14
+ const PARAM_PROBE = 0x1n;
15
+ /** Setup Parameter id for the request Path (client-only, URI-less transports). */
16
+ const PARAM_PATH = 0x2n;
17
+ /** Setup Parameter id for the client's intended {@link Role} (client-only). */
18
+ const PARAM_ROLE = 0x3n;
19
+ /** Setup Parameter id for the endpoint's origin (hop) id. */
20
+ const PARAM_ORIGIN = 0x5n;
21
+ /** Cap on the number of parameters in a bag, matching the Rust decoder. */
22
+ const MAX_PARAMS = 64;
6
23
  /**
7
- * The moq-lite-05 SETUP message, sent once per endpoint on a unidirectional Setup stream.
24
+ * The probe capability an endpoint advertises in SETUP.
8
25
  *
9
- * The browser conveys its path via the WebTransport URL, so it never sends a Path
10
- * parameter; this class still parses one for completeness when reading a peer's SETUP.
26
+ * Monotonic: a higher level implies every lower one. An unknown (future) value
27
+ * decodes as the highest level we understand, so a peer that gains a new level is
28
+ * treated as at least {@link ProbeLevel.Increase}.
11
29
  */
12
- export class Setup {
13
- /// The request path, only sent on transport bindings without a request URI.
14
- path;
15
- constructor(props = {}) {
16
- this.path = props.path;
30
+ export const ProbeLevel = {
31
+ /** No probing. Equivalent to omitting the parameter. */
32
+ None: 0,
33
+ /** The publisher can measure and periodically report its estimated bitrate. */
34
+ Report: 1,
35
+ /** The publisher can additionally pad the connection (or send redundant data). */
36
+ Increase: 2,
37
+ };
38
+ /** Map a wire value to a level, saturating unknown values to {@link ProbeLevel.Increase}. */
39
+ function probeFromCode(code) {
40
+ switch (code) {
41
+ case 0n:
42
+ return ProbeLevel.None;
43
+ case 1n:
44
+ return ProbeLevel.Report;
45
+ default:
46
+ return ProbeLevel.Increase;
17
47
  }
18
- async #encode(w) {
19
- if (this.path !== undefined) {
20
- await w.u53(1); // parameter count
21
- const value = new TextEncoder().encode(this.path);
22
- await w.u53(PARAM_PATH);
48
+ }
49
+ /**
50
+ * The direction a client intends to use the session for.
51
+ *
52
+ * A client advertises this in its SETUP so the server can reject a token that lacks the
53
+ * matching scope during the handshake, instead of accepting a session that then silently
54
+ * carries no media (a subscribe-only token used to publish, or vice versa). It only ever
55
+ * narrows what the server grants, so it is not a security boundary: the server still
56
+ * enforces the token's scope regardless.
57
+ */
58
+ export const Role = {
59
+ /** The client may do either, or declined to say. Equivalent to omitting the parameter. */
60
+ Both: 0,
61
+ /** The client will publish tracks (ingest); the server must consume. */
62
+ Publisher: 1,
63
+ /** The client will subscribe to tracks (egress); the server must publish. */
64
+ Subscriber: 2,
65
+ };
66
+ /**
67
+ * Map a wire value to a role, falling back to {@link Role.Both}.
68
+ *
69
+ * The draft requires a receiver that does not recognize the value to treat it as `Both`,
70
+ * so a newer client can't break an older server: it just loses the early reject and defers
71
+ * to the token's scope.
72
+ */
73
+ function roleFromCode(code) {
74
+ switch (code) {
75
+ case 1n:
76
+ return Role.Publisher;
77
+ case 2n:
78
+ return Role.Subscriber;
79
+ default:
80
+ return Role.Both;
81
+ }
82
+ }
83
+ /**
84
+ * A bag of `id -> raw bytes` parameters, the body shared by SETUP. Encoded as a varint
85
+ * count followed by `id, length, value` triples; duplicate ids are rejected on decode.
86
+ */
87
+ class Parameters {
88
+ #entries = new Map();
89
+ /** Set a parameter to a raw byte value, replacing any existing entry. */
90
+ setBytes(id, value) {
91
+ this.#entries.set(id, value);
92
+ }
93
+ /** Return a parameter's raw byte value, if present. */
94
+ getBytes(id) {
95
+ return this.#entries.get(id);
96
+ }
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)));
100
+ }
101
+ /** Decode a parameter as a single varint, if present. Throws if trailing bytes remain. */
102
+ getVarint(id) {
103
+ const bytes = this.#entries.get(id);
104
+ if (bytes === undefined)
105
+ return undefined;
106
+ const [value, remain] = Varint.decode(bytes);
107
+ if (remain.byteLength !== 0) {
108
+ throw new Error("trailing bytes after varint parameter");
109
+ }
110
+ return BigInt(value);
111
+ }
112
+ async encode(w) {
113
+ if (this.#entries.size > MAX_PARAMS) {
114
+ throw new Error("too many parameters");
115
+ }
116
+ await w.u53(this.#entries.size);
117
+ for (const [id, value] of this.#entries) {
118
+ await w.u62(id);
23
119
  await w.u53(value.byteLength);
24
120
  await w.write(value);
25
121
  }
26
- else {
27
- await w.u53(0); // no parameters
28
- }
29
122
  }
30
- static async #decode(r) {
123
+ static async decode(r) {
124
+ const params = new Parameters();
31
125
  const count = await r.u53();
32
- let path;
126
+ if (count > MAX_PARAMS) {
127
+ throw new Error("too many parameters");
128
+ }
33
129
  for (let i = 0; i < count; i++) {
34
- const id = await r.u53();
35
- const len = await r.u53();
36
- const value = await r.read(len);
37
- // Unknown parameters are ignored so new ones stay backward compatible.
38
- if (id === PARAM_PATH) {
39
- path = new TextDecoder().decode(value);
130
+ const id = await r.u62();
131
+ if (params.#entries.has(id)) {
132
+ throw new Error(`duplicate parameter id: ${id.toString()}`);
40
133
  }
134
+ const size = await r.u53();
135
+ const value = await r.read(size);
136
+ params.#entries.set(id, value);
137
+ }
138
+ return params;
139
+ }
140
+ }
141
+ /**
142
+ * The SETUP message, sent once per endpoint on the unidirectional Setup Stream.
143
+ *
144
+ * lite-05+ only. The two endpoints' SETUP messages are independent: neither side
145
+ * blocks on the peer's before opening other streams, but a stream whose encoding
146
+ * depends on a negotiated capability (e.g. PROBE) must wait for it.
147
+ */
148
+ export class Setup {
149
+ /** The probe capability this endpoint supports. {@link ProbeLevel.None} when absent. */
150
+ probe;
151
+ /**
152
+ * The request path, for transports that carry no request URI (native QUIC, qmux over
153
+ * TCP/TLS, unix sockets), with `?` and the URI query appended when there is one. Sent
154
+ * only by the client; a server never sends one and a relay never forwards it.
155
+ * `undefined` on URI-carrying bindings such as WebTransport, where sending one is a
156
+ * protocol violation. An empty string means the same as `undefined`.
157
+ */
158
+ path;
159
+ /**
160
+ * The client's intended {@link Role}. `Both` is sent as the absence of the parameter, so
161
+ * a client that never sets it decodes back to `Both`. Sent only by the client; a server
162
+ * never sends one and a relay never forwards it.
163
+ */
164
+ role;
165
+ /**
166
+ * This endpoint's origin (hop) id. The peer uses it to filter announcements and
167
+ * subscriptions whose route flows through this endpoint (lite-06 removed the
168
+ * per-stream `exclude_hop` in its favor). `undefined` when the endpoint declares
169
+ * no identity; a wire value of 0 decodes the same way.
170
+ */
171
+ origin;
172
+ constructor({ probe, path, role, origin } = {}) {
173
+ this.probe = probe ?? ProbeLevel.None;
174
+ this.path = path;
175
+ this.role = role ?? Role.Both;
176
+ this.origin = origin;
177
+ }
178
+ static #guard(version) {
179
+ if (!hasSetupStream(version)) {
180
+ throw new Error("setup stream not supported for this version");
181
+ }
182
+ }
183
+ async #encode(w) {
184
+ const params = new Parameters();
185
+ // None is the wire default, so omit it to keep the message empty when nothing is set.
186
+ if (this.probe !== ProbeLevel.None) {
187
+ params.setVarint(PARAM_PROBE, this.probe);
41
188
  }
42
- return new Setup({ path });
189
+ if (this.path !== undefined) {
190
+ params.setBytes(PARAM_PATH, new TextEncoder().encode(this.path));
191
+ }
192
+ // Both is the wire default, sent as the absence of the parameter.
193
+ if (this.role !== Role.Both) {
194
+ params.setVarint(PARAM_ROLE, this.role);
195
+ }
196
+ if (this.origin !== undefined && this.origin !== 0n) {
197
+ params.setVarint(PARAM_ORIGIN, this.origin);
198
+ }
199
+ await params.encode(w);
200
+ }
201
+ static async #decode(r) {
202
+ const params = await Parameters.decode(r);
203
+ const probeCode = params.getVarint(PARAM_PROBE);
204
+ const probe = probeCode === undefined ? ProbeLevel.None : probeFromCode(probeCode);
205
+ // An empty path is valid and means the same as omitting the parameter, so a
206
+ // client that wants the root doesn't have to special-case it.
207
+ const pathBytes = params.getBytes(PARAM_PATH);
208
+ const path = pathBytes === undefined ? undefined : decodeUtf8(pathBytes);
209
+ const roleCode = params.getVarint(PARAM_ROLE);
210
+ const role = roleCode === undefined ? Role.Both : roleFromCode(roleCode);
211
+ // 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 });
43
215
  }
216
+ /** Encode the SETUP message with its size prefix. Throws on pre-lite-05 versions. */
44
217
  async encode(w, version) {
45
- if (!hasSetupStream(version))
46
- throw new Error("SETUP requires moq-lite-05+");
218
+ Setup.#guard(version);
47
219
  return Message.encode(w, this.#encode.bind(this));
48
220
  }
221
+ /** Decode a SETUP message with its size prefix. Throws on pre-lite-05 versions. */
49
222
  static async decode(r, version) {
50
- if (!hasSetupStream(version))
51
- throw new Error("SETUP requires moq-lite-05+");
223
+ Setup.#guard(version);
52
224
  return Message.decode(r, Setup.#decode);
53
225
  }
54
226
  }
package/lite/setup.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/lite/setup.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,cAAc,EAAgB,MAAM,cAAc,CAAC;AAE5D,kFAAkF;AAClF,MAAM,UAAU,GAAG,GAAG,CAAC;AAEvB;;;;;GAKG;AACH,MAAM,OAAO,KAAK;IACjB,4EAA4E;IAC5E,IAAI,CAAU;IAEd,YAAY,KAAK,GAAsB,EAAE;QACxC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,CAAS;QACtB,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB;YAClC,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClD,MAAM,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACxB,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC9B,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;aAAM,CAAC;YACP,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB;QACjC,CAAC;IACF,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAS;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;QAC5B,IAAI,IAAwB,CAAC;QAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChC,uEAAuE;YACvE,IAAI,EAAE,KAAK,UAAU,EAAE,CAAC;gBACvB,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACxC,CAAC;QACF,CAAC;QACD,OAAO,IAAI,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,CAAS,EAAE,OAAgB;QACvC,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QAC7E,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAS,EAAE,OAAgB;QAC9C,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QAC7E,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACzC,CAAC;CACD","sourcesContent":["import type { Reader, Writer } from \"../stream.ts\";\nimport * as Message from \"./message.ts\";\nimport { hasSetupStream, type Version } from \"./version.ts\";\n\n/// Setup parameter ID for the request Path (client-only, on URI-less transports).\nconst PARAM_PATH = 0x2;\n\n/**\n * The moq-lite-05 SETUP message, sent once per endpoint on a unidirectional Setup stream.\n *\n * The browser conveys its path via the WebTransport URL, so it never sends a Path\n * parameter; this class still parses one for completeness when reading a peer's SETUP.\n */\nexport class Setup {\n\t/// The request path, only sent on transport bindings without a request URI.\n\tpath?: string;\n\n\tconstructor(props: { path?: string } = {}) {\n\t\tthis.path = props.path;\n\t}\n\n\tasync #encode(w: Writer) {\n\t\tif (this.path !== undefined) {\n\t\t\tawait w.u53(1); // parameter count\n\t\t\tconst value = new TextEncoder().encode(this.path);\n\t\t\tawait w.u53(PARAM_PATH);\n\t\t\tawait w.u53(value.byteLength);\n\t\t\tawait w.write(value);\n\t\t} else {\n\t\t\tawait w.u53(0); // no parameters\n\t\t}\n\t}\n\n\tstatic async #decode(r: Reader): Promise<Setup> {\n\t\tconst count = await r.u53();\n\t\tlet path: string | undefined;\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tconst id = await r.u53();\n\t\t\tconst len = await r.u53();\n\t\t\tconst value = await r.read(len);\n\t\t\t// Unknown parameters are ignored so new ones stay backward compatible.\n\t\t\tif (id === PARAM_PATH) {\n\t\t\t\tpath = new TextDecoder().decode(value);\n\t\t\t}\n\t\t}\n\t\treturn new Setup({ path });\n\t}\n\n\tasync encode(w: Writer, version: Version): Promise<void> {\n\t\tif (!hasSetupStream(version)) throw new Error(\"SETUP requires moq-lite-05+\");\n\t\treturn Message.encode(w, this.#encode.bind(this));\n\t}\n\n\tstatic async decode(r: Reader, version: Version): Promise<Setup> {\n\t\tif (!hasSetupStream(version)) throw new Error(\"SETUP requires moq-lite-05+\");\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 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"]}
package/lite/stream.d.ts CHANGED
@@ -1,9 +1,10 @@
1
- import type { AnnounceInterest } from "./announce";
1
+ import type { AnnounceRequest } from "./announce";
2
2
  import type { Goaway } from "./goaway";
3
3
  import type { Group } from "./group";
4
4
  import type { SessionClient } from "./session";
5
5
  import type { Subscribe } from "./subscribe";
6
- export type StreamBi = SessionClient | AnnounceInterest | Subscribe | Goaway;
6
+ import type { Track } from "./track";
7
+ export type StreamBi = SessionClient | AnnounceRequest | Subscribe | Track | Goaway;
7
8
  export type StreamUni = Group;
8
9
  export declare const StreamId: {
9
10
  readonly Session: 0;
@@ -16,8 +17,16 @@ export declare const StreamId: {
16
17
  readonly ClientCompat: 32;
17
18
  readonly ServerCompat: 33;
18
19
  };
19
- export declare const DataId: {
20
+ /**
21
+ * The varint type prefix on a unidirectional data stream.
22
+ *
23
+ * `Group` is the per-group frame stream. `Setup` (lite-05+) carries the single SETUP
24
+ * message advertising this endpoint's capabilities.
25
+ */
26
+ export declare const DataType: {
20
27
  readonly Group: 0;
21
28
  readonly Setup: 1;
22
29
  };
30
+ /** A unidirectional data-stream type. See {@link DataType}. */
31
+ export type DataType = (typeof DataType)[keyof typeof DataType];
23
32
  //# sourceMappingURL=stream.d.ts.map