@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,27 +1,54 @@
1
- import type { Signal } from "@norskvideo/moq-signals";
2
- import type { Announced } from "../announced";
3
- import type { Bandwidth } from "../bandwidth";
4
- import type { Broadcast } from "../broadcast";
1
+ import type { Getter } from "@norskvideo/moq-signals";
2
+ import type * as announce from "../announced";
3
+ import type * as broadcast from "../broadcast";
5
4
  import type * as Path from "../path";
6
- import type * as Time from "../time";
5
+ import type { Probe, Stats } from "./stats";
6
+ import type { Transport } from "./transport";
7
7
  /** An established MoQ session, implemented by both the moq-lite and moq-ietf protocols. */
8
8
  export interface Established {
9
9
  /** URL of the connected server. */
10
10
  readonly url: URL;
11
11
  /** Negotiated wire protocol version. */
12
12
  readonly version: string;
13
- /** Estimated send bitrate from the congestion controller (if supported). */
14
- readonly sendBandwidth?: Bandwidth;
15
- /** Estimated receive bitrate from PROBE (moq-lite-03+ only). */
16
- readonly recvBandwidth?: Bandwidth;
17
- /** RTT in milliseconds from PROBE (moq-lite-04+ only). */
18
- readonly rtt?: Signal<Time.Milli | undefined>;
19
- /** Subscribe to broadcast announcements under an optional path prefix. */
20
- announced(prefix?: Path.Valid): Announced;
13
+ /** The wire transport this session runs over. */
14
+ readonly transport: Transport;
15
+ /**
16
+ * Estimates measured by the peer, updated as PROBE messages arrive. Stays empty on
17
+ * versions without PROBE. See {@link Stats} for what the local transport counts.
18
+ */
19
+ readonly probe: Getter<Probe>;
20
+ /**
21
+ * Whether the relay supports broadcast discovery: announcing which broadcasts exist under a
22
+ * prefix. When false, {@link announced} never yields, so a consumer must subscribe blind
23
+ * rather than wait for an announcement. Set via `discovery` on the connect options.
24
+ */
25
+ readonly discovery: boolean;
26
+ /** Subscribe to broadcast announcements under an optional path prefix, returning paths relative to that prefix. */
27
+ announced(prefix?: Path.Valid): announce.Consumer;
21
28
  /** Publish a broadcast at the given path. */
22
- publish(path: Path.Valid, broadcast: Broadcast): void;
23
- /** Consume the broadcast at the given path. */
24
- consume(broadcast: Path.Valid): Broadcast;
29
+ publish(path: Path.Valid, broadcast: broadcast.Producer): void;
30
+ /**
31
+ * Consume the broadcast at the given path, immediately.
32
+ *
33
+ * The subscription is reset if nobody publishes the path, so use
34
+ * {@link announcedBroadcast} instead when the broadcast may not be online yet.
35
+ */
36
+ consume(path: Path.Valid): broadcast.Consumer;
37
+ /**
38
+ * A reactive handle to the broadcast at the given path, live only while it is announced.
39
+ *
40
+ * The announcement-gated counterpart to {@link consume}: it waits for the broadcast to come
41
+ * online instead of resetting, and drops back to `undefined` when it goes away. See
42
+ * {@link announce.Broadcast}. Close the handle when done.
43
+ */
44
+ announcedBroadcast(path: Path.Valid): announce.Broadcast;
45
+ /**
46
+ * Snapshot the transport's counters, querying it fresh on each call.
47
+ *
48
+ * Resolves to an empty snapshot on a transport without `getStats()`. Sample it on
49
+ * whatever schedule you need rather than expecting the library to poll for you.
50
+ */
51
+ stats(): Promise<Stats>;
25
52
  /** Close the session. */
26
53
  close(): void;
27
54
  /** Resolves when the session closes. */
@@ -1 +1 @@
1
- {"version":3,"file":"established.d.ts","sourceRoot":"","sources":["../../src/connection/established.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,KAAK,IAAI,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,KAAK,IAAI,MAAM,YAAY,CAAC;AAExC,2FAA2F;AAC3F,MAAM,WAAW,WAAW;IAC3B,mCAAmC;IACnC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAElB,wCAAwC;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,4EAA4E;IAC5E,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC;IAEnC,gEAAgE;IAChE,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC;IAEnC,0DAA0D;IAC1D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAE9C,0EAA0E;IAC1E,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;IAE1C,6CAA6C;IAC7C,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAEtD,+CAA+C;IAC/C,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;IAE1C,yBAAyB;IACzB,KAAK,IAAI,IAAI,CAAC;IAEd,wCAAwC;IACxC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CACtB"}
1
+ {"version":3,"file":"established.d.ts","sourceRoot":"","sources":["../../src/connection/established.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,KAAK,IAAI,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,2FAA2F;AAC3F,MAAM,WAAW,WAAW;IAC3B,mCAAmC;IACnC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAElB,wCAAwC;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,iDAAiD;IACjD,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAE9B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAE9B;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAE5B,mHAAmH;IACnH,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC;IAElD,6CAA6C;IAC7C,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC,QAAQ,GAAG,IAAI,CAAC;IAE/D;;;;;OAKG;IACH,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC;IAE9C;;;;;;OAMG;IACH,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC;IAEzD;;;;;OAKG;IACH,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC;IAExB,yBAAyB;IACzB,KAAK,IAAI,IAAI,CAAC;IAEd,wCAAwC;IACxC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CACtB"}
@@ -1 +1 @@
1
- {"version":3,"file":"established.js","sourceRoot":"","sources":["../../src/connection/established.ts"],"names":[],"mappings":"","sourcesContent":["import type { Signal } from \"@moq/signals\";\nimport type { Announced } from \"../announced.ts\";\nimport type { Bandwidth } from \"../bandwidth.ts\";\nimport type { Broadcast } from \"../broadcast.ts\";\nimport type * as Path from \"../path.ts\";\nimport type * as Time from \"../time.ts\";\n\n/** An established MoQ session, implemented by both the moq-lite and moq-ietf protocols. */\nexport interface Established {\n\t/** URL of the connected server. */\n\treadonly url: URL;\n\n\t/** Negotiated wire protocol version. */\n\treadonly version: string;\n\n\t/** Estimated send bitrate from the congestion controller (if supported). */\n\treadonly sendBandwidth?: Bandwidth;\n\n\t/** Estimated receive bitrate from PROBE (moq-lite-03+ only). */\n\treadonly recvBandwidth?: Bandwidth;\n\n\t/** RTT in milliseconds from PROBE (moq-lite-04+ only). */\n\treadonly rtt?: Signal<Time.Milli | undefined>;\n\n\t/** Subscribe to broadcast announcements under an optional path prefix. */\n\tannounced(prefix?: Path.Valid): Announced;\n\n\t/** Publish a broadcast at the given path. */\n\tpublish(path: Path.Valid, broadcast: Broadcast): void;\n\n\t/** Consume the broadcast at the given path. */\n\tconsume(broadcast: Path.Valid): Broadcast;\n\n\t/** Close the session. */\n\tclose(): void;\n\n\t/** Resolves when the session closes. */\n\tclosed: Promise<void>;\n}\n"]}
1
+ {"version":3,"file":"established.js","sourceRoot":"","sources":["../../src/connection/established.ts"],"names":[],"mappings":"","sourcesContent":["import type { Getter } from \"@moq/signals\";\nimport type * as announce from \"../announced.ts\";\nimport type * as broadcast from \"../broadcast.ts\";\nimport type * as Path from \"../path.ts\";\nimport type { Probe, Stats } from \"./stats.ts\";\nimport type { Transport } from \"./transport.ts\";\n\n/** An established MoQ session, implemented by both the moq-lite and moq-ietf protocols. */\nexport interface Established {\n\t/** URL of the connected server. */\n\treadonly url: URL;\n\n\t/** Negotiated wire protocol version. */\n\treadonly version: string;\n\n\t/** The wire transport this session runs over. */\n\treadonly transport: Transport;\n\n\t/**\n\t * Estimates measured by the peer, updated as PROBE messages arrive. Stays empty on\n\t * versions without PROBE. See {@link Stats} for what the local transport counts.\n\t */\n\treadonly probe: Getter<Probe>;\n\n\t/**\n\t * Whether the relay supports broadcast discovery: announcing which broadcasts exist under a\n\t * prefix. When false, {@link announced} never yields, so a consumer must subscribe blind\n\t * rather than wait for an announcement. Set via `discovery` on the connect options.\n\t */\n\treadonly discovery: boolean;\n\n\t/** Subscribe to broadcast announcements under an optional path prefix, returning paths relative to that prefix. */\n\tannounced(prefix?: Path.Valid): announce.Consumer;\n\n\t/** Publish a broadcast at the given path. */\n\tpublish(path: Path.Valid, broadcast: broadcast.Producer): void;\n\n\t/**\n\t * Consume the broadcast at the given path, immediately.\n\t *\n\t * The subscription is reset if nobody publishes the path, so use\n\t * {@link announcedBroadcast} instead when the broadcast may not be online yet.\n\t */\n\tconsume(path: Path.Valid): broadcast.Consumer;\n\n\t/**\n\t * A reactive handle to the broadcast at the given path, live only while it is announced.\n\t *\n\t * The announcement-gated counterpart to {@link consume}: it waits for the broadcast to come\n\t * online instead of resetting, and drops back to `undefined` when it goes away. See\n\t * {@link announce.Broadcast}. Close the handle when done.\n\t */\n\tannouncedBroadcast(path: Path.Valid): announce.Broadcast;\n\n\t/**\n\t * Snapshot the transport's counters, querying it fresh on each call.\n\t *\n\t * Resolves to an empty snapshot on a transport without `getStats()`. Sample it on\n\t * whatever schedule you need rather than expecting the library to poll for you.\n\t */\n\tstats(): Promise<Stats>;\n\n\t/** Close the session. */\n\tclose(): void;\n\n\t/** Resolves when the session closes. */\n\tclosed: Promise<void>;\n}\n"]}
@@ -5,6 +5,17 @@ import { Stream } from "../stream";
5
5
  * message, and reads the peer's Setup off an incoming uni stream. The two
6
6
  * halves run in parallel and the protocol is symmetric, so both `connect`
7
7
  * (client) and `accept` (server) use this same function.
8
+ *
9
+ * Returns the control stream plus what the peer's SETUP declared: whether it requires
10
+ * solicitation, which decides whether we announce namespaces unprompted (see the MoQ Solicit
11
+ * extension), and its Hop ID (see the MoQ Cluster extension). We declare both ourselves on
12
+ * every session: we send SUBSCRIBE_NAMESPACE for each prefix we want, so an unsolicited
13
+ * advertisement can tell us nothing we won't have asked for, and a peer that knows our Hop
14
+ * ID can withhold the advertisements that already flowed through us.
8
15
  */
9
- export declare function exchangeSetup(transport: WebTransport, version: Ietf.IetfVersion, implementation: string): Promise<Stream>;
16
+ export declare function exchangeSetup(transport: WebTransport, version: Ietf.IetfVersion, implementation: string): Promise<{
17
+ control: Stream;
18
+ solicit: boolean | undefined;
19
+ cluster: Ietf.Cluster.Hops;
20
+ }>;
10
21
  //# sourceMappingURL=handshake.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"handshake.d.ts","sourceRoot":"","sources":["../../src/connection/handshake.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAU,MAAM,EAAU,MAAM,cAAc,CAAC;AAEtD;;;;;GAKG;AACH,wBAAsB,aAAa,CAClC,SAAS,EAAE,YAAY,EACvB,OAAO,EAAE,IAAI,CAAC,WAAW,EACzB,cAAc,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC,CAiBjB"}
1
+ {"version":3,"file":"handshake.d.ts","sourceRoot":"","sources":["../../src/connection/handshake.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,kBAAkB,CAAC;AAEzC,OAAO,EAAU,MAAM,EAAU,MAAM,cAAc,CAAC;AAEtD;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CAClC,SAAS,EAAE,YAAY,EACvB,OAAO,EAAE,IAAI,CAAC,WAAW,EACzB,cAAc,EAAE,MAAM,GACpB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAA;CAAE,CAAC,CAuBxF"}
@@ -1,34 +1,47 @@
1
1
  /* @ts-self-types="./handshake.d.ts" */
2
2
  import * as Ietf from "../ietf/index.js";
3
+ import { randomOrigin } from "../origin.js";
3
4
  import { Reader, Stream, Writer } from "../stream.js";
4
5
  /**
5
6
  * Draft-17+ SETUP exchange. Each side opens a uni stream, writes its Setup
6
7
  * message, and reads the peer's Setup off an incoming uni stream. The two
7
8
  * halves run in parallel and the protocol is symmetric, so both `connect`
8
9
  * (client) and `accept` (server) use this same function.
10
+ *
11
+ * Returns the control stream plus what the peer's SETUP declared: whether it requires
12
+ * solicitation, which decides whether we announce namespaces unprompted (see the MoQ Solicit
13
+ * extension), and its Hop ID (see the MoQ Cluster extension). We declare both ourselves on
14
+ * every session: we send SUBSCRIBE_NAMESPACE for each prefix we want, so an unsolicited
15
+ * advertisement can tell us nothing we won't have asked for, and a peer that knows our Hop
16
+ * ID can withhold the advertisements that already flowed through us.
9
17
  */
10
18
  export async function exchangeSetup(transport, version, implementation) {
11
19
  const encoder = new TextEncoder();
12
20
  const params = new Ietf.SetupOptions();
13
21
  params.setBytes(Ietf.SetupOption.Implementation, encoder.encode(implementation));
22
+ Ietf.solicitIntoSetup(params);
23
+ // One id per session, like the moq-lite connection: nothing in this process forwards
24
+ // between sessions, so there is nothing for a shared id to detect.
25
+ const self = randomOrigin();
26
+ Ietf.Cluster.intoSetup(params, self, version);
14
27
  const setupMsg = new Ietf.Setup({ parameters: params });
15
- const [sent, received] = await Promise.all([
28
+ const [writer, received] = await Promise.all([
16
29
  sendSetup(transport, version, setupMsg),
17
30
  receiveSetup(transport, version),
18
31
  ]);
19
- return new Stream({
20
- writable: sent.writable,
21
- readable: received.readable,
22
- writer: sent.writer,
23
- reader: received.reader,
24
- });
32
+ return {
33
+ control: new Stream({ writer, reader: received.reader }),
34
+ solicit: received.solicit,
35
+ cluster: { self, peer: received.cluster },
36
+ };
25
37
  }
26
38
  async function sendSetup(transport, version, setupMsg) {
27
- const writable = (await transport.createUnidirectionalStream());
28
- const writer = new Writer(writable, version);
39
+ // Via Writer.open for its deadline: a peer can advertise a stream limit of zero and
40
+ // never raise it, which would otherwise hang the handshake rather than failing it.
41
+ const writer = await Writer.open(transport, { version });
29
42
  await writer.u53(Ietf.Setup.id); // 0x2F00 stream type
30
43
  await setupMsg.encode(writer, version);
31
- return { writable, writer };
44
+ return writer;
32
45
  }
33
46
  async function receiveSetup(transport, version) {
34
47
  const uniReader = transport.incomingUnidirectionalStreams.getReader();
@@ -36,13 +49,16 @@ async function receiveSetup(transport, version) {
36
49
  uniReader.releaseLock();
37
50
  if (next.done)
38
51
  throw new Error("no incoming uni stream for SETUP");
39
- const readable = next.value;
40
- const reader = new Reader(readable, undefined, version);
52
+ const reader = new Reader(next.value, undefined, version);
41
53
  const streamType = await reader.u53();
42
54
  if (streamType !== Ietf.Setup.id) {
43
55
  throw new Error(`unexpected stream type on setup uni: 0x${streamType.toString(16)}`);
44
56
  }
45
- await Ietf.Setup.decode(reader, version);
46
- return { readable, reader };
57
+ const setup = await Ietf.Setup.decode(reader, version);
58
+ return {
59
+ reader,
60
+ solicit: Ietf.solicitFromSetup(setup.parameters),
61
+ cluster: Ietf.Cluster.fromSetup(setup.parameters, version),
62
+ };
47
63
  }
48
64
  //# sourceMappingURL=handshake.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"handshake.js","sourceRoot":"","sources":["../../src/connection/handshake.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAClC,SAAuB,EACvB,OAAyB,EACzB,cAAsB;IAEtB,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;IACvC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC;IACjF,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;IAExD,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC1C,SAAS,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC;QACvC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC;KAChC,CAAC,CAAC;IAEH,OAAO,IAAI,MAAM,CAAC;QACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,MAAM,EAAE,QAAQ,CAAC,MAAM;KACvB,CAAC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,SAAS,CACvB,SAAuB,EACvB,OAAyB,EACzB,QAAoB;IAEpB,MAAM,QAAQ,GAAG,CAAC,MAAM,SAAS,CAAC,0BAA0B,EAAE,CAA+B,CAAC;IAC9F,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC7C,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,qBAAqB;IACtD,MAAM,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAC7B,CAAC;AAED,KAAK,UAAU,YAAY,CAC1B,SAAuB,EACvB,OAAyB;IAEzB,MAAM,SAAS,GAAG,SAAS,CAAC,6BAA6B,CAAC,SAAS,EAElE,CAAC;IACF,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;IACpC,SAAS,CAAC,WAAW,EAAE,CAAC;IACxB,IAAI,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IAEnE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC;IAC5B,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAExD,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;IACtC,IAAI,UAAU,KAAK,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,0CAA0C,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACtF,CAAC;IACD,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEzC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAC7B,CAAC","sourcesContent":["import * as Ietf from \"../ietf/index.ts\";\nimport { Reader, Stream, Writer } from \"../stream.ts\";\n\n/**\n * Draft-17+ SETUP exchange. Each side opens a uni stream, writes its Setup\n * message, and reads the peer's Setup off an incoming uni stream. The two\n * halves run in parallel and the protocol is symmetric, so both `connect`\n * (client) and `accept` (server) use this same function.\n */\nexport async function exchangeSetup(\n\ttransport: WebTransport,\n\tversion: Ietf.IetfVersion,\n\timplementation: string,\n): Promise<Stream> {\n\tconst encoder = new TextEncoder();\n\tconst params = new Ietf.SetupOptions();\n\tparams.setBytes(Ietf.SetupOption.Implementation, encoder.encode(implementation));\n\tconst setupMsg = new Ietf.Setup({ parameters: params });\n\n\tconst [sent, received] = await Promise.all([\n\t\tsendSetup(transport, version, setupMsg),\n\t\treceiveSetup(transport, version),\n\t]);\n\n\treturn new Stream({\n\t\twritable: sent.writable,\n\t\treadable: received.readable,\n\t\twriter: sent.writer,\n\t\treader: received.reader,\n\t});\n}\n\nasync function sendSetup(\n\ttransport: WebTransport,\n\tversion: Ietf.IetfVersion,\n\tsetupMsg: Ietf.Setup,\n): Promise<{ writable: WritableStream<Uint8Array>; writer: Writer }> {\n\tconst writable = (await transport.createUnidirectionalStream()) as WritableStream<Uint8Array>;\n\tconst writer = new Writer(writable, version);\n\tawait writer.u53(Ietf.Setup.id); // 0x2F00 stream type\n\tawait setupMsg.encode(writer, version);\n\treturn { writable, writer };\n}\n\nasync function receiveSetup(\n\ttransport: WebTransport,\n\tversion: Ietf.IetfVersion,\n): Promise<{ readable: ReadableStream<Uint8Array>; reader: Reader }> {\n\tconst uniReader = transport.incomingUnidirectionalStreams.getReader() as ReadableStreamDefaultReader<\n\t\tReadableStream<Uint8Array>\n\t>;\n\tconst next = await uniReader.read();\n\tuniReader.releaseLock();\n\tif (next.done) throw new Error(\"no incoming uni stream for SETUP\");\n\n\tconst readable = next.value;\n\tconst reader = new Reader(readable, undefined, version);\n\n\tconst streamType = await reader.u53();\n\tif (streamType !== Ietf.Setup.id) {\n\t\tthrow new Error(`unexpected stream type on setup uni: 0x${streamType.toString(16)}`);\n\t}\n\tawait Ietf.Setup.decode(reader, version);\n\n\treturn { readable, reader };\n}\n"]}
1
+ {"version":3,"file":"handshake.js","sourceRoot":"","sources":["../../src/connection/handshake.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAe,YAAY,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAClC,SAAuB,EACvB,OAAyB,EACzB,cAAsB;IAEtB,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;IACvC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC;IACjF,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAE9B,qFAAqF;IACrF,mEAAmE;IACnE,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;IAC5B,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAE9C,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;IAExD,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC5C,SAAS,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC;QACvC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC;KAChC,CAAC,CAAC;IAEH,OAAO;QACN,OAAO,EAAE,IAAI,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;QACxD,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,OAAO,EAAE;KACzC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,SAAuB,EAAE,OAAyB,EAAE,QAAoB;IAChG,oFAAoF;IACpF,mFAAmF;IACnF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IACzD,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,qBAAqB;IACtD,MAAM,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,OAAO,MAAM,CAAC;AACf,CAAC;AAED,KAAK,UAAU,YAAY,CAC1B,SAAuB,EACvB,OAAyB;IAEzB,MAAM,SAAS,GAAG,SAAS,CAAC,6BAA6B,CAAC,SAAS,EAElE,CAAC;IACF,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;IACpC,SAAS,CAAC,WAAW,EAAE,CAAC;IACxB,IAAI,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IAEnE,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAE1D,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;IACtC,IAAI,UAAU,KAAK,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,0CAA0C,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACtF,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEvD,OAAO;QACN,MAAM;QACN,OAAO,EAAE,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,UAAU,CAAC;QAChD,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,EAAE,OAAO,CAAC;KAC1D,CAAC;AACH,CAAC","sourcesContent":["import * as Ietf from \"../ietf/index.ts\";\nimport { type Origin, randomOrigin } from \"../origin.ts\";\nimport { Reader, Stream, Writer } from \"../stream.ts\";\n\n/**\n * Draft-17+ SETUP exchange. Each side opens a uni stream, writes its Setup\n * message, and reads the peer's Setup off an incoming uni stream. The two\n * halves run in parallel and the protocol is symmetric, so both `connect`\n * (client) and `accept` (server) use this same function.\n *\n * Returns the control stream plus what the peer's SETUP declared: whether it requires\n * solicitation, which decides whether we announce namespaces unprompted (see the MoQ Solicit\n * extension), and its Hop ID (see the MoQ Cluster extension). We declare both ourselves on\n * every session: we send SUBSCRIBE_NAMESPACE for each prefix we want, so an unsolicited\n * advertisement can tell us nothing we won't have asked for, and a peer that knows our Hop\n * ID can withhold the advertisements that already flowed through us.\n */\nexport async function exchangeSetup(\n\ttransport: WebTransport,\n\tversion: Ietf.IetfVersion,\n\timplementation: string,\n): Promise<{ control: Stream; solicit: boolean | undefined; cluster: Ietf.Cluster.Hops }> {\n\tconst encoder = new TextEncoder();\n\tconst params = new Ietf.SetupOptions();\n\tparams.setBytes(Ietf.SetupOption.Implementation, encoder.encode(implementation));\n\tIetf.solicitIntoSetup(params);\n\n\t// One id per session, like the moq-lite connection: nothing in this process forwards\n\t// between sessions, so there is nothing for a shared id to detect.\n\tconst self = randomOrigin();\n\tIetf.Cluster.intoSetup(params, self, version);\n\n\tconst setupMsg = new Ietf.Setup({ parameters: params });\n\n\tconst [writer, received] = await Promise.all([\n\t\tsendSetup(transport, version, setupMsg),\n\t\treceiveSetup(transport, version),\n\t]);\n\n\treturn {\n\t\tcontrol: new Stream({ writer, reader: received.reader }),\n\t\tsolicit: received.solicit,\n\t\tcluster: { self, peer: received.cluster },\n\t};\n}\n\nasync function sendSetup(transport: WebTransport, version: Ietf.IetfVersion, setupMsg: Ietf.Setup): Promise<Writer> {\n\t// Via Writer.open for its deadline: a peer can advertise a stream limit of zero and\n\t// never raise it, which would otherwise hang the handshake rather than failing it.\n\tconst writer = await Writer.open(transport, { version });\n\tawait writer.u53(Ietf.Setup.id); // 0x2F00 stream type\n\tawait setupMsg.encode(writer, version);\n\treturn writer;\n}\n\nasync function receiveSetup(\n\ttransport: WebTransport,\n\tversion: Ietf.IetfVersion,\n): Promise<{ reader: Reader; solicit: boolean | undefined; cluster: Origin | undefined }> {\n\tconst uniReader = transport.incomingUnidirectionalStreams.getReader() as ReadableStreamDefaultReader<\n\t\tReadableStream<Uint8Array>\n\t>;\n\tconst next = await uniReader.read();\n\tuniReader.releaseLock();\n\tif (next.done) throw new Error(\"no incoming uni stream for SETUP\");\n\n\tconst reader = new Reader(next.value, undefined, version);\n\n\tconst streamType = await reader.u53();\n\tif (streamType !== Ietf.Setup.id) {\n\t\tthrow new Error(`unexpected stream type on setup uni: 0x${streamType.toString(16)}`);\n\t}\n\tconst setup = await Ietf.Setup.decode(reader, version);\n\n\treturn {\n\t\treader,\n\t\tsolicit: Ietf.solicitFromSetup(setup.parameters),\n\t\tcluster: Ietf.Cluster.fromSetup(setup.parameters, version),\n\t};\n}\n"]}
@@ -1,5 +1,13 @@
1
+ /**
2
+ * Connection helpers: connect to or accept a MoQ session and reconnect on failure.
3
+ *
4
+ * @module
5
+ */
1
6
  export * from "./accept";
7
+ export { isWebTransportSupported } from "./browser";
2
8
  export * from "./connect";
3
9
  export * from "./established";
4
10
  export * from "./reload";
11
+ export type { Probe, Stats } from "./stats";
12
+ export type { Transport } from "./transport";
5
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/connection/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/connection/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC/C,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
@@ -1,5 +1,11 @@
1
1
  /* @ts-self-types="./index.d.ts" */
2
+ /**
3
+ * Connection helpers: connect to or accept a MoQ session and reconnect on failure.
4
+ *
5
+ * @module
6
+ */
2
7
  export * from "./accept.js";
8
+ export { isWebTransportSupported } from "./browser.js";
3
9
  export * from "./connect.js";
4
10
  export * from "./established.js";
5
11
  export * from "./reload.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/connection/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC","sourcesContent":["export * from \"./accept.ts\";\nexport * from \"./connect.ts\";\nexport * from \"./established.ts\";\nexport * from \"./reload.ts\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/connection/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC","sourcesContent":["/**\n * Connection helpers: connect to or accept a MoQ session and reconnect on failure.\n *\n * @module\n */\nexport * from \"./accept.ts\";\nexport { isWebTransportSupported } from \"./browser.ts\";\nexport * from \"./connect.ts\";\nexport * from \"./established.ts\";\nexport * from \"./reload.ts\";\nexport type { Probe, Stats } from \"./stats.ts\";\nexport type { Transport } from \"./transport.ts\";\n"]}
@@ -1,18 +1,35 @@
1
- import { Effect, type Getter, Signal } from "@norskvideo/moq-signals";
1
+ import { type Getter, Signal } from "@norskvideo/moq-signals";
2
+ import * as Announce from "../announced";
2
3
  import type * as Path from "../path";
3
4
  import { type ConnectProps, type WebSocketOptions, type WebTransportProps } from "./connect";
4
5
  import type { Established } from "./established";
5
- /** Exponential backoff settings for {@link Reload}'s reconnect loop. */
6
+ import type { Probe, Stats } from "./stats";
7
+ /**
8
+ * Exponential backoff settings for {@link Reload}'s reconnect loop.
9
+ *
10
+ * The delays carry jitter, so a fleet of tabs knocked offline together doesn't reconnect in
11
+ * lockstep. Every failure is retried; {@link ReloadDelay.timeout} is what stops the loop.
12
+ */
6
13
  export type ReloadDelay = {
14
+ /** The delay in milliseconds before reconnecting (default: 1000). */
7
15
  initial: DOMHighResTimeStamp;
16
+ /** The multiplier for the delay (default: 2). */
8
17
  multiplier: number;
18
+ /** The maximum delay in milliseconds (default: 5000). */
9
19
  max: DOMHighResTimeStamp;
20
+ /**
21
+ * Maximum total time in milliseconds to spend retrying before giving up (default:
22
+ * 10000). Resets after each successful connection. Set to 0 for unlimited retries.
23
+ */
10
24
  timeout?: DOMHighResTimeStamp;
11
25
  };
12
- /** Options for {@link Reload}: connect options plus reactive URL/enabled signals and backoff tuning. */
13
- export type ReloadProps = ConnectProps & {
26
+ /** Connection and retry options for {@link Reload}. */
27
+ export type ReloadProps = Omit<ConnectProps, "signal"> & {
28
+ /** Whether to reload the connection when it disconnects (default: true). */
14
29
  enabled?: boolean | Signal<boolean>;
30
+ /** The URL of the relay server. */
15
31
  url?: URL | Signal<URL | undefined>;
32
+ /** Backoff settings for the reconnect loop. */
16
33
  delay?: ReloadDelay;
17
34
  };
18
35
  /** Current state of a {@link Reload} connection. */
@@ -28,19 +45,59 @@ export declare class Reload {
28
45
  status: Signal<ReloadStatus>;
29
46
  /** The currently established session, or undefined while disconnected. */
30
47
  established: Signal<Established | undefined>;
31
- /** The set of broadcast paths currently announced by the server, updated reactively. */
32
- readonly announced: Getter<Set<Path.Valid>>;
48
+ /**
49
+ * The current connection's PROBE estimates, spanning reconnects.
50
+ *
51
+ * Undefined while disconnected: the estimates belong to a single connection.
52
+ * See {@link Established.probe}.
53
+ */
54
+ readonly probe: Getter<Probe | undefined>;
33
55
  /** WebTransport options applied to each connection attempt (not reactive). */
34
56
  webtransport?: WebTransportProps;
35
57
  /** WebSocket fallback options applied to each connection attempt (not reactive). */
36
58
  websocket: WebSocketOptions | undefined;
59
+ /**
60
+ * Whether the relay supports broadcast discovery, applied to each connection attempt (not
61
+ * reactive). Undefined defers to the default for the URL. See {@link Established.discovery}.
62
+ */
63
+ discovery?: boolean;
37
64
  /** Backoff settings for the reconnect loop. */
38
65
  delay: ReloadDelay;
39
- /** The reactive effect scope driving the connect loop; closed by {@link Reload.close}. */
40
- signals: Effect;
41
- /** Resolves when the reconnect loop stops via {@link Reload.close} or the retry timeout. */
66
+ /**
67
+ * Resolves when the reconnect loop stops via {@link Reload.close}.
68
+ *
69
+ * Rejects when the loop gives up instead, carrying the failure that was in flight when the
70
+ * retry window expired.
71
+ */
42
72
  closed: Promise<void>;
43
73
  constructor(props?: ReloadProps);
74
+ /**
75
+ * Subscribe to broadcast announcements under an optional prefix, spanning reconnects.
76
+ *
77
+ * The same {@link Announce.Consumer} stream as {@link Established.announced}, but everything active
78
+ * is retracted (an `active: false` update) whenever the connection drops and re-announced on
79
+ * reconnect, so a consumer draining `next()` never clings to a dead route across a reconnect.
80
+ *
81
+ * Stays empty while the relay lacks {@link Established.discovery}.
82
+ */
83
+ announced(prefix?: Path.Valid): Announce.Consumer;
84
+ /**
85
+ * A reactive handle to one broadcast, spanning reconnects.
86
+ *
87
+ * The same {@link Announce.Broadcast} as {@link Established.announcedBroadcast}, but it
88
+ * follows the reconnect loop: the broadcast drops to `undefined` when the connection dies
89
+ * and resolves again once the new connection announces the path. Use it instead of
90
+ * consuming off {@link Reload.established} whenever the broadcast may come online after you
91
+ * do, which is exactly the case a blind `consume` loses.
92
+ *
93
+ * Close the handle when done; {@link Reload.close} only drops it to `undefined`.
94
+ */
95
+ announcedBroadcast(path: Path.Valid): Announce.Broadcast;
96
+ /**
97
+ * Snapshot the live connection's transport counters, or undefined while disconnected.
98
+ * See {@link Established.stats}.
99
+ */
100
+ stats(): Promise<Stats | undefined>;
44
101
  /** Stop reconnecting, close the current connection, and resolve {@link Reload.closed}. */
45
102
  close(): void;
46
103
  }
@@ -1 +1 @@
1
- {"version":3,"file":"reload.d.ts","sourceRoot":"","sources":["../../src/connection/reload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,KAAK,IAAI,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,KAAK,YAAY,EAAW,KAAK,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACzG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,wEAAwE;AACxE,MAAM,MAAM,WAAW,GAAG;IAGzB,OAAO,EAAE,mBAAmB,CAAC;IAI7B,UAAU,EAAE,MAAM,CAAC;IAInB,GAAG,EAAE,mBAAmB,CAAC;IAKzB,OAAO,CAAC,EAAE,mBAAmB,CAAC;CAC9B,CAAC;AAEF,wGAAwG;AACxG,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG;IAGxC,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAGpC,GAAG,CAAC,EAAE,GAAG,GAAG,MAAM,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC;IAGpC,KAAK,CAAC,EAAE,WAAW,CAAC;CACpB,CAAC;AAEF,oDAAoD;AACpD,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,WAAW,GAAG,cAAc,CAAC;AAEvE,uFAAuF;AACvF,qBAAa,MAAM;;IAClB,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC;IAE7B,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAEzB,iCAAiC;IACjC,MAAM,uBAA4C;IAElD,0EAA0E;IAC1E,WAAW,kCAAkD;IAK7D,wFAAwF;IACxF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAmB;IAE9D,8EAA8E;IAC9E,YAAY,CAAC,EAAE,iBAAiB,CAAC;IAEjC,oFAAoF;IACpF,SAAS,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAExC,+CAA+C;IAC/C,KAAK,EAAE,WAAW,CAAC;IAEnB,0FAA0F;IAC1F,OAAO,SAAgB;IAEvB,4FAA4F;IAC5F,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAgBtB,YAAY,KAAK,CAAC,EAAE,WAAW,EAmB9B;IAiGD,0FAA0F;IAC1F,KAAK,SAGJ;CACD"}
1
+ {"version":3,"file":"reload.d.ts","sourceRoot":"","sources":["../../src/connection/reload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,KAAK,IAAI,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,KAAK,YAAY,EAAW,KAAK,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACzG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG;IACzB,qEAAqE;IACrE,OAAO,EAAE,mBAAmB,CAAC;IAE7B,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;IAEnB,yDAAyD;IACzD,GAAG,EAAE,mBAAmB,CAAC;IAEzB;;;OAGG;IACH,OAAO,CAAC,EAAE,mBAAmB,CAAC;CAC9B,CAAC;AAEF,uDAAuD;AACvD,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,GAAG;IACxD,4EAA4E;IAC5E,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAEpC,mCAAmC;IACnC,GAAG,CAAC,EAAE,GAAG,GAAG,MAAM,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC;IAEpC,+CAA+C;IAC/C,KAAK,CAAC,EAAE,WAAW,CAAC;CACpB,CAAC;AAUF,oDAAoD;AACpD,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,WAAW,GAAG,cAAc,CAAC;AAEvE,uFAAuF;AACvF,qBAAa,MAAM;;IAClB,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC;IAE7B,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAEzB,iCAAiC;IACjC,MAAM,uBAA4C;IAElD,0EAA0E;IAC1E,WAAW,kCAAkD;IAE7D;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAE1C,8EAA8E;IAC9E,YAAY,CAAC,EAAE,iBAAiB,CAAC;IAEjC,oFAAoF;IACpF,SAAS,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAExC;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,+CAA+C;IAC/C,KAAK,EAAE,WAAW,CAAC;IAKnB;;;;;OAKG;IACH,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAkBtB,YAAY,KAAK,CAAC,EAAE,WAAW,EAmC9B;IAmGD;;;;;;;;OAQG;IACH,SAAS,CAAC,MAAM,GAAE,IAAI,CAAC,KAAmB,GAAG,QAAQ,CAAC,QAAQ,CAoD7D;IAED;;;;;;;;;;OAUG;IACH,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,SAAS,CAEvD;IAED;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAExC;IAED,0FAA0F;IAC1F,KAAK,SAGJ;CACD"}