@norskvideo/moq-net 0.1.7 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (286) hide show
  1. package/README.md +2 -2
  2. package/announce.d.ts +7 -0
  3. package/announce.d.ts.map +1 -0
  4. package/announce.js +8 -0
  5. package/announce.js.map +1 -0
  6. package/announced.d.ts +49 -91
  7. package/announced.d.ts.map +1 -1
  8. package/announced.js +21 -156
  9. package/announced.js.map +1 -1
  10. package/bandwidth.d.ts +163 -0
  11. package/bandwidth.d.ts.map +1 -0
  12. package/bandwidth.js +304 -0
  13. package/bandwidth.js.map +1 -0
  14. package/bandwidth_api.d.ts +7 -0
  15. package/bandwidth_api.d.ts.map +1 -0
  16. package/bandwidth_api.js +8 -0
  17. package/bandwidth_api.js.map +1 -0
  18. package/broadcast.d.ts +44 -35
  19. package/broadcast.d.ts.map +1 -1
  20. package/broadcast.js +104 -60
  21. package/broadcast.js.map +1 -1
  22. package/connection/accept.d.ts +16 -1
  23. package/connection/accept.d.ts.map +1 -1
  24. package/connection/accept.js +52 -28
  25. package/connection/accept.js.map +1 -1
  26. package/connection/browser.d.ts.map +1 -1
  27. package/connection/browser.js +9 -7
  28. package/connection/browser.js.map +1 -1
  29. package/connection/connect.d.ts +30 -6
  30. package/connection/connect.d.ts.map +1 -1
  31. package/connection/connect.js +110 -54
  32. package/connection/connect.js.map +1 -1
  33. package/connection/established.d.ts +17 -21
  34. package/connection/established.d.ts.map +1 -1
  35. package/connection/established.js.map +1 -1
  36. package/connection/forward.d.ts +2 -0
  37. package/connection/forward.d.ts.map +1 -0
  38. package/connection/forward.js +173 -0
  39. package/connection/forward.js.map +1 -0
  40. package/connection/handshake.d.ts +1 -0
  41. package/connection/handshake.d.ts.map +1 -1
  42. package/connection/handshake.js +5 -2
  43. package/connection/handshake.js.map +1 -1
  44. package/connection/index.d.ts +5 -5
  45. package/connection/index.d.ts.map +1 -1
  46. package/connection/index.js +4 -5
  47. package/connection/index.js.map +1 -1
  48. package/connection/pool.d.ts +186 -0
  49. package/connection/pool.d.ts.map +1 -0
  50. package/connection/pool.js +361 -0
  51. package/connection/pool.js.map +1 -0
  52. package/connection/reload.d.ts +14 -93
  53. package/connection/reload.d.ts.map +1 -1
  54. package/connection/reload.js +217 -81
  55. package/connection/reload.js.map +1 -1
  56. package/connection/stats.d.ts +3 -26
  57. package/connection/stats.d.ts.map +1 -1
  58. package/connection/stats.js.map +1 -1
  59. package/connection/transport.d.ts +0 -7
  60. package/connection/transport.d.ts.map +1 -1
  61. package/consume.d.ts +1 -43
  62. package/consume.d.ts.map +1 -1
  63. package/consume.js +1 -1
  64. package/consume.js.map +1 -1
  65. package/error.d.ts +180 -29
  66. package/error.d.ts.map +1 -1
  67. package/error.js +331 -16
  68. package/error.js.map +1 -1
  69. package/errors.d.ts +7 -0
  70. package/errors.d.ts.map +1 -0
  71. package/errors.js +8 -0
  72. package/errors.js.map +1 -0
  73. package/group.d.ts +9 -43
  74. package/group.d.ts.map +1 -1
  75. package/group.js +284 -69
  76. package/group.js.map +1 -1
  77. package/hop.d.ts +115 -0
  78. package/hop.d.ts.map +1 -0
  79. package/hop.js +119 -0
  80. package/hop.js.map +1 -0
  81. package/ietf/adapter.d.ts +5 -1
  82. package/ietf/adapter.d.ts.map +1 -1
  83. package/ietf/adapter.js +105 -60
  84. package/ietf/adapter.js.map +1 -1
  85. package/ietf/aliases.d.ts +1 -78
  86. package/ietf/aliases.d.ts.map +1 -1
  87. package/ietf/cluster.d.ts +9 -123
  88. package/ietf/cluster.d.ts.map +1 -1
  89. package/ietf/cluster.js +84 -44
  90. package/ietf/cluster.js.map +1 -1
  91. package/ietf/connection.d.ts +6 -72
  92. package/ietf/connection.d.ts.map +1 -1
  93. package/ietf/connection.js +62 -56
  94. package/ietf/connection.js.map +1 -1
  95. package/ietf/error.d.ts +11 -0
  96. package/ietf/error.d.ts.map +1 -0
  97. package/ietf/error.js +193 -0
  98. package/ietf/error.js.map +1 -0
  99. package/ietf/fetch.d.ts +7 -20
  100. package/ietf/fetch.d.ts.map +1 -1
  101. package/ietf/fetch.js +52 -22
  102. package/ietf/fetch.js.map +1 -1
  103. package/ietf/filter.d.ts +2 -0
  104. package/ietf/filter.d.ts.map +1 -1
  105. package/ietf/filter.js +10 -1
  106. package/ietf/filter.js.map +1 -1
  107. package/ietf/goaway.d.ts.map +1 -1
  108. package/ietf/goaway.js +22 -5
  109. package/ietf/goaway.js.map +1 -1
  110. package/ietf/hidden.d.ts +2 -0
  111. package/ietf/hidden.d.ts.map +1 -0
  112. package/ietf/hidden.js +30 -0
  113. package/ietf/hidden.js.map +1 -0
  114. package/ietf/index.d.ts +2 -0
  115. package/ietf/index.d.ts.map +1 -1
  116. package/ietf/index.js +2 -0
  117. package/ietf/index.js.map +1 -1
  118. package/ietf/object.d.ts +15 -8
  119. package/ietf/object.d.ts.map +1 -1
  120. package/ietf/object.js +51 -36
  121. package/ietf/object.js.map +1 -1
  122. package/ietf/parameters.d.ts +14 -2
  123. package/ietf/parameters.d.ts.map +1 -1
  124. package/ietf/parameters.js +97 -29
  125. package/ietf/parameters.js.map +1 -1
  126. package/ietf/properties.d.ts +1 -0
  127. package/ietf/properties.d.ts.map +1 -1
  128. package/ietf/properties.js +14 -0
  129. package/ietf/properties.js.map +1 -1
  130. package/ietf/publish.d.ts +19 -2
  131. package/ietf/publish.d.ts.map +1 -1
  132. package/ietf/publish.js +40 -6
  133. package/ietf/publish.js.map +1 -1
  134. package/ietf/publish_namespace.d.ts +25 -0
  135. package/ietf/publish_namespace.d.ts.map +1 -1
  136. package/ietf/publish_namespace.js +63 -0
  137. package/ietf/publish_namespace.js.map +1 -1
  138. package/ietf/publisher.d.ts +1 -82
  139. package/ietf/publisher.d.ts.map +1 -1
  140. package/ietf/publisher.js +483 -235
  141. package/ietf/publisher.js.map +1 -1
  142. package/ietf/solicit.d.ts +1 -40
  143. package/ietf/solicit.d.ts.map +1 -1
  144. package/ietf/subscribe.d.ts +8 -6
  145. package/ietf/subscribe.d.ts.map +1 -1
  146. package/ietf/subscribe.js +33 -27
  147. package/ietf/subscribe.js.map +1 -1
  148. package/ietf/subscribe_namespace.d.ts +8 -2
  149. package/ietf/subscribe_namespace.d.ts.map +1 -1
  150. package/ietf/subscribe_namespace.js +18 -8
  151. package/ietf/subscribe_namespace.js.map +1 -1
  152. package/ietf/subscriber.d.ts +1 -65
  153. package/ietf/subscriber.d.ts.map +1 -1
  154. package/ietf/subscriber.js +337 -123
  155. package/ietf/subscriber.js.map +1 -1
  156. package/ietf/token.d.ts +2 -0
  157. package/ietf/token.d.ts.map +1 -0
  158. package/ietf/token.js +99 -0
  159. package/ietf/token.js.map +1 -0
  160. package/ietf/track.d.ts +4 -0
  161. package/ietf/track.d.ts.map +1 -1
  162. package/ietf/track.js +6 -20
  163. package/ietf/track.js.map +1 -1
  164. package/ietf/version.d.ts +12 -1
  165. package/ietf/version.d.ts.map +1 -1
  166. package/ietf/version.js +13 -0
  167. package/ietf/version.js.map +1 -1
  168. package/index.d.ts +12 -7
  169. package/index.d.ts.map +1 -1
  170. package/index.js +10 -5
  171. package/index.js.map +1 -1
  172. package/internal.d.ts +115 -1
  173. package/internal.d.ts.map +1 -1
  174. package/internal.js +108 -0
  175. package/internal.js.map +1 -1
  176. package/lite/announce.d.ts +60 -10
  177. package/lite/announce.d.ts.map +1 -1
  178. package/lite/announce.js +176 -31
  179. package/lite/announce.js.map +1 -1
  180. package/lite/connection.d.ts +9 -59
  181. package/lite/connection.d.ts.map +1 -1
  182. package/lite/connection.js +34 -35
  183. package/lite/connection.js.map +1 -1
  184. package/lite/datagram.d.ts +3 -2
  185. package/lite/datagram.d.ts.map +1 -1
  186. package/lite/datagram.js +7 -8
  187. package/lite/datagram.js.map +1 -1
  188. package/lite/fetch.d.ts +15 -1
  189. package/lite/fetch.d.ts.map +1 -1
  190. package/lite/fetch.js +39 -7
  191. package/lite/fetch.js.map +1 -1
  192. package/lite/goaway.d.ts.map +1 -1
  193. package/lite/goaway.js +7 -1
  194. package/lite/goaway.js.map +1 -1
  195. package/lite/group.d.ts +30 -12
  196. package/lite/group.d.ts.map +1 -1
  197. package/lite/group.js +68 -26
  198. package/lite/group.js.map +1 -1
  199. package/lite/message.d.ts +2 -2
  200. package/lite/message.d.ts.map +1 -1
  201. package/lite/message.js +14 -5
  202. package/lite/message.js.map +1 -1
  203. package/lite/priority.d.ts +1 -61
  204. package/lite/priority.d.ts.map +1 -1
  205. package/lite/priority.js +4 -5
  206. package/lite/priority.js.map +1 -1
  207. package/lite/publisher.d.ts +1 -69
  208. package/lite/publisher.d.ts.map +1 -1
  209. package/lite/publisher.js +630 -262
  210. package/lite/publisher.js.map +1 -1
  211. package/lite/setup.d.ts +8 -8
  212. package/lite/setup.d.ts.map +1 -1
  213. package/lite/setup.js +33 -30
  214. package/lite/setup.js.map +1 -1
  215. package/lite/subscribe.d.ts +71 -17
  216. package/lite/subscribe.d.ts.map +1 -1
  217. package/lite/subscribe.js +205 -53
  218. package/lite/subscribe.js.map +1 -1
  219. package/lite/subscriber.d.ts +15 -56
  220. package/lite/subscriber.d.ts.map +1 -1
  221. package/lite/subscriber.js +451 -247
  222. package/lite/subscriber.js.map +1 -1
  223. package/lite/track.d.ts +4 -10
  224. package/lite/track.d.ts.map +1 -1
  225. package/lite/track.js +34 -29
  226. package/lite/track.js.map +1 -1
  227. package/lite/version.d.ts +42 -6
  228. package/lite/version.d.ts.map +1 -1
  229. package/lite/version.js +126 -10
  230. package/lite/version.js.map +1 -1
  231. package/origin.d.ts +256 -29
  232. package/origin.d.ts.map +1 -1
  233. package/origin.js +1427 -37
  234. package/origin.js.map +1 -1
  235. package/package.json +8 -3
  236. package/path.d.ts +25 -7
  237. package/path.d.ts.map +1 -1
  238. package/path.js +5 -3
  239. package/path.js.map +1 -1
  240. package/stream.d.ts +73 -14
  241. package/stream.d.ts.map +1 -1
  242. package/stream.js +372 -141
  243. package/stream.js.map +1 -1
  244. package/tail.d.ts +18 -0
  245. package/tail.d.ts.map +1 -0
  246. package/tail.js +167 -0
  247. package/tail.js.map +1 -0
  248. package/time.d.ts +15 -2
  249. package/time.d.ts.map +1 -1
  250. package/time.js +28 -9
  251. package/time.js.map +1 -1
  252. package/track.d.ts +211 -83
  253. package/track.d.ts.map +1 -1
  254. package/track.js +816 -205
  255. package/track.js.map +1 -1
  256. package/util/abort.d.ts +2 -0
  257. package/util/abort.d.ts.map +1 -0
  258. package/util/abort.js +20 -0
  259. package/util/abort.js.map +1 -0
  260. package/util/log.d.ts +5 -0
  261. package/util/log.d.ts.map +1 -0
  262. package/util/log.js +17 -0
  263. package/util/log.js.map +1 -0
  264. package/util/u64.d.ts +39 -0
  265. package/util/u64.d.ts.map +1 -0
  266. package/util/u64.js +83 -0
  267. package/util/u64.js.map +1 -0
  268. package/util/varint.d.ts +29 -0
  269. package/util/varint.d.ts.map +1 -0
  270. package/util/varint.js +198 -0
  271. package/util/varint.js.map +1 -0
  272. package/varint.d.ts +10 -6
  273. package/varint.d.ts.map +1 -1
  274. package/varint.js +40 -237
  275. package/varint.js.map +1 -1
  276. package/wire.d.ts +80 -0
  277. package/wire.d.ts.map +1 -0
  278. package/wire.js +32 -0
  279. package/wire.js.map +1 -0
  280. package/zod.d.ts +1 -1
  281. package/zod.d.ts.map +1 -1
  282. package/zod.js.map +1 -1
  283. package/mock.d.ts +0 -66
  284. package/mock.d.ts.map +0 -1
  285. package/mock.js +0 -243
  286. package/mock.js.map +0 -1
@@ -1,11 +1,11 @@
1
1
  /* @ts-self-types="./connection.d.ts" */
2
2
  import { Signal } from "@norskvideo/moq-signals";
3
- import * as announce from "../announced.js";
4
3
  import { transportStats } from "../connection/stats.js";
5
4
  import { transportOf } from "../connection/transport.js";
6
- import { randomOrigin } from "../origin.js";
7
- import * as Path from "../path.js";
5
+ import { closeError, error, fromClose, StreamCode, StreamError, sessionCause } from "../error.js";
6
+ import { randomHop } from "../hop.js";
8
7
  import { Readers, Stream, Writer } from "../stream.js";
8
+ import { registerWire } from "../wire.js";
9
9
  import { AnnounceRequest } from "./announce.js";
10
10
  import { Fetch } from "./fetch.js";
11
11
  import { Goaway } from "./goaway.js";
@@ -44,9 +44,9 @@ export class Connection {
44
44
  #subscriber;
45
45
  /** The peer's PROBE estimates; see {@link Established.probe}. */
46
46
  probe;
47
- /** Random per-connection origin id. Shared by Publisher (for outbound hop
47
+ /** Random per-connection Hop ID. Shared by Publisher (for outbound hop
48
48
  * chains) and Subscriber (available for optional self-filtering on announces). */
49
- origin;
49
+ hop;
50
50
  // The peer's SETUP, recorded once its Setup stream is read (lite-05+). Streams whose
51
51
  // encoding depends on a negotiated capability (e.g. PROBE) wait on this. undefined
52
52
  // until the peer's SETUP arrives; stays undefined forever on older drafts.
@@ -73,18 +73,24 @@ export class Connection {
73
73
  *
74
74
  * @internal
75
75
  */
76
- constructor({ url, quic, version, session, discovery = true }) {
76
+ constructor({ url, quic, version, session, discovery = true, publish }) {
77
77
  this.url = url;
78
78
  this.#quic = quic;
79
79
  this.#session = session;
80
+ // The session stream was opened at the SETUP exchange's version; the rest of it speaks this one.
81
+ if (session) {
82
+ session.reader.version = version;
83
+ session.writer.version = version;
84
+ }
80
85
  this.version = versionName(version);
81
86
  this.#version = version;
82
87
  this.transport = transportOf(quic);
83
88
  this.discovery = discovery;
84
89
  this.probe = this.#probe;
85
- this.origin = randomOrigin();
86
- this.#publisher = new Publisher(this.#quic, this.#version, this.origin);
87
- this.#subscriber = new Subscriber(this.#quic, this.#version, this.origin, this.#probe, this.#peerSetup);
90
+ this.hop = randomHop();
91
+ this.#publisher = new Publisher(this.#quic, this.#version, this.hop, publish);
92
+ this.#subscriber = new Subscriber(this.#quic, this.#version, this.hop, this.#probe, this.#peerSetup);
93
+ registerWire(this, { consume: (path) => this.#subscriber.consume(path) });
88
94
  void this.#run();
89
95
  }
90
96
  /**
@@ -112,33 +118,24 @@ export class Connection {
112
118
  if (hasDatagrams(this.#version)) {
113
119
  tasks.push(this.#subscriber.runDatagrams());
114
120
  }
121
+ let fatal;
115
122
  try {
116
123
  await Promise.all(tasks);
117
124
  }
118
125
  catch (err) {
119
126
  console.error("fatal error running connection", err);
127
+ // A session-sourced failure is the peer's close, not the raw transport error.
128
+ fatal = await sessionCause(this.#quic, err);
120
129
  }
121
130
  finally {
131
+ // The session died under every track it was receiving, so they end with its
132
+ // error. A deliberate close() already ended them cleanly, which makes this a no-op.
133
+ this.#subscriber.close(fatal ?? (await closeError(this.#quic)));
122
134
  this.close();
123
135
  }
124
136
  }
125
- publish(path, producer) {
126
- this.#publisher.publish(path, producer);
127
- }
128
- announced(prefix = Path.empty()) {
129
- return this.#subscriber.announced(prefix);
130
- }
131
- consume(path) {
132
- return this.#subscriber.consume(path);
133
- }
134
- /**
135
- * Watches a broadcast, live only while it is announced.
136
- *
137
- * @param path - The path of the broadcast to watch
138
- * @returns A reactive handle to the broadcast
139
- */
140
- announcedBroadcast(path) {
141
- return new announce.Broadcast({ connection: this, path });
137
+ announced(scope, options) {
138
+ return this.#subscriber.announced(scope, options);
142
139
  }
143
140
  async #runSession() {
144
141
  if (!this.#session) {
@@ -159,15 +156,16 @@ export class Connection {
159
156
  // The browser uses WebTransport, which carries the request URI, so we advertise no
160
157
  // path and leave routing to the URL. The probe level reflects what this transport
161
158
  // can actually measure; we never pad, so we never advertise Increase.
162
- // Role stays Both: publish/consume are called after this point, so there is nothing
163
- // to narrow yet. The origin declares our session identity so the peer can filter
159
+ // Role stays Both: the publish origin starts empty and fills later, and consume is
160
+ // called after this point, so there is nothing to narrow yet. The origin declares
161
+ // our session identity so the peer can filter
164
162
  // reflected announcements (lite-06 removed ANNOUNCE_REQUEST's exclude_hop for it).
165
163
  async #sendSetup() {
166
- const writer = await Writer.open(this.#quic);
164
+ const writer = await Writer.open(this.#quic, { version: this.#version });
167
165
  try {
168
166
  await writer.u53(DataType.Setup);
169
167
  const probe = await probeLevel(this.#quic, this.#version);
170
- await new Setup({ probe, origin: this.origin }).encode(writer, this.#version);
168
+ await new Setup({ probe, hop: this.hop }).encode(writer, this.#version);
171
169
  writer.close();
172
170
  }
173
171
  catch (err) {
@@ -177,7 +175,7 @@ export class Connection {
177
175
  }
178
176
  async #runBidis() {
179
177
  for (;;) {
180
- const stream = await Stream.accept(this.#quic);
178
+ const stream = await Stream.accept(this.#quic, this.#version);
181
179
  if (!stream)
182
180
  break;
183
181
  this.#runBidi(stream)
@@ -222,14 +220,14 @@ export class Connection {
222
220
  }
223
221
  }
224
222
  async #runUnis() {
225
- const readers = new Readers(this.#quic);
223
+ const readers = new Readers(this.#quic, this.#version);
226
224
  for (;;) {
227
225
  const stream = await readers.next();
228
226
  if (!stream)
229
227
  break;
230
228
  this.#runUni(stream)
231
229
  .then(() => {
232
- stream.stop(new Error("cancel"));
230
+ stream.stop(new StreamError(StreamCode.Cancel, { message: "cancel" }));
233
231
  })
234
232
  .catch((err) => {
235
233
  stream.stop(err);
@@ -239,7 +237,7 @@ export class Connection {
239
237
  async #runUni(stream) {
240
238
  const typ = await stream.u53();
241
239
  if (typ === DataType.Group) {
242
- const msg = await Group.decode(stream);
240
+ const msg = await Group.decode(stream, this.#version);
243
241
  await this.#subscriber.runGroup(msg, stream);
244
242
  }
245
243
  else if (typ === DataType.Setup) {
@@ -257,8 +255,9 @@ export class Connection {
257
255
  async stats() {
258
256
  return transportStats(this.#quic);
259
257
  }
258
+ /** Resolves when the session closes, decoding the peer's close code; see {@link Established.closed}. */
260
259
  get closed() {
261
- return this.#quic.closed.then(() => undefined);
260
+ return this.#quic.closed.then(fromClose, (err) => error(err));
262
261
  }
263
262
  }
264
263
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/lite/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,MAAM,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAA0B,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAAkB,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAe,YAAY,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AACnC,OAAO,EAAe,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAa,KAAK,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,KAAK,IAAI,YAAY,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAgB,WAAW,EAAE,MAAM,cAAc,CAAC;AAoBpG;;;;GAIG;AACH,MAAM,OAAO,UAAU;IACtB,6BAA6B;IACpB,GAAG,CAAM;IAElB,4DAA4D;IACnD,OAAO,CAAS;IAEzB,6CAA6C;IACpC,SAAS,CAAY;IAE9B,yFAAyF;IAChF,SAAS,CAAU;IAE5B,0CAA0C;IAC1C,QAAQ,CAAU;IAElB,wCAAwC;IACxC,KAAK,CAAe;IAEpB,wCAAwC;IACxC,QAAQ,CAAU;IAElB,kCAAkC;IAClC,UAAU,CAAY;IAEtB,kCAAkC;IAClC,WAAW,CAAa;IAExB,iEAAiE;IACxD,KAAK,CAAgB;IAE9B;sFACkF;IACzE,MAAM,CAAS;IAExB,qFAAqF;IACrF,mFAAmF;IACnF,2EAA2E;IAC3E,UAAU,GAAG,IAAI,MAAM,CAAoB,SAAS,CAAC,CAAC;IAEtD,wFAAwF;IACxF,2FAA2F;IAC3F,SAAS,GAAG,IAAI,MAAM,CAAmB,SAAS,CAAC,CAAC;IAEpD,sDAAsD;IACtD,MAAM,GAAG,IAAI,MAAM,CAAQ,EAAE,CAAC,CAAC;IAE/B;;;;;;;;OAQG;IACH,IAAI,QAAQ;QACX,OAAO,IAAI,CAAC,SAAS,CAAC;IACvB,CAAC;IAED;;;;OAIG;IACH,YAAY,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,GAAG,IAAI,EAAmB;QAC7E,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAE3B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;QAEzB,IAAI,CAAC,MAAM,GAAG,YAAY,EAAE,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACxE,IAAI,CAAC,WAAW,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAExG,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;IAClB,CAAC;IAED;;OAEG;IACH,KAAK;QACJ,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACxB,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QAEzB,IAAI,CAAC;YACJ,oEAAoE;YACpE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC;QAAC,MAAM,CAAC;YACR,SAAS;QACV,CAAC;IACF,CAAC;IAED,KAAK,CAAC,IAAI;QACT,MAAM,KAAK,GAAoB,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEvF,IAAI,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QAC/B,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC;QAExC,iFAAiF;QACjF,kDAAkD;QAClD,IAAI,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,CAAC;QAC7C,CAAC;QAED,IAAI,CAAC;YACJ,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,GAAG,CAAC,CAAC;QACtD,CAAC;gBAAS,CAAC;YACV,IAAI,CAAC,KAAK,EAAE,CAAC;QACd,CAAC;IACF,CAAC;IAED,OAAO,CAAC,IAAgB,EAAE,QAA4B;QACrD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACzC,CAAC;IAED,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE;QAC9B,OAAO,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,CAAC,IAAgB;QACvB,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IAED;;;;;OAKG;IACH,kBAAkB,CAAC,IAAgB;QAClC,OAAO,IAAI,QAAQ,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,KAAK,CAAC,WAAW;QAChB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpB,OAAO;QACR,CAAC;QAED,IAAI,CAAC;YACJ,SAAS,CAAC;gBACT,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC/E,IAAI,CAAC,GAAG;oBAAE,MAAM;YACjB,CAAC;QACF,CAAC;gBAAS,CAAC;YACV,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACxC,CAAC;IACF,CAAC;IAED,mFAAmF;IACnF,mFAAmF;IACnF,kFAAkF;IAClF,sEAAsE;IACtE,oFAAoF;IACpF,iFAAiF;IACjF,mFAAmF;IACnF,KAAK,CAAC,UAAU;QACf,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,CAAC;YACJ,MAAM,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACjC,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC1D,MAAM,IAAI,KAAK,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9E,MAAM,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACvB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAClB,MAAM,GAAG,CAAC;QACX,CAAC;IACF,CAAC;IAED,KAAK,CAAC,SAAS;QACd,SAAS,CAAC;YACT,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/C,IAAI,CAAC,MAAM;gBAAE,MAAM;YAEnB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;iBACnB,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;gBACvB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC1B,CAAC,CAAC;iBACD,OAAO,CAAC,GAAG,EAAE;gBACb,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACvB,CAAC,CAAC,CAAC;QACL,CAAC;IACF,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAAc;QAC5B,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAEtC,IAAI,GAAG,KAAK,QAAQ,CAAC,OAAO,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC7C,CAAC;aAAM,IAAI,GAAG,KAAK,QAAQ,CAAC,QAAQ,EAAE,CAAC;YACtC,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvE,MAAM,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAChD,CAAC;aAAM,IAAI,GAAG,KAAK,QAAQ,CAAC,SAAS,EAAE,CAAC;YACvC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YACjE,MAAM,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACjD,CAAC;aAAM,IAAI,GAAG,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC7D,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC7C,CAAC;aAAM,IAAI,GAAG,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnC,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YACpE,MAAM,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACjD,CAAC;aAAM,IAAI,GAAG,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnC,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACxC,CAAC;aAAM,IAAI,GAAG,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;YACpC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9D,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC3D,CAAC;IACF,CAAC;IAED,KAAK,CAAC,QAAQ;QACb,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAExC,SAAS,CAAC;YACT,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YACpC,IAAI,CAAC,MAAM;gBAAE,MAAM;YAEnB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;iBAClB,IAAI,CAAC,GAAG,EAAE;gBACV,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;YAClC,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;gBACvB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;QACL,CAAC;IACF,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAc;QAC3B,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;QAC/B,IAAI,GAAG,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACvC,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC9C,CAAC;aAAM,IAAI,GAAG,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnC,6EAA6E;YAC7E,yDAAyD;YACzD,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YACxD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC3B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC3D,CAAC;IACF,CAAC;IAED,wEAAwE;IACxE,KAAK,CAAC,KAAK;QACV,OAAO,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAED,IAAI,MAAM;QACT,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAChD,CAAC;CACD;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAkB,EAAE,OAAgB;IACpE,MAAM,QAAQ,GACb,IAGA,CAAC,QAAQ,CAAC;IACX,IAAI,OAAO,QAAQ,KAAK,UAAU;QAAE,OAAO,UAAU,CAAC,IAAI,CAAC;IAE3D,6EAA6E;IAC7E,IAAI,KAAwE,CAAC;IAC7E,IAAI,CAAC;QACJ,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,UAAU,CAAC,IAAI,CAAC;IACxB,CAAC;IAED,MAAM,GAAG,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;IACjE,OAAO,KAAK,CAAC,iBAAiB,IAAI,IAAI,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;AAC7F,CAAC","sourcesContent":["import { type Getter, Signal } from \"@moq/signals\";\nimport * as announce from \"../announced.ts\";\nimport type * as broadcast from \"../broadcast.ts\";\nimport type { Established } from \"../connection/established.ts\";\nimport { type Probe, type Stats, transportStats } from \"../connection/stats.ts\";\nimport { type Transport, transportOf } from \"../connection/transport.ts\";\nimport { type Origin, randomOrigin } from \"../origin.ts\";\nimport * as Path from \"../path.ts\";\nimport { type Reader, Readers, Stream, Writer } from \"../stream.ts\";\nimport { AnnounceRequest } from \"./announce.ts\";\nimport { Fetch } from \"./fetch.ts\";\nimport { Goaway } from \"./goaway.ts\";\nimport { Group } from \"./group.ts\";\nimport { Publisher } from \"./publisher.ts\";\nimport { SessionInfo } from \"./session.ts\";\nimport { ProbeLevel, type Role, Setup } from \"./setup.ts\";\nimport { DataType, StreamId } from \"./stream.ts\";\nimport { Subscribe } from \"./subscribe.ts\";\nimport { Subscriber } from \"./subscriber.ts\";\nimport { Track as TrackMessage } from \"./track.ts\";\nimport { hasDatagrams, hasProbeRtt, hasSetupStream, type Version, versionName } from \"./version.ts\";\n\n/**\n * Constructor options for {@link Connection}.\n *\n * @internal\n */\nexport interface ConnectionProps {\n\t/** The URL of the connection. */\n\turl: URL;\n\t/** The established WebTransport session. */\n\tquic: WebTransport;\n\t/** The negotiated wire version. */\n\tversion: Version;\n\t/** The session stream, absent on drafts that have none. */\n\tsession?: Stream;\n\t/** Whether the relay supports broadcast discovery. Defaults to true. */\n\tdiscovery?: boolean;\n}\n\n/**\n * Represents a connection to a MoQ server.\n *\n * @public\n */\nexport class Connection implements Established {\n\t// The URL of the connection.\n\treadonly url: URL;\n\n\t// The version of the connection as a human-readable string.\n\treadonly version: string;\n\n\t// The wire transport this session runs over.\n\treadonly transport: Transport;\n\n\t/** Whether the relay supports broadcast discovery; see {@link Established.discovery}. */\n\treadonly discovery: boolean;\n\n\t// The version used for encoding/decoding.\n\t#version: Version;\n\n\t// The established WebTransport session.\n\t#quic: WebTransport;\n\n\t// Use to receive/send session messages.\n\t#session?: Stream;\n\n\t// Module for contributing tracks.\n\t#publisher: Publisher;\n\n\t// Module for distributing tracks.\n\t#subscriber: Subscriber;\n\n\t/** The peer's PROBE estimates; see {@link Established.probe}. */\n\treadonly probe: Getter<Probe>;\n\n\t/** Random per-connection origin id. Shared by Publisher (for outbound hop\n\t * chains) and Subscriber (available for optional self-filtering on announces). */\n\treadonly origin: Origin;\n\n\t// The peer's SETUP, recorded once its Setup stream is read (lite-05+). Streams whose\n\t// encoding depends on a negotiated capability (e.g. PROBE) wait on this. undefined\n\t// until the peer's SETUP arrives; stays undefined forever on older drafts.\n\t#peerSetup = new Signal<Setup | undefined>(undefined);\n\n\t// Mirrors the role out of #peerSetup, so the public surface exposes the peer's declared\n\t// direction without handing out the whole SETUP (whose probe level gates our own streams).\n\t#peerRole = new Signal<Role | undefined>(undefined);\n\n\t// Written by the Subscriber as PROBE messages arrive.\n\t#probe = new Signal<Probe>({});\n\n\t/**\n\t * The {@link Role} the peer advertised in its SETUP, for a server deciding whether the\n\t * peer's authorization grants the direction it intends to use.\n\t *\n\t * `undefined` until the peer's SETUP arrives, and forever on pre-lite-05 versions, which\n\t * carry no in-band role. {@link Role.Both} is the absence of the parameter, so it is what\n\t * a peer reports when it declines to declare a direction, sends a value we don't\n\t * recognize, or is a server (which never sends one).\n\t */\n\tget peerRole(): Getter<Role | undefined> {\n\t\treturn this.#peerRole;\n\t}\n\n\t/**\n\t * Creates a new Connection instance.\n\t *\n\t * @internal\n\t */\n\tconstructor({ url, quic, version, session, discovery = true }: ConnectionProps) {\n\t\tthis.url = url;\n\t\tthis.#quic = quic;\n\t\tthis.#session = session;\n\t\tthis.version = versionName(version);\n\t\tthis.#version = version;\n\t\tthis.transport = transportOf(quic);\n\t\tthis.discovery = discovery;\n\n\t\tthis.probe = this.#probe;\n\n\t\tthis.origin = randomOrigin();\n\t\tthis.#publisher = new Publisher(this.#quic, this.#version, this.origin);\n\t\tthis.#subscriber = new Subscriber(this.#quic, this.#version, this.origin, this.#probe, this.#peerSetup);\n\n\t\tvoid this.#run();\n\t}\n\n\t/**\n\t * Closes the connection.\n\t */\n\tclose() {\n\t\tthis.#publisher.close();\n\t\tthis.#subscriber.close();\n\n\t\ttry {\n\t\t\t// TODO: For whatever reason, this try/catch doesn't seem to work..?\n\t\t\tthis.#quic.close();\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t}\n\n\tasync #run(): Promise<void> {\n\t\tconst tasks: Promise<void>[] = [this.#runSession(), this.#runBidis(), this.#runUnis()];\n\n\t\tif (hasSetupStream(this.#version)) {\n\t\t\ttasks.push(this.#sendSetup());\n\t\t}\n\n\t\ttasks.push(this.#subscriber.runProbe());\n\n\t\t// Route incoming QUIC datagrams into their subscriptions (lite-05+; runDatagrams\n\t\t// no-ops on a transport that doesn't carry them).\n\t\tif (hasDatagrams(this.#version)) {\n\t\t\ttasks.push(this.#subscriber.runDatagrams());\n\t\t}\n\n\t\ttry {\n\t\t\tawait Promise.all(tasks);\n\t\t} catch (err) {\n\t\t\tconsole.error(\"fatal error running connection\", err);\n\t\t} finally {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\tpublish(path: Path.Valid, producer: broadcast.Producer) {\n\t\tthis.#publisher.publish(path, producer);\n\t}\n\n\tannounced(prefix = Path.empty()): announce.Consumer {\n\t\treturn this.#subscriber.announced(prefix);\n\t}\n\n\tconsume(path: Path.Valid): broadcast.Consumer {\n\t\treturn this.#subscriber.consume(path);\n\t}\n\n\t/**\n\t * Watches a broadcast, live only while it is announced.\n\t *\n\t * @param path - The path of the broadcast to watch\n\t * @returns A reactive handle to the broadcast\n\t */\n\tannouncedBroadcast(path: Path.Valid): announce.Broadcast {\n\t\treturn new announce.Broadcast({ connection: this, path });\n\t}\n\n\tasync #runSession() {\n\t\tif (!this.#session) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tfor (;;) {\n\t\t\t\tconst msg = await SessionInfo.decodeMaybe(this.#session.reader, this.#version);\n\t\t\t\tif (!msg) break;\n\t\t\t}\n\t\t} finally {\n\t\t\tconsole.debug(\"session stream closed\");\n\t\t}\n\t}\n\n\t// Open the unidirectional Setup Stream, send our single SETUP, and FIN (lite-05+).\n\t// The browser uses WebTransport, which carries the request URI, so we advertise no\n\t// path and leave routing to the URL. The probe level reflects what this transport\n\t// can actually measure; we never pad, so we never advertise Increase.\n\t// Role stays Both: publish/consume are called after this point, so there is nothing\n\t// to narrow yet. The origin declares our session identity so the peer can filter\n\t// reflected announcements (lite-06 removed ANNOUNCE_REQUEST's exclude_hop for it).\n\tasync #sendSetup(): Promise<void> {\n\t\tconst writer = await Writer.open(this.#quic);\n\t\ttry {\n\t\t\tawait writer.u53(DataType.Setup);\n\t\t\tconst probe = await probeLevel(this.#quic, this.#version);\n\t\t\tawait new Setup({ probe, origin: this.origin }).encode(writer, this.#version);\n\t\t\twriter.close();\n\t\t} catch (err: unknown) {\n\t\t\twriter.reset(err);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tasync #runBidis() {\n\t\tfor (;;) {\n\t\t\tconst stream = await Stream.accept(this.#quic);\n\t\t\tif (!stream) break;\n\n\t\t\tthis.#runBidi(stream)\n\t\t\t\t.catch((err: unknown) => {\n\t\t\t\t\tstream.writer.reset(err);\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tstream.writer.close();\n\t\t\t\t});\n\t\t}\n\t}\n\n\tasync #runBidi(stream: Stream) {\n\t\tconst typ = await stream.reader.u53();\n\n\t\tif (typ === StreamId.Session) {\n\t\t\tthrow new Error(\"duplicate session stream\");\n\t\t} else if (typ === StreamId.Announce) {\n\t\t\tconst msg = await AnnounceRequest.decode(stream.reader, this.#version);\n\t\t\tawait this.#publisher.runAnnounce(msg, stream);\n\t\t} else if (typ === StreamId.Subscribe) {\n\t\t\tconst msg = await Subscribe.decode(stream.reader, this.#version);\n\t\t\tawait this.#publisher.runSubscribe(msg, stream);\n\t\t} else if (typ === StreamId.Fetch) {\n\t\t\tconst msg = await Fetch.decode(stream.reader, this.#version);\n\t\t\tawait this.#publisher.runFetch(msg, stream);\n\t\t} else if (typ === StreamId.Track) {\n\t\t\tconst msg = await TrackMessage.decode(stream.reader, this.#version);\n\t\t\tawait this.#publisher.runTrackInfo(msg, stream);\n\t\t} else if (typ === StreamId.Probe) {\n\t\t\tawait this.#publisher.runProbe(stream);\n\t\t} else if (typ === StreamId.Goaway) {\n\t\t\tconst msg = await Goaway.decode(stream.reader, this.#version);\n\t\t\tconsole.info(\"received goaway:\", msg.uri);\n\t\t} else {\n\t\t\tthrow new Error(`unknown stream type: ${typ.toString()}`);\n\t\t}\n\t}\n\n\tasync #runUnis() {\n\t\tconst readers = new Readers(this.#quic);\n\n\t\tfor (;;) {\n\t\t\tconst stream = await readers.next();\n\t\t\tif (!stream) break;\n\n\t\t\tthis.#runUni(stream)\n\t\t\t\t.then(() => {\n\t\t\t\t\tstream.stop(new Error(\"cancel\"));\n\t\t\t\t})\n\t\t\t\t.catch((err: unknown) => {\n\t\t\t\t\tstream.stop(err);\n\t\t\t\t});\n\t\t}\n\t}\n\n\tasync #runUni(stream: Reader) {\n\t\tconst typ = await stream.u53();\n\t\tif (typ === DataType.Group) {\n\t\t\tconst msg = await Group.decode(stream);\n\t\t\tawait this.#subscriber.runGroup(msg, stream);\n\t\t} else if (typ === DataType.Setup) {\n\t\t\t// The peer sends exactly one SETUP, then FINs. Record it so capability-gated\n\t\t\t// streams (e.g. PROBE) can react, then drain to the FIN.\n\t\t\tconst setup = await Setup.decode(stream, this.#version);\n\t\t\tthis.#peerSetup.set(setup);\n\t\t\tthis.#peerRole.set(setup.role);\n\t\t} else {\n\t\t\tthrow new Error(`unknown stream type: ${typ.toString()}`);\n\t\t}\n\t}\n\n\t/** Snapshot the transport's counters; see {@link Established.stats}. */\n\tasync stats(): Promise<Stats> {\n\t\treturn transportStats(this.#quic);\n\t}\n\n\tget closed(): Promise<void> {\n\t\treturn this.#quic.closed.then(() => undefined);\n\t}\n}\n\n/**\n * The probe level to advertise in SETUP, from what the transport can measure.\n *\n * `Report` claims we can measure and periodically report, so it is only truthful\n * when a metric this version can carry actually exists. The qmux/WebSocket fallback\n * implements no `getStats()` at all, and even a transport that has one may report\n * neither figure. Advertising `Report` and then holding the subscriber's PROBE\n * stream open with nothing to send is the state this avoids; the subscriber's own\n * gate then skips a stream it could not use.\n *\n * Mirrors `ProbeLevel::detect` in `moq-net`, including its limitation: a metric\n * that only appears after SETUP reads as unsupported here.\n *\n * @internal\n */\nexport async function probeLevel(quic: WebTransport, version: Version): Promise<ProbeLevel> {\n\tconst getStats = (\n\t\tquic as unknown as {\n\t\t\tgetStats?: () => Promise<{ estimatedSendRate: number | null; smoothedRtt?: number | null }>;\n\t\t}\n\t).getStats;\n\tif (typeof getStats !== \"function\") return ProbeLevel.None;\n\n\t// A transport that can't answer tells us nothing, which is itself an answer.\n\tlet stats: { estimatedSendRate: number | null; smoothedRtt?: number | null };\n\ttry {\n\t\tstats = await getStats.call(quic);\n\t} catch {\n\t\treturn ProbeLevel.None;\n\t}\n\n\tconst rtt = hasProbeRtt(version) ? stats.smoothedRtt : undefined;\n\treturn stats.estimatedSendRate != null || rtt != null ? ProbeLevel.Report : ProbeLevel.None;\n}\n"]}
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/lite/connection.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Getter, Signal } from \"@moq/signals\";\nimport type * as announce from \"../announced.ts\";\nimport type { Established } from \"../connection/established.ts\";\nimport { type Probe, type Stats, transportStats } from \"../connection/stats.ts\";\nimport { type Transport, transportOf } from \"../connection/transport.ts\";\nimport { closeError, error, fromClose, StreamCode, StreamError, sessionCause } from \"../error.ts\";\nimport { type Hop, randomHop } from \"../hop.ts\";\nimport type { Consumer as OriginConsumer } from \"../origin.ts\";\nimport type * as Path from \"../path.ts\";\nimport { type Reader, Readers, Stream, Writer } from \"../stream.ts\";\nimport { registerWire } from \"../wire.ts\";\nimport { AnnounceRequest } from \"./announce.ts\";\nimport { Fetch } from \"./fetch.ts\";\nimport { Goaway } from \"./goaway.ts\";\nimport { Group } from \"./group.ts\";\nimport { Publisher } from \"./publisher.ts\";\nimport { SessionInfo } from \"./session.ts\";\nimport { ProbeLevel, type Role, Setup } from \"./setup.ts\";\nimport { DataType, StreamId } from \"./stream.ts\";\nimport { Subscribe } from \"./subscribe.ts\";\nimport { Subscriber } from \"./subscriber.ts\";\nimport { Track as TrackMessage } from \"./track.ts\";\nimport { hasDatagrams, hasProbeRtt, hasSetupStream, type Version, versionName } from \"./version.ts\";\n\n/**\n * Constructor options for {@link Connection}.\n *\n * @internal\n */\nexport interface ConnectionProps {\n\t/** The URL of the connection. */\n\turl: URL;\n\t/** The established WebTransport session. */\n\tquic: WebTransport;\n\t/** The negotiated wire version. */\n\tversion: Version;\n\t/** The session stream, absent on drafts that have none. */\n\tsession?: Stream;\n\t/** Whether the relay supports broadcast discovery. Defaults to true. */\n\tdiscovery?: boolean;\n\t/** The origin whose broadcasts are served to the peer. Omit to publish nothing. */\n\tpublish?: OriginConsumer;\n}\n\n/**\n * Represents a connection to a MoQ server.\n *\n * @public\n */\nexport class Connection implements Established {\n\t// The URL of the connection.\n\treadonly url: URL;\n\n\t// The version of the connection as a human-readable string.\n\treadonly version: string;\n\n\t// The wire transport this session runs over.\n\treadonly transport: Transport;\n\n\t/** Whether the relay supports broadcast discovery; see {@link Established.discovery}. */\n\treadonly discovery: boolean;\n\n\t// The version used for encoding/decoding.\n\t#version: Version;\n\n\t// The established WebTransport session.\n\t#quic: WebTransport;\n\n\t// Use to receive/send session messages.\n\t#session?: Stream;\n\n\t// Module for contributing tracks.\n\t#publisher: Publisher;\n\n\t// Module for distributing tracks.\n\t#subscriber: Subscriber;\n\n\t/** The peer's PROBE estimates; see {@link Established.probe}. */\n\treadonly probe: Getter<Probe>;\n\n\t/** Random per-connection Hop ID. Shared by Publisher (for outbound hop\n\t * chains) and Subscriber (available for optional self-filtering on announces). */\n\treadonly hop: Hop;\n\n\t// The peer's SETUP, recorded once its Setup stream is read (lite-05+). Streams whose\n\t// encoding depends on a negotiated capability (e.g. PROBE) wait on this. undefined\n\t// until the peer's SETUP arrives; stays undefined forever on older drafts.\n\t#peerSetup = new Signal<Setup | undefined>(undefined);\n\n\t// Mirrors the role out of #peerSetup, so the public surface exposes the peer's declared\n\t// direction without handing out the whole SETUP (whose probe level gates our own streams).\n\t#peerRole = new Signal<Role | undefined>(undefined);\n\n\t// Written by the Subscriber as PROBE messages arrive.\n\t#probe = new Signal<Probe>({});\n\n\t/**\n\t * The {@link Role} the peer advertised in its SETUP, for a server deciding whether the\n\t * peer's authorization grants the direction it intends to use.\n\t *\n\t * `undefined` until the peer's SETUP arrives, and forever on pre-lite-05 versions, which\n\t * carry no in-band role. {@link Role.Both} is the absence of the parameter, so it is what\n\t * a peer reports when it declines to declare a direction, sends a value we don't\n\t * recognize, or is a server (which never sends one).\n\t */\n\tget peerRole(): Getter<Role | undefined> {\n\t\treturn this.#peerRole;\n\t}\n\n\t/**\n\t * Creates a new Connection instance.\n\t *\n\t * @internal\n\t */\n\tconstructor({ url, quic, version, session, discovery = true, publish }: ConnectionProps) {\n\t\tthis.url = url;\n\t\tthis.#quic = quic;\n\t\tthis.#session = session;\n\t\t// The session stream was opened at the SETUP exchange's version; the rest of it speaks this one.\n\t\tif (session) {\n\t\t\tsession.reader.version = version;\n\t\t\tsession.writer.version = version;\n\t\t}\n\t\tthis.version = versionName(version);\n\t\tthis.#version = version;\n\t\tthis.transport = transportOf(quic);\n\t\tthis.discovery = discovery;\n\n\t\tthis.probe = this.#probe;\n\n\t\tthis.hop = randomHop();\n\t\tthis.#publisher = new Publisher(this.#quic, this.#version, this.hop, publish);\n\t\tthis.#subscriber = new Subscriber(this.#quic, this.#version, this.hop, this.#probe, this.#peerSetup);\n\t\tregisterWire(this, { consume: (path) => this.#subscriber.consume(path) });\n\n\t\tvoid this.#run();\n\t}\n\n\t/**\n\t * Closes the connection.\n\t */\n\tclose() {\n\t\tthis.#publisher.close();\n\t\tthis.#subscriber.close();\n\n\t\ttry {\n\t\t\t// TODO: For whatever reason, this try/catch doesn't seem to work..?\n\t\t\tthis.#quic.close();\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t}\n\n\tasync #run(): Promise<void> {\n\t\tconst tasks: Promise<void>[] = [this.#runSession(), this.#runBidis(), this.#runUnis()];\n\n\t\tif (hasSetupStream(this.#version)) {\n\t\t\ttasks.push(this.#sendSetup());\n\t\t}\n\n\t\ttasks.push(this.#subscriber.runProbe());\n\n\t\t// Route incoming QUIC datagrams into their subscriptions (lite-05+; runDatagrams\n\t\t// no-ops on a transport that doesn't carry them).\n\t\tif (hasDatagrams(this.#version)) {\n\t\t\ttasks.push(this.#subscriber.runDatagrams());\n\t\t}\n\n\t\tlet fatal: Error | undefined;\n\t\ttry {\n\t\t\tawait Promise.all(tasks);\n\t\t} catch (err) {\n\t\t\tconsole.error(\"fatal error running connection\", err);\n\t\t\t// A session-sourced failure is the peer's close, not the raw transport error.\n\t\t\tfatal = await sessionCause(this.#quic, err);\n\t\t} finally {\n\t\t\t// The session died under every track it was receiving, so they end with its\n\t\t\t// error. A deliberate close() already ended them cleanly, which makes this a no-op.\n\t\t\tthis.#subscriber.close(fatal ?? (await closeError(this.#quic)));\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\tannounced(scope?: Path.Pattern, options?: announce.Options): announce.Consumer {\n\t\treturn this.#subscriber.announced(scope, options);\n\t}\n\n\tasync #runSession() {\n\t\tif (!this.#session) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tfor (;;) {\n\t\t\t\tconst msg = await SessionInfo.decodeMaybe(this.#session.reader, this.#version);\n\t\t\t\tif (!msg) break;\n\t\t\t}\n\t\t} finally {\n\t\t\tconsole.debug(\"session stream closed\");\n\t\t}\n\t}\n\n\t// Open the unidirectional Setup Stream, send our single SETUP, and FIN (lite-05+).\n\t// The browser uses WebTransport, which carries the request URI, so we advertise no\n\t// path and leave routing to the URL. The probe level reflects what this transport\n\t// can actually measure; we never pad, so we never advertise Increase.\n\t// Role stays Both: the publish origin starts empty and fills later, and consume is\n\t// called after this point, so there is nothing to narrow yet. The origin declares\n\t// our session identity so the peer can filter\n\t// reflected announcements (lite-06 removed ANNOUNCE_REQUEST's exclude_hop for it).\n\tasync #sendSetup(): Promise<void> {\n\t\tconst writer = await Writer.open(this.#quic, { version: this.#version });\n\t\ttry {\n\t\t\tawait writer.u53(DataType.Setup);\n\t\t\tconst probe = await probeLevel(this.#quic, this.#version);\n\t\t\tawait new Setup({ probe, hop: this.hop }).encode(writer, this.#version);\n\t\t\twriter.close();\n\t\t} catch (err: unknown) {\n\t\t\twriter.reset(err);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tasync #runBidis() {\n\t\tfor (;;) {\n\t\t\tconst stream = await Stream.accept(this.#quic, this.#version);\n\t\t\tif (!stream) break;\n\n\t\t\tthis.#runBidi(stream)\n\t\t\t\t.catch((err: unknown) => {\n\t\t\t\t\tstream.writer.reset(err);\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tstream.writer.close();\n\t\t\t\t});\n\t\t}\n\t}\n\n\tasync #runBidi(stream: Stream) {\n\t\tconst typ = await stream.reader.u53();\n\n\t\tif (typ === StreamId.Session) {\n\t\t\tthrow new Error(\"duplicate session stream\");\n\t\t} else if (typ === StreamId.Announce) {\n\t\t\tconst msg = await AnnounceRequest.decode(stream.reader, this.#version);\n\t\t\tawait this.#publisher.runAnnounce(msg, stream);\n\t\t} else if (typ === StreamId.Subscribe) {\n\t\t\tconst msg = await Subscribe.decode(stream.reader, this.#version);\n\t\t\tawait this.#publisher.runSubscribe(msg, stream);\n\t\t} else if (typ === StreamId.Fetch) {\n\t\t\tconst msg = await Fetch.decode(stream.reader, this.#version);\n\t\t\tawait this.#publisher.runFetch(msg, stream);\n\t\t} else if (typ === StreamId.Track) {\n\t\t\tconst msg = await TrackMessage.decode(stream.reader, this.#version);\n\t\t\tawait this.#publisher.runTrackInfo(msg, stream);\n\t\t} else if (typ === StreamId.Probe) {\n\t\t\tawait this.#publisher.runProbe(stream);\n\t\t} else if (typ === StreamId.Goaway) {\n\t\t\tconst msg = await Goaway.decode(stream.reader, this.#version);\n\t\t\tconsole.info(\"received goaway:\", msg.uri);\n\t\t} else {\n\t\t\tthrow new Error(`unknown stream type: ${typ.toString()}`);\n\t\t}\n\t}\n\n\tasync #runUnis() {\n\t\tconst readers = new Readers(this.#quic, this.#version);\n\n\t\tfor (;;) {\n\t\t\tconst stream = await readers.next();\n\t\t\tif (!stream) break;\n\n\t\t\tthis.#runUni(stream)\n\t\t\t\t.then(() => {\n\t\t\t\t\tstream.stop(new StreamError(StreamCode.Cancel, { message: \"cancel\" }));\n\t\t\t\t})\n\t\t\t\t.catch((err: unknown) => {\n\t\t\t\t\tstream.stop(err);\n\t\t\t\t});\n\t\t}\n\t}\n\n\tasync #runUni(stream: Reader) {\n\t\tconst typ = await stream.u53();\n\t\tif (typ === DataType.Group) {\n\t\t\tconst msg = await Group.decode(stream, this.#version);\n\t\t\tawait this.#subscriber.runGroup(msg, stream);\n\t\t} else if (typ === DataType.Setup) {\n\t\t\t// The peer sends exactly one SETUP, then FINs. Record it so capability-gated\n\t\t\t// streams (e.g. PROBE) can react, then drain to the FIN.\n\t\t\tconst setup = await Setup.decode(stream, this.#version);\n\t\t\tthis.#peerSetup.set(setup);\n\t\t\tthis.#peerRole.set(setup.role);\n\t\t} else {\n\t\t\tthrow new Error(`unknown stream type: ${typ.toString()}`);\n\t\t}\n\t}\n\n\t/** Snapshot the transport's counters; see {@link Established.stats}. */\n\tasync stats(): Promise<Stats> {\n\t\treturn transportStats(this.#quic);\n\t}\n\n\t/** Resolves when the session closes, decoding the peer's close code; see {@link Established.closed}. */\n\tget closed(): Promise<Error | null> {\n\t\treturn this.#quic.closed.then(fromClose, (err: unknown) => error(err));\n\t}\n}\n\n/**\n * The probe level to advertise in SETUP, from what the transport can measure.\n *\n * `Report` claims we can measure and periodically report, so it is only truthful\n * when a metric this version can carry actually exists. The qmux/WebSocket fallback\n * implements no `getStats()` at all, and even a transport that has one may report\n * neither figure. Advertising `Report` and then holding the subscriber's PROBE\n * stream open with nothing to send is the state this avoids; the subscriber's own\n * gate then skips a stream it could not use.\n *\n * Mirrors `ProbeLevel::detect` in `moq-net`, including its limitation: a metric\n * that only appears after SETUP reads as unsupported here.\n *\n * @internal\n */\nexport async function probeLevel(quic: WebTransport, version: Version): Promise<ProbeLevel> {\n\tconst getStats = (\n\t\tquic as unknown as {\n\t\t\tgetStats?: () => Promise<{ estimatedSendRate: number | null; smoothedRtt?: number | null }>;\n\t\t}\n\t).getStats;\n\tif (typeof getStats !== \"function\") return ProbeLevel.None;\n\n\t// A transport that can't answer tells us nothing, which is itself an answer.\n\tlet stats: { estimatedSendRate: number | null; smoothedRtt?: number | null };\n\ttry {\n\t\tstats = await getStats.call(quic);\n\t} catch {\n\t\treturn ProbeLevel.None;\n\t}\n\n\tconst rtt = hasProbeRtt(version) ? stats.smoothedRtt : undefined;\n\treturn stats.estimatedSendRate != null || rtt != null ? ProbeLevel.Report : ProbeLevel.None;\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import type { Version } from "./version";
1
2
  /**
2
3
  * A QUIC datagram body: `subscribe (i) | sequence (i) | timestamp (i) | payload (b)`.
3
4
  *
@@ -16,8 +17,8 @@ export declare class Datagram {
16
17
  payload: Uint8Array;
17
18
  constructor(subscribe: bigint, sequence: number, timestamp: number, payload: Uint8Array);
18
19
  /** Encode the body to a single `Uint8Array` (no length prefix; the datagram boundary delimits it). */
19
- encode(): Uint8Array;
20
+ encode(version: Version): Uint8Array;
20
21
  /** Decode a datagram body from the raw bytes of one QUIC datagram. */
21
- static decode(data: Uint8Array): Promise<Datagram>;
22
+ static decode(data: Uint8Array, version: Version): Promise<Datagram>;
22
23
  }
23
24
  //# sourceMappingURL=datagram.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"datagram.d.ts","sourceRoot":"","sources":["../../src/lite/datagram.ts"],"names":[],"mappings":"AAQA;;;;;;GAMG;AACH,qBAAa,QAAQ;IACpB,kDAAkD;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,QAAQ,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,OAAO,EAAE,UAAU,CAAC;IAEpB,YAAY,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAKtF;IAED,sGAAsG;IACtG,MAAM,IAAI,UAAU,CAiBnB;IAED,sEAAsE;IACtE,OAAa,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAOvD;CACD"}
1
+ {"version":3,"file":"datagram.d.ts","sourceRoot":"","sources":["../../src/lite/datagram.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;;;GAMG;AACH,qBAAa,QAAQ;IACpB,kDAAkD;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,QAAQ,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,OAAO,EAAE,UAAU,CAAC;IAEpB,YAAY,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAKtF;IAED,sGAAsG;IACtG,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CAiBnC;IAED,sEAAsE;IACtE,OAAa,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAOzE;CACD"}
package/lite/datagram.js CHANGED
@@ -4,8 +4,7 @@
4
4
  *
5
5
  * @module
6
6
  */
7
- import { Reader } from "../stream.js";
8
- import * as Varint from "../varint.js";
7
+ import { encodeVarint, Reader } from "../stream.js";
9
8
  /**
10
9
  * A QUIC datagram body: `subscribe (i) | sequence (i) | timestamp (i) | payload (b)`.
11
10
  *
@@ -29,10 +28,10 @@ export class Datagram {
29
28
  this.payload = payload;
30
29
  }
31
30
  /** Encode the body to a single `Uint8Array` (no length prefix; the datagram boundary delimits it). */
32
- encode() {
33
- const subscribe = Varint.encodeTo(new ArrayBuffer(8), this.subscribe);
34
- const sequence = Varint.encodeTo(new ArrayBuffer(8), this.sequence);
35
- const timestamp = Varint.encodeTo(new ArrayBuffer(8), this.timestamp);
31
+ encode(version) {
32
+ const subscribe = encodeVarint(this.subscribe, version);
33
+ const sequence = encodeVarint(this.sequence, version);
34
+ const timestamp = encodeVarint(this.timestamp, version);
36
35
  const out = new Uint8Array(subscribe.byteLength + sequence.byteLength + timestamp.byteLength + this.payload.byteLength);
37
36
  let offset = 0;
38
37
  out.set(subscribe, offset);
@@ -45,8 +44,8 @@ export class Datagram {
45
44
  return out;
46
45
  }
47
46
  /** Decode a datagram body from the raw bytes of one QUIC datagram. */
48
- static async decode(data) {
49
- const r = new Reader(undefined, data);
47
+ static async decode(data, version) {
48
+ const r = new Reader(undefined, data, version);
50
49
  const subscribe = await r.u62();
51
50
  const sequence = await r.u53();
52
51
  const timestamp = await r.u53();
@@ -1 +1 @@
1
- {"version":3,"file":"datagram.js","sourceRoot":"","sources":["../../src/lite/datagram.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AAEvC;;;;;;GAMG;AACH,MAAM,OAAO,QAAQ;IACpB,kDAAkD;IAClD,SAAS,CAAS;IAClB,uEAAuE;IACvE,QAAQ,CAAS;IACjB,4EAA4E;IAC5E,SAAS,CAAS;IAClB,6DAA6D;IAC7D,OAAO,CAAa;IAEpB,YAAY,SAAiB,EAAE,QAAgB,EAAE,SAAiB,EAAE,OAAmB;QACtF,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,CAAC;IAED,sGAAsG;IACtG,MAAM;QACL,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACtE,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpE,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAEtE,MAAM,GAAG,GAAG,IAAI,UAAU,CACzB,SAAS,CAAC,UAAU,GAAG,QAAQ,CAAC,UAAU,GAAG,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAC3F,CAAC;QACF,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC3B,MAAM,IAAI,SAAS,CAAC,UAAU,CAAC;QAC/B,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC1B,MAAM,IAAI,QAAQ,CAAC,UAAU,CAAC;QAC9B,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC3B,MAAM,IAAI,SAAS,CAAC,UAAU,CAAC;QAC/B,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC9B,OAAO,GAAG,CAAC;IACZ,CAAC;IAED,sEAAsE;IACtE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAgB;QACnC,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACtC,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;QAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;QAClC,OAAO,IAAI,QAAQ,CAAC,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;CACD","sourcesContent":["/**\n * Wire-level QUIC datagram body for moq-lite-05 (§6.4).\n *\n * @module\n */\nimport { Reader } from \"../stream.ts\";\nimport * as Varint from \"../varint.ts\";\n\n/**\n * A QUIC datagram body: `subscribe (i) | sequence (i) | timestamp (i) | payload (b)`.\n *\n * The payload runs to the datagram boundary, so unlike a size-prefixed lite message there is no\n * inner length prefix. Mirrors the Rust `lite::Datagram`; the model counterpart is\n * {@link Datagram} in `../datagram.ts`.\n */\nexport class Datagram {\n\t/** Subscribe ID this datagram is delivered on. */\n\tsubscribe: bigint;\n\t/** Group sequence number (shared with the track's group namespace). */\n\tsequence: number;\n\t/** Absolute presentation timestamp, in the track's negotiated timescale. */\n\ttimestamp: number;\n\t/** The frame payload, delimited by the datagram boundary. */\n\tpayload: Uint8Array;\n\n\tconstructor(subscribe: bigint, sequence: number, timestamp: number, payload: Uint8Array) {\n\t\tthis.subscribe = subscribe;\n\t\tthis.sequence = sequence;\n\t\tthis.timestamp = timestamp;\n\t\tthis.payload = payload;\n\t}\n\n\t/** Encode the body to a single `Uint8Array` (no length prefix; the datagram boundary delimits it). */\n\tencode(): Uint8Array {\n\t\tconst subscribe = Varint.encodeTo(new ArrayBuffer(8), this.subscribe);\n\t\tconst sequence = Varint.encodeTo(new ArrayBuffer(8), this.sequence);\n\t\tconst timestamp = Varint.encodeTo(new ArrayBuffer(8), this.timestamp);\n\n\t\tconst out = new Uint8Array(\n\t\t\tsubscribe.byteLength + sequence.byteLength + timestamp.byteLength + this.payload.byteLength,\n\t\t);\n\t\tlet offset = 0;\n\t\tout.set(subscribe, offset);\n\t\toffset += subscribe.byteLength;\n\t\tout.set(sequence, offset);\n\t\toffset += sequence.byteLength;\n\t\tout.set(timestamp, offset);\n\t\toffset += timestamp.byteLength;\n\t\tout.set(this.payload, offset);\n\t\treturn out;\n\t}\n\n\t/** Decode a datagram body from the raw bytes of one QUIC datagram. */\n\tstatic async decode(data: Uint8Array): Promise<Datagram> {\n\t\tconst r = new Reader(undefined, data);\n\t\tconst subscribe = await r.u62();\n\t\tconst sequence = await r.u53();\n\t\tconst timestamp = await r.u53();\n\t\tconst payload = await r.readAll();\n\t\treturn new Datagram(subscribe, sequence, timestamp, payload);\n\t}\n}\n"]}
1
+ {"version":3,"file":"datagram.js","sourceRoot":"","sources":["../../src/lite/datagram.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAGpD;;;;;;GAMG;AACH,MAAM,OAAO,QAAQ;IACpB,kDAAkD;IAClD,SAAS,CAAS;IAClB,uEAAuE;IACvE,QAAQ,CAAS;IACjB,4EAA4E;IAC5E,SAAS,CAAS;IAClB,6DAA6D;IAC7D,OAAO,CAAa;IAEpB,YAAY,SAAiB,EAAE,QAAgB,EAAE,SAAiB,EAAE,OAAmB;QACtF,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,CAAC;IAED,sGAAsG;IACtG,MAAM,CAAC,OAAgB;QACtB,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACxD,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACtD,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAExD,MAAM,GAAG,GAAG,IAAI,UAAU,CACzB,SAAS,CAAC,UAAU,GAAG,QAAQ,CAAC,UAAU,GAAG,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAC3F,CAAC;QACF,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC3B,MAAM,IAAI,SAAS,CAAC,UAAU,CAAC;QAC/B,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC1B,MAAM,IAAI,QAAQ,CAAC,UAAU,CAAC;QAC9B,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC3B,MAAM,IAAI,SAAS,CAAC,UAAU,CAAC;QAC/B,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC9B,OAAO,GAAG,CAAC;IACZ,CAAC;IAED,sEAAsE;IACtE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAgB,EAAE,OAAgB;QACrD,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAC/C,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;QAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;QAClC,OAAO,IAAI,QAAQ,CAAC,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;CACD","sourcesContent":["/**\n * Wire-level QUIC datagram body for moq-lite-05 (§6.4).\n *\n * @module\n */\nimport { encodeVarint, Reader } from \"../stream.ts\";\nimport type { Version } from \"./version.ts\";\n\n/**\n * A QUIC datagram body: `subscribe (i) | sequence (i) | timestamp (i) | payload (b)`.\n *\n * The payload runs to the datagram boundary, so unlike a size-prefixed lite message there is no\n * inner length prefix. Mirrors the Rust `lite::Datagram`; the model counterpart is\n * {@link Datagram} in `../datagram.ts`.\n */\nexport class Datagram {\n\t/** Subscribe ID this datagram is delivered on. */\n\tsubscribe: bigint;\n\t/** Group sequence number (shared with the track's group namespace). */\n\tsequence: number;\n\t/** Absolute presentation timestamp, in the track's negotiated timescale. */\n\ttimestamp: number;\n\t/** The frame payload, delimited by the datagram boundary. */\n\tpayload: Uint8Array;\n\n\tconstructor(subscribe: bigint, sequence: number, timestamp: number, payload: Uint8Array) {\n\t\tthis.subscribe = subscribe;\n\t\tthis.sequence = sequence;\n\t\tthis.timestamp = timestamp;\n\t\tthis.payload = payload;\n\t}\n\n\t/** Encode the body to a single `Uint8Array` (no length prefix; the datagram boundary delimits it). */\n\tencode(version: Version): Uint8Array {\n\t\tconst subscribe = encodeVarint(this.subscribe, version);\n\t\tconst sequence = encodeVarint(this.sequence, version);\n\t\tconst timestamp = encodeVarint(this.timestamp, version);\n\n\t\tconst out = new Uint8Array(\n\t\t\tsubscribe.byteLength + sequence.byteLength + timestamp.byteLength + this.payload.byteLength,\n\t\t);\n\t\tlet offset = 0;\n\t\tout.set(subscribe, offset);\n\t\toffset += subscribe.byteLength;\n\t\tout.set(sequence, offset);\n\t\toffset += sequence.byteLength;\n\t\tout.set(timestamp, offset);\n\t\toffset += timestamp.byteLength;\n\t\tout.set(this.payload, offset);\n\t\treturn out;\n\t}\n\n\t/** Decode a datagram body from the raw bytes of one QUIC datagram. */\n\tstatic async decode(data: Uint8Array, version: Version): Promise<Datagram> {\n\t\tconst r = new Reader(undefined, data, version);\n\t\tconst subscribe = await r.u62();\n\t\tconst sequence = await r.u53();\n\t\tconst timestamp = await r.u53();\n\t\tconst payload = await r.readAll();\n\t\treturn new Datagram(subscribe, sequence, timestamp, payload);\n\t}\n}\n"]}
package/lite/fetch.d.ts CHANGED
@@ -7,7 +7,21 @@ export declare class Fetch {
7
7
  track: string;
8
8
  priority: number;
9
9
  group: number;
10
- constructor(broadcast: Path.Valid, track: string, priority: number, group: number);
10
+ /** Index of the first frame to return; 0 is the start of the group. Lite-06+. */
11
+ startFrame: number;
12
+ /**
13
+ * Index of the last frame to return (inclusive), or undefined for through the end
14
+ * of the group. Lite-06+.
15
+ */
16
+ endFrame?: number;
17
+ constructor({ broadcast, track, priority, group, startFrame, endFrame, }: {
18
+ broadcast: Path.Valid;
19
+ track: string;
20
+ priority: number;
21
+ group: number;
22
+ startFrame?: number;
23
+ endFrame?: number;
24
+ });
11
25
  encode(w: Writer, version: Version): Promise<void>;
12
26
  static decode(r: Reader, version: Version): Promise<Fetch>;
13
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/lite/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAYvC,qBAAa,KAAK;;IACjB,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IAEd,YAAY,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAKhF;IAkBK,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":"fetch.d.ts","sourceRoot":"","sources":["../../src/lite/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAkB,OAAO,EAAE,MAAM,cAAc,CAAC;AAYvD,qBAAa,KAAK;;IACjB,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IAEd,iFAAiF;IACjF,UAAU,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,YAAY,EACX,SAAS,EACT,KAAK,EACL,QAAQ,EACR,KAAK,EACL,UAAc,EACd,QAAQ,GACR,EAAE;QACF,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC;QACtB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;KAClB,EAOA;IA2CK,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"}
package/lite/fetch.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /* @ts-self-types="./fetch.d.ts" */
2
2
  import * as Path from "../path.js";
3
3
  import * as Message from "./message.js";
4
- import { Version } from "./version.js";
4
+ import { hasFrameBounds, Version } from "./version.js";
5
5
  function guardFetch(version) {
6
6
  switch (version) {
7
7
  case Version.DRAFT_01:
@@ -16,32 +16,64 @@ export class Fetch {
16
16
  track;
17
17
  priority;
18
18
  group;
19
- constructor(broadcast, track, priority, group) {
19
+ /** Index of the first frame to return; 0 is the start of the group. Lite-06+. */
20
+ startFrame;
21
+ /**
22
+ * Index of the last frame to return (inclusive), or undefined for through the end
23
+ * of the group. Lite-06+.
24
+ */
25
+ endFrame;
26
+ constructor({ broadcast, track, priority, group, startFrame = 0, endFrame, }) {
20
27
  this.broadcast = broadcast;
21
28
  this.track = track;
22
29
  this.priority = priority;
23
30
  this.group = group;
31
+ this.startFrame = startFrame;
32
+ this.endFrame = endFrame;
24
33
  }
25
- async #encode(w) {
34
+ async #encode(w, version) {
26
35
  await w.string(Path.encode(this.broadcast));
27
36
  await w.string(this.track);
28
37
  await w.u8(this.priority);
29
38
  await w.u53(this.group);
39
+ if (hasFrameBounds(version)) {
40
+ await w.u53(this.startFrame);
41
+ await w.u53(this.endFrame !== undefined ? this.endFrame + 1 : 0);
42
+ }
43
+ else if (this.startFrame !== 0 || this.endFrame !== undefined) {
44
+ // The peer would serve the whole group, including frames we excluded.
45
+ throw new Error("frame bounds not supported for this version");
46
+ }
30
47
  }
31
- static async #decode(r) {
48
+ static async #decode(r, version) {
32
49
  const broadcast = Path.decode(await r.string());
33
50
  const track = await r.string();
34
51
  const priority = await r.u8();
35
52
  const group = await r.u53();
36
- return new Fetch(broadcast, track, priority, group);
53
+ if (!hasFrameBounds(version)) {
54
+ return new Fetch({ broadcast, track, priority, group });
55
+ }
56
+ const startFrame = await r.u53();
57
+ const endFrame = await r.u53();
58
+ if (endFrame > 0 && endFrame - 1 < startFrame) {
59
+ throw new Error("fetch frame range ends before it starts");
60
+ }
61
+ return new Fetch({
62
+ broadcast,
63
+ track,
64
+ priority,
65
+ group,
66
+ startFrame,
67
+ endFrame: endFrame > 0 ? endFrame - 1 : undefined,
68
+ });
37
69
  }
38
70
  async encode(w, version) {
39
71
  guardFetch(version);
40
- return Message.encode(w, (w) => this.#encode(w));
72
+ return Message.encode(w, (w) => this.#encode(w, version));
41
73
  }
42
74
  static async decode(r, version) {
43
75
  guardFetch(version);
44
- return Message.decode(r, (r) => Fetch.#decode(r));
76
+ return Message.decode(r, (r) => Fetch.#decode(r, version));
45
77
  }
46
78
  }
47
79
  //# sourceMappingURL=fetch.js.map
package/lite/fetch.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/lite/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AAEnC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,SAAS,UAAU,CAAC,OAAgB;IACnC,QAAQ,OAAO,EAAE,CAAC;QACjB,KAAK,OAAO,CAAC,QAAQ,CAAC;QACtB,KAAK,OAAO,CAAC,QAAQ;YACpB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACzD;YACC,MAAM;IACR,CAAC;AACF,CAAC;AAED,MAAM,OAAO,KAAK;IACjB,SAAS,CAAa;IACtB,KAAK,CAAS;IACd,QAAQ,CAAS;IACjB,KAAK,CAAS;IAEd,YAAY,SAAqB,EAAE,KAAa,EAAE,QAAgB,EAAE,KAAa;QAChF,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,CAAS;QACtB,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QAC5C,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1B,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAS;QAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;QAE5B,OAAO,IAAI,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,CAAS,EAAE,OAAgB;QACvC,UAAU,CAAC,OAAO,CAAC,CAAC;QACpB,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAS,EAAE,OAAgB;QAC9C,UAAU,CAAC,OAAO,CAAC,CAAC;QACpB,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC;CACD","sourcesContent":["import * as Path from \"../path.ts\";\nimport type { Reader, Writer } from \"../stream.ts\";\nimport * as Message from \"./message.ts\";\nimport { Version } from \"./version.ts\";\n\nfunction guardFetch(version: Version) {\n\tswitch (version) {\n\t\tcase Version.DRAFT_01:\n\t\tcase Version.DRAFT_02:\n\t\t\tthrow new Error(\"fetch not supported for this version\");\n\t\tdefault:\n\t\t\tbreak;\n\t}\n}\n\nexport class Fetch {\n\tbroadcast: Path.Valid;\n\ttrack: string;\n\tpriority: number;\n\tgroup: number;\n\n\tconstructor(broadcast: Path.Valid, track: string, priority: number, group: number) {\n\t\tthis.broadcast = broadcast;\n\t\tthis.track = track;\n\t\tthis.priority = priority;\n\t\tthis.group = group;\n\t}\n\n\tasync #encode(w: Writer) {\n\t\tawait w.string(Path.encode(this.broadcast));\n\t\tawait w.string(this.track);\n\t\tawait w.u8(this.priority);\n\t\tawait w.u53(this.group);\n\t}\n\n\tstatic async #decode(r: Reader): Promise<Fetch> {\n\t\tconst broadcast = Path.decode(await r.string());\n\t\tconst track = await r.string();\n\t\tconst priority = await r.u8();\n\t\tconst group = await r.u53();\n\n\t\treturn new Fetch(broadcast, track, priority, group);\n\t}\n\n\tasync encode(w: Writer, version: Version): Promise<void> {\n\t\tguardFetch(version);\n\t\treturn Message.encode(w, (w) => this.#encode(w));\n\t}\n\n\tstatic async decode(r: Reader, version: Version): Promise<Fetch> {\n\t\tguardFetch(version);\n\t\treturn Message.decode(r, (r) => Fetch.#decode(r));\n\t}\n}\n"]}
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/lite/fetch.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Path from \"../path.ts\";\nimport type { Reader, Writer } from \"../stream.ts\";\nimport * as Message from \"./message.ts\";\nimport { hasFrameBounds, Version } from \"./version.ts\";\n\nfunction guardFetch(version: Version) {\n\tswitch (version) {\n\t\tcase Version.DRAFT_01:\n\t\tcase Version.DRAFT_02:\n\t\t\tthrow new Error(\"fetch not supported for this version\");\n\t\tdefault:\n\t\t\tbreak;\n\t}\n}\n\nexport class Fetch {\n\tbroadcast: Path.Valid;\n\ttrack: string;\n\tpriority: number;\n\tgroup: number;\n\n\t/** Index of the first frame to return; 0 is the start of the group. Lite-06+. */\n\tstartFrame: number;\n\n\t/**\n\t * Index of the last frame to return (inclusive), or undefined for through the end\n\t * of the group. Lite-06+.\n\t */\n\tendFrame?: number;\n\n\tconstructor({\n\t\tbroadcast,\n\t\ttrack,\n\t\tpriority,\n\t\tgroup,\n\t\tstartFrame = 0,\n\t\tendFrame,\n\t}: {\n\t\tbroadcast: Path.Valid;\n\t\ttrack: string;\n\t\tpriority: number;\n\t\tgroup: number;\n\t\tstartFrame?: number;\n\t\tendFrame?: number;\n\t}) {\n\t\tthis.broadcast = broadcast;\n\t\tthis.track = track;\n\t\tthis.priority = priority;\n\t\tthis.group = group;\n\t\tthis.startFrame = startFrame;\n\t\tthis.endFrame = endFrame;\n\t}\n\n\tasync #encode(w: Writer, version: Version) {\n\t\tawait w.string(Path.encode(this.broadcast));\n\t\tawait w.string(this.track);\n\t\tawait w.u8(this.priority);\n\t\tawait w.u53(this.group);\n\n\t\tif (hasFrameBounds(version)) {\n\t\t\tawait w.u53(this.startFrame);\n\t\t\tawait w.u53(this.endFrame !== undefined ? this.endFrame + 1 : 0);\n\t\t} else if (this.startFrame !== 0 || this.endFrame !== undefined) {\n\t\t\t// The peer would serve the whole group, including frames we excluded.\n\t\t\tthrow new Error(\"frame bounds not supported for this version\");\n\t\t}\n\t}\n\n\tstatic async #decode(r: Reader, version: Version): Promise<Fetch> {\n\t\tconst broadcast = Path.decode(await r.string());\n\t\tconst track = await r.string();\n\t\tconst priority = await r.u8();\n\t\tconst group = await r.u53();\n\n\t\tif (!hasFrameBounds(version)) {\n\t\t\treturn new Fetch({ broadcast, track, priority, group });\n\t\t}\n\n\t\tconst startFrame = await r.u53();\n\t\tconst endFrame = await r.u53();\n\t\tif (endFrame > 0 && endFrame - 1 < startFrame) {\n\t\t\tthrow new Error(\"fetch frame range ends before it starts\");\n\t\t}\n\n\t\treturn new Fetch({\n\t\t\tbroadcast,\n\t\t\ttrack,\n\t\t\tpriority,\n\t\t\tgroup,\n\t\t\tstartFrame,\n\t\t\tendFrame: endFrame > 0 ? endFrame - 1 : undefined,\n\t\t});\n\t}\n\n\tasync encode(w: Writer, version: Version): Promise<void> {\n\t\tguardFetch(version);\n\t\treturn Message.encode(w, (w) => this.#encode(w, version));\n\t}\n\n\tstatic async decode(r: Reader, version: Version): Promise<Fetch> {\n\t\tguardFetch(version);\n\t\treturn Message.decode(r, (r) => Fetch.#decode(r, version));\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"goaway.d.ts","sourceRoot":"","sources":["../../src/lite/goaway.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAgBvC,qBAAa,MAAM;;IAClB,GAAG,EAAE,MAAM,CAAC;IAEZ,YAAY,GAAG,EAAE,MAAM,EAEtB;IAUK,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,MAAM,CAAC,CAGhE;CACD"}
1
+ {"version":3,"file":"goaway.d.ts","sourceRoot":"","sources":["../../src/lite/goaway.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAgBvC,qBAAa,MAAM;;IAClB,GAAG,EAAE,MAAM,CAAC;IAEZ,YAAY,GAAG,EAAE,MAAM,EAEtB;IAgBK,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,MAAM,CAAC,CAGhE;CACD"}
package/lite/goaway.js CHANGED
@@ -23,7 +23,13 @@ export class Goaway {
23
23
  await w.string(this.uri);
24
24
  }
25
25
  static async #decode(r) {
26
- return new Goaway(await r.string());
26
+ const uri = await r.string();
27
+ // The URI is capped at 8,192 bytes, matching the IETF wire and the Rust
28
+ // decoder; a longer one is a protocol violation.
29
+ if (new TextEncoder().encode(uri).byteLength > 8192) {
30
+ throw new Error("GOAWAY URI exceeds 8,192 bytes");
31
+ }
32
+ return new Goaway(uri);
27
33
  }
28
34
  async encode(w, version) {
29
35
  guardGoaway(version);
@@ -1 +1 @@
1
- {"version":3,"file":"goaway.js","sourceRoot":"","sources":["../../src/lite/goaway.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,SAAS,WAAW,CAAC,OAAgB;IACpC,QAAQ,OAAO,EAAE,CAAC;QACjB,KAAK,OAAO,CAAC,QAAQ,CAAC;QACtB,KAAK,OAAO,CAAC,QAAQ,CAAC;QACtB,KAAK,OAAO,CAAC,QAAQ;YACpB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC1D;YACC,MAAM;IACR,CAAC;AACF,CAAC;AAED,gFAAgF;AAChF,GAAG;AACH,iBAAiB;AACjB,MAAM,OAAO,MAAM;IAClB,GAAG,CAAS;IAEZ,YAAY,GAAW;QACtB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,CAAS;QACtB,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAS;QAC7B,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,CAAS,EAAE,OAAgB;QACvC,WAAW,CAAC,OAAO,CAAC,CAAC;QACrB,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,WAAW,CAAC,OAAO,CAAC,CAAC;QACrB,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;CACD","sourcesContent":["import type { Reader, Writer } from \"../stream.ts\";\nimport * as Message from \"./message.ts\";\nimport { Version } from \"./version.ts\";\n\nfunction guardGoaway(version: Version) {\n\tswitch (version) {\n\t\tcase Version.DRAFT_01:\n\t\tcase Version.DRAFT_02:\n\t\tcase Version.DRAFT_03:\n\t\t\tthrow new Error(\"goaway not supported for this version\");\n\t\tdefault:\n\t\t\tbreak;\n\t}\n}\n\n/// Sent to gracefully shut down a session and optionally redirect to a new URI.\n///\n/// Lite04+ only.\nexport class Goaway {\n\turi: string;\n\n\tconstructor(uri: string) {\n\t\tthis.uri = uri;\n\t}\n\n\tasync #encode(w: Writer) {\n\t\tawait w.string(this.uri);\n\t}\n\n\tstatic async #decode(r: Reader): Promise<Goaway> {\n\t\treturn new Goaway(await r.string());\n\t}\n\n\tasync encode(w: Writer, version: Version): Promise<void> {\n\t\tguardGoaway(version);\n\t\treturn Message.encode(w, this.#encode.bind(this));\n\t}\n\n\tstatic async decode(r: Reader, version: Version): Promise<Goaway> {\n\t\tguardGoaway(version);\n\t\treturn Message.decode(r, Goaway.#decode);\n\t}\n}\n"]}
1
+ {"version":3,"file":"goaway.js","sourceRoot":"","sources":["../../src/lite/goaway.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,SAAS,WAAW,CAAC,OAAgB;IACpC,QAAQ,OAAO,EAAE,CAAC;QACjB,KAAK,OAAO,CAAC,QAAQ,CAAC;QACtB,KAAK,OAAO,CAAC,QAAQ,CAAC;QACtB,KAAK,OAAO,CAAC,QAAQ;YACpB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC1D;YACC,MAAM;IACR,CAAC;AACF,CAAC;AAED,gFAAgF;AAChF,GAAG;AACH,iBAAiB;AACjB,MAAM,OAAO,MAAM;IAClB,GAAG,CAAS;IAEZ,YAAY,GAAW;QACtB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,CAAS;QACtB,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAS;QAC7B,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;QAC7B,wEAAwE;QACxE,iDAAiD;QACjD,IAAI,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,GAAG,IAAI,EAAE,CAAC;YACrD,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,CAAS,EAAE,OAAgB;QACvC,WAAW,CAAC,OAAO,CAAC,CAAC;QACrB,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,WAAW,CAAC,OAAO,CAAC,CAAC;QACrB,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;CACD","sourcesContent":["import type { Reader, Writer } from \"../stream.ts\";\nimport * as Message from \"./message.ts\";\nimport { Version } from \"./version.ts\";\n\nfunction guardGoaway(version: Version) {\n\tswitch (version) {\n\t\tcase Version.DRAFT_01:\n\t\tcase Version.DRAFT_02:\n\t\tcase Version.DRAFT_03:\n\t\t\tthrow new Error(\"goaway not supported for this version\");\n\t\tdefault:\n\t\t\tbreak;\n\t}\n}\n\n/// Sent to gracefully shut down a session and optionally redirect to a new URI.\n///\n/// Lite04+ only.\nexport class Goaway {\n\turi: string;\n\n\tconstructor(uri: string) {\n\t\tthis.uri = uri;\n\t}\n\n\tasync #encode(w: Writer) {\n\t\tawait w.string(this.uri);\n\t}\n\n\tstatic async #decode(r: Reader): Promise<Goaway> {\n\t\tconst uri = await r.string();\n\t\t// The URI is capped at 8,192 bytes, matching the IETF wire and the Rust\n\t\t// decoder; a longer one is a protocol violation.\n\t\tif (new TextEncoder().encode(uri).byteLength > 8192) {\n\t\t\tthrow new Error(\"GOAWAY URI exceeds 8,192 bytes\");\n\t\t}\n\t\treturn new Goaway(uri);\n\t}\n\n\tasync encode(w: Writer, version: Version): Promise<void> {\n\t\tguardGoaway(version);\n\t\treturn Message.encode(w, this.#encode.bind(this));\n\t}\n\n\tstatic async decode(r: Reader, version: Version): Promise<Goaway> {\n\t\tguardGoaway(version);\n\t\treturn Message.decode(r, Goaway.#decode);\n\t}\n}\n"]}
package/lite/group.d.ts CHANGED
@@ -1,18 +1,36 @@
1
- import type { Reader, Writer } from "../stream";
1
+ import type * as netGroup from "../group";
2
+ import type { Cursor, Reader, Writer } from "../stream";
3
+ import { type Version } from "./version";
2
4
  export declare class Group {
3
5
  #private;
4
6
  subscribe: bigint;
5
7
  sequence: number;
6
- constructor(subscribe: bigint, sequence: number);
7
- encode(w: Writer): Promise<void>;
8
- static decode(r: Reader): Promise<Group>;
9
- static decodeMaybe(r: Reader): Promise<Group | undefined>;
10
- }
11
- export declare class Frame {
12
- #private;
13
- payload: Uint8Array;
14
- constructor(payload: Uint8Array);
15
- encode(w: Writer): Promise<void>;
16
- static decode(r: Reader): Promise<Frame>;
8
+ /**
9
+ * The index of the first frame on this stream within the group.
10
+ *
11
+ * 0 (the common case) means the stream carries the group from its beginning. A
12
+ * higher value means the leading frames are not here, either because the
13
+ * subscription started partway into the group or because the publisher only holds
14
+ * the tail. Lite-06+; older versions always start at 0.
15
+ */
16
+ frameStart: number;
17
+ constructor({ subscribe, sequence, frameStart, }: {
18
+ subscribe: bigint;
19
+ sequence: number;
20
+ frameStart?: number;
21
+ });
22
+ encode(w: Writer, version: Version): Promise<void>;
23
+ static decode(r: Reader, version: Version): Promise<Group>;
24
+ static decodeMaybe(r: Reader, version: Version): Promise<Group | undefined>;
17
25
  }
26
+ /**
27
+ * A synchronous decode for one frame of a group or FETCH response stream.
28
+ *
29
+ * A non-zero `scale` means every frame is prefixed with a zigzag-delta timestamp (the lite-05
30
+ * FRAME format), decoded into a Timestamp at that scale. Scale 0 (pre-lite-05) carries no
31
+ * timestamp, so frames are wall-clock stamped on arrival.
32
+ */
33
+ export declare function frameDecoder(scale: number): (c: Cursor) => netGroup.Frame;
34
+ /** Write a group stream's frames into `producer` until the stream ends or the producer closes. */
35
+ export declare function readFrames(stream: Reader, producer: netGroup.Producer, scale: number): Promise<void>;
18
36
  //# sourceMappingURL=group.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../../src/lite/group.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAGnD,qBAAa,KAAK;;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IAEjB,YAAY,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAG9C;IAWK,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAErC;IAED,OAAa,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAE7C;IAED,OAAa,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAE9D;CACD;AAED,qBAAa,KAAK;;IACjB,OAAO,EAAE,UAAU,CAAC;IAEpB,YAAY,OAAO,EAAE,UAAU,EAE9B;IAWK,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAErC;IAED,OAAa,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAE7C;CACD"}
1
+ {"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../../src/lite/group.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,QAAQ,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAG3D,OAAO,EAAkB,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5D,qBAAa,KAAK;;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;;;OAOG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB,YAAY,EACX,SAAS,EACT,QAAQ,EACR,UAAc,GACd,EAAE;QACF,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;KACpB,EAIA;IAoBK,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAEvD;IAED,OAAa,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAE/D;IAED,OAAa,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAEhF;CACD;AAOD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,QAAQ,CAAC,KAAK,CAczE;AAED,kGAAkG;AAClG,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAW1G"}