@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,19 +1,52 @@
1
1
  import * as Path from "../path";
2
2
  import type { Reader, Writer } from "../stream";
3
3
  import { Version } from "./version";
4
+ /**
5
+ * Exclusive model/local cap from a decoded inclusive last group.
6
+ *
7
+ * The wire's `Group End` is inclusive once decoded; the track model and `setGroups` are
8
+ * exclusive. `undefined` stays unbounded.
9
+ */
10
+ export declare function exclusiveGroupEnd(inclusive?: number): number | undefined;
11
+ /** The error for a requested range the wire cannot carry; see {@link emptyRange}. */
12
+ export declare const EMPTY_RANGE = "empty subscription range cannot be encoded";
13
+ /**
14
+ * Inclusive last group a Subscribe message carries, from an exclusive model end.
15
+ *
16
+ * Empty (`0`) cannot be encoded: the wire's 0 means unbounded. Callers refuse an empty
17
+ * requested range with {@link emptyRange} before reaching here.
18
+ */
19
+ export declare function inclusiveGroupEnd(exclusive?: number): number | undefined;
20
+ /**
21
+ * Whether a requested range asks for nothing.
22
+ *
23
+ * The wire has no encoding for one: its bounds are inclusive, so flooring the end would
24
+ * either hand back the group the caller excluded (0 means unbounded) or invert the
25
+ * range once the two bounds meet. An absent start is the live edge, so it only empties
26
+ * the range when the end is 0.
27
+ */
28
+ export declare function emptyRange({ startGroup, endGroup }: {
29
+ startGroup?: number;
30
+ endGroup?: number;
31
+ }): boolean;
4
32
  export declare class SubscribeUpdate {
5
33
  #private;
6
34
  priority: number;
7
- ordered: boolean;
8
- maxLatency: number;
35
+ /** Subscriber max latency in milliseconds; zero skips once a newer group is available. */
36
+ maxAge: number;
9
37
  startGroup?: number;
10
38
  endGroup?: number;
39
+ /** See {@link Subscribe.startFrame}. */
40
+ startFrame: number;
41
+ /** See {@link Subscribe.endFrame}. */
42
+ endFrame?: number;
11
43
  constructor(props: {
12
44
  priority: number;
13
- ordered?: boolean;
14
- maxLatency?: number;
45
+ maxAge?: number;
15
46
  startGroup?: number;
16
47
  endGroup?: number;
48
+ startFrame?: number;
49
+ endFrame?: number;
17
50
  });
18
51
  encode(w: Writer, version: Version): Promise<void>;
19
52
  static decode(r: Reader, version: Version): Promise<SubscribeUpdate>;
@@ -25,19 +58,31 @@ export declare class Subscribe {
25
58
  broadcast: Path.Valid;
26
59
  track: string;
27
60
  priority: number;
28
- ordered: boolean;
29
- maxLatency: number;
61
+ /** Subscriber max latency in milliseconds; zero skips once a newer group is available. */
62
+ maxAge: number;
30
63
  startGroup?: number;
31
64
  endGroup?: number;
65
+ /**
66
+ * First frame to deliver within `startGroup`'s group; 0 is the whole group.
67
+ * Lite-06+. It qualifies the named group, so it needs `startGroup` to name one
68
+ * (defined, including 0: group 0 can host a mid-group resume).
69
+ */
70
+ startFrame: number;
71
+ /**
72
+ * Last frame to deliver (inclusive) within `endGroup`'s group, or undefined for the
73
+ * whole group. Lite-06+, and meaningless without an explicit `endGroup`.
74
+ */
75
+ endFrame?: number;
32
76
  constructor(props: {
33
77
  id: bigint;
34
78
  broadcast: Path.Valid;
35
79
  track: string;
36
80
  priority: number;
37
- ordered?: boolean;
38
- maxLatency?: number;
81
+ maxAge?: number;
39
82
  startGroup?: number;
40
83
  endGroup?: number;
84
+ startFrame?: number;
85
+ endFrame?: number;
41
86
  });
42
87
  encode(w: Writer, version: Version): Promise<void>;
43
88
  static decode(r: Reader, version: Version): Promise<Subscribe>;
@@ -51,14 +96,13 @@ export declare class Subscribe {
51
96
  export declare class SubscribeOk {
52
97
  #private;
53
98
  priority: number;
54
- ordered: boolean;
55
- maxLatency: number;
99
+ /** Accepted subscriber max latency in milliseconds. */
100
+ maxAge: number;
56
101
  startGroup?: number;
57
102
  endGroup?: number;
58
- constructor({ priority, ordered, maxLatency, startGroup, endGroup, }: {
103
+ constructor({ priority, maxAge, startGroup, endGroup, }: {
59
104
  priority?: number;
60
- ordered?: boolean;
61
- maxLatency?: number;
105
+ maxAge?: number;
62
106
  startGroup?: number;
63
107
  endGroup?: number;
64
108
  });
@@ -69,6 +113,10 @@ export declare class SubscribeOk {
69
113
  * Resolves the absolute start group of a Draft-05+ subscription. The first message
70
114
  * the publisher sends, once the start group is known. A value greater than the
71
115
  * requested start implicitly drops the leading range.
116
+ *
117
+ * There is no start frame: a partial group is only served to a subscriber that asked
118
+ * for one, so delivery begins either at the requested `startFrame` (when this is the
119
+ * requested group) or at frame 0 (when the publisher resolved to a later one).
72
120
  */
73
121
  export declare class SubscribeStart {
74
122
  group: number;
@@ -83,9 +131,14 @@ export declare class SubscribeStart {
83
131
  export declare class SubscribeEnd {
84
132
  /** The exclusive final group sequence: the first sequence that will never be produced. */
85
133
  group: number;
86
- constructor(group: number);
87
- encode(w: Writer): Promise<void>;
88
- static decode(r: Reader): Promise<SubscribeEnd>;
134
+ /**
135
+ * The number of group streams the publisher opened for this subscription.
136
+ * Draft-07+ only; not on the wire before, where it decodes as 0.
137
+ */
138
+ streams: number;
139
+ constructor(group: number, streams?: number);
140
+ encode(w: Writer, version: Version): Promise<void>;
141
+ static decode(r: Reader, version: Version): Promise<SubscribeEnd>;
89
142
  }
90
143
  export declare class SubscribeDrop {
91
144
  #private;
@@ -106,8 +159,9 @@ export declare class SubscribeDrop {
106
159
  *
107
160
  * The discriminator is version-dependent:
108
161
  * - Draft-03/04: `0x0` SUBSCRIBE_OK, `0x1` SUBSCRIBE_DROP.
109
- * - Draft-05+: `0x0` SUBSCRIBE_START, `0x1` SUBSCRIBE_END, `0x2` SUBSCRIBE_DROP
162
+ * - Draft-05/06: `0x0` SUBSCRIBE_START, `0x1` SUBSCRIBE_END, `0x2` SUBSCRIBE_DROP
110
163
  * (SUBSCRIBE_OK was removed; acceptance is implicit).
164
+ * - Draft-07+: `0x0` SUBSCRIBE_START, `0x1` SUBSCRIBE_END (SUBSCRIBE_DROP was removed).
111
165
  */
112
166
  export type SubscribeResponse = {
113
167
  ok: SubscribeOk;
@@ -1 +1 @@
1
- {"version":3,"file":"subscribe.d.ts","sourceRoot":"","sources":["../../src/lite/subscribe.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"subscribe.d.ts","sourceRoot":"","sources":["../../src/lite/subscribe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAgE,OAAO,EAAE,MAAM,cAAc,CAAC;AA2GrG;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAExE;AAED,qFAAqF;AACrF,eAAO,MAAM,WAAW,+CAA+C,CAAC;AAExE;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIxE;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAExG;AAED,qBAAa,eAAe;;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,0FAA0F;IAC1F,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,YAAY,KAAK,EAAE;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,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,CAEvD;IAED,OAAa,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CAEzE;IAED,OAAa,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAE1F;CACD;AAED,qBAAa,SAAS;;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,0FAA0F;IAC1F,MAAM,EAAE,MAAM,CAAC;IAEf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,YAAY,KAAK,EAAE;QAClB,EAAE,EAAE,MAAM,CAAC;QACX,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC;QACtB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;KAClB,EAUA;IAqDK,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,SAAS,CAAC,CAEnE;CACD;AAED;;;;;GAKG;AACH,qBAAa,WAAW;;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,YAAY,EACX,QAAY,EACZ,MAAU,EACV,UAAsB,EACtB,QAAoB,GACpB,EAAE;QACF,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;KAClB,EAKA;IAoDK,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,WAAW,CAAC,CAErE;CACD;AAED;;;;;;;;GAQG;AACH,qBAAa,cAAc;IAC1B,KAAK,EAAE,MAAM,CAAC;IAEd,YAAY,KAAK,EAAE,MAAM,EAExB;IAEK,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIrC;IAED,OAAa,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAEtD;CACD;AAED;;;GAGG;AACH,qBAAa,YAAY;IACxB,0FAA0F;IAC1F,KAAK,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB,YAAY,KAAK,EAAE,MAAM,EAAE,OAAO,SAAI,EAGrC;IAEK,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAKvD;IAED,OAAa,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAKtE;CACD;AAKD,qBAAa,aAAa;;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IAEd,YAAY,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAI/D;IAYK,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAErC;IAED,OAAa,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAErD;CACD;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GAC1B;IAAE,EAAE,EAAE,WAAW,CAAA;CAAE,GACnB;IAAE,KAAK,EAAE,cAAc,CAAA;CAAE,GACzB;IAAE,GAAG,EAAE,YAAY,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC;AAE3B,wBAAsB,uBAAuB,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAsCjH;AAED,wBAAsB,uBAAuB,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAgCrG;AAED,oFAAoF;AACpF,wBAAsB,4BAA4B,CACjD,CAAC,EAAE,MAAM,EACT,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAGxC"}
package/lite/subscribe.js CHANGED
@@ -1,19 +1,142 @@
1
1
  /* @ts-self-types="./subscribe.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, hasGroupOrder, hasStreamCount, resolvesStart, Version } from "./version.js";
5
+ /**
6
+ * Encode the `Group Start` field shared by SUBSCRIBE and SUBSCRIBE_UPDATE.
7
+ *
8
+ * Lite-06 writes the raw floor (`undefined` and 0 are the same absence of a constraint),
9
+ * while a pre-06 wire encodes the sequence + 1 and gets a vacuous floor folded back to
10
+ * absent: an explicit group 0 there means "replay from the beginning", which is not what
11
+ * a floor of 0 asks for.
12
+ */
13
+ async function encodeStartGroup(w, version, startGroup) {
14
+ if (resolvesStart(version)) {
15
+ await w.u53(startGroup ?? 0);
16
+ return;
17
+ }
18
+ await w.u53(startGroup !== undefined && startGroup > 0 ? startGroup + 1 : 0);
19
+ }
20
+ /**
21
+ * Decode the `Group Start` field shared by SUBSCRIBE and SUBSCRIBE_UPDATE.
22
+ *
23
+ * The inverse of {@link encodeStartGroup}. Callers canonicalize with
24
+ * {@link canonicalStartGroup} once the frame bounds are known.
25
+ */
26
+ async function decodeStartGroup(r, version) {
27
+ const value = await r.u53();
28
+ if (resolvesStart(version))
29
+ return value;
30
+ return value > 0 ? value - 1 : undefined;
31
+ }
32
+ /**
33
+ * Canonicalize a decoded floor: a lite-06 `Group Start` of 0 with no frame offset is the
34
+ * same absence of a constraint as no floor at all, so it decodes as undefined. Group 0
35
+ * stays named only when a `Frame Start` actually qualifies it (a subscription can resume
36
+ * partway through group 0: a catalog never leaves it).
37
+ */
38
+ function canonicalStartGroup(version, startGroup, startFrame) {
39
+ if (resolvesStart(version) && startGroup === 0 && startFrame === 0)
40
+ return undefined;
41
+ return startGroup;
42
+ }
43
+ /**
44
+ * Encode the trailing `Frame Start` / `Frame End` pair shared by SUBSCRIBE and
45
+ * SUBSCRIBE_UPDATE. A no-op before lite-06, which has nowhere to put them.
46
+ */
47
+ async function encodeFrameBounds(w, version, { startGroup, startFrame, endGroup, endFrame, }) {
48
+ if ((startFrame !== 0 && startGroup === undefined) || (endFrame !== undefined && endGroup === undefined)) {
49
+ throw new Error("frame bound without a group bound");
50
+ }
51
+ if (!hasFrameBounds(version)) {
52
+ // Silently widening to the whole group would deliver frames we excluded.
53
+ if (startFrame !== 0 || endFrame !== undefined) {
54
+ throw new Error("frame bounds not supported for this version");
55
+ }
56
+ return;
57
+ }
58
+ await w.u53(startFrame);
59
+ await w.u53(endFrame !== undefined ? endFrame + 1 : 0);
60
+ }
61
+ /**
62
+ * Decode the trailing `Frame Start` / `Frame End` pair, defaulting to the whole group.
63
+ *
64
+ * A frame bound without the group bound it qualifies is a protocol violation: frames
65
+ * are numbered per group, so there is nothing to count from.
66
+ */
67
+ async function decodeFrameBounds(r, version, startGroup, endGroup) {
68
+ if (!hasFrameBounds(version)) {
69
+ return { startFrame: 0 };
70
+ }
71
+ const startFrame = await r.u53();
72
+ const endFrame = await r.u53();
73
+ if ((startFrame !== 0 && startGroup === undefined) || (endFrame !== 0 && endGroup === undefined)) {
74
+ throw new Error("frame bound without a group bound");
75
+ }
76
+ return { startFrame, endFrame: endFrame > 0 ? endFrame - 1 : undefined };
77
+ }
78
+ /** Step over the retired `Ordered` byte on a version whose layout still has it. */
79
+ async function skipGroupOrder(r, version) {
80
+ if (hasGroupOrder(version))
81
+ await r.bool();
82
+ }
83
+ /** Write the retired `Ordered` byte as 0, keeping a deployed version's field offsets. */
84
+ async function padGroupOrder(w, version) {
85
+ if (hasGroupOrder(version))
86
+ await w.bool(false);
87
+ }
88
+ /**
89
+ * Exclusive model/local cap from a decoded inclusive last group.
90
+ *
91
+ * The wire's `Group End` is inclusive once decoded; the track model and `setGroups` are
92
+ * exclusive. `undefined` stays unbounded.
93
+ */
94
+ export function exclusiveGroupEnd(inclusive) {
95
+ return inclusive === undefined ? undefined : inclusive + 1;
96
+ }
97
+ /** The error for a requested range the wire cannot carry; see {@link emptyRange}. */
98
+ export const EMPTY_RANGE = "empty subscription range cannot be encoded";
99
+ /**
100
+ * Inclusive last group a Subscribe message carries, from an exclusive model end.
101
+ *
102
+ * Empty (`0`) cannot be encoded: the wire's 0 means unbounded. Callers refuse an empty
103
+ * requested range with {@link emptyRange} before reaching here.
104
+ */
105
+ export function inclusiveGroupEnd(exclusive) {
106
+ if (exclusive === undefined)
107
+ return undefined;
108
+ if (exclusive === 0)
109
+ throw new Error(EMPTY_RANGE);
110
+ return exclusive - 1;
111
+ }
112
+ /**
113
+ * Whether a requested range asks for nothing.
114
+ *
115
+ * The wire has no encoding for one: its bounds are inclusive, so flooring the end would
116
+ * either hand back the group the caller excluded (0 means unbounded) or invert the
117
+ * range once the two bounds meet. An absent start is the live edge, so it only empties
118
+ * the range when the end is 0.
119
+ */
120
+ export function emptyRange({ startGroup, endGroup }) {
121
+ return endGroup !== undefined && (startGroup ?? 0) >= endGroup;
122
+ }
5
123
  export class SubscribeUpdate {
6
124
  priority;
7
- ordered;
8
- maxLatency;
125
+ /** Subscriber max latency in milliseconds; zero skips once a newer group is available. */
126
+ maxAge;
9
127
  startGroup;
10
128
  endGroup;
129
+ /** See {@link Subscribe.startFrame}. */
130
+ startFrame;
131
+ /** See {@link Subscribe.endFrame}. */
132
+ endFrame;
11
133
  constructor(props) {
12
134
  this.priority = props.priority;
13
- this.ordered = props.ordered ?? false;
14
- this.maxLatency = props.maxLatency ?? 0;
135
+ this.maxAge = props.maxAge ?? 0;
15
136
  this.startGroup = props.startGroup;
16
137
  this.endGroup = props.endGroup;
138
+ this.startFrame = props.startFrame ?? 0;
139
+ this.endFrame = props.endFrame;
17
140
  }
18
141
  async #encode(w, version) {
19
142
  switch (version) {
@@ -23,10 +146,11 @@ export class SubscribeUpdate {
23
146
  break;
24
147
  default:
25
148
  await w.u8(this.priority);
26
- await w.bool(this.ordered);
27
- await w.u53(this.maxLatency);
28
- await w.u53(this.startGroup !== undefined ? this.startGroup + 1 : 0);
149
+ await padGroupOrder(w, version);
150
+ await w.u53(this.maxAge);
151
+ await encodeStartGroup(w, version, this.startGroup);
29
152
  await w.u53(this.endGroup !== undefined ? this.endGroup + 1 : 0);
153
+ await encodeFrameBounds(w, version, this);
30
154
  break;
31
155
  }
32
156
  }
@@ -37,16 +161,18 @@ export class SubscribeUpdate {
37
161
  return new SubscribeUpdate({ priority: await r.u8() });
38
162
  default: {
39
163
  const priority = await r.u8();
40
- const ordered = await r.bool();
41
- const maxLatency = await r.u53();
42
- const startGroup = await r.u53();
43
- const endGroup = await r.u53();
164
+ await skipGroupOrder(r, version);
165
+ const maxAge = await r.u53();
166
+ const startGroup = await decodeStartGroup(r, version);
167
+ const endGroup = (await r.u53()) || undefined;
168
+ const end = endGroup !== undefined ? endGroup - 1 : undefined;
169
+ const frames = await decodeFrameBounds(r, version, startGroup, end);
44
170
  return new SubscribeUpdate({
45
171
  priority,
46
- ordered,
47
- maxLatency,
48
- startGroup: startGroup > 0 ? startGroup - 1 : undefined,
49
- endGroup: endGroup > 0 ? endGroup - 1 : undefined,
172
+ maxAge,
173
+ startGroup: canonicalStartGroup(version, startGroup, frames.startFrame),
174
+ endGroup: end,
175
+ ...frames,
50
176
  });
51
177
  }
52
178
  }
@@ -66,19 +192,31 @@ export class Subscribe {
66
192
  broadcast;
67
193
  track;
68
194
  priority;
69
- ordered;
70
- maxLatency;
195
+ /** Subscriber max latency in milliseconds; zero skips once a newer group is available. */
196
+ maxAge;
71
197
  startGroup;
72
198
  endGroup;
199
+ /**
200
+ * First frame to deliver within `startGroup`'s group; 0 is the whole group.
201
+ * Lite-06+. It qualifies the named group, so it needs `startGroup` to name one
202
+ * (defined, including 0: group 0 can host a mid-group resume).
203
+ */
204
+ startFrame;
205
+ /**
206
+ * Last frame to deliver (inclusive) within `endGroup`'s group, or undefined for the
207
+ * whole group. Lite-06+, and meaningless without an explicit `endGroup`.
208
+ */
209
+ endFrame;
73
210
  constructor(props) {
74
211
  this.id = props.id;
75
212
  this.broadcast = props.broadcast;
76
213
  this.track = props.track;
77
214
  this.priority = props.priority;
78
- this.ordered = props.ordered ?? false;
79
- this.maxLatency = props.maxLatency ?? 0;
215
+ this.maxAge = props.maxAge ?? 0;
80
216
  this.startGroup = props.startGroup;
81
217
  this.endGroup = props.endGroup;
218
+ this.startFrame = props.startFrame ?? 0;
219
+ this.endFrame = props.endFrame;
82
220
  }
83
221
  async #encode(w, version) {
84
222
  await w.u62(this.id);
@@ -90,10 +228,11 @@ export class Subscribe {
90
228
  case Version.DRAFT_02:
91
229
  break;
92
230
  default:
93
- await w.bool(this.ordered);
94
- await w.u53(this.maxLatency);
95
- await w.u53(this.startGroup !== undefined ? this.startGroup + 1 : 0);
231
+ await padGroupOrder(w, version);
232
+ await w.u53(this.maxAge);
233
+ await encodeStartGroup(w, version, this.startGroup);
96
234
  await w.u53(this.endGroup !== undefined ? this.endGroup + 1 : 0);
235
+ await encodeFrameBounds(w, version, this);
97
236
  break;
98
237
  }
99
238
  }
@@ -107,19 +246,21 @@ export class Subscribe {
107
246
  case Version.DRAFT_02:
108
247
  return new Subscribe({ id, broadcast, track, priority });
109
248
  default: {
110
- const ordered = await r.bool();
111
- const maxLatency = await r.u53();
112
- const startGroup = await r.u53();
113
- const endGroup = await r.u53();
249
+ await skipGroupOrder(r, version);
250
+ const maxAge = await r.u53();
251
+ const startGroup = await decodeStartGroup(r, version);
252
+ const endGroup = (await r.u53()) || undefined;
253
+ const end = endGroup !== undefined ? endGroup - 1 : undefined;
254
+ const frames = await decodeFrameBounds(r, version, startGroup, end);
114
255
  return new Subscribe({
115
256
  id,
116
257
  broadcast,
117
258
  track,
118
259
  priority,
119
- ordered,
120
- maxLatency,
121
- startGroup: startGroup > 0 ? startGroup - 1 : undefined,
122
- endGroup: endGroup > 0 ? endGroup - 1 : undefined,
260
+ maxAge,
261
+ startGroup: canonicalStartGroup(version, startGroup, frames.startFrame),
262
+ endGroup: end,
263
+ ...frames,
123
264
  });
124
265
  }
125
266
  }
@@ -139,14 +280,13 @@ export class Subscribe {
139
280
  */
140
281
  export class SubscribeOk {
141
282
  priority;
142
- ordered;
143
- maxLatency;
283
+ /** Accepted subscriber max latency in milliseconds. */
284
+ maxAge;
144
285
  startGroup;
145
286
  endGroup;
146
- constructor({ priority = 0, ordered = false, maxLatency = 0, startGroup = undefined, endGroup = undefined, }) {
287
+ constructor({ priority = 0, maxAge = 0, startGroup = undefined, endGroup = undefined, }) {
147
288
  this.priority = priority;
148
- this.ordered = ordered;
149
- this.maxLatency = maxLatency;
289
+ this.maxAge = maxAge;
150
290
  this.startGroup = startGroup;
151
291
  this.endGroup = endGroup;
152
292
  }
@@ -162,8 +302,8 @@ export class SubscribeOk {
162
302
  // Draft-03/04 so a stray future use stays well-formed.
163
303
  default:
164
304
  await w.u8(this.priority);
165
- await w.bool(this.ordered);
166
- await w.u53(this.maxLatency);
305
+ await padGroupOrder(w, version);
306
+ await w.u53(this.maxAge);
167
307
  await w.u53(this.startGroup !== undefined ? this.startGroup + 1 : 0);
168
308
  await w.u53(this.endGroup !== undefined ? this.endGroup + 1 : 0);
169
309
  break;
@@ -171,8 +311,7 @@ export class SubscribeOk {
171
311
  }
172
312
  static async #decode(version, r) {
173
313
  let priority;
174
- let ordered;
175
- let maxLatency;
314
+ let maxAge;
176
315
  let startGroup;
177
316
  let endGroup;
178
317
  switch (version) {
@@ -184,16 +323,15 @@ export class SubscribeOk {
184
323
  break;
185
324
  default:
186
325
  priority = await r.u8();
187
- ordered = await r.bool();
188
- maxLatency = await r.u53();
326
+ await skipGroupOrder(r, version);
327
+ maxAge = await r.u53();
189
328
  startGroup = await r.u53();
190
329
  endGroup = await r.u53();
191
330
  break;
192
331
  }
193
332
  return new SubscribeOk({
194
333
  priority,
195
- ordered,
196
- maxLatency,
334
+ maxAge,
197
335
  startGroup: startGroup !== undefined && startGroup > 0 ? startGroup - 1 : undefined,
198
336
  endGroup: endGroup !== undefined && endGroup > 0 ? endGroup - 1 : undefined,
199
337
  });
@@ -209,6 +347,10 @@ export class SubscribeOk {
209
347
  * Resolves the absolute start group of a Draft-05+ subscription. The first message
210
348
  * the publisher sends, once the start group is known. A value greater than the
211
349
  * requested start implicitly drops the leading range.
350
+ *
351
+ * There is no start frame: a partial group is only served to a subscriber that asked
352
+ * for one, so delivery begins either at the requested `startFrame` (when this is the
353
+ * requested group) or at frame 0 (when the publisher resolved to a later one).
212
354
  */
213
355
  export class SubscribeStart {
214
356
  group;
@@ -231,21 +373,29 @@ export class SubscribeStart {
231
373
  export class SubscribeEnd {
232
374
  /** The exclusive final group sequence: the first sequence that will never be produced. */
233
375
  group;
234
- constructor(group) {
376
+ /**
377
+ * The number of group streams the publisher opened for this subscription.
378
+ * Draft-07+ only; not on the wire before, where it decodes as 0.
379
+ */
380
+ streams;
381
+ constructor(group, streams = 0) {
235
382
  this.group = group;
383
+ this.streams = streams;
236
384
  }
237
- async encode(w) {
385
+ async encode(w, version) {
238
386
  return Message.encode(w, async (w) => {
239
387
  await w.u53(this.group);
388
+ if (hasStreamCount(version))
389
+ await w.u53(this.streams);
240
390
  });
241
391
  }
242
- static async decode(r) {
243
- return Message.decode(r, async (r) => new SubscribeEnd(await r.u53()));
392
+ static async decode(r, version) {
393
+ return Message.decode(r, async (r) => new SubscribeEnd(await r.u53(), hasStreamCount(version) ? await r.u53() : 0));
244
394
  }
245
395
  }
246
396
  /// Indicates that one or more groups have been dropped.
247
397
  ///
248
- /// Draft03+ only.
398
+ /// Draft-03 to Draft-06 only: Draft-07 counts group streams in SUBSCRIBE_END instead.
249
399
  export class SubscribeDrop {
250
400
  start;
251
401
  end;
@@ -303,14 +453,14 @@ export async function encodeSubscribeResponse(w, resp, version) {
303
453
  }
304
454
  else if ("end" in resp) {
305
455
  await w.u53(0x1);
306
- await resp.end.encode(w);
456
+ await resp.end.encode(w, version);
307
457
  }
308
- else if ("drop" in resp) {
458
+ else if ("drop" in resp && !hasStreamCount(version)) {
309
459
  await w.u53(0x2);
310
460
  await resp.drop.encode(w);
311
461
  }
312
462
  else {
313
- throw new Error("SUBSCRIBE_OK not supported for this version");
463
+ throw new Error("subscribe response not supported for this version");
314
464
  }
315
465
  break;
316
466
  }
@@ -338,8 +488,10 @@ export async function decodeSubscribeResponse(r, version) {
338
488
  case 0x0:
339
489
  return { start: await SubscribeStart.decode(r) };
340
490
  case 0x1:
341
- return { end: await SubscribeEnd.decode(r) };
491
+ return { end: await SubscribeEnd.decode(r, version) };
342
492
  case 0x2:
493
+ if (hasStreamCount(version))
494
+ throw new Error(`unknown subscribe response type: ${typ}`);
343
495
  return { drop: await SubscribeDrop.decode(r) };
344
496
  default:
345
497
  throw new Error(`unknown subscribe response type: ${typ}`);