@norskvideo/moq-net 0.1.3 → 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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consume.d.ts","sourceRoot":"","sources":["../src/consume.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,SAAS,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAC;AAEvC;;;;;;;;;;;;GAYG;AACH,qBAAa,cAAc;;IAI1B,yFAAyF;IACzF,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,QAAQ,GAAG,SAAS,CAIpD;IAED;;;OAGG;IACH,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAUzE;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAE5B;CACD"}
package/consume.js ADDED
@@ -0,0 +1,60 @@
1
+ /* @ts-self-types="./consume.d.ts" */
2
+ /**
3
+ * Per-path dedup cache for consumed broadcasts, shared by the moq-lite and moq-ietf
4
+ * subscribers.
5
+ *
6
+ * `Connection.consume(path)` must not mint a fresh subscription per call: repeat requests
7
+ * for the same path (e.g. several renditions referencing one `broadcast: "./source"`) should
8
+ * share a single upstream subscription. This mirrors the Rust `origin::Consumer` weak-cache:
9
+ * a still-live path resolves to a shared {@link broadcast.Consumer.clone}, a closed one is
10
+ * re-consumed on the next request. Each handle is reference-counted, so the shared broadcast
11
+ * closes once every caller has closed its handle.
12
+ *
13
+ * @internal
14
+ */
15
+ export class BroadcastCache {
16
+ // The base handle per path; callers get reference-counted clones of it.
17
+ #cache = new Map();
18
+ /** A shared handle to the live broadcast cached for `path`, or `undefined` on a miss. */
19
+ get(path) {
20
+ const base = this.#cache.get(path);
21
+ if (base && base.closed.peek() === undefined)
22
+ return base.clone();
23
+ return undefined;
24
+ }
25
+ /**
26
+ * Cache `consumer` as the base handle for `path` (evicting it once it closes) and return it.
27
+ * Call on a {@link get} miss, after wiring up the fresh consumer's subscribe loop.
28
+ */
29
+ insert(path, consumer) {
30
+ this.#cache.set(path, consumer);
31
+ // Drop the entry once the broadcast closes (every handle released), so the next request
32
+ // re-consumes rather than cloning a dead handle. Guard against a newer entry for the path.
33
+ void consumer.closed.then(() => {
34
+ if (this.#cache.get(path) === consumer)
35
+ this.#cache.delete(path);
36
+ });
37
+ return consumer;
38
+ }
39
+ /**
40
+ * Stop sharing the broadcast cached for `path`, so the next request subscribes fresh.
41
+ *
42
+ * Call when the path's advertisement goes away. A handle only leaves the cache on its own
43
+ * once *every* holder has closed it, so one holder outliving the publisher (a second
44
+ * watcher, or a caller consuming the path directly) would otherwise keep the dead
45
+ * generation's cached tracks alive and hand them to whoever consumes the path next.
46
+ * Existing handles are left alone: they belong to their holders, and the wire resets
47
+ * whatever they still have open.
48
+ *
49
+ * Eviction is unconditional, which costs a dedup miss when two announcement streams watch
50
+ * one path: the second stream's retraction can arrive after the first has already seen the
51
+ * replacement, dropping the fresh entry so the next request subscribes again instead of
52
+ * sharing. Telling that stale retraction from a live one needs a generation id on the
53
+ * advertisement (moq-lite's `Epoch`, not yet on the wire), so until then this errs toward a
54
+ * duplicate subscription rather than risk handing out a dead one.
55
+ */
56
+ evict(path) {
57
+ this.#cache.delete(path);
58
+ }
59
+ }
60
+ //# sourceMappingURL=consume.js.map
package/consume.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consume.js","sourceRoot":"","sources":["../src/consume.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,cAAc;IAC1B,wEAAwE;IACxE,MAAM,GAAG,IAAI,GAAG,EAAkC,CAAC;IAEnD,yFAAyF;IACzF,GAAG,CAAC,IAAgB;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC;QAClE,OAAO,SAAS,CAAC;IAClB,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,IAAgB,EAAE,QAA4B;QACpD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAEhC,wFAAwF;QACxF,2FAA2F;QAC3F,KAAK,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;YAC9B,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,QAAQ;gBAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QAEH,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,IAAgB;QACrB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CACD","sourcesContent":["import type * as broadcast from \"./broadcast.ts\";\nimport type * as Path from \"./path.ts\";\n\n/**\n * Per-path dedup cache for consumed broadcasts, shared by the moq-lite and moq-ietf\n * subscribers.\n *\n * `Connection.consume(path)` must not mint a fresh subscription per call: repeat requests\n * for the same path (e.g. several renditions referencing one `broadcast: \"./source\"`) should\n * share a single upstream subscription. This mirrors the Rust `origin::Consumer` weak-cache:\n * a still-live path resolves to a shared {@link broadcast.Consumer.clone}, a closed one is\n * re-consumed on the next request. Each handle is reference-counted, so the shared broadcast\n * closes once every caller has closed its handle.\n *\n * @internal\n */\nexport class BroadcastCache {\n\t// The base handle per path; callers get reference-counted clones of it.\n\t#cache = new Map<Path.Valid, broadcast.Consumer>();\n\n\t/** A shared handle to the live broadcast cached for `path`, or `undefined` on a miss. */\n\tget(path: Path.Valid): broadcast.Consumer | undefined {\n\t\tconst base = this.#cache.get(path);\n\t\tif (base && base.closed.peek() === undefined) return base.clone();\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Cache `consumer` as the base handle for `path` (evicting it once it closes) and return it.\n\t * Call on a {@link get} miss, after wiring up the fresh consumer's subscribe loop.\n\t */\n\tinsert(path: Path.Valid, consumer: broadcast.Consumer): broadcast.Consumer {\n\t\tthis.#cache.set(path, consumer);\n\n\t\t// Drop the entry once the broadcast closes (every handle released), so the next request\n\t\t// re-consumes rather than cloning a dead handle. Guard against a newer entry for the path.\n\t\tvoid consumer.closed.then(() => {\n\t\t\tif (this.#cache.get(path) === consumer) this.#cache.delete(path);\n\t\t});\n\n\t\treturn consumer;\n\t}\n\n\t/**\n\t * Stop sharing the broadcast cached for `path`, so the next request subscribes fresh.\n\t *\n\t * Call when the path's advertisement goes away. A handle only leaves the cache on its own\n\t * once *every* holder has closed it, so one holder outliving the publisher (a second\n\t * watcher, or a caller consuming the path directly) would otherwise keep the dead\n\t * generation's cached tracks alive and hand them to whoever consumes the path next.\n\t * Existing handles are left alone: they belong to their holders, and the wire resets\n\t * whatever they still have open.\n\t *\n\t * Eviction is unconditional, which costs a dedup miss when two announcement streams watch\n\t * one path: the second stream's retraction can arrive after the first has already seen the\n\t * replacement, dropping the fresh entry so the next request subscribes again instead of\n\t * sharing. Telling that stale retraction from a live one needs a generation id on the\n\t * advertisement (moq-lite's `Epoch`, not yet on the wire), so until then this errs toward a\n\t * duplicate subscription rather than risk handing out a dead one.\n\t */\n\tevict(path: Path.Valid): void {\n\t\tthis.#cache.delete(path);\n\t}\n}\n"]}
package/datagram.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * A datagram: a single unreliable payload on a track, parallel to groups.
3
+ *
4
+ * @module
5
+ */
6
+ import type { Timestamp } from "./time";
7
+ /**
8
+ * A single unreliable payload on a track: a sequence number, a presentation timestamp, and the bytes.
9
+ *
10
+ * Unlike a {@link Group} (an ordered stream of frames over a QUIC stream), a datagram is one
11
+ * self-contained payload carried in a single QUIC datagram: best-effort, unordered, never
12
+ * retransmitted. It shares the track's monotonic sequence-number namespace with groups but is
13
+ * otherwise independent. Mirrors the Rust `Datagram`.
14
+ */
15
+ export interface Datagram {
16
+ /** Per-track sequence number, shared with the group namespace. */
17
+ sequence: number;
18
+ /** Presentation timestamp in the track's timescale. */
19
+ timestamp: Timestamp;
20
+ /** The datagram payload. */
21
+ payload: Uint8Array;
22
+ }
23
+ //# sourceMappingURL=datagram.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datagram.d.ts","sourceRoot":"","sources":["../src/datagram.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ;IACxB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,SAAS,EAAE,SAAS,CAAC;IACrB,4BAA4B;IAC5B,OAAO,EAAE,UAAU,CAAC;CACpB"}
package/datagram.js ADDED
@@ -0,0 +1,3 @@
1
+ /* @ts-self-types="./datagram.d.ts" */
2
+ export {};
3
+ //# sourceMappingURL=datagram.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datagram.js","sourceRoot":"","sources":["../src/datagram.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * A datagram: a single unreliable payload on a track, parallel to groups.\n *\n * @module\n */\nimport type { Timestamp } from \"./time.ts\";\n\n/**\n * A single unreliable payload on a track: a sequence number, a presentation timestamp, and the bytes.\n *\n * Unlike a {@link Group} (an ordered stream of frames over a QUIC stream), a datagram is one\n * self-contained payload carried in a single QUIC datagram: best-effort, unordered, never\n * retransmitted. It shares the track's monotonic sequence-number namespace with groups but is\n * otherwise independent. Mirrors the Rust `Datagram`.\n */\nexport interface Datagram {\n\t/** Per-track sequence number, shared with the group namespace. */\n\tsequence: number;\n\t/** Presentation timestamp in the track's timescale. */\n\ttimestamp: Timestamp;\n\t/** The datagram payload. */\n\tpayload: Uint8Array;\n}\n"]}
package/error.d.ts ADDED
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Errors, including the code a peer reports when it resets a stream.
3
+ *
4
+ * @module
5
+ */
6
+ /**
7
+ * An error the peer reported by resetting a stream, carrying the raw code it sent.
8
+ *
9
+ * The codes are not standardized, so this deliberately does not translate one into a local
10
+ * error: the number means whatever the peer's implementation says it means. A read or write
11
+ * rejects with this on every transport, so branch on {@link code} rather than feature-detecting
12
+ * `WebTransportError`, which a non-browser runtime never defines and the WebSocket fallback
13
+ * never throws.
14
+ *
15
+ * Code 0 is what a transport sends when a stream is dropped or aborted with no code of its own.
16
+ *
17
+ * ```ts
18
+ * try {
19
+ * frame = await group.readFrame();
20
+ * } catch (err) {
21
+ * // Whatever this peer's code 2 means to it.
22
+ * if (err instanceof RemoteError && err.code === 2) return;
23
+ * throw err;
24
+ * }
25
+ * ```
26
+ *
27
+ * @public
28
+ */
29
+ export declare class RemoteError extends Error {
30
+ /** The code the peer sent, verbatim. */
31
+ readonly code: number;
32
+ constructor(code: number, options?: {
33
+ cause?: unknown;
34
+ });
35
+ }
36
+ /**
37
+ * A peer broke the protocol in a way the spec says must end the session.
38
+ *
39
+ * Thrown where the violation is detected, rather than handled there: a decoder has no session
40
+ * to close. The dispatch that owns the session watches for it and closes, so a nonconforming
41
+ * peer cannot repeat the violation on the next stream.
42
+ *
43
+ * @internal
44
+ */
45
+ export declare class ProtocolViolation extends Error {
46
+ constructor(message: string, options?: {
47
+ cause?: unknown;
48
+ });
49
+ }
50
+ /**
51
+ * Decode a transport failure into a {@link RemoteError} error when it carries a stream reset code,
52
+ * otherwise pass it through.
53
+ *
54
+ * Native WebTransport rejects with a `WebTransportError`; the WebSocket fallback mints an error
55
+ * with the same `source`/`streamErrorCode` fields. Reading the fields rather than the class
56
+ * covers both, and works in a runtime with no `WebTransportError` at all.
57
+ *
58
+ * @internal Called at the transport boundary so the raw error never reaches an application.
59
+ */
60
+ export declare function fromTransport(err: unknown): Error;
61
+ /**
62
+ * Coerce an unknown thrown value into an `Error`.
63
+ *
64
+ * @internal
65
+ */
66
+ export declare function error(err: unknown): Error;
67
+ /**
68
+ * Format an error into a non-empty, human-readable string for logging.
69
+ *
70
+ * Safari always leaves `WebTransportError.message` blank, so a bare `err.message` degrades to
71
+ * an empty string and the reason is lost. This falls back to the error type name and appends
72
+ * the WebTransport `source` and application `streamErrorCode`, so the log line always says
73
+ * something.
74
+ */
75
+ export declare function reason(err: unknown): string;
76
+ //# sourceMappingURL=error.d.ts.map
package/error.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,WAAY,SAAQ,KAAK;IACrC,wCAAwC;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,YAAY,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAItD;CACD;AAED;;;;;;;;GAQG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC3C,YAAY,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAGzD;CACD;AAcD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,CAIjD;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,CAEzC;AAED;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAa3C"}
package/error.js ADDED
@@ -0,0 +1,107 @@
1
+ /* @ts-self-types="./error.d.ts" */
2
+ /**
3
+ * Errors, including the code a peer reports when it resets a stream.
4
+ *
5
+ * @module
6
+ */
7
+ /**
8
+ * An error the peer reported by resetting a stream, carrying the raw code it sent.
9
+ *
10
+ * The codes are not standardized, so this deliberately does not translate one into a local
11
+ * error: the number means whatever the peer's implementation says it means. A read or write
12
+ * rejects with this on every transport, so branch on {@link code} rather than feature-detecting
13
+ * `WebTransportError`, which a non-browser runtime never defines and the WebSocket fallback
14
+ * never throws.
15
+ *
16
+ * Code 0 is what a transport sends when a stream is dropped or aborted with no code of its own.
17
+ *
18
+ * ```ts
19
+ * try {
20
+ * frame = await group.readFrame();
21
+ * } catch (err) {
22
+ * // Whatever this peer's code 2 means to it.
23
+ * if (err instanceof RemoteError && err.code === 2) return;
24
+ * throw err;
25
+ * }
26
+ * ```
27
+ *
28
+ * @public
29
+ */
30
+ export class RemoteError extends Error {
31
+ /** The code the peer sent, verbatim. */
32
+ code;
33
+ constructor(code, options) {
34
+ super(`remote error: ${code}`, options);
35
+ this.name = "RemoteError";
36
+ this.code = code;
37
+ }
38
+ }
39
+ /**
40
+ * A peer broke the protocol in a way the spec says must end the session.
41
+ *
42
+ * Thrown where the violation is detected, rather than handled there: a decoder has no session
43
+ * to close. The dispatch that owns the session watches for it and closes, so a nonconforming
44
+ * peer cannot repeat the violation on the next stream.
45
+ *
46
+ * @internal
47
+ */
48
+ export class ProtocolViolation extends Error {
49
+ constructor(message, options) {
50
+ super(message, options);
51
+ this.name = "ProtocolViolation";
52
+ }
53
+ }
54
+ function streamCode(err) {
55
+ if (typeof err !== "object" || err === null)
56
+ return undefined;
57
+ const { source, streamErrorCode } = err;
58
+ if (source !== "stream" || typeof streamErrorCode !== "number")
59
+ return undefined;
60
+ return streamErrorCode;
61
+ }
62
+ /**
63
+ * Decode a transport failure into a {@link RemoteError} error when it carries a stream reset code,
64
+ * otherwise pass it through.
65
+ *
66
+ * Native WebTransport rejects with a `WebTransportError`; the WebSocket fallback mints an error
67
+ * with the same `source`/`streamErrorCode` fields. Reading the fields rather than the class
68
+ * covers both, and works in a runtime with no `WebTransportError` at all.
69
+ *
70
+ * @internal Called at the transport boundary so the raw error never reaches an application.
71
+ */
72
+ export function fromTransport(err) {
73
+ const code = streamCode(err);
74
+ if (code === undefined)
75
+ return error(err);
76
+ return new RemoteError(code, { cause: err });
77
+ }
78
+ /**
79
+ * Coerce an unknown thrown value into an `Error`.
80
+ *
81
+ * @internal
82
+ */
83
+ export function error(err) {
84
+ return err instanceof Error ? err : new Error(String(err));
85
+ }
86
+ /**
87
+ * Format an error into a non-empty, human-readable string for logging.
88
+ *
89
+ * Safari always leaves `WebTransportError.message` blank, so a bare `err.message` degrades to
90
+ * an empty string and the reason is lost. This falls back to the error type name and appends
91
+ * the WebTransport `source` and application `streamErrorCode`, so the log line always says
92
+ * something.
93
+ */
94
+ export function reason(err) {
95
+ const e = error(err);
96
+ // WebTransportError carries the failure origin and the peer's application error code,
97
+ // often the only identifying detail since WebKit leaves `message` empty.
98
+ if (typeof WebTransportError !== "undefined" && e instanceof WebTransportError) {
99
+ const parts = [`source=${e.source}`];
100
+ if (e.streamErrorCode !== null)
101
+ parts.push(`code=${e.streamErrorCode}`);
102
+ const detail = parts.join(" ");
103
+ return e.message ? `${e.message} (${detail})` : `WebTransportError: ${detail}`;
104
+ }
105
+ return e.message || e.name || "unknown error";
106
+ }
107
+ //# sourceMappingURL=error.js.map
package/error.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,OAAO,WAAY,SAAQ,KAAK;IACrC,wCAAwC;IAC/B,IAAI,CAAS;IAEtB,YAAY,IAAY,EAAE,OAA6B;QACtD,KAAK,CAAC,iBAAiB,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IAClB,CAAC;CACD;AAED;;;;;;;;GAQG;AACH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC3C,YAAY,OAAe,EAAE,OAA6B;QACzD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IACjC,CAAC;CACD;AAKD,SAAS,UAAU,CAAC,GAAY;IAC/B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAE9D,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,GAAsB,CAAC;IAC3D,IAAI,MAAM,KAAK,QAAQ,IAAI,OAAO,eAAe,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAEjF,OAAO,eAAe,CAAC;AACxB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,GAAY;IACzC,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1C,OAAO,IAAI,WAAW,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,GAAY;IACjC,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,MAAM,CAAC,GAAY;IAClC,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IAErB,sFAAsF;IACtF,yEAAyE;IACzE,IAAI,OAAO,iBAAiB,KAAK,WAAW,IAAI,CAAC,YAAY,iBAAiB,EAAE,CAAC;QAChF,MAAM,KAAK,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,CAAC,eAAe,KAAK,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;QACxE,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/B,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,MAAM,GAAG,CAAC,CAAC,CAAC,sBAAsB,MAAM,EAAE,CAAC;IAChF,CAAC;IAED,OAAO,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,IAAI,eAAe,CAAC;AAC/C,CAAC","sourcesContent":["/**\n * Errors, including the code a peer reports when it resets a stream.\n *\n * @module\n */\n\n/**\n * An error the peer reported by resetting a stream, carrying the raw code it sent.\n *\n * The codes are not standardized, so this deliberately does not translate one into a local\n * error: the number means whatever the peer's implementation says it means. A read or write\n * rejects with this on every transport, so branch on {@link code} rather than feature-detecting\n * `WebTransportError`, which a non-browser runtime never defines and the WebSocket fallback\n * never throws.\n *\n * Code 0 is what a transport sends when a stream is dropped or aborted with no code of its own.\n *\n * ```ts\n * try {\n * frame = await group.readFrame();\n * } catch (err) {\n * // Whatever this peer's code 2 means to it.\n * if (err instanceof RemoteError && err.code === 2) return;\n * throw err;\n * }\n * ```\n *\n * @public\n */\nexport class RemoteError extends Error {\n\t/** The code the peer sent, verbatim. */\n\treadonly code: number;\n\n\tconstructor(code: number, options?: { cause?: unknown }) {\n\t\tsuper(`remote error: ${code}`, options);\n\t\tthis.name = \"RemoteError\";\n\t\tthis.code = code;\n\t}\n}\n\n/**\n * A peer broke the protocol in a way the spec says must end the session.\n *\n * Thrown where the violation is detected, rather than handled there: a decoder has no session\n * to close. The dispatch that owns the session watches for it and closes, so a nonconforming\n * peer cannot repeat the violation on the next stream.\n *\n * @internal\n */\nexport class ProtocolViolation extends Error {\n\tconstructor(message: string, options?: { cause?: unknown }) {\n\t\tsuper(message, options);\n\t\tthis.name = \"ProtocolViolation\";\n\t}\n}\n\n/** The WebTransport-shaped fields a stream reset code arrives in. */\ntype StreamErrorLike = { source?: unknown; streamErrorCode?: unknown };\n\nfunction streamCode(err: unknown): number | undefined {\n\tif (typeof err !== \"object\" || err === null) return undefined;\n\n\tconst { source, streamErrorCode } = err as StreamErrorLike;\n\tif (source !== \"stream\" || typeof streamErrorCode !== \"number\") return undefined;\n\n\treturn streamErrorCode;\n}\n\n/**\n * Decode a transport failure into a {@link RemoteError} error when it carries a stream reset code,\n * otherwise pass it through.\n *\n * Native WebTransport rejects with a `WebTransportError`; the WebSocket fallback mints an error\n * with the same `source`/`streamErrorCode` fields. Reading the fields rather than the class\n * covers both, and works in a runtime with no `WebTransportError` at all.\n *\n * @internal Called at the transport boundary so the raw error never reaches an application.\n */\nexport function fromTransport(err: unknown): Error {\n\tconst code = streamCode(err);\n\tif (code === undefined) return error(err);\n\treturn new RemoteError(code, { cause: err });\n}\n\n/**\n * Coerce an unknown thrown value into an `Error`.\n *\n * @internal\n */\nexport function error(err: unknown): Error {\n\treturn err instanceof Error ? err : new Error(String(err));\n}\n\n/**\n * Format an error into a non-empty, human-readable string for logging.\n *\n * Safari always leaves `WebTransportError.message` blank, so a bare `err.message` degrades to\n * an empty string and the reason is lost. This falls back to the error type name and appends\n * the WebTransport `source` and application `streamErrorCode`, so the log line always says\n * something.\n */\nexport function reason(err: unknown): string {\n\tconst e = error(err);\n\n\t// WebTransportError carries the failure origin and the peer's application error code,\n\t// often the only identifying detail since WebKit leaves `message` empty.\n\tif (typeof WebTransportError !== \"undefined\" && e instanceof WebTransportError) {\n\t\tconst parts = [`source=${e.source}`];\n\t\tif (e.streamErrorCode !== null) parts.push(`code=${e.streamErrorCode}`);\n\t\tconst detail = parts.join(\" \");\n\t\treturn e.message ? `${e.message} (${detail})` : `WebTransportError: ${detail}`;\n\t}\n\n\treturn e.message || e.name || \"unknown error\";\n}\n"]}
package/group.d.ts CHANGED
@@ -1,66 +1,171 @@
1
- /** An ordered stream of frames within a track, delivered over a single QUIC stream. */
2
- export declare class Group {
1
+ /**
2
+ * Group role handles: an ordered stream of frames within a track, delivered over one QUIC stream.
3
+ *
4
+ * @module
5
+ */
6
+ import { type GetPromise, type Getter } from "@norskvideo/moq-signals";
7
+ import { Timestamp } from "./time";
8
+ /** Maximum bytes of frames cached in a group before old frames are evicted from the front. */
9
+ export declare const MAX_GROUP_CACHE_BYTES: number;
10
+ /** Maximum number of frames cached in a group before old frames are evicted from the front. */
11
+ export declare const MAX_GROUP_FRAMES = 1024;
12
+ /**
13
+ * A frame buffered in a group: its presentation {@link Timestamp} and payload bytes.
14
+ *
15
+ * The timestamp carries its own scale, so a track can pick its units; the wire layer
16
+ * converts it into the track's negotiated timescale.
17
+ */
18
+ export interface Frame {
19
+ /** The frame payload. */
20
+ payload: Uint8Array;
21
+ /**
22
+ * Presentation timestamp. Required: for a payload with no presentation time of its own
23
+ * (a JSON catalog, control state) pass {@link Timestamp.now} explicitly.
24
+ */
25
+ timestamp: Timestamp;
26
+ }
27
+ /** Options for a sequence-aware frame read. */
28
+ export interface ReadOptions {
29
+ /**
30
+ * The lowest sequence number the caller wants; defaults to the whole group.
31
+ *
32
+ * Frames below it are discarded instead of returned, and frames evicted below it are not
33
+ * a gap: the read resumes at the next retained frame rather than throwing {@link Lagged}.
34
+ * An eviction at or above it still throws, because the caller asked for that frame.
35
+ */
36
+ from?: number;
37
+ }
38
+ /** Immutable group metadata. */
39
+ export interface Info {
40
+ /** Sequence number of this group within its track. */
41
+ sequence: number;
42
+ }
43
+ /**
44
+ * Thrown by a frame read when the reader fell behind the group's eviction window: frames
45
+ * it had not yet read were dropped to stay under the cache cap, so the stream has a gap.
46
+ */
47
+ export declare class Lagged extends Error {
48
+ constructor();
49
+ }
50
+ /**
51
+ * The write side of an ordered stream of frames within a track.
52
+ *
53
+ * @public
54
+ */
55
+ export declare class Producer {
3
56
  #private;
4
57
  /** Sequence number of this group within its track. */
5
58
  readonly sequence: number;
6
- /** Resolves with the abort error (or undefined) once closed. */
7
- readonly closed: Promise<Error | undefined>;
8
59
  constructor(sequence: number);
9
60
  /**
10
- * Writes a frame to the group.
11
- * @param frame - The frame to write
61
+ * Settles once the group closes: `null` on a clean close, or the abort {@link Error}.
62
+ * Peek it synchronously (`undefined` while open), observe it reactively, or `await` it.
63
+ */
64
+ get closed(): GetPromise<Error | null>;
65
+ /** A read handle for this group. */
66
+ consume(): Consumer;
67
+ /**
68
+ * Create an independent read handle that receives every frame written here.
69
+ *
70
+ * Frames written so far are replayed synchronously; later writes and close are teed
71
+ * in as they happen.
72
+ *
73
+ * @internal Track fan-out and fetch coalescing only. Use {@link consume} instead.
74
+ */
75
+ mirror(): Consumer;
76
+ /**
77
+ * Whether any mirror reader is currently attached.
78
+ *
79
+ * Pairs with {@link unused}. Fetch coalescing watches it to cancel a download once every reader
80
+ * has gone: a group can stay open indefinitely (a catalog track, a JSON stream), so it can't
81
+ * rely on the stream ending on its own.
82
+ *
83
+ * @internal Track fan-out and fetch coalescing only.
84
+ */
85
+ get used(): Getter<boolean>;
86
+ /**
87
+ * Resolves once no mirror reader remains (or the group closes).
88
+ *
89
+ * @internal Track fan-out and fetch coalescing only.
12
90
  */
13
- writeFrame(frame: Uint8Array, extensions?: Uint8Array): void;
14
- /** Write a string as a single UTF-8 encoded frame. */
91
+ unused(): Promise<void>;
92
+ /** Writes a frame to the group. */
93
+ writeFrame(frame: Frame): void;
94
+ /** Write a string as a single UTF-8 encoded frame, stamped with {@link Timestamp.now}. */
15
95
  writeString(str: string): void;
16
- /** Write a value as a single JSON-encoded frame. */
96
+ /** Write a value as a single JSON-encoded frame, stamped with {@link Timestamp.now}. */
17
97
  writeJson(json: unknown): void;
18
- /** Write a boolean as a single one-byte frame. */
98
+ /** Write a boolean as a single one-byte frame, stamped with {@link Timestamp.now}. */
19
99
  writeBool(bool: boolean): void;
100
+ /** True once the group has been closed. */
101
+ get isClosed(): boolean;
102
+ /** Closes the group, optionally with an error to abort readers. */
103
+ close(abort?: Error): void;
104
+ }
105
+ /**
106
+ * The read side of an ordered stream of frames within a track.
107
+ *
108
+ * Created internally: obtain one from {@link Producer.consume} or a track subscriber's
109
+ * group reads.
110
+ *
111
+ * @public
112
+ */
113
+ export declare class Consumer {
114
+ #private;
115
+ /** Sequence number of this group within its track. */
116
+ readonly sequence: number;
117
+ private constructor();
118
+ /**
119
+ * Settles once the group closes: `null` on a clean close, or the abort {@link Error}.
120
+ * Peek it synchronously (`undefined` while open), observe it reactively, or `await` it.
121
+ */
122
+ get closed(): GetPromise<Error | null>;
20
123
  /** True once no further frames can be read: the group has closed and every buffered frame is read. */
21
124
  get done(): boolean;
125
+ /** True once the group has been closed, regardless of whether buffered frames remain unread. Synchronous complement to the {@link closed} promise. */
126
+ get isClosed(): boolean;
127
+ /** True if frames were evicted from the front of this group before being read. */
128
+ get skipped(): boolean;
22
129
  /**
23
- * Reads the next already-buffered frame without blocking.
130
+ * How many frames the group has held, including any already read or evicted.
24
131
  *
25
- * Returns `undefined` when nothing is buffered right now. That is *not* by itself end-of-group:
26
- * check {@link done} to tell "no frame buffered yet" (more may arrive) from "the group finished".
27
- * Drain a backlog by looping until this returns `undefined`, then branch on {@link done}: if not
28
- * done, {@link readable} resolves when the next frame arrives.
132
+ * It is also the next frame's sequence number, so `frameCount - 1` names the newest
133
+ * frame written so far. A publisher snapshots it to resolve the track's live edge.
29
134
  */
30
- tryReadFrame(): Uint8Array | undefined;
31
- /** Like {@link tryReadFrame} but also reports the frame's sequence number within the group. */
32
- tryReadFrameSequence(): {
33
- sequence: number;
34
- data: Uint8Array;
35
- extensions?: Uint8Array;
36
- } | undefined;
135
+ get frameCount(): number;
37
136
  /**
38
- * Resolves once {@link readFrame} would not block: a frame is buffered, or the group has closed.
39
- * Always settles (never hangs), so on a finished group it resolves immediately; pair it with
40
- * {@link done} to avoid re-waiting on a group that has nothing left.
137
+ * Reads the next already-buffered frame without blocking.
138
+ * Treat the returned frame bytes as read-only; they are shared with other consumers.
41
139
  *
42
- * Lets a caller fold "this group has a frame" into a larger wait (e.g. racing it against a new
43
- * group arriving) without touching the group's internal signals.
140
+ * Returns `undefined` when nothing is buffered right now. That is not by itself
141
+ * end-of-group: check {@link done} to tell "no frame buffered yet" from "finished".
44
142
  */
143
+ tryReadFrame(): Frame | undefined;
144
+ /** Like {@link tryReadFrame} but also reports the frame's sequence number within the group. */
145
+ tryReadFrameSequence(): ({
146
+ sequence: number;
147
+ } & Frame) | undefined;
148
+ /** Resolves once {@link readFrame} would not block. */
45
149
  readable(): Promise<void>;
46
150
  /**
47
151
  * Reads the next frame from the group.
48
- * @returns A promise that resolves to the next frame or undefined
152
+ * Treat the returned frame bytes as read-only; they are shared with other consumers.
153
+ */
154
+ readFrame(): Promise<Frame | undefined>;
155
+ /**
156
+ * Reads the next frame along with its sequence number within the group.
157
+ * Treat the returned frame bytes as read-only; they are shared with other consumers.
49
158
  */
50
- readFrame(): Promise<Uint8Array | undefined>;
51
- /** Reads the next frame along with its sequence number within the group. */
52
- readFrameSequence(): Promise<{
159
+ readFrameSequence(options?: ReadOptions): Promise<({
53
160
  sequence: number;
54
- data: Uint8Array;
55
- extensions?: Uint8Array;
56
- } | undefined>;
57
- /** Reads the next frame and decodes it as a UTF-8 string. */
161
+ } & Frame) | undefined>;
162
+ /** Reads the next frame and decodes its payload as a UTF-8 string. */
58
163
  readString(): Promise<string | undefined>;
59
- /** Reads the next frame and parses it as JSON. */
164
+ /** Reads the next frame and parses its payload as JSON. */
60
165
  readJson(): Promise<unknown | undefined>;
61
- /** Reads the next frame and decodes it as a one-byte boolean. */
166
+ /** Reads the next frame and decodes its payload as a one-byte boolean. */
62
167
  readBool(): Promise<boolean | undefined>;
63
- /** Closes the group, optionally with an error to abort readers. */
168
+ /** Closes the group, optionally with an error to abort readers. Idempotent. */
64
169
  close(abort?: Error): void;
65
170
  }
66
171
  //# sourceMappingURL=group.d.ts.map
package/group.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../src/group.ts"],"names":[],"mappings":"AAeA,uFAAuF;AACvF,qBAAa,KAAK;;IACjB,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAM1B,gEAAgE;IAChE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAE5C,YAAY,QAAQ,EAAE,MAAM,EAW3B;IAED;;;OAGG;IACH,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,UAAU,QAQpD;IAED,sDAAsD;IACtD,WAAW,CAAC,GAAG,EAAE,MAAM,QAEtB;IAED,oDAAoD;IACpD,SAAS,CAAC,IAAI,EAAE,OAAO,QAEtB;IAED,kDAAkD;IAClD,SAAS,CAAC,IAAI,EAAE,OAAO,QAEtB;IAED,sGAAsG;IACtG,IAAI,IAAI,IAAI,OAAO,CAElB;IAED;;;;;;;OAOG;IACH,YAAY,IAAI,UAAU,GAAG,SAAS,CAErC;IAED,+FAA+F;IAC/F,oBAAoB,IAAI;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAC;QAAC,UAAU,CAAC,EAAE,UAAU,CAAA;KAAE,GAAG,SAAS,CAKlG;IAED;;;;;;;OAOG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAM9B;IAED;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAEjD;IAED,4EAA4E;IACtE,iBAAiB,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAC;QAAC,UAAU,CAAC,EAAE,UAAU,CAAA;KAAE,GAAG,SAAS,CAAC,CAY9G;IAED,6DAA6D;IACvD,UAAU,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAG9C;IAED,kDAAkD;IAC5C,QAAQ,IAAI,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAG7C;IAED,iEAAiE;IAC3D,QAAQ,IAAI,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAG7C;IAED,mEAAmE;IACnE,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,QAElB;CACD"}
1
+ {"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../src/group.ts"],"names":[],"mappings":"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"}